diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index 6786fcbe1f958c8e8ddecbeff500cdad8e80df7e..f68cc9d280414fe37020a9c9827d850746b08b61 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -5374,6 +5374,68 @@ uint256_t dap_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_cha return l_ret_value; } +dap_ledger_datum_iter_t *dap_ledger_datum_iter_create(dap_chain_net_t *a_net) +{ + dap_ledger_datum_iter_t *l_ret = DAP_NEW_Z(dap_ledger_datum_iter_t); + if(!l_ret){ + log_it(L_CRITICAL, "Memory allocation error!"); + return NULL; + } + l_ret->net = a_net; + return l_ret; +} + +void dap_ledger_datum_iter_delete(dap_ledger_datum_iter_t *a_iter) +{ + DAP_DELETE(a_iter); +} + +dap_chain_datum_tx_t *dap_ledger_datum_iter_get_first(dap_ledger_datum_iter_t *a_iter) +{ + dap_ledger_private_t *l_ledger_pvt = PVT(a_iter->net->pub.ledger); + pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); + a_iter->cur_ledger_tx_item = l_ledger_pvt->ledger_items; + a_iter->cur = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx; + a_iter->cur_hash = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx_hash_fast; + a_iter->is_unspent = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->cache_data.ts_spent ? false : true; + a_iter->ret_code = 0; + pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); + return a_iter->cur; +} + +dap_chain_datum_tx_t *dap_ledger_datum_iter_get_next(dap_ledger_datum_iter_t *a_iter) +{ + dap_ledger_private_t *l_ledger_pvt = PVT(a_iter->net->pub.ledger); + pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); + a_iter->cur_ledger_tx_item = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->hh.next; + if (a_iter->cur_ledger_tx_item){ + a_iter->cur = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx; + a_iter->cur_hash = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx_hash_fast; + a_iter->ret_code = 0; + a_iter->is_unspent = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->cache_data.ts_spent ? false : true; + } else { + a_iter->cur = NULL; + memset(&a_iter->cur_hash, 0, sizeof(dap_hash_fast_t)); + a_iter->ret_code = 0; + a_iter->is_unspent = false; + } + pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); + return a_iter->cur; +} + +dap_chain_datum_tx_t *dap_ledger_datum_iter_get_last(dap_ledger_datum_iter_t *a_iter) +{ + dap_ledger_private_t *l_ledger_pvt = PVT(a_iter->net->pub.ledger); + pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); + a_iter->cur_ledger_tx_item = l_ledger_pvt->ledger_items->hh.prev; + a_iter->cur = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx; + a_iter->cur_hash = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx_hash_fast; + a_iter->is_unspent = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->cache_data.ts_spent ? false : true; + a_iter->ret_code = 0; + pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); + return a_iter->cur; +} + /** * @brief dap_ledger_get_list_tx_outs_with_val * @param a_ledger diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index ab49811d50dac2f171eae90fd44ce3fc88ac4b07..561878d9bf5350ded688591f114eb19906dd77f4 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -47,7 +47,7 @@ typedef struct cond_all_by_srv_uid_arg{ dap_time_t time_to; } cond_all_by_srv_uid_arg_t; -static void s_tx_cond_all_with_spends_by_srv_uid_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, void *a_arg) +static void s_tx_cond_all_with_spends_by_srv_uid_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg) { cond_all_with_spends_by_srv_uid_arg_t *l_arg = (cond_all_with_spends_by_srv_uid_arg_t*)a_arg; dap_chain_datum_tx_t *l_tx = a_tx; @@ -83,7 +83,7 @@ static void s_tx_cond_all_with_spends_by_srv_uid_callback(dap_chain_net_t* a_net } size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); dap_chain_datum_tx_t * l_tx_dup = DAP_DUP_SIZE(l_tx,l_tx_size); - dap_hash_fast(l_tx_dup,l_tx_size, &l_item_in->tx_hash); + l_item_in->tx_hash = *a_tx_hash; l_item_in->tx = l_tx_dup; // Calc same offset from tx duplicate @@ -104,7 +104,7 @@ static void s_tx_cond_all_with_spends_by_srv_uid_callback(dap_chain_net_t* a_net } size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); dap_chain_datum_tx_t * l_tx_dup = DAP_DUP_SIZE(l_tx,l_tx_size); - dap_hash_fast(l_tx,l_tx_size, &l_item->tx_hash); + l_item->tx_hash = *a_tx_hash; l_item->tx = l_tx_dup; // Calc same offset from tx duplicate l_item->out_cond = (dap_chain_tx_out_cond_t*) (l_tx_dup->tx_items + l_tx_items_pos); @@ -188,27 +188,19 @@ void dap_chain_net_get_tx_all(dap_chain_net_t * a_net, dap_chain_net_tx_search_t { assert(a_tx_callback); switch (a_search_type) { - case TX_SEARCH_TYPE_NET_UNSPENT:{ - size_t l_tx_count = dap_ledger_count(a_net->pub.ledger); - dap_list_t *l_txs_list = dap_ledger_get_txs(a_net->pub.ledger, l_tx_count, 1, false, true); - dap_list_t *l_temp = l_txs_list; - while(l_temp){ - dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_temp->data; - a_tx_callback(a_net, l_tx, a_arg); - l_temp = dap_list_next(l_temp); - } - break; - } + case TX_SEARCH_TYPE_NET_UNSPENT: case TX_SEARCH_TYPE_NET: case TX_SEARCH_TYPE_LOCAL:{ - size_t l_tx_count = dap_ledger_count(a_net->pub.ledger); - dap_list_t *l_txs_list = dap_ledger_get_txs(a_net->pub.ledger, l_tx_count, 1, false, false); - dap_list_t *l_temp = l_txs_list; - while(l_temp){ - dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_temp->data; - a_tx_callback(a_net, l_tx, a_arg); - l_temp = dap_list_next(l_temp); + dap_ledger_datum_iter_t *l_iter = dap_ledger_datum_iter_create(a_net); + dap_ledger_datum_iter_get_first(l_iter); + while(l_iter->cur){ + if (a_search_type != TX_SEARCH_TYPE_NET_UNSPENT || + (a_search_type == TX_SEARCH_TYPE_NET_UNSPENT && l_iter->is_unspent)){ + a_tx_callback(a_net, l_iter->cur, &l_iter->cur_hash, a_arg); + } + dap_ledger_datum_iter_get_next(l_iter); } + dap_ledger_datum_iter_delete(l_iter); break; } case TX_SEARCH_TYPE_CELL_SPENT: @@ -218,39 +210,32 @@ void dap_chain_net_get_tx_all(dap_chain_net_t * a_net, dap_chain_net_tx_search_t case TX_SEARCH_TYPE_BLOCKCHAIN:{ // pass all chains for ( dap_chain_t * l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next){ - dap_chain_cell_t * l_cell, *l_cell_tmp; - // Go through all cells - HASH_ITER(hh,l_chain->cells,l_cell, l_cell_tmp){ - dap_chain_atom_iter_t * l_atom_iter = l_chain->callback_atom_iter_create(l_chain,l_cell->id, false ); - // try to find transaction in chain ( inside shard ) - size_t l_atom_size = 0; - dap_chain_atom_ptr_t l_atom = l_chain->callback_atom_iter_get_first(l_atom_iter, &l_atom_size); +// dap_chain_cell_t * l_cell, *l_cell_tmp; +// // Go through all cells +// HASH_ITER(hh,l_chain->cells,l_cell, l_cell_tmp){ + dap_chain_datum_iter_t * l_datum_iter = l_chain->callback_datum_iter_create(l_chain); + l_chain->callback_datum_iter_get_first(l_datum_iter); // Check atoms in chain - while(l_atom && l_atom_size) { - size_t l_datums_count = 0; - dap_chain_datum_t **l_datums = l_chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count); - // transaction - dap_chain_datum_tx_t *l_tx = NULL; - - for (size_t i = 0; i < l_datums_count; i++) { - // Check if its transaction - if (l_datums && (l_datums[i]->header.type_id == DAP_CHAIN_DATUM_TX)) { - l_tx = (dap_chain_datum_tx_t *) l_datums[i]->data; - } - - // If found TX - - if ( l_tx ) { - a_tx_callback(a_net, l_tx, a_arg); - } - } - DAP_DEL_Z(l_datums); - // go to next atom - l_atom = l_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size); + while(l_datum_iter->cur) { + dap_chain_datum_t *l_datum = l_datum_iter->cur; + // transaction + dap_chain_datum_tx_t *l_tx = NULL; + // Check if its transaction + if (l_datum && (l_datum->header.type_id == DAP_CHAIN_DATUM_TX)) { + l_tx = (dap_chain_datum_tx_t *) l_datum->data; } - l_chain->callback_atom_iter_delete(l_atom_iter); + + // If found TX + if ( l_tx ) { + a_tx_callback(a_net, l_tx, l_datum_iter->cur_hash, a_arg); + } + + // go to next datum + l_chain->callback_datum_iter_get_next(l_datum_iter); } + l_chain->callback_datum_iter_delete(l_datum_iter); +// } } } break; } @@ -275,14 +260,14 @@ struct get_tx_cond_all_from_tx * @param a_tx * @param a_arg */ -static void s_get_tx_cond_chain_callback(dap_chain_net_t UNUSED_ARG *a_net, dap_chain_datum_tx_t *a_tx, void *a_arg) +static void s_get_tx_cond_chain_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg) { struct get_tx_cond_all_from_tx * l_args = (struct get_tx_cond_all_from_tx* ) a_arg; if( l_args->ret ){ int l_item_idx = 0; byte_t *l_tx_item; - dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx); + dap_hash_fast_t * l_tx_hash = a_tx_hash; // Get items from transaction while ((l_tx_item = dap_chain_datum_tx_item_get(a_tx, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL)) != NULL){ dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *) l_tx_item; @@ -306,7 +291,7 @@ static void s_get_tx_cond_chain_callback(dap_chain_net_t UNUSED_ARG *a_net, dap_ } DAP_DELETE(l_tx_hash); }else if(a_tx){ - dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx); + dap_hash_fast_t * l_tx_hash = a_tx_hash; if (!l_tx_hash) { log_it(L_CRITICAL, "Memory allocation error"); return; @@ -347,7 +332,7 @@ dap_list_t * dap_chain_net_get_tx_cond_chain(dap_chain_net_t * a_net, dap_hash_f } l_args->tx_begin_hash = a_tx_hash; l_args->srv_uid = a_srv_uid; - dap_chain_net_get_tx_all(a_net,TX_SEARCH_TYPE_NET,s_get_tx_cond_chain_callback, l_args); + dap_chain_net_get_tx_all(a_net,TX_SEARCH_TYPE_NET, s_get_tx_cond_chain_callback, l_args); dap_list_t * l_ret = l_args->ret; DAP_DELETE(l_args); return l_ret; @@ -370,8 +355,10 @@ struct get_tx_cond_all_for_addr * @param a_tx * @param a_arg */ -static void s_get_tx_cond_all_for_addr_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_datum_tx, void *a_arg) +static void s_get_tx_cond_all_for_addr_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_datum_tx, dap_hash_fast_t *a_hash, void *a_arg) { + UNUSED(a_net); + UNUSED(a_hash); struct get_tx_cond_all_for_addr * l_args = (struct get_tx_cond_all_for_addr* ) a_arg; int l_item_idx = 0; dap_chain_datum_tx_item_t *l_tx_item; @@ -473,7 +460,11 @@ dap_list_t * dap_chain_net_get_tx_cond_all_for_addr(dap_chain_net_t * a_net, dap return l_ret; } -static void s_tx_cond_all_by_srv_uid_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, void *a_arg){ +static void s_tx_cond_all_by_srv_uid_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg) +{ + UNUSED(a_net); + UNUSED(a_tx_hash); + cond_all_by_srv_uid_arg_t *l_ret = (cond_all_by_srv_uid_arg_t *)a_arg; dap_chain_datum_tx_t *l_tx = a_tx; diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h index 129086c4b023b80fe2659ba9d28a8caa99fa1176..a7995926180af9004a4207ee8d3d22484c871510 100644 --- a/modules/net/include/dap_chain_ledger.h +++ b/modules/net/include/dap_chain_ledger.h @@ -114,6 +114,15 @@ typedef enum dap_ledger_token_decl_add_err{ DAP_LEDGER_TOKEN_DECL_ADD_UNKNOWN /* MAX */ } dap_ledger_token_decl_add_err_t; +typedef struct dap_ledger_datum_iter { + dap_chain_net_t *net; + dap_chain_datum_tx_t *cur; + dap_chain_hash_fast_t cur_hash; + bool is_unspent; + int ret_code; + void *cur_ledger_tx_item; +} dap_ledger_datum_iter_t; + typedef bool (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); typedef void (*dap_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_cond); typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx); @@ -350,6 +359,12 @@ dap_list_t * dap_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a //bool dap_ledger_fee_verificator(dap_ledger_t* a_ledger, dap_chain_tx_out_cond_t* a_cond, dap_chain_datum_tx_t* a_tx, bool a_owner); +dap_ledger_datum_iter_t *dap_ledger_datum_iter_create(dap_chain_net_t *a_net); +void dap_ledger_datum_iter_delete(dap_ledger_datum_iter_t *a_iter); +dap_chain_datum_tx_t *dap_ledger_datum_iter_get_first(dap_ledger_datum_iter_t *a_iter); +dap_chain_datum_tx_t *dap_ledger_datum_iter_get_next(dap_ledger_datum_iter_t *a_iter); +dap_chain_datum_tx_t *dap_ledger_datum_iter_get_last(dap_ledger_datum_iter_t *a_iter); + void dap_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_ledger_tx_add_notify_t a_callback, void *a_arg); void dap_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_ledger_bridged_tx_notify_t a_callback, void *a_arg); diff --git a/modules/net/include/dap_chain_net_tx.h b/modules/net/include/dap_chain_net_tx.h index f886a4b36884e1f71683806d9c3d3c698cd65ac0..e3a7b6af511d408e41ead6709f0baf0ad48437e4 100644 --- a/modules/net/include/dap_chain_net_tx.h +++ b/modules/net/include/dap_chain_net_tx.h @@ -58,7 +58,7 @@ typedef struct dap_chain_datum_tx_spends_items{ dap_chain_datum_tx_spends_item_t * tx_outs; dap_chain_datum_tx_spends_item_t * tx_ins; } dap_chain_datum_tx_spends_items_t; -typedef void (dap_chain_net_tx_hash_callback_t)(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, void *a_arg); +typedef void (dap_chain_net_tx_hash_callback_t)(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg); // TX functions diff --git a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c index d2f4542abeb9acbba96c2d0ecd789df6a7709836..8d6e6d513badc7924b8ecee6fb6d14388be98682 100644 --- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c +++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c @@ -2094,7 +2094,7 @@ struct get_tx_cond_pos_del_from_tx * @param a_tx * @param a_arg */ -static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, void *a_arg) +static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg) { struct get_tx_cond_pos_del_from_tx * l_args = (struct get_tx_cond_pos_del_from_tx* ) a_arg; int l_out_idx_tmp = 0; @@ -2105,8 +2105,7 @@ static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_ if (dap_chain_addr_is_blank(&l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr) || l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64 == 0) return; - dap_hash_fast_t l_datum_hash; - dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_datum_hash); + dap_hash_fast_t l_datum_hash = *a_tx_hash; if (dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_datum_hash, l_out_idx_tmp, NULL)) return; dap_chain_net_srv_stake_item_t *l_stake = NULL; diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index c1e8f25e29b52063fb2cb9f098c6c6d47c1eaeb7..e1a549718545a8bfb56a3f51e79d956909143669 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -1724,9 +1724,10 @@ size_t l_tx_total; return 0; } -void s_tx_is_order_check(dap_chain_net_t *a_net, dap_chain_datum_tx_t *a_tx, void *a_arg) +void s_tx_is_order_check (dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg) { UNUSED(a_net); + UNUSED(a_tx_hash); dap_list_t **l_tx_list_ptr = a_arg; if (dap_chain_datum_tx_out_cond_get(a_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE , NULL) && !dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_IN_COND, NULL))