diff --git a/modules/type/blocks/dap_chain_block_cache.c b/modules/type/blocks/dap_chain_block_cache.c index 98c58befea309b449f248bffc228d486bd53d2b7..685e736fca54f309a9857a905949908f484545b6 100644 --- a/modules/type/blocks/dap_chain_block_cache.c +++ b/modules/type/blocks/dap_chain_block_cache.c @@ -92,6 +92,46 @@ void dap_chain_block_cache_update(dap_chain_block_cache_t * a_block_cache) 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 ); + a_block_cache->meta = dap_chain_block_get_meta (a_block_cache->block, a_block_cache->block_size, &a_block_cache->meta_count); + + dap_chain_block_meta_extract( a_block_cache->meta,a_block_cache->meta_count, + &a_block_cache->prev_hash, + &a_block_cache->anchor_hash, + &a_block_cache->links_hash, + &a_block_cache->links_hash_count, + &a_block_cache->is_genesis, + &a_block_cache->nonce, + &a_block_cache->nonce2 + ); + + for (size_t i = 0; i< a_block_cache->datum_count; i++){ + dap_chain_datum_t * l_datum = a_block_cache->datum[i]; + if ( l_datum && l_datum->header.data_size && l_datum->header.type_id == DAP_CHAIN_DATUM_TX){ + dap_chain_hash_fast_t l_tx_hash; + dap_chain_block_cache_tx_index_t * l_tx_index = NULL; + dap_hash_fast(l_datum->data,l_datum->header.data_size, &l_tx_hash); + HASH_FIND(hh, a_block_cache->tx_index, &l_tx_hash, sizeof (l_tx_hash), l_tx_index); + if ( ! l_tx_index ){ + l_tx_index = DAP_NEW_Z(dap_chain_block_cache_tx_index_t); + memcpy(&l_tx_index->tx_hash,&l_tx_hash, sizeof (l_tx_hash) ); + l_tx_index->tx =(dap_chain_datum_tx_t*) l_datum->data; + HASH_ADD(hh, a_block_cache->tx_index, tx_hash, sizeof (l_tx_hash), l_tx_index); + } + } + } +} + +/** + * @brief dap_chain_block_cache_get_tx_by_hash + * @param a_block_cache + * @param a_tx_hash + * @return + */ +dap_chain_datum_tx_t* dap_chain_block_cache_get_tx_by_hash (dap_chain_block_cache_t * a_block_cache, dap_chain_hash_fast_t * a_tx_hash) +{ + dap_chain_block_cache_tx_index_t * l_tx_index = NULL; + HASH_FIND(hh, a_block_cache->tx_index, a_tx_hash,sizeof (*a_tx_hash), l_tx_index); + return l_tx_index? l_tx_index->tx : NULL; } /** @@ -103,3 +143,4 @@ void dap_chain_block_cache_delete(dap_chain_block_cache_t * a_block_cache) DAP_DELETE(a_block_cache); log_it(L_DEBUG,"Block cache deleted"); } + diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 9c245fc597c827b5476eb2a2a1bbf800fd0fee5c..d02ba6150202f33350873de83363c62dc7c9b0ec 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -72,6 +72,7 @@ typedef struct dap_chain_cs_blocks_pvt typedef struct dap_chain_cs_blocks_iter { dap_chain_cs_blocks_t * blocks; + dap_chain_block_cache_t * cache; } dap_chain_cs_blocks_iter_t; #define PVT(a) ((dap_chain_cs_blocks_pvt_t *) a->_pvt ) @@ -812,6 +813,8 @@ 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); + ITER_PVT(l_atom_iter)->blocks = DAP_CHAIN_CS_BLOCKS(a_chain); + return l_atom_iter; } @@ -824,7 +827,19 @@ static dap_chain_atom_iter_t* s_callback_atom_iter_create(dap_chain_t * a_chain */ static dap_chain_atom_iter_t* s_callback_atom_iter_create_from(dap_chain_t * a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size) { - + if (a_atom && a_atom_size){ + dap_chain_hash_fast_t l_atom_hash; + dap_hash_fast(a_atom, a_atom_size, &l_atom_hash); + dap_chain_atom_iter_t * l_atom_iter = s_callback_atom_iter_create(a_chain); + if (l_atom_iter){ + l_atom_iter->cur_item =ITER_PVT(l_atom_iter)->cache = dap_chain_block_cache_get_by_hash(l_atom_hash); + l_atom_iter->cur = a_atom; + l_atom_iter->cur_size = a_atom_size; + return l_atom_iter; + }else + return NULL; + }else + return NULL; } /** @@ -837,7 +852,18 @@ static dap_chain_atom_iter_t* s_callback_atom_iter_create_from(dap_chain_t * a_c 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) { - + assert(a_atom_iter); + dap_chain_atom_ptr_t * l_ret = NULL; + pthread_rwlock_rdlock(& PVT(ITER_PVT(a_atom_iter)->blocks)->rwlock ); + dap_chain_block_cache_t * l_block_cache = NULL; + HASH_FIND(hh, PVT(ITER_PVT(a_atom_iter)->blocks)->blocks, a_atom_hash,sizeof (*a_atom_hash), l_block_cache); + a_atom_iter->cur_item = l_block_cache; + if (l_block_cache){ + l_ret = a_atom_iter->cur = l_block_cache->block; + *a_atom_size = a_atom_iter->cur_size = l_block_cache->block_size; + } + pthread_rwlock_unlock(& PVT(ITER_PVT(a_atom_iter)->blocks)->rwlock ); + return l_ret; } /** @@ -848,7 +874,17 @@ static dap_chain_atom_ptr_t s_callback_atom_iter_find_by_hash(dap_chain_atom_ite */ 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) { - + dap_chain_cs_blocks_t * l_cs_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); + dap_chain_tx_block_index_t * l_tx_block_index = NULL; + HASH_FIND(hh, PVT(l_cs_blocks)->tx_block_index,a_tx_hash, sizeof (*a_tx_hash), l_tx_block_index); + if (l_tx_block_index){ + dap_chain_block_cache_t * l_block_cache = dap_chain_block_cache_get_by_hash( l_tx_block_index->block_hash ); + if ( l_block_cache){ + return dap_chain_block_cache_get_tx_by_hash(l_block_cache, a_tx_hash); + }else + return NULL; + }else + return NULL; } /** diff --git a/modules/type/blocks/include/dap_chain_block_cache.h b/modules/type/blocks/include/dap_chain_block_cache.h index 1018855d18035598ee0e4660b5c32de2f1c6a1bc..0aa35e3cb7894a6e91577bf1de664f6a88c28e75 100644 --- a/modules/type/blocks/include/dap_chain_block_cache.h +++ b/modules/type/blocks/include/dap_chain_block_cache.h @@ -22,10 +22,18 @@ */ #pragma once #include "dap_chain_block.h" +#include "dap_chain_datum_tx.h" #include "dap_sign.h" #include "dap_hash.h" #include "uthash.h" +typedef struct dap_chain_block_cache_tx_index +{ + dap_chain_hash_fast_t tx_hash; + dap_chain_datum_tx_t* tx; + UT_hash_handle hh; +} dap_chain_block_cache_tx_index_t; + typedef struct dap_chain_block_cache{ // Block's general non-nested attributes dap_chain_hash_fast_t block_hash; @@ -38,11 +46,22 @@ typedef struct dap_chain_block_cache{ // Block's datums size_t datum_count; dap_chain_datum_t ** datum; + dap_chain_block_cache_tx_index_t * tx_index; // Block's metadatas - uint32_t meta_count; + 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* links_hash; + size_t links_hash_count; + + uint64_t nonce; + uint64_t nonce2; + bool is_genesis; + // Block's signatures size_t sign_count; // Number of signatures in block's tail dap_sign_t ** sign; // Pointer to signatures in block @@ -50,6 +69,8 @@ typedef struct dap_chain_block_cache{ // Pointer to block itself dap_chain_block_t * block; + + // Inhertied nested data void * _inheritor; @@ -65,3 +86,5 @@ dap_chain_block_cache_t * dap_chain_block_cache_new(dap_chain_block_t * a_block, dap_chain_block_cache_t * dap_chain_block_cache_dup(dap_chain_block_cache_t * a_block); void dap_chain_block_cache_update(dap_chain_block_cache_t * a_block_cache); void dap_chain_block_cache_delete(dap_chain_block_cache_t * a_block_cache); +dap_chain_datum_tx_t* dap_chain_block_cache_get_tx_by_hash (dap_chain_block_cache_t * a_block_cache, dap_chain_hash_fast_t * a_tx_hash); +