From 4e1ccc3d6458e3a46edec63e0230a0a1a8333089 Mon Sep 17 00:00:00 2001 From: Roman Khlopkov <roman.khlopkov@demlabs.net> Date: Fri, 24 Nov 2023 09:23:37 +0000 Subject: [PATCH] feature-9808 --- CMakeLists.txt | 16 +- dap-sdk | 2 +- modules/CMakeLists.txt | 5 - modules/chain/dap_chain.c | 4 - modules/chain/dap_chain_tx.c | 1 - modules/chain/include/dap_chain.h | 17 +- modules/chain/include/dap_chain_ledger.h | 350 --- modules/chain/tests/dap_chain_ledger_tests.c | 124 +- .../tests/include/dap_chain_ledger_tests.h | 5 +- modules/chain/tests/main.c | 4 +- .../dap_stream_ch_chain_net_srv.c | 10 +- modules/common/dap_chain_datum.c | 16 +- modules/common/dap_chain_datum_decree.c | 21 +- modules/common/dap_chain_datum_token.c | 10 +- modules/common/dap_chain_datum_tx.c | 11 + modules/common/dap_chain_datum_tx_items.c | 49 +- modules/common/include/dap_chain_common.h | 26 +- .../common/include/dap_chain_datum_decree.h | 31 +- .../common/include/dap_chain_datum_token.h | 16 +- modules/common/include/dap_chain_datum_tx.h | 7 + .../include/dap_chain_datum_tx_in_cond.h | 4 +- .../include/dap_chain_datum_tx_in_reward.h | 30 + .../common/include/dap_chain_datum_tx_items.h | 7 +- .../common/include/dap_chain_datum_tx_out.h | 2 +- .../include/dap_chain_datum_tx_out_cond.h | 53 - .../consensus/esbocs/dap_chain_cs_esbocs.c | 17 +- modules/mempool/dap_chain_mempool.c | 174 +- modules/mempool/include/dap_chain_mempool.h | 4 +- modules/{chain => net}/dap_chain_ledger.c | 2078 ++++++++--------- modules/net/dap_chain_net.c | 125 +- modules/net/dap_chain_net_anchor.c | 1 + modules/net/dap_chain_net_decree.c | 52 +- modules/net/dap_chain_net_tx.c | 52 +- modules/net/dap_chain_node.c | 3 +- modules/net/dap_chain_node_cli_cmd.c | 45 +- modules/net/dap_chain_node_cli_cmd_tx.c | 52 +- modules/net/include/dap_chain_ledger.h | 357 +++ modules/net/include/dap_chain_net.h | 13 +- modules/net/include/dap_chain_net_decree.h | 1 - modules/net/include/dap_chain_net_tx.h | 3 +- modules/net/srv/dap_chain_net_srv.c | 19 +- modules/net/srv/dap_chain_net_srv_order.c | 2 +- .../service/datum/dap_chain_net_srv_datum.c | 2 +- .../stake/dap_chain_net_srv_stake_lock.c | 49 +- .../dap_chain_net_srv_stake_pos_delegate.c | 50 +- .../xchange/dap_chain_net_srv_xchange.c | 76 +- modules/test/CMakeLists.txt | 9 - modules/test/dap_test.c | 112 - modules/test/dap_test.h | 113 - modules/test/dap_test_generator.c | 21 - modules/test/dap_test_generator.h | 7 - modules/type/blocks/dap_chain_block.c | 77 +- modules/type/blocks/dap_chain_block_cache.c | 8 +- modules/type/blocks/dap_chain_block_chunk.c | 3 +- modules/type/blocks/dap_chain_cs_blocks.c | 339 ++- modules/type/blocks/include/dap_chain_block.h | 12 +- .../blocks/include/dap_chain_block_cache.h | 6 +- .../type/blocks/include/dap_chain_cs_blocks.h | 2 +- modules/type/dag/dap_chain_cs_dag.c | 2 +- modules/wallet/dap_chain_wallet.c | 3 +- 60 files changed, 2363 insertions(+), 2347 deletions(-) delete mode 100644 modules/chain/include/dap_chain_ledger.h create mode 100644 modules/common/include/dap_chain_datum_tx_in_reward.h rename modules/{chain => net}/dap_chain_ledger.c (75%) create mode 100644 modules/net/include/dap_chain_ledger.h delete mode 100644 modules/test/CMakeLists.txt delete mode 100644 modules/test/dap_test.c delete mode 100644 modules/test/dap_test.h delete mode 100644 modules/test/dap_test_generator.c delete mode 100644 modules/test/dap_test_generator.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d1f20a536d..020c2f42ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,9 +6,6 @@ set(CELLFRAME_SDK_NATIVE_VERSION "3.3-0") add_definitions ("-DCELLFRAME_SDK_VERSION=\"${CELLFRAME_SDK_NATIVE_VERSION}\"") - -set(DAPSDK_MODULES "") - if(NOT DEFINED CELLFRAME_MODULES) include (dap-sdk/cmake/OS_Detection.cmake) @@ -17,9 +14,10 @@ if(NOT DEFINED CELLFRAME_MODULES) if(LINUX OR DARWIN) set(CELLFRAME_MODULES "${CELLFRAME_MODULES} srv-vpn") endif() - if (BUILD_CELLFRAME_SDK_TESTS) - set (CELLFRAME_MODULES ${CELLFRAME_MODULES} "test-framework") - endif () + + if(BUILD_CELLFRAME_SDK_TESTS) + set(DAPSDK_MODULES "test-framework") + endif() add_subdirectory(dap-sdk) @@ -43,8 +41,7 @@ else() endif(NOT DAP_INT128_SUPPORT) if (BUILD_CELLFRAME_SDK_TESTS) - enable_testing() - add_definitions("-DDAP_CHAIN_LEDGER_TEST") + add_definitions("-DDAP_LEDGER_TEST") endif() if (BUILD_WITH_ZIP) @@ -53,9 +50,6 @@ if (BUILD_WITH_ZIP) endif() add_subdirectory(3rdparty/monero_crypto) -if(DAPSDK_MODULES MATCHES "ssl-support") - add_subdirectory(3rdparty/wolfssl) -endif() add_subdirectory(modules/) diff --git a/dap-sdk b/dap-sdk index 47998bb5e3..60d9770561 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 47998bb5e3d464ee991b1bdee910db824fdca723 +Subproject commit 60d9770561950957837b9e2c2b9173d01de74510 diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index f5d8b8fd44..5dd9d33504 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -110,8 +110,3 @@ endif() if (CELLFRAME_MODULES MATCHES "srv-stake") add_subdirectory(service/stake) endif() - -# Unit tests -if( BUILD_TESTS) - add_subdirectory(test) -endif() diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index 994aecde4f..106f2ec150 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -35,7 +35,6 @@ #include "dap_file_utils.h" #include "dap_config.h" #include "dap_chain.h" -#include "dap_chain_ledger.h" #include "dap_cert.h" #include "dap_chain_cell.h" #include "dap_chain_cs.h" @@ -69,7 +68,6 @@ int dap_chain_init(void) { // Cell sharding init dap_chain_cell_init(); - dap_chain_ledger_init(); dap_chain_cs_init(); //dap_chain_show_hash_blocks_file(g_gold_hash_blocks_file); //dap_chain_show_hash_blocks_file(g_silver_hash_blocks_file); @@ -85,8 +83,6 @@ void dap_chain_deinit(void) HASH_ITER(hh, s_chain_items, l_item, l_tmp) { dap_chain_delete(l_item->chain); } - dap_chain_ledger_deinit(); - } /** diff --git a/modules/chain/dap_chain_tx.c b/modules/chain/dap_chain_tx.c index 6e4fb145d2..4bd8019e9c 100644 --- a/modules/chain/dap_chain_tx.c +++ b/modules/chain/dap_chain_tx.c @@ -23,7 +23,6 @@ */ #include "dap_chain_tx.h" #include "dap_chain_datum_tx.h" -#include "dap_chain_ledger.h" #include "dap_common.h" #include "uthash.h" #define LOG_TAG "dap_chain_tx" diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index c961413784..6912588c49 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -115,14 +115,12 @@ typedef size_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); - typedef uint256_t (*dap_chain_callback_get_minimum_fee)(dap_chain_t *a_chain); typedef dap_enc_key_t* (*dap_chain_callback_get_signing_certificate)(dap_chain_t *a_chain); - typedef void (*dap_chain_callback_load_from_gdb)(dap_chain_t *a_chain); +typedef uint256_t (*dap_chain_callback_calc_reward)(dap_chain_t *a_chain, dap_hash_fast_t *a_block_hash, dap_pkey_t *a_block_sign_pkey); -typedef enum dap_chain_type -{ +typedef enum dap_chain_type { CHAIN_TYPE_FIRST, CHAIN_TYPE_TOKEN, CHAIN_TYPE_EMISSION, @@ -195,23 +193,22 @@ typedef struct dap_chain { dap_chain_callback_get_count callback_count_atom; dap_chain_callback_get_list callback_get_atoms; + // Consensus specific callbacks dap_chain_callback_get_poa_certs callback_get_poa_certs; dap_chain_callback_set_min_validators_count callback_set_min_validators_count; - dap_chain_callback_get_minimum_fee callback_get_minimum_fee; dap_chain_callback_get_signing_certificate callback_get_signing_certificate; - + dap_chain_callback_calc_reward callback_calc_reward; dap_chain_callback_load_from_gdb callback_load_from_gdb; - dap_list_t *atom_notifiers; -// dap_chain_callback_notify_t callback_notify; -// void *callback_notify_arg; - + // Iterator callbacks dap_chain_datum_callback_iter_create_t callback_datum_iter_create; dap_chain_datum_callback_iter_get_first_t callback_datum_iter_get_first; dap_chain_datum_callback_iter_get_first_t callback_datum_iter_get_next; dap_chain_datum_callback_iter_delete_t callback_datum_iter_delete; + dap_list_t *atom_notifiers; + void * _pvt; // private data void * _inheritor; // inheritor object } dap_chain_t; diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h deleted file mode 100644 index 12dbb04da3..0000000000 --- a/modules/chain/include/dap_chain_ledger.h +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Authors: - * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> - * Alexander Lysikov <alexander.lysikov@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://github.com/demlabsinc - * Copyright (c) 2017-2019 - * All rights reserved. - - This file is part of DAP (Deus Applications Prototypes) the open source project - - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once -#include <stdint.h> -#include <stdbool.h> -#include "dap_common.h" -#include "dap_hash.h" -#include "dap_list.h" -#include "dap_math_ops.h" -#include "dap_chain_common.h" -#include "dap_chain_datum_token.h" -#include "dap_chain_datum_tx.h" -#include "dap_chain_datum_tx_in_ems.h" -#include "dap_chain_datum_tx_items.h" - -typedef struct dap_ledger { - char *net_name; - dap_chain_net_id_t net_id; - void *_internal; -} dap_ledger_t; - -/** - * @brief Error codes for accepting a transaction to the ledger. - */ -typedef enum dap_chain_ledger_tx_check{ - DAP_CHAIN_LEDGER_TX_CHECK_OK = 0, - DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX, - DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE, - DAP_CHAIN_LEDGER_TX_ALREADY_CACHED, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN, - DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED, - DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND, - DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN, - DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS, - DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS, - DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY, - DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE, - DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND, - DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET, - DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND, - DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS, - /* add custom codes here */ - - DAP_CHAIN_LEDGER_TX_CHECK_UNKNOWN /* MAX */ -} dap_chain_ledger_tx_check_t; - -typedef enum dap_chain_ledger_emission_err{ - DAP_CHAIN_LEDGER_EMISSION_ADD_OK = 0, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE, - DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED, - /* add custom codes here */ - DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM, - DAP_CHAIN_LEDGER_EMISSION_ADD_UNKNOWN /* MAX */ -} dap_chain_ledger_emission_err_code_t; - -typedef enum dap_chain_ledger_token_decl_add_err{ - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK = 0, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS, - /* add custom codes here */ - - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_UNKNOWN /* MAX */ -} dap_chain_ledger_token_decl_add_err_t; - -typedef bool (*dap_chain_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_chain_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_chain_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx); -typedef void (* dap_chain_ledger_bridged_tx_notify_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg); -typedef bool (*dap_chain_ledger_cache_tx_check_callback_t)(dap_hash_fast_t *a_tx_hash); -typedef struct dap_chain_net dap_chain_net_t; - -//Change this UUID to automatically reload ledger cache on next node startup -#define DAP_CHAIN_LEDGER_CACHE_RELOAD_ONCE_UUID "0c92b759-a565-448f-b8bd-99103dacf7fc" - -// Checks the emission of the token, usualy on zero chain -#define DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION 0x0001 - -// Check double spending in local cell -#define DAP_CHAIN_LEDGER_CHECK_LOCAL_DS 0x0002 - -// Check the double spending in all cells -#define DAP_CHAIN_LEDGER_CHECK_CELLS_DS 0x0100 - -#define DAP_CHAIN_LEDGER_CACHE_ENABLED 0x0200 - -// Error code for no previous transaction (for stay in mempool) -#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND -// Error code for no emission for a transaction (for stay in mempoold) -#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND -// Error code for no decree for anchor (for stay in mempool) -#define DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE -1113 - -#define DAP_CHAIN_LEDGER_TOKENS_STR "tokens" -#define DAP_CHAIN_LEDGER_EMISSIONS_STR "emissions" -#define DAP_CHAIN_LEDGER_STAKE_LOCK_STR "stake_lock" -#define DAP_CHAIN_LEDGER_TXS_STR "txs" -#define DAP_CHAIN_LEDGER_SPENT_TXS_STR "spent_txs" -#define DAP_CHAIN_LEDGER_BALANCES_STR "balances" - -int dap_chain_ledger_init(); -void dap_chain_ledger_deinit(); - -dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, dap_chain_net_id_t a_net_id, char *a_net_name, const char *a_net_native_ticker, dap_list_t *a_poa_certs); - -void dap_chain_ledger_set_fee(dap_ledger_t *a_ledger, uint256_t a_fee, dap_chain_addr_t a_fee_addr); - -// Remove dap_ledger_t structure -void dap_chain_ledger_handle_free(dap_ledger_t *a_ledger); - -// Load ledger from mempool -//int dap_chain_ledger_load(const char *a_net_name, const char *a_chain_name); - -void dap_chain_ledger_set_local_cell_id(dap_ledger_t *a_ledger, dap_chain_cell_id_t a_local_cell_id); - -/** - * @brief dap_chain_node_datum_tx_calc_hash - * @param a_tx - * @return - */ -DAP_STATIC_INLINE dap_chain_hash_fast_t* dap_chain_node_datum_tx_calc_hash(dap_chain_datum_tx_t *a_tx) -{ - dap_chain_hash_fast_t *tx_hash = DAP_NEW_Z(dap_chain_hash_fast_t); - if (!tx_hash) { - return NULL; - } - dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), tx_hash); - return tx_hash; -} - -DAP_STATIC_INLINE char *dap_chain_ledger_get_gdb_group(dap_ledger_t *a_ledger, const char *a_suffix) -{ - return a_ledger && a_ledger->net_name && a_suffix - ? dap_strdup_printf("local.ledger-cache.%s.%s", a_ledger->net_name, a_suffix) - : NULL; -} - -/** - * Add new transaction to the cache - * - * return 1 OK, -1 error - */ -int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold); -int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_hash_fast_t *a_tx_hash); - - -int dap_chain_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash); - -char* dap_chain_ledger_tx_check_err_str(int a_code); - -/** - * Print list transaction from ledger - * - */ - -char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only); - -/** - * Check token ticker existance - * - */ - -dap_chain_datum_token_t *dap_chain_ledger_token_ticker_check(dap_ledger_t * a_ledger, const char *a_token_ticker); - -/** - * Add new token datum - * - */ - -int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); -int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size); -int dap_chain_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); -char *dap_chain_ledger_token_decl_add_err_code_to_str(int a_code); -dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger); - -// Get all token-declarations -dap_list_t* dap_chain_ledger_token_decl_all(dap_ledger_t *a_ledger); - -dap_string_t *dap_chain_ledger_threshold_info(dap_ledger_t *a_ledger); -dap_string_t *dap_chain_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_tx_treshold_hash); -dap_string_t *dap_chain_ledger_balance_info(dap_ledger_t *a_ledger); - -size_t dap_chain_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker); -size_t dap_chain_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker); -dap_list_t * dap_chain_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker); - -/** - * Add token emission datum - */ -int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, - dap_hash_fast_t *a_emission_hash, bool a_from_threshold); -int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_hash_fast_t *a_token_emission_hash); -char *dap_chain_ledger_token_emission_err_code_to_str(int a_code); - -// Check if it addable -int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash); - -/* Add stake-lock item */ -int dap_chain_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash); - -dap_chain_datum_token_emission_t *dap_chain_ledger_token_emission_find(dap_ledger_t *a_ledger, - const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash); - -const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_chain_hash_fast_t *a_tx_hash); - -void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, - char *** a_tickers, size_t * a_tickers_size); - -void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, - char *** a_tickers, size_t * a_tickers_size); - -bool dap_chain_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx); - -// Checking a new transaction before adding to the cache -int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, - bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker); - -/** - * Delete all transactions from the cache - */ -void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db); - -/** - * End of load mode with no chackes for incoming datums - */ -void dap_chain_ledger_load_end(dap_ledger_t *a_ledger); - -/** - * Return number transactions from the cache - */ -unsigned dap_chain_ledger_count(dap_ledger_t *a_ledger); -uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts_from, dap_time_t a_ts_to); -size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to); -void dap_chain_ledger_set_tps_start_time(dap_ledger_t *a_ledger); - -/** - * Check whether used 'out' items - */ -bool dap_chain_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, int a_idx_out, dap_hash_fast_t *a_out_spender); - -/** - * Calculate balance of addr - * - */ -uint256_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, - const char *a_token_ticker); - -uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, - const char *a_token_ticker); - -/** - * Get transaction in the cache by hash - * - * return transaction, or NULL if transaction not found in the cache - */ -dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); -dap_chain_datum_tx_t* dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); -dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash); - - // Get the transaction in the cache by the addr in out item -dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_addr(dap_ledger_t *a_ledger, const char * a_token, - const dap_chain_addr_t *a_addr, dap_chain_hash_fast_t *a_tx_first_hash); - -// Get the transaction in the cache by the public key that signed the transaction, starting with a_tx_first_hash -const dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger, - char *a_public_key, size_t a_public_key_size, dap_chain_hash_fast_t *a_tx_first_hash); - -// Get the transaction in the cache with the out_cond item -dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, - dap_chain_hash_fast_t *a_tx_first_hash, dap_chain_tx_out_cond_t **a_out_cond, - int *a_out_cond_idx, char *a_token_ticker); - -// Get all transactions from the cache with the specified out_cond items -dap_list_t* dap_chain_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_chain_net_srv_uid_t a_srv_uid); - -// Get the value from all transactions in the cache with out_cond item -uint256_t dap_chain_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_addr_t *a_addr, - dap_chain_tx_out_cond_t **tx_out_cond); - -// Get the list of 'out' items from previous transactions with summary value >= than a_value_need -// Put this summary value to a_value_transfer -dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from, - uint256_t a_value_need, uint256_t *a_value_transfer); - -// Get the list of 'out_cond' items with summary value >= than a_value_need -dap_list_t *dap_chain_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from, - dap_chain_tx_out_cond_subtype_t a_subtype, uint256_t a_value_need, uint256_t *a_value_transfer); - -// Add new verificator callback with associated subtype. Returns 1 if callback replaced, overwise returns 0 -int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_chain_ledger_verificator_callback_t a_callback, - dap_chain_ledger_updater_callback_t a_callback_added); - -// Getting a list of transactions from the ledger. -dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only); - -//bool dap_chain_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); - -void dap_chain_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_ledger_tx_add_notify_t a_callback, void *a_arg); -void dap_chain_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_chain_ledger_bridged_tx_notify_t a_callback, void *a_arg); - - -bool dap_chain_ledger_cache_enabled(dap_ledger_t *a_ledger); -void dap_chain_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_chain_ledger_cache_tx_check_callback_t a_callback); diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c index 588c694695..94ff695443 100644 --- a/modules/chain/tests/dap_chain_ledger_tests.c +++ b/modules/chain/tests/dap_chain_ledger_tests.c @@ -1,15 +1,17 @@ +#include "dap_test.h" #include "dap_chain_ledger_tests.h" #include "dap_chain_datum.h" #include "dap_cert.h" #include "dap_chain_wallet.h" #include "dap_math_ops.h" +#include "dap_chain_net.h" static const uint64_t s_fee = 2; static const uint64_t s_total_supply = 500; static const uint64_t s_standard_value_tx = 500; static const char* s_token_ticker = "TestCoins"; -dap_chain_datum_token_t *dap_chain_ledger_test_create_datum_decl(dap_cert_t *a_cert, size_t *a_token_size, +dap_chain_datum_token_t *dap_ledger_test_create_datum_decl(dap_cert_t *a_cert, size_t *a_token_size, const char *a_token_ticker, uint256_t a_total_supply, byte_t *a_tsd_section, size_t a_size_tsd_section, uint16_t flags) { dap_chain_datum_token_t *l_token = DAP_NEW_Z(dap_chain_datum_token_t); @@ -44,13 +46,13 @@ dap_chain_datum_token_t *dap_chain_ledger_test_create_datum_decl(dap_cert_t *a_ } } -dap_chain_datum_tx_t *dap_chain_ledger_test_create_datum_base_tx( +dap_chain_datum_tx_t *dap_ledger_test_create_datum_base_tx( dap_chain_datum_token_emission_t *a_emi, dap_chain_hash_fast_t *l_emi_hash, dap_chain_addr_t a_addr_to, dap_cert_t *a_cert) { uint256_t l_value_fee = dap_chain_uint256_from(s_fee); - uint256_t l_value_need = a_emi->hdr.value_256; + uint256_t l_value_need = a_emi->hdr.value; dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); l_tx->header.ts_created = time(NULL); dap_chain_tx_in_ems_t *l_in_ems = DAP_NEW_Z(dap_chain_tx_in_ems_t); @@ -72,7 +74,7 @@ dap_chain_datum_tx_t *dap_chain_ledger_test_create_datum_base_tx( return l_tx; } -dap_chain_datum_tx_t *dap_chain_ledger_test_create_tx(dap_enc_key_t *a_key_from, dap_chain_hash_fast_t *a_hash_prev, +dap_chain_datum_tx_t *dap_ledger_test_create_tx(dap_enc_key_t *a_key_from, dap_chain_hash_fast_t *a_hash_prev, dap_chain_addr_t *a_addr_to, uint256_t a_value) { dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); dap_chain_tx_in_t *l_in = dap_chain_datum_tx_item_in_create(a_hash_prev, 0); @@ -85,42 +87,42 @@ dap_chain_datum_tx_t *dap_chain_ledger_test_create_tx(dap_enc_key_t *a_key_from, return l_tx; } -void dap_chain_ledger_test_double_spending( +void dap_ledger_test_double_spending( dap_ledger_t *a_ledger, dap_hash_fast_t *a_prev_hash, dap_enc_key_t *a_from_key, dap_chain_net_id_t a_net_id) { - dap_print_module_name("dap_chain_ledger_double_spending"); + dap_print_module_name("dap_ledger_double_spending"); dap_cert_t *l_first_cert = dap_cert_generate_mem_with_seed("newCert", DAP_ENC_KEY_TYPE_SIG_PICNIC, "FMknbirh8*^#$RYU*H", 18); dap_chain_addr_t l_addr_first = {0}; dap_chain_addr_fill_from_key(&l_addr_first, l_first_cert->enc_key, a_net_id); - dap_chain_datum_tx_t *l_first_tx = dap_chain_ledger_test_create_tx(a_from_key, a_prev_hash, + dap_chain_datum_tx_t *l_first_tx = dap_ledger_test_create_tx(a_from_key, a_prev_hash, &l_addr_first, dap_chain_uint256_from(s_standard_value_tx - s_fee)); dap_assert_PIF(l_first_tx, "Can't creating base transaction."); dap_chain_hash_fast_t l_first_tx_hash = {0}; dap_hash_fast(l_first_tx, dap_chain_datum_tx_get_size(l_first_tx), &l_first_tx_hash); - dap_assert_PIF(!dap_chain_ledger_tx_add(a_ledger, l_first_tx, &l_first_tx_hash, false), "Can't added first transaction on ledger"); - //uint256_t l_balance = dap_chain_ledger_calc_balance(a_ledger, &l_addr_first, s_token_ticker); + dap_assert_PIF(!dap_ledger_tx_add(a_ledger, l_first_tx, &l_first_tx_hash, false), "Can't added first transaction on ledger"); + //uint256_t l_balance = dap_ledger_calc_balance(a_ledger, &l_addr_first, s_token_ticker); // Second tx - dap_chain_datum_tx_t *l_second_tx = dap_chain_ledger_test_create_tx(a_from_key, a_prev_hash, + dap_chain_datum_tx_t *l_second_tx = dap_ledger_test_create_tx(a_from_key, a_prev_hash, &l_addr_first, dap_chain_uint256_from(s_standard_value_tx - s_fee)); dap_chain_hash_fast_t l_second_tx_hash = {0}; dap_hash_fast(l_second_tx, dap_chain_datum_tx_get_size(l_second_tx), &l_second_tx_hash); - dap_assert_PIF(dap_chain_ledger_tx_add(a_ledger, l_second_tx, &l_second_tx_hash, false), "Added second transaction on ledger"); + dap_assert_PIF(dap_ledger_tx_add(a_ledger, l_second_tx, &l_second_tx_hash, false), "Added second transaction on ledger"); dap_pass_msg("The verification test is not able to make two normal transactions per one basic transaction."); } -void dap_chain_ledger_test_excess_supply(dap_ledger_t *a_ledger, dap_cert_t *a_cert, dap_chain_addr_t *a_addr){ - dap_print_module_name("dap_chain_ledger_test_excess_supply"); +void dap_ledger_test_excess_supply(dap_ledger_t *a_ledger, dap_cert_t *a_cert, dap_chain_addr_t *a_addr){ + dap_print_module_name("dap_ledger_test_excess_supply"); const char *l_token_ticker = "Test2"; uint256_t l_value_first_emi = dap_chain_uint256_from(s_total_supply / 2); uint256_t l_value_second_emi = dap_chain_uint256_from(s_total_supply); size_t l_decl_size = 0; - dap_chain_datum_token_t *l_decl = dap_chain_ledger_test_create_datum_decl(a_cert, &l_decl_size, l_token_ticker, + dap_chain_datum_token_t *l_decl = dap_ledger_test_create_datum_decl(a_cert, &l_decl_size, l_token_ticker, dap_chain_uint256_from(s_total_supply), NULL, 0, DAP_CHAIN_DATUM_TOKEN_FLAG_NONE); - dap_assert_PIF(!dap_chain_ledger_token_add(a_ledger, l_decl, l_decl_size), "Adding token declaration to ledger."); + dap_assert_PIF(!dap_ledger_token_add(a_ledger, l_decl, l_decl_size), "Adding token declaration to ledger."); dap_chain_datum_token_emission_t *l_femi = dap_chain_datum_emission_create(l_value_first_emi, l_token_ticker, a_addr); l_femi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_femi); dap_chain_hash_fast_t l_femi_hash = {0}; dap_hash_fast(l_femi, dap_chain_datum_emission_get_size((byte_t*)l_femi), &l_femi_hash); - dap_assert_PIF(!dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_femi, + dap_assert_PIF(!dap_ledger_token_emission_add(a_ledger, (byte_t*)l_femi, dap_chain_datum_emission_get_size((byte_t*)l_femi), &l_femi_hash, false), "Added first emission in ledger"); //Second emi @@ -128,7 +130,7 @@ void dap_chain_ledger_test_excess_supply(dap_ledger_t *a_ledger, dap_cert_t *a_c l_semi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_semi); dap_chain_hash_fast_t l_semi_hash = {0}; dap_hash_fast(l_semi, dap_chain_datum_emission_get_size((byte_t*)l_semi), &l_semi_hash); - int res =dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_semi, + int res =dap_ledger_token_emission_add(a_ledger, (byte_t*)l_semi, dap_chain_datum_emission_get_size((byte_t*)l_semi), &l_semi_hash, false); if (!res){ @@ -156,8 +158,8 @@ addr_key_container_t *gen_addr(dap_chain_net_id_t a_iddn){ return l_container; } -void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a_cert, dap_chain_net_id_t a_net_id) { - dap_print_module_name("dap_chain_ledger_test_write_back_list"); +void dap_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a_cert, dap_chain_net_id_t a_net_id) { + dap_print_module_name("dap_ledger_test_write_back_list"); addr_key_container_t *l_addr_1 = gen_addr(a_net_id); addr_key_container_t *l_addr_2 = gen_addr(a_net_id); addr_key_container_t *l_addr_3 = gen_addr(a_net_id); @@ -199,7 +201,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a uint16_t l_flags_decl = 0; l_flags_decl |= DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED; l_flags_decl |= DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED; - dap_chain_datum_token_t *l_decl = dap_chain_ledger_test_create_datum_decl(a_cert, &l_decl_size, + dap_chain_datum_token_t *l_decl = dap_ledger_test_create_datum_decl(a_cert, &l_decl_size, l_token_ticker, dap_chain_uint256_from( s_total_supply), @@ -208,7 +210,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a //DAP_CHAIN_DATUM_TOKEN_FLAG_NONE); l_flags_decl); - dap_assert_PIF(!dap_chain_ledger_token_add(a_ledger, l_decl, l_decl_size), + dap_assert_PIF(!dap_ledger_token_add(a_ledger, l_decl, l_decl_size), "Can't added datum in ledger"); //Check emission in not a white list dap_chain_datum_token_emission_t *l_emi = dap_chain_datum_emission_create( @@ -216,7 +218,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a l_emi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_emi); dap_chain_hash_fast_t l_emi_hash = {0}; dap_hash_fast(l_emi, dap_chain_datum_emission_get_size((uint8_t*)l_emi), &l_emi_hash); - dap_assert(dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_emi, dap_chain_datum_emission_get_size((byte_t*)l_emi), + dap_assert(dap_ledger_token_emission_add(a_ledger, (byte_t*)l_emi, dap_chain_datum_emission_get_size((byte_t*)l_emi), &l_emi_hash, false) != 0, "Checking the impossibility of emission to an address not from the white list."); //Emission in white list @@ -225,28 +227,28 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a l_emi_whi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_emi_whi); dap_chain_hash_fast_t l_emi_whi_hash = {0}; dap_hash_fast(l_emi_whi, dap_chain_datum_emission_get_size((uint8_t*)l_emi_whi), &l_emi_whi_hash); - dap_assert_PIF(!dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_emi_whi, dap_chain_datum_emission_get_size((byte_t*)l_emi_whi), + dap_assert_PIF(!dap_ledger_token_emission_add(a_ledger, (byte_t*)l_emi_whi, dap_chain_datum_emission_get_size((byte_t*)l_emi_whi), &l_emi_whi_hash, false), "Can't add emission in white address"); - dap_chain_datum_tx_t *l_btx_addr1 = dap_chain_ledger_test_create_datum_base_tx(l_emi_whi, &l_emi_whi_hash, + dap_chain_datum_tx_t *l_btx_addr1 = dap_ledger_test_create_datum_base_tx(l_emi_whi, &l_emi_whi_hash, *l_addr_1->addr, a_cert); dap_hash_fast_t l_btx_addr1_hash = {0}; dap_hash_fast(l_btx_addr1, dap_chain_datum_tx_get_size(l_btx_addr1), &l_btx_addr1_hash); - int l_ledger_add_code = dap_chain_ledger_tx_add(a_ledger, l_btx_addr1, &l_btx_addr1_hash, false); + int l_ledger_add_code = dap_ledger_tx_add(a_ledger, l_btx_addr1, &l_btx_addr1_hash, false); char *l_ledger_tx_add_str = dap_strdup_printf("Can't add base tx in white address. Code: %d", l_ledger_add_code); dap_assert_PIF(!l_ledger_add_code, l_ledger_tx_add_str); DAP_DELETE(l_ledger_tx_add_str); dap_hash_fast_t l_tx_addr4_hash = {0}; - dap_chain_datum_tx_t *l_tx_to_addr4 = dap_chain_ledger_test_create_tx(l_addr_1->enc_key, &l_btx_addr1_hash, + dap_chain_datum_tx_t *l_tx_to_addr4 = dap_ledger_test_create_tx(l_addr_1->enc_key, &l_btx_addr1_hash, l_addr_4->addr, dap_chain_uint256_from(s_total_supply-s_fee)); dap_hash_fast(l_tx_to_addr4, dap_chain_datum_tx_get_size(l_tx_to_addr4), &l_tx_addr4_hash); - dap_assert_PIF(!dap_chain_ledger_tx_add(a_ledger, l_tx_to_addr4, &l_tx_addr4_hash, false), + dap_assert_PIF(!dap_ledger_tx_add(a_ledger, l_tx_to_addr4, &l_tx_addr4_hash, false), "Can't add transaction to address from white list in ledger"); - dap_chain_datum_tx_t *l_tx_to_addr3 = dap_chain_ledger_test_create_tx(l_addr_4->enc_key, &l_tx_addr4_hash, + dap_chain_datum_tx_t *l_tx_to_addr3 = dap_ledger_test_create_tx(l_addr_4->enc_key, &l_tx_addr4_hash, l_addr_3->addr, dap_chain_uint256_from(s_total_supply-s_fee)); dap_hash_fast_t l_tx_addr3_hash = {0}; dap_hash_fast(l_tx_to_addr3, dap_chain_datum_tx_get_size(l_tx_to_addr3), &l_tx_addr3_hash); - int res_add_tx = dap_chain_ledger_tx_add(a_ledger, l_tx_to_addr3, &l_tx_addr3_hash, false); + int res_add_tx = dap_ledger_tx_add(a_ledger, l_tx_to_addr3, &l_tx_addr3_hash, false); if (!res_add_tx) { dap_fail("It was possible to carry out a transaction to a forbidden address"); } else { @@ -286,7 +288,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a // memcpy(l_datum_token_update->data_n_tsd + l_offset, l_sign, l_sign_size); // DAP_DELETE(l_sign); // size_t l_token_update_size = sizeof(dap_chain_datum_token_t) + l_sign_size + l_offset; -// dap_assert(!dap_chain_ledger_token_add(a_ledger, l_datum_token_update, l_token_update_size), +// dap_assert(!dap_ledger_token_add(a_ledger, l_datum_token_update, l_token_update_size), // "Added token update in ledger."); // } else { // dap_fail("Can't creating sign for token update"); @@ -313,7 +315,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a l_flags_decl |= DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED; const char *l_token_ticker = "TestBL"; size_t l_decl_size = 0; - dap_chain_datum_token_t *l_decl = dap_chain_ledger_test_create_datum_decl(a_cert, &l_decl_size, + dap_chain_datum_token_t *l_decl = dap_ledger_test_create_datum_decl(a_cert, &l_decl_size, l_token_ticker, dap_chain_uint256_from( s_total_supply), @@ -322,7 +324,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a //DAP_CHAIN_DATUM_TOKEN_FLAG_NONE); l_flags_decl); - dap_assert_PIF(!dap_chain_ledger_token_add(a_ledger, l_decl, l_decl_size), + dap_assert_PIF(!dap_ledger_token_add(a_ledger, l_decl, l_decl_size), "Can't added datum in ledger"); //Check emission at addr in block list dap_chain_datum_token_emission_t *l_emi_block = dap_chain_datum_emission_create( @@ -330,7 +332,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a l_emi_block = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_emi_block); dap_chain_hash_fast_t l_emi_block_hash = {0}; dap_hash_fast(l_emi_block, dap_chain_datum_emission_get_size((uint8_t*)l_emi_block), &l_emi_block_hash); - dap_assert(dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_emi_block, dap_chain_datum_emission_get_size((byte_t*)l_emi_block), + dap_assert(dap_ledger_token_emission_add(a_ledger, (byte_t*)l_emi_block, dap_chain_datum_emission_get_size((byte_t*)l_emi_block), &l_emi_block_hash, false), "Test for emission rejection to an address from the prohibited list."); //Check emission at addr @@ -339,49 +341,53 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a l_emi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_emi); dap_chain_hash_fast_t l_emi_hash = {0}; dap_hash_fast(l_emi, dap_chain_datum_emission_get_size((uint8_t*)l_emi), &l_emi_hash); - dap_assert(!dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_emi, dap_chain_datum_emission_get_size((byte_t*)l_emi), + dap_assert(!dap_ledger_token_emission_add(a_ledger, (byte_t*)l_emi, dap_chain_datum_emission_get_size((byte_t*)l_emi), &l_emi_hash, false), "Emission test for a non-blacklisted address."); - dap_chain_datum_tx_t *l_btx_addr2 = dap_chain_ledger_test_create_datum_base_tx(l_emi, &l_emi_hash, + dap_chain_datum_tx_t *l_btx_addr2 = dap_ledger_test_create_datum_base_tx(l_emi, &l_emi_hash, *l_addr_2->addr, a_cert); dap_hash_fast_t l_btx_addr2_hash = {0}; dap_hash_fast(l_btx_addr2, dap_chain_datum_tx_get_size(l_btx_addr2), &l_btx_addr2_hash); - dap_assert_PIF(!dap_chain_ledger_tx_add(a_ledger, l_btx_addr2, &l_btx_addr2_hash, false), + dap_assert_PIF(!dap_ledger_tx_add(a_ledger, l_btx_addr2, &l_btx_addr2_hash, false), "Can't add base tx in white address"); //Check tx in addr from block list - dap_chain_datum_tx_t *l_tx_to_addr1 = dap_chain_ledger_test_create_tx(l_addr_4->enc_key, &l_btx_addr2_hash, + dap_chain_datum_tx_t *l_tx_to_addr1 = dap_ledger_test_create_tx(l_addr_4->enc_key, &l_btx_addr2_hash, l_addr_1->addr, dap_chain_uint256_from(s_total_supply)); dap_hash_fast_t l_tx_addr1_hash = {0}; dap_hash_fast(l_tx_to_addr1, dap_chain_datum_tx_get_size(l_tx_to_addr1), &l_tx_addr1_hash); - dap_assert(dap_chain_ledger_tx_add(a_ledger, l_tx_to_addr1, &l_tx_addr1_hash, false), "Transfer test to a forbidden address."); + dap_assert(dap_ledger_tx_add(a_ledger, l_tx_to_addr1, &l_tx_addr1_hash, false), "Transfer test to a forbidden address."); //Check tx in addr from list - dap_chain_datum_tx_t *l_tx_to_addr3 = dap_chain_ledger_test_create_tx(l_addr_4->enc_key, &l_tx_addr1_hash, + dap_chain_datum_tx_t *l_tx_to_addr3 = dap_ledger_test_create_tx(l_addr_4->enc_key, &l_tx_addr1_hash, l_addr_3->addr, dap_chain_uint256_from(s_total_supply)); dap_hash_fast_t l_tx_addr3_hash = {0}; dap_hash_fast(l_tx_to_addr3, dap_chain_datum_tx_get_size(l_tx_to_addr3), &l_tx_addr3_hash); - dap_assert(dap_chain_ledger_tx_add(a_ledger, l_tx_to_addr3, &l_tx_addr3_hash, false), "Transfer test to a not forbidden address."); + dap_assert(dap_ledger_tx_add(a_ledger, l_tx_to_addr3, &l_tx_addr3_hash, false), "Transfer test to a not forbidden address."); } } -void dap_chain_ledger_test_run(void){ +void dap_ledger_test_run(void){ dap_chain_net_id_t l_iddn = {0}; dap_sscanf("0xFA0", "0x%16"DAP_UINT64_FORMAT_x, &l_iddn.uint64); - dap_print_module_name("dap_chain_ledger"); + dap_print_module_name("dap_ledger"); uint16_t l_flags = 0; - l_flags |= DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION; - dap_ledger_t *l_ledger = dap_chain_ledger_create(l_flags, l_iddn, "Snet", s_token_ticker, NULL); + l_flags |= DAP_LEDGER_CHECK_TOKEN_EMISSION; + dap_chain_net_t *l_net = DAP_NEW_Z(dap_chain_net_t); + l_net->pub.id = l_iddn; + l_net->pub.native_ticker = s_token_ticker; + l_net->pub.name = "Snet"; + dap_ledger_t *l_ledger = dap_ledger_create(l_net, l_flags); char *l_seed_ph = "H58i9GJKbn91238937^#$t6cjdf"; size_t l_seed_ph_size = strlen(l_seed_ph); dap_cert_t *l_cert = dap_cert_generate_mem_with_seed("testCert", DAP_ENC_KEY_TYPE_SIG_PICNIC, l_seed_ph, l_seed_ph_size); size_t l_token_decl_size = 0; - dap_chain_datum_token_t *l_token_decl = dap_chain_ledger_test_create_datum_decl(l_cert, + dap_chain_datum_token_t *l_token_decl = dap_ledger_test_create_datum_decl(l_cert, &l_token_decl_size, s_token_ticker, dap_chain_uint256_from(s_total_supply), NULL, 0, DAP_CHAIN_DATUM_TOKEN_FLAG_NONE); dap_assert_PIF(l_token_decl || l_token_decl_size == 0, "Generate token declaration."); int l_check_added_decl_token = 0; - l_check_added_decl_token = dap_chain_ledger_token_decl_add_check(l_ledger, l_token_decl, l_token_decl_size); + l_check_added_decl_token = dap_ledger_token_decl_add_check(l_ledger, l_token_decl, l_token_decl_size); dap_assert_PIF(l_check_added_decl_token == 0, "Checking whether it is possible to add a token declaration to ledger."); - dap_assert_PIF(!dap_chain_ledger_token_add(l_ledger, l_token_decl, l_token_decl_size), "Adding token declaration to ledger."); + dap_assert_PIF(!dap_ledger_token_add(l_ledger, l_token_decl, l_token_decl_size), "Adding token declaration to ledger."); // Create emission dap_chain_addr_t l_addr = {0}; @@ -391,38 +397,38 @@ void dap_chain_ledger_test_run(void){ size_t l_emi_size = dap_chain_datum_emission_get_size((byte_t*)l_emi_sign); dap_chain_hash_fast_t l_emi_hash = {0}; dap_hash_fast(l_emi, l_emi_size, &l_emi_hash); - int l_emi_check = dap_chain_ledger_token_emission_add_check(l_ledger, (byte_t*)l_emi_sign, l_emi_size, &l_emi_hash); + int l_emi_check = dap_ledger_token_emission_add_check(l_ledger, (byte_t*)l_emi_sign, l_emi_size, &l_emi_hash); dap_assert_PIF(l_emi_check == 0, "check emission for add in ledger"); - dap_assert_PIF(!dap_chain_ledger_token_emission_add(l_ledger, (byte_t*)l_emi_sign, l_emi_size, &l_emi_hash, false), "Added emission in ledger"); + dap_assert_PIF(!dap_ledger_token_emission_add(l_ledger, (byte_t*)l_emi_sign, l_emi_size, &l_emi_hash, false), "Added emission in ledger"); //first base tx - dap_chain_datum_tx_t *l_base_tx = dap_chain_ledger_test_create_datum_base_tx(l_emi_sign, &l_emi_hash, l_addr, l_cert); + dap_chain_datum_tx_t *l_base_tx = dap_ledger_test_create_datum_base_tx(l_emi_sign, &l_emi_hash, l_addr, l_cert); size_t l_base_tx_size = dap_chain_datum_tx_get_size(l_base_tx); dap_hash_fast_t l_hash_btx = {0}; dap_hash_fast(l_base_tx, l_base_tx_size, &l_hash_btx); - dap_assert_PIF(!dap_chain_ledger_tx_add_check(l_ledger, l_base_tx, l_base_tx_size, &l_hash_btx), "Check can added base tx in ledger"); - dap_assert_PIF(!dap_chain_ledger_tx_add(l_ledger, l_base_tx, &l_hash_btx, false), "Added base tx in ledger."); + dap_assert_PIF(!dap_ledger_tx_add_check(l_ledger, l_base_tx, l_base_tx_size, &l_hash_btx), "Check can added base tx in ledger"); + dap_assert_PIF(!dap_ledger_tx_add(l_ledger, l_base_tx, &l_hash_btx, false), "Added base tx in ledger."); uint256_t l_balance_example = dap_chain_uint256_from(s_standard_value_tx); - uint256_t l_balance = dap_chain_ledger_calc_balance(l_ledger, &l_addr, s_token_ticker); + uint256_t l_balance = dap_ledger_calc_balance(l_ledger, &l_addr, s_token_ticker); uint256_t l_fee = dap_chain_uint256_from(s_fee); SUM_256_256(l_balance,l_fee,&l_balance); dap_assert_PIF(!compare256(l_balance, l_balance_example), "Checking the availability of the necessary balance " "on the wallet after the first transaction."); dap_pass_msg("Validation of the declaration of the tocen, creation of an emission and a basic transaction using this in the ledger."); //second base tx - dap_chain_datum_tx_t *l_base_tx_second = dap_chain_ledger_test_create_datum_base_tx(l_emi_sign, &l_emi_hash, l_addr, l_cert); + dap_chain_datum_tx_t *l_base_tx_second = dap_ledger_test_create_datum_base_tx(l_emi_sign, &l_emi_hash, l_addr, l_cert); size_t l_base_tx_size2 = dap_chain_datum_tx_get_size(l_base_tx_second); dap_hash_fast_t l_hash_btx_second = {0}; dap_hash_fast(l_base_tx_second, l_base_tx_size2, &l_hash_btx_second); - if (dap_chain_ledger_tx_add_check(l_ledger, l_base_tx_second, l_base_tx_size2, &l_hash_btx_second)) { + if (dap_ledger_tx_add_check(l_ledger, l_base_tx_second, l_base_tx_size2, &l_hash_btx_second)) { dap_pass_msg("Checking can added second base tx in ledger"); } - if (dap_chain_ledger_tx_add(l_ledger, l_base_tx_second, &l_hash_btx_second, false)){ + if (dap_ledger_tx_add(l_ledger, l_base_tx_second, &l_hash_btx_second, false)){ dap_pass_msg("Checking for a failure to add a second base transaction for the same issue to the ledger."); } else { dap_fail("Checking for a failure to add a second base transaction for the same issue to the ledger."); } - dap_chain_ledger_test_double_spending(l_ledger, &l_hash_btx, l_cert->enc_key, l_iddn); - dap_chain_ledger_test_excess_supply(l_ledger, l_cert, &l_addr); - dap_chain_ledger_test_write_back_list(l_ledger, l_cert, l_iddn); + dap_ledger_test_double_spending(l_ledger, &l_hash_btx, l_cert->enc_key, l_iddn); + dap_ledger_test_excess_supply(l_ledger, l_cert, &l_addr); + dap_ledger_test_write_back_list(l_ledger, l_cert, l_iddn); } diff --git a/modules/chain/tests/include/dap_chain_ledger_tests.h b/modules/chain/tests/include/dap_chain_ledger_tests.h index 5d36be4f1b..0018b3e6ce 100644 --- a/modules/chain/tests/include/dap_chain_ledger_tests.h +++ b/modules/chain/tests/include/dap_chain_ledger_tests.h @@ -1,6 +1,3 @@ -#include "dap_test.h" #include "dap_chain_ledger.h" -void dap_chain_ledger_test_run(void); - -//dap_ledger_t *dap_chain_ledger_create_test(); +void dap_ledger_test_run(void); diff --git a/modules/chain/tests/main.c b/modules/chain/tests/main.c index 0d111fd5e9..2af8441cfc 100644 --- a/modules/chain/tests/main.c +++ b/modules/chain/tests/main.c @@ -1,5 +1,5 @@ #include "dap_chain_ledger_tests.h" int main(void){ - dap_chain_ledger_test_run(); + dap_ledger_test_run(); return 0; -} \ No newline at end of file +} diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c index a0d7fb5a36..2481153ee9 100644 --- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c +++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c @@ -412,7 +412,7 @@ static void s_grace_period_start(dap_chain_net_srv_grace_t *a_grace) return; } - l_tx = a_grace->usage->is_waiting_new_tx_cond ? NULL : dap_chain_ledger_tx_find_by_hash(l_ledger, &a_grace->usage->tx_cond_hash); + l_tx = a_grace->usage->is_waiting_new_tx_cond ? NULL : dap_ledger_tx_find_by_hash(l_ledger, &a_grace->usage->tx_cond_hash); if (!l_tx) { // No tx cond transaction, start grace-period if (!a_grace->usage->is_active){ dap_chain_net_srv_banlist_item_t *l_item = NULL; @@ -569,7 +569,7 @@ static void s_grace_period_start(dap_chain_net_srv_grace_t *a_grace) return; } - const char *l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &a_grace->usage->tx_cond_hash); + const char *l_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &a_grace->usage->tx_cond_hash); if (!l_ticker) { char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; dap_hash_fast_to_str(&a_grace->usage->tx_cond_hash, l_hash_str, sizeof(l_hash_str)); @@ -806,7 +806,7 @@ static bool s_grace_period_finish(usages_in_grace_t *a_grace_item) RET_WITH_DEL_A_GRACE; } log_it(L_INFO, "Grace period is over! Check tx in ledger."); - l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &l_grace->usage->tx_cond_hash); + l_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_grace->usage->tx_cond_hash); if ( ! l_tx ){ // No tx cond transaction, start grace-period log_it( L_WARNING, "No tx cond transaction"); l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND ; @@ -843,7 +843,7 @@ static bool s_grace_period_finish(usages_in_grace_t *a_grace_item) dap_chain_net_srv_price_t * l_price = NULL; const char * l_ticker = NULL; - l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_grace->usage->tx_cond_hash); + l_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_grace->usage->tx_cond_hash); dap_stpcpy(l_grace->usage->token_ticker, l_ticker); if (dap_hash_fast_is_blank(&l_grace->usage->static_order_hash)){ @@ -1543,7 +1543,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) break; } - dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_usage->net->pub.ledger, &l_responce->hdr.tx_cond); + dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_usage->net->pub.ledger, &l_responce->hdr.tx_cond); if (l_tx){ // Replace if (l_curr_grace_item){ diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c index dc3cae2a85..0dfb3c3f6e 100644 --- a/modules/common/dap_chain_datum.c +++ b/modules/common/dap_chain_datum.c @@ -317,6 +317,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, ((dap_chain_tx_in_ems_t*)item)->header.token_emission_chain_id.uint64); DAP_DELETE(l_hash_str); } break; + /* case TX_ITEM_TYPE_IN_EMS_EXT: { l_hash_tmp = &((dap_chain_tx_in_ems_ext_t*)item)->header.ext_tx_hash; l_hash_str = dap_strcmp(a_hash_out_type, "hex") @@ -336,7 +337,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, l_hash_str, ((dap_chain_tx_in_ems_ext_t*)item)->header.ext_tx_out_idx); DAP_DELETE(l_hash_str); - } break; + } break; */ case TX_ITEM_TYPE_SIG: { l_sign_tmp = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)item); dap_sign_get_information(l_sign_tmp, a_str_out, a_hash_out_type); @@ -503,11 +504,10 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, DAP_DELETE(l_hash_str); } break; case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: { -// char *l_value_str = dap_chain_balance_print(((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_value); char *l_rate_str = dap_chain_balance_to_coins(((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.rate); dap_string_append_printf(a_str_out, "\t\t\t net id: 0x%016"DAP_UINT64_FORMAT_x"\n" "\t\t\t buy_token: %s\n" - "\t\t\t rate: %s (%s)\n", + "\t\t\t rate: %s\n", ((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_net_id.uint64, ((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_token, l_rate_str); @@ -556,9 +556,9 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, /** * @brief dap_chain_net_dump_datum * process datum verification process. Can be: - * if DAP_CHAIN_DATUM_TX, called dap_chain_ledger_tx_add_check - * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_chain_ledger_token_decl_add_check - * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_chain_ledger_token_emission_add_check + * if DAP_CHAIN_DATUM_TX, called dap_ledger_tx_add_check + * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_ledger_token_decl_add_check + * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_ledger_token_emission_add_check * @param a_str_out * @param a_datum */ @@ -688,8 +688,8 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c case DAP_CHAIN_DATUM_TOKEN_EMISSION: { size_t l_emisssion_size = a_datum->header.data_size; dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_datum->data, &l_emisssion_size); - char *l_value_str = dap_chain_balance_print(l_emission->hdr.value_256); - char *l_coins_str = dap_chain_balance_to_coins(l_emission->hdr.value_256); + char *l_value_str = dap_chain_balance_print(l_emission->hdr.value); + char *l_coins_str = dap_chain_balance_to_coins(l_emission->hdr.value); char *l_addr_str = dap_chain_addr_to_str(&(l_emission->hdr.address)); dap_string_append_printf(a_str_out, "emission: hash %s\n\t%s(%s) %s, type: %s, version: %d\n", l_hash_str, diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c index 5c9ca94b59..a4e94e5859 100644 --- a/modules/common/dap_chain_datum_decree.c +++ b/modules/common/dap_chain_datum_decree.c @@ -61,6 +61,13 @@ int dap_chain_datum_decree_get_fee(dap_chain_datum_decree_t *a_decree, uint256_t return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_fee_value); 0; }) : 1; } +int dap_chain_datum_decree_get_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_value) +{ + dap_return_val_if_fail(a_decree && a_value, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE); + return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_value); 0; }) : 1; +} + int dap_chain_datum_decree_get_fee_addr(dap_chain_datum_decree_t *a_decree, dap_chain_addr_t *a_fee_wallet) { if(!a_decree || !a_fee_wallet) { @@ -179,9 +186,19 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree dap_tsd_t *l_tsd = (dap_tsd_t *)((byte_t*)a_decree->data_n_signs + l_offset); l_offset += dap_tsd_size(l_tsd); switch(l_tsd->type) { + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE: + if (l_tsd->size > sizeof(uint256_t)){ + dap_string_append_printf(a_str_out, "\tValue: <WRONG SIZE>\n"); + break; + } + uint256_t l_value = uint256_0; + _dap_tsd_get_scalar(l_tsd, &l_value); + char *l_value_str = dap_chain_balance_print(l_value); + dap_string_append_printf(a_str_out, "\tValue: %s\n", l_value_str); + DAP_DELETE(l_value_str); + break; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN: break; -// return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN"; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE: if (l_tsd->size > sizeof(uint256_t)){ dap_string_append_printf(a_str_out, "\tFee: <WRONG SIZE>\n"); @@ -358,7 +375,7 @@ void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_sign } } -dap_chain_datum_decree_t* dap_chain_datum_decree_in_cycle(dap_cert_t ** a_certs, dap_chain_datum_decree_t *a_datum_decree, +dap_chain_datum_decree_t* dap_chain_datum_decree_sign_in_cycle(dap_cert_t ** a_certs, dap_chain_datum_decree_t *a_datum_decree, size_t a_certs_count, size_t *a_total_sign_count) { size_t l_cur_sign_offset = a_datum_decree->header.data_size + a_datum_decree->header.signs_size; diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index 4566139492..352b87901f 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -358,7 +358,7 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_create(uint256_t a_va return NULL; } l_emission->hdr.version = 3; - l_emission->hdr.value_256 = a_value; + l_emission->hdr.value = a_value; strncpy(l_emission->hdr.ticker, a_ticker, DAP_CHAIN_TICKER_SIZE_MAX - 1); l_emission->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH; l_emission->hdr.address = *a_addr; @@ -406,8 +406,8 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_read(byte_t *a_emissi memcpy((byte_t *)l_emission + sizeof(l_emission->hdr), a_emission_serial + l_old_hdr_size, (uint32_t)(l_emission_size - l_old_hdr_size)); - l_emission->hdr.value_256 = dap_chain_uint256_from( - ((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.value); + l_emission->hdr.value = dap_chain_uint256_from( + ((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.value64); l_emission_size += l_add_size; (*a_emission_size) = l_emission_size; } else { @@ -417,8 +417,8 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_read(byte_t *a_emissi return NULL; } if (((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.version == 1) - l_emission->hdr.value_256 = dap_chain_uint256_from( - ((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.value); + l_emission->hdr.value = dap_chain_uint256_from( + ((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.value64); } return l_emission; } diff --git a/modules/common/dap_chain_datum_tx.c b/modules/common/dap_chain_datum_tx.c index 01c40f6e37..78e9268f6c 100644 --- a/modules/common/dap_chain_datum_tx.c +++ b/modules/common/dap_chain_datum_tx.c @@ -158,6 +158,17 @@ uint256_t dap_chain_datum_tx_add_in_cond_item_list(dap_chain_datum_tx_t **a_tx, } return l_value_to_items; } + +int dap_chain_datum_tx_add_in_reward_item(dap_chain_datum_tx_t **a_tx, dap_chain_hash_fast_t *a_block_hash) +{ + dap_chain_tx_in_reward_t *l_tx_in_reward = dap_chain_datum_tx_item_in_reward_create(a_block_hash); + if (!l_tx_in_reward) + return -1; + dap_chain_datum_tx_add_item(a_tx, (uint8_t*)l_tx_in_reward); + DAP_DELETE(l_tx_in_reward); + return 1; +} + /** * Create 'out_cond' item with fee value and insert to transaction * diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index 233099e58e..782c239dfa 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -31,10 +31,6 @@ #include "dap_sign.h" #include "dap_hash.h" #include "dap_chain_datum_tx.h" -#include "dap_chain_datum_tx_in.h" -#include "dap_chain_datum_tx_out.h" -#include "dap_chain_datum_tx_in_cond.h" -#include "dap_chain_datum_tx_out_cond.h" #include "dap_chain_datum_tx_items.h" static size_t dap_chain_tx_in_get_size(const dap_chain_tx_in_t *a_item) @@ -92,13 +88,19 @@ static size_t dap_chain_tx_sig_get_size(const dap_chain_tx_sig_t *a_item) return size; } -static size_t dap_chain_tx_token_get_size(const dap_chain_tx_in_ems_t *a_item) +static size_t dap_chain_tx_in_ems_get_size(const dap_chain_tx_in_ems_t *a_item) { (void) a_item; size_t size = sizeof(dap_chain_tx_in_ems_t); return size; } +static size_t dap_chain_tx_in_reward_get_size(const dap_chain_tx_in_reward_t UNUSED_ARG *a_item) +{ + size_t size = sizeof(dap_chain_tx_in_reward_t); + return size; +} + static size_t dap_chain_datum_tx_receipt_get_size(const dap_chain_datum_tx_receipt_t *a_item) { size_t size = a_item->size; @@ -120,6 +122,10 @@ dap_chain_tx_item_type_t dap_chain_datum_tx_item_str_to_type(const char *a_datum return TX_ITEM_TYPE_UNKNOWN; if(!dap_strcmp(a_datum_name, "in")) return TX_ITEM_TYPE_IN; + else if(!dap_strcmp(a_datum_name, "in_ems")) + return TX_ITEM_TYPE_IN_EMS; + else if(!dap_strcmp(a_datum_name, "in_reward")) + return TX_ITEM_TYPE_IN_REWARD; else if(!dap_strcmp(a_datum_name, "out")) return TX_ITEM_TYPE_OUT; else if(!dap_strcmp(a_datum_name, "out_ext")) @@ -186,10 +192,10 @@ size_t dap_chain_datum_item_tx_get_size(const void *a_item) case TX_ITEM_TYPE_IN: // Transaction inputs size = dap_chain_tx_in_get_size((const dap_chain_tx_in_t*) a_item); break; - case TX_ITEM_TYPE_OUT_OLD: // Transaction outputs + case TX_ITEM_TYPE_OUT_OLD: //64 size = dap_chain_tx_out_get_size((const dap_chain_tx_out_old_t*) a_item); break; - case TX_ITEM_TYPE_OUT: // 256 + case TX_ITEM_TYPE_OUT: // Transaction outputs size = dap_chain_256_tx_out_get_size((const dap_chain_tx_out_t*) a_item); break; case TX_ITEM_TYPE_OUT_EXT: // Exchange transaction outputs @@ -201,10 +207,7 @@ size_t dap_chain_datum_item_tx_get_size(const void *a_item) case TX_ITEM_TYPE_IN_COND: // Transaction inputs with condition size = dap_chain_tx_in_cond_get_size((const dap_chain_tx_in_cond_t*) a_item); break; - case TX_ITEM_TYPE_OUT_COND_OLD: // Transaction output with condition - size = 0; // obsolete dap_chain_tx_out_cond_get_size((const dap_chain_tx_out_cond_t*) a_item); - break; - case TX_ITEM_TYPE_OUT_COND: // 256 + case TX_ITEM_TYPE_OUT_COND: // Condtional output size = dap_chain_tx_out_cond_get_size((const dap_chain_tx_out_cond_t *)a_item); break; case TX_ITEM_TYPE_PKEY: // Transaction public keys @@ -213,8 +216,11 @@ size_t dap_chain_datum_item_tx_get_size(const void *a_item) case TX_ITEM_TYPE_SIG: // Transaction signatures size = dap_chain_tx_sig_get_size((const dap_chain_tx_sig_t*) a_item); break; - case TX_ITEM_TYPE_IN_EMS: // token item - size = dap_chain_tx_token_get_size((const dap_chain_tx_in_ems_t*) a_item); + case TX_ITEM_TYPE_IN_EMS: // token emission pointer + size = dap_chain_tx_in_ems_get_size((const dap_chain_tx_in_ems_t*) a_item); + break; + case TX_ITEM_TYPE_IN_REWARD: // block emission pointer + size = dap_chain_tx_in_reward_get_size((const dap_chain_tx_in_reward_t *)a_item); break; case TX_ITEM_TYPE_TSD: size = dap_chain_tx_tsd_get_size((const dap_chain_tx_tsd_t*)a_item); @@ -269,15 +275,26 @@ dap_chain_tx_in_t* dap_chain_datum_tx_item_in_create(dap_chain_hash_fast_t *a_tx if(!a_tx_prev_hash) return NULL; dap_chain_tx_in_t *l_item = DAP_NEW_Z(dap_chain_tx_in_t); - if (!l_item) { + if (!l_item) return NULL; - } l_item->header.type = TX_ITEM_TYPE_IN; l_item->header.tx_out_prev_idx = a_tx_out_prev_idx; l_item->header.tx_prev_hash = *a_tx_prev_hash; return l_item; } +dap_chain_tx_in_reward_t *dap_chain_datum_tx_item_in_reward_create(dap_chain_hash_fast_t *a_block_hash) +{ + if (!a_block_hash) + return NULL; + dap_chain_tx_in_reward_t *l_item = DAP_NEW_Z(dap_chain_tx_in_reward_t); + if (!l_item) + return NULL; + l_item->type = TX_ITEM_TYPE_IN_REWARD; + l_item->block_hash = *a_block_hash; + return l_item; +} + /** * Create tsd section */ @@ -741,7 +758,7 @@ uint8_t* dap_chain_datum_tx_item_get( dap_chain_datum_tx_t *a_tx, int *a_item_id (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN) || (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_COND) || (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_EMS) || - (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_EMS_EXT)) { + (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_REWARD)) { if(a_item_idx) *a_item_idx = l_item_idx; if(a_item_out_size) diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h index 86e0a0d917..ddef34874a 100644 --- a/modules/common/include/dap_chain_common.h +++ b/modules/common/include/dap_chain_common.h @@ -112,7 +112,7 @@ typedef struct dap_chain_addr{ dap_chain_hash_fast_t hash_fast; } DAP_ALIGN_PACKED data; dap_chain_hash_fast_t checksum; -} DAP_ALIGN_PACKED dap_chain_addr_t; +} DAP_ALIGN_PACKED dap_chain_addr_t; #define DAP_CHAIN_NET_SRV_UID_SIZE 8 @@ -182,26 +182,26 @@ typedef union { } DAP_ALIGN_PACKED dap_chain_net_srv_price_unit_uid_t; enum dap_chain_tx_item_type { - TX_ITEM_TYPE_IN = 0x00, /// @brief Transaction: inputs + /// @brief Transaction: inputs + TX_ITEM_TYPE_IN = 0x00, + TX_ITEM_TYPE_IN_COND = 0x50, + TX_ITEM_TYPE_IN_REWARD = 0x07, + TX_ITEM_TYPE_IN_EMS = 0x40, - TX_ITEM_TYPE_OUT_OLD = 0x10, /// @brief Transaction: outputs + /// @brief Transaction: outputs + TX_ITEM_TYPE_OUT_OLD = 0x10, // Deprecated TX_ITEM_TYPE_OUT_EXT = 0x11, - TX_ITEM_TYPE_OUT = 0x12, // 256 + TX_ITEM_TYPE_OUT = 0x12, + TX_ITEM_TYPE_OUT_COND = 0x61, + /// @brief Transaction: misc TX_ITEM_TYPE_PKEY = 0x20, TX_ITEM_TYPE_SIG = 0x30, - TX_ITEM_TYPE_IN_EMS = 0x40, - TX_ITEM_TYPE_IN_EMS_EXT = 0x41, - - TX_ITEM_TYPE_IN_COND = 0x50, /// @brief Transaction: conditon inputs - - TX_ITEM_TYPE_OUT_COND_OLD = 0x60, // Obsolete - TX_ITEM_TYPE_OUT_COND = 0x61, /// @brief Transaction: 256 bit conditon outputs - TX_ITEM_TYPE_RECEIPT = 0x70, - TX_ITEM_TYPE_TSD = 0x80, + /// @brief Virtual types for items enumearting + TX_ITEM_TYPE_IN_EMS_LOCK = 0xf1, TX_ITEM_TYPE_IN_ALL = 0xfd, TX_ITEM_TYPE_OUT_ALL = 0xfe, TX_ITEM_TYPE_ANY = 0xff diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h index 2d88482561..6cef21196f 100644 --- a/modules/common/include/dap_chain_datum_decree.h +++ b/modules/common/include/dap_chain_datum_decree.h @@ -72,8 +72,10 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_ #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT 0x0008 #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN 0x0009 #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN 0x000A +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD 0x000B // DECREE TSD types +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE 0x0100 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN 0x0101 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE 0x0102 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER 0x0103 @@ -99,17 +101,19 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN: return "DECREE_COMMON_SUBTYPE_OWNERS_MIN"; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE: - return "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE"; + return "DECREE_COMMON_SUBTYPE_STAKE_APPROVE"; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE: - return "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE"; + return "DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE"; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE: - return "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE"; + return "DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE"; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT: - return"DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT"; + return "COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT"; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN: - return "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN"; + return "DECREE_COMMON_SUBTYPE_BAN"; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN: - return "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN"; + return "DECREE_COMMON_SUBTYPE_UNBAN"; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD: + return "DECREE_COMMON_SUBTYPE_REWARD"; default: return "DECREE_SUBTYPE_UNKNOWN"; } @@ -117,6 +121,8 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d DAP_STATIC_INLINE const char *dap_chain_datum_decree_tsd_type_to_str(uint16_t a_decree_tsd_type) { switch (a_decree_tsd_type) { + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE"; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN: return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN"; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE: @@ -207,6 +213,15 @@ int dap_chain_datum_decree_get_stake_tx_hash(dap_chain_datum_decree_t *a_decree, */ int dap_chain_datum_decree_get_stake_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_stake_value); + +/** + * @brief dap_chain_datum_decree_get_stake_value get stake value + * @param a_decree pointer to decree + * @param a_stake_value pointer to stake value buffer + * @return result code. 0 - success + */ +int dap_chain_datum_decree_get_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_value); + /** * @brief dap_chain_datum_decree_get_stake_signing_addr get signing address * @param a_decree pointer to decree @@ -257,7 +272,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type); /** - * @brief dap_chain_datum_decree_in_cycle + * @brief dap_chain_datum_decree_sign_in_cycle * sign data (datum_decree) by certificates (1 or more) * successful count of signes return in l_sign_counter * @param l_certs - array with certificates loaded from dcert file @@ -267,5 +282,5 @@ void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_sign * @param l_sign_counter - counter of successful data signing operation * @return dap_chain_datum_token_t* */ -dap_chain_datum_decree_t* dap_chain_datum_decree_in_cycle(dap_cert_t ** a_certs, dap_chain_datum_decree_t *a_datum_decree, +dap_chain_datum_decree_t* dap_chain_datum_decree_sign_in_cycle(dap_cert_t ** a_certs, dap_chain_datum_decree_t *a_datum_decree, size_t a_certs_count, size_t *a_total_sign_count); diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index a47c216189..dcc0c1ce25 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -438,15 +438,15 @@ struct DAP_ALIGN_PACKED dap_chain_emission_header_v0 { }; // Token emission -typedef struct dap_chain_datum_token_emission{ +typedef struct dap_chain_datum_token_emission { struct { uint8_t version; - uint8_t type; // Emission Type + uint8_t type; // Emission Type char ticker[DAP_CHAIN_TICKER_SIZE_MAX]; - dap_chain_addr_t address; // Emission holder's address + dap_chain_addr_t address; // Emission holder's address union { - uint64_t value; - uint256_t value_256; + uint64_t value64; // Deprecated + uint256_t value; }; uint8_t nonce[DAP_CHAIN_DATUM_NONCE_SIZE]; } DAP_ALIGN_PACKED hdr; @@ -457,7 +457,7 @@ typedef struct dap_chain_datum_token_emission{ uint64_t lock_time; } DAP_ALIGN_PACKED type_presale; struct { - uint64_t value_start;// Default value. Static if nothing else is defined + uint64_t value_start; // Default value. Static if nothing else is defined char value_change_algo_codename[32]; } DAP_ALIGN_PACKED type_atom_owner; struct { @@ -467,10 +467,10 @@ typedef struct dap_chain_datum_token_emission{ uint64_t size; uint64_t tsd_total_size; uint16_t signs_count; - } DAP_ALIGN_PACKED type_auth;// Signs if exists + } DAP_ALIGN_PACKED type_auth; byte_t free_space[128]; // For future changes } data; - byte_t tsd_n_signs[]; + byte_t tsd_n_signs[]; // TSD sections and signs if any } DAP_ALIGN_PACKED dap_chain_datum_token_emission_t; // Different emissions type diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h index 92b0a8cacb..f2cc1c7e4e 100644 --- a/modules/common/include/dap_chain_datum_tx.h +++ b/modules/common/include/dap_chain_datum_tx.h @@ -99,6 +99,13 @@ int dap_chain_datum_tx_add_in_cond_item(dap_chain_datum_tx_t **a_tx, dap_chain_h */ uint256_t dap_chain_datum_tx_add_in_cond_item_list(dap_chain_datum_tx_t **a_tx, dap_list_t *a_list_used_out_cound); +/** + * Create 'in_reward' item and insert to transaction + * + * return 1 Ok, -1 Error + */ +int dap_chain_datum_tx_add_in_reward_item(dap_chain_datum_tx_t **a_tx, dap_chain_hash_fast_t *a_block_hash); + /** * Create 'out' item and insert to transaction * diff --git a/modules/common/include/dap_chain_datum_tx_in_cond.h b/modules/common/include/dap_chain_datum_tx_in_cond.h index eda89c996f..cea12feffd 100644 --- a/modules/common/include/dap_chain_datum_tx_in_cond.h +++ b/modules/common/include/dap_chain_datum_tx_in_cond.h @@ -38,5 +38,5 @@ typedef struct dap_chain_tx_in_cond { dap_chain_hash_fast_t tx_prev_hash; /// @param tx_prev_hash @brief Hash of the previous transaction. 0 for generation TX uint32_t tx_out_prev_idx; /// @param tx_prev_idx @brief Previous tx_out index. 0 for generation TX uint32_t receipt_idx; - } header; /// Only header's hash is used for verification -}DAP_ALIGN_PACKED dap_chain_tx_in_cond_t; + } header; +} DAP_ALIGN_PACKED dap_chain_tx_in_cond_t; diff --git a/modules/common/include/dap_chain_datum_tx_in_reward.h b/modules/common/include/dap_chain_datum_tx_in_reward.h new file mode 100644 index 0000000000..4a12539114 --- /dev/null +++ b/modules/common/include/dap_chain_datum_tx_in_reward.h @@ -0,0 +1,30 @@ +/* +* Authors: +* Roman Khlopkov <roman.khlopkov@demlabs.net> +* Cellframe https://cellframe.net +* DeM Labs Inc. https://demlabs.net +* Copyright (c) 2017-2023 +* All rights reserved. + +This file is part of DAP SDK the open source project + +DAP SDK is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +DAP SDK is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#include "dap_common.h" +#include "dap_chain_datum_tx_items.h" + +typedef struct dap_chain_tx_in_reward { + dap_chain_tx_item_type_t type : 8; /// @param type @brief Transaction item type + dap_hash_t block_hash; /// @param block_hash @brief Hash of the block signed with current validator +} DAP_ALIGN_PACKED dap_chain_tx_in_reward_t; diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h index d9815983dd..9d31a756c3 100644 --- a/modules/common/include/dap_chain_datum_tx_items.h +++ b/modules/common/include/dap_chain_datum_tx_items.h @@ -42,6 +42,7 @@ #include "dap_chain_datum_tx_in_ems.h" #include "dap_chain_datum_tx_receipt.h" #include "dap_chain_datum_tx_tsd.h" +#include "dap_chain_datum_tx_in_reward.h" /** * Get item type @@ -71,13 +72,11 @@ DAP_STATIC_INLINE const char * dap_chain_datum_tx_item_type_to_str(dap_chain_tx_ case TX_ITEM_TYPE_PKEY: return "TX_ITEM_TYPE_PKEY"; case TX_ITEM_TYPE_SIG: return "TX_ITEM_TYPE_SIG"; case TX_ITEM_TYPE_IN_EMS: return "TX_ITEM_TYPE_IN_EMS"; - case TX_ITEM_TYPE_IN_EMS_EXT: return "TX_ITEM_TYPE_IN_EMS_EXT"; + case TX_ITEM_TYPE_IN_REWARD: return "TX_ITEM_TYPE_IN_REWARD"; case TX_ITEM_TYPE_IN_COND: return "TX_ITEM_TYPE_IN_COND"; case TX_ITEM_TYPE_OUT_COND: return "TX_ITEM_TYPE_OUT_COND"; // 256 case TX_ITEM_TYPE_RECEIPT: return "TX_ITEM_TYPE_RECEIPT"; case TX_ITEM_TYPE_TSD: return "TX_ITEM_TYPE_TSD"; - case TX_ITEM_TYPE_OUT_ALL: return "TX_ITEM_TYPE_OUT_OLDALL"; - case TX_ITEM_TYPE_ANY: return "TX_ITEM_TYPE_ANY"; default: return "UNDEFINED"; } } @@ -119,6 +118,8 @@ json_object *dap_chain_datum_tx_item_in_ems_to_json(const dap_chain_tx_in_ems_t */ dap_chain_tx_in_t* dap_chain_datum_tx_item_in_create(dap_chain_hash_fast_t *a_tx_prev_hash, uint32_t a_tx_out_prev_idx); +dap_chain_tx_in_reward_t *dap_chain_datum_tx_item_in_reward_create(dap_chain_hash_fast_t *a_block_hash); + json_object* dap_chain_datum_tx_item_in_to_json(dap_chain_tx_in_t *a_in); dap_chain_tx_tsd_t *dap_chain_datum_tx_item_tsd_create(void *a_data, int a_type, size_t a_size); diff --git a/modules/common/include/dap_chain_datum_tx_out.h b/modules/common/include/dap_chain_datum_tx_out.h index 852975d64c..19e136671f 100644 --- a/modules/common/include/dap_chain_datum_tx_out.h +++ b/modules/common/include/dap_chain_datum_tx_out.h @@ -45,6 +45,6 @@ typedef struct dap_chain_tx_out { struct { dap_chain_tx_item_type_t type; /// @param type @brief Transaction item type uint256_t value; /// @param value @brief Number of Datoshis ( DAP/10^9 ) to be transfered - } header; /// Only header's hash is used for verification + } header; dap_chain_addr_t addr; //// } DAP_ALIGN_PACKED dap_chain_tx_out_t; diff --git a/modules/common/include/dap_chain_datum_tx_out_cond.h b/modules/common/include/dap_chain_datum_tx_out_cond.h index 0348c717a2..94fdd48b6c 100644 --- a/modules/common/include/dap_chain_datum_tx_out_cond.h +++ b/modules/common/include/dap_chain_datum_tx_out_cond.h @@ -125,56 +125,3 @@ typedef struct dap_chain_tx_out_cond { uint32_t tsd_size; // Condition parameters size uint8_t tsd[]; // condition parameters, pkey, hash or smth like this } DAP_ALIGN_PACKED dap_chain_tx_out_cond_t; - - -/** - * @struct dap_chain_tx_out - * @brief Transaction item out_cond - */ -typedef struct dap_chain_tx_out_cond_old { // Obsolete - struct { - /// Transaction item type - dap_chain_tx_item_type_t item_type; - /// Condition subtype - dap_chain_tx_out_cond_subtype_t subtype; - /// Number of Datoshis ( DAP/10^9 ) to be reserver for service - uint64_t value; - /// When time expires this output could be used only by transaction owner - dap_time_t ts_expires; - } header; - union { - /// Structure with specific for service pay condition subtype - struct { - /// Public key hash that could use this conditioned outout - dap_chain_hash_fast_t pkey_hash; - /// Service uid that only could be used for this outout - dap_chain_net_srv_uid_t srv_uid; - /// Price unit thats used to check price max - dap_chain_net_srv_price_unit_uid_t unit; - /// Maximum price per unit - uint64_t unit_price_max_datoshi; - } srv_pay; - struct { - // Service uid that only could be used for this outout - dap_chain_net_srv_uid_t srv_uid; - // Token ticker to change to - char token[DAP_CHAIN_TICKER_SIZE_MAX]; - // Chain network to change to - dap_chain_net_id_t net_id; - // Total amount of datoshi to change to - uint64_t value; - } srv_xchange; - struct { - // Service uid that only could be used for this outout - dap_chain_net_srv_uid_t srv_uid; - // Stake holder address - dap_chain_addr_t hldr_addr; - // Fee address - dap_chain_addr_t fee_addr; - // Fee value in percent - long double fee_value; - } srv_stake; - } subtype; - uint32_t params_size; // Condition parameters size - uint8_t params[]; // condition parameters, pkey, hash or smth like this -} DAP_ALIGN_PACKED dap_chain_tx_out_cond_old_t; diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index fae28da629..4b2e112bdc 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -851,7 +851,7 @@ static void s_session_attempt_new(dap_chain_esbocs_session_t *a_session) return; } } - debug_if(PVT(a_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U"." + debug_if(PVT(a_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U". " "All synced validators already tryed their attempts", a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id); @@ -1470,7 +1470,7 @@ static bool s_check_db_callback_fee_collect (UNUSED_ARG dap_global_db_instance_t dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain); dap_list_t *l_block_list = NULL; log_it(L_MSG, "Fee collector start work"); - l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_arg->block_hash); + l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_arg->block_hash); if(!l_block_cache) { log_it(L_WARNING, "The block_cache is empty"); return false; @@ -1482,10 +1482,10 @@ static bool s_check_db_callback_fee_collect (UNUSED_ARG dap_global_db_instance_t return false; } dap_list_free_full(l_list_used_out, NULL); - l_block_list = dap_list_append(l_block_list, l_block_cache); + l_block_list = dap_list_append(l_block_list, DAP_DUP(&l_arg->block_hash)); if(!a_values_count){ if(compare256(l_value_out_block,l_arg->fee_need_cfg) == 1) { - char *l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_arg->key_from, l_arg->a_addr_to, + char *l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_blocks, l_arg->key_from, l_arg->a_addr_to, l_block_list, l_arg->value_fee, "hex"); if(l_hash_tx) { log_it(L_NOTICE, "Fee collect transaction successfully created, hash=%s\n",l_hash_tx); @@ -1503,13 +1503,12 @@ static bool s_check_db_callback_fee_collect (UNUSED_ARG dap_global_db_instance_t for(size_t i=0;i<a_values_count;i++) { dap_hash_fast_t block_hash; dap_chain_hash_fast_from_hex_str(a_values[i].key,&block_hash); - dap_chain_block_cache_t *block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &block_hash); - l_block_list = dap_list_append(l_block_list, block_cache); + l_block_list = dap_list_append(l_block_list, DAP_DUP(&block_hash)); SUM_256_256(*(uint256_t*)a_values[i].value,l_value_gdb,&l_value_gdb); } SUM_256_256(l_value_out_block,l_value_gdb,&l_value_total); if(compare256(l_value_total,l_arg->fee_need_cfg) == 1) { - char *l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_arg->key_from, l_arg->a_addr_to, + char *l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_blocks, l_arg->key_from, l_arg->a_addr_to, l_block_list, l_arg->value_fee, "hex"); if(l_hash_tx) { dap_global_db_del(s_block_fee_group, NULL, NULL, NULL); @@ -1524,7 +1523,7 @@ static bool s_check_db_callback_fee_collect (UNUSED_ARG dap_global_db_instance_t log_it(L_NOTICE, "The block was successfully added to the database"); } } - dap_list_free(l_block_list); + dap_list_free_full(l_block_list, NULL); DAP_DEL_Z(l_arg->a_addr_to); DAP_DELETE(l_arg); return true; @@ -2037,7 +2036,7 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod l_session->chain->net_name, l_session->chain->name, l_message->hdr.round_id, l_validator_addr_str, l_sync_attempt); if (!PVT(l_session->esbocs)->emergency_mode && - !dap_global_db_driver_hash_compare(((struct sync_params *)l_message_data)->db_hash, l_session->db_hash)) { + dap_global_db_driver_hash_compare(((struct sync_params *)l_message_data)->db_hash, l_session->db_hash)) { debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", sync_attempt %"DAP_UINT64_FORMAT_U " SYNC message is rejected cause DB hash mismatch", l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index 2b5537d756..b27a585e03 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -163,14 +163,14 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr if (l_single_channel) SUM_256_256(l_value_need, l_total_fee, &l_value_need); else if (!IS_ZERO_256(l_total_fee)) { - l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, + l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, a_addr_from, l_total_fee, &l_fee_transfer); if (!l_list_fee_out) { log_it(L_WARNING, "Not enough funds to pay fee"); return NULL; } } - dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker, + dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker, a_addr_from, l_value_need, &l_value_transfer); if (!l_list_used_out) { log_it(L_WARNING, "Not enough funds to transfer"); @@ -285,22 +285,17 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr * * return hash_tx Ok, , NULL other Error */ -char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_chain_addr_t* a_addr_to,dap_list_t *a_block_list, +char *dap_chain_mempool_tx_coll_fee_create(dap_chain_cs_blocks_t *a_blocks, dap_enc_key_t *a_key_from, + const dap_chain_addr_t *a_addr_to, dap_list_t *a_block_list, uint256_t a_value_fee, const char *a_hash_out_type) { uint256_t l_value_out = {}; uint256_t l_net_fee = {}; dap_chain_datum_tx_t *l_tx; dap_chain_addr_t l_addr_fee = {}; - dap_chain_t *l_chain = NULL; - if(a_block_list) - l_chain = DAP_CHAIN_CS_BLOCKS((dap_chain_block_cache_t *)a_block_list->data)->chain; - else - { - log_it(L_WARNING, "There aren't block hash"); - return NULL; - } + dap_return_val_if_fail(a_blocks && a_key_from && a_addr_to && a_block_list, NULL); + dap_chain_t *l_chain = a_blocks->chain; bool l_net_fee_used = dap_chain_net_tx_get_fee(l_chain->net_id, &l_net_fee, &l_addr_fee); //add tx if (NULL == (l_tx = dap_chain_datum_tx_create())) { @@ -308,9 +303,33 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_c return NULL; } dap_ledger_t *l_ledger = dap_chain_net_by_id(l_chain->net_id)->pub.ledger; + dap_pkey_t *l_sign_pkey = dap_pkey_from_enc_key(a_key_from); + if (!l_sign_pkey) { + log_it(L_ERROR, "Can't serialize public key of sign certificate"); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } for(dap_list_t *bl = a_block_list; bl; bl = bl->next) { uint256_t l_value_out_block = {}; - dap_chain_block_cache_t *l_block_cache = (dap_chain_block_cache_t *)bl->data; + dap_hash_fast_t *l_block_hash = bl->data; + dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(a_blocks, l_block_hash); + if (!l_block_cache) { + char l_block_hash_str[DAP_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(l_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE); + log_it(L_ERROR, "Can't find cache for block hash %s", l_block_hash_str); + DAP_DELETE(l_sign_pkey); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + //verification of signatures of all blocks + dap_sign_t *l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0); + if (!l_sign || !dap_pkey_compare_with_sign(l_sign_pkey, l_sign)) { + log_it(L_WARNING, "Block %s signature does not match certificate key", l_block_cache->block_hash_str); + DAP_DELETE(l_sign_pkey); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val(l_ledger, l_block_cache, &l_value_out_block); if (!l_list_used_out) continue; @@ -373,8 +392,115 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_c } size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); - //dap_hash_fast_t l_tx_hash; - //dap_hash_fast(l_tx, l_tx_size, &l_tx_hash); + dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size); + DAP_DELETE(l_tx); + char *l_ret = dap_chain_mempool_datum_add(l_datum, l_chain, a_hash_out_type); + DAP_DELETE(l_datum); + return l_ret; +} + + +/** + * Make transfer transaction to collect block sign rewards and place it to the mempool + * + * return hash_tx Ok, NULL Error + */ +char *dap_chain_mempool_tx_reward_create(dap_chain_cs_blocks_t *a_blocks, dap_enc_key_t *a_sign_key, + dap_chain_addr_t *a_addr_to, dap_list_t *a_block_list, + uint256_t a_value_fee, const char *a_hash_out_type) +{ + dap_return_val_if_fail(a_blocks && a_sign_key && a_addr_to && a_block_list, NULL); + dap_chain_t *l_chain = a_blocks->chain; + //add tx + dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); + if (!l_tx) { + log_it(L_ERROR, "Can't create datum tx"); + return NULL; + } + dap_pkey_t *l_sign_pkey = dap_pkey_from_enc_key(a_sign_key); + if (!l_sign_pkey) { + log_it(L_ERROR, "Can't serialize public key of sign certificate"); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + dap_hash_fast_t l_sign_pkey_hash; + dap_pkey_get_hash(l_sign_pkey, &l_sign_pkey_hash); + uint256_t l_value_out = uint256_0; + dap_ledger_t *l_ledger = dap_chain_net_by_id(l_chain->net_id)->pub.ledger; + for (dap_list_t *it = a_block_list; it; it = it->next) { + dap_hash_fast_t *l_block_hash = it->data; + uint256_t l_reward_value = l_chain->callback_calc_reward(l_chain, l_block_hash, l_sign_pkey); + if (IS_ZERO_256(l_reward_value)) { + char l_block_hash_str[DAP_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(l_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE); + log_it(L_WARNING, "Block %s signatures does not match certificate key", l_block_hash_str); + DAP_DELETE(l_sign_pkey); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + if (dap_ledger_is_used_reward(l_ledger, l_block_hash, &l_sign_pkey_hash)) { + char l_block_hash_str[DAP_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(l_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE); + char l_sign_pkey_hash_str[DAP_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(&l_sign_pkey_hash, l_sign_pkey_hash_str, DAP_HASH_FAST_STR_SIZE); + log_it(L_WARNING, "Block %s reward is already collected by signer %s", l_block_hash_str, l_sign_pkey_hash_str); + DAP_DELETE(l_sign_pkey); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + //add 'in_reward' items + if (dap_chain_datum_tx_add_in_reward_item(&l_tx, l_block_hash) != 1) { + log_it(L_ERROR, "Can't create in_reward item for reward collect TX"); + DAP_DELETE(l_sign_pkey); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + SUM_256_256(l_value_out, l_reward_value, &l_value_out); + } + DAP_DELETE(l_sign_pkey); + + uint256_t l_net_fee = uint256_0, l_total_fee = uint256_0; + dap_chain_addr_t l_addr_fee = c_dap_chain_addr_blank; + bool l_net_fee_used = dap_chain_net_tx_get_fee(l_chain->net_id, &l_net_fee, &l_addr_fee); + // Network fee + if (l_net_fee_used) { + if (dap_chain_datum_tx_add_out_item(&l_tx, &l_addr_fee, l_net_fee) == 1) + SUM_256_256(l_total_fee, l_net_fee, &l_total_fee); + else { + log_it(L_WARNING, "Can't create network fee out item for reward collect TX"); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + } + // Validator's fee + if (!IS_ZERO_256(a_value_fee)) { + if (dap_chain_datum_tx_add_fee_item(&l_tx, a_value_fee) == 1) + SUM_256_256(l_total_fee, a_value_fee, &l_total_fee); + else { + log_it(L_WARNING, "Can't create validator fee out item for reward collect TX"); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + } + if (SUBTRACT_256_256(l_value_out, l_total_fee, &l_value_out)) { + log_it(L_WARNING, "The transaction fee is greater than the sum of the block sign rewards"); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + //add 'out' item + if (dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, l_value_out) != 1) { + dap_chain_datum_tx_delete(l_tx); + log_it(L_WARNING, "Can't create out item in transaction fee"); + return NULL; + } + // add 'sign' item + if(dap_chain_datum_tx_add_sign_item(&l_tx, a_sign_key) != 1) { + dap_chain_datum_tx_delete(l_tx); + log_it(L_WARNING, "Can't sign item in transaction fee"); + return NULL; + } + + size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size); DAP_DELETE(l_tx); char *l_ret = dap_chain_mempool_datum_add(l_datum, l_chain, a_hash_out_type); @@ -421,7 +547,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a log_it(L_DEBUG, "Create %"DAP_UINT64_FORMAT_U" transactions, summary %s", a_tx_num, l_balance); DAP_DELETE(l_balance); dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger; - dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker, + dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker, a_addr_from, l_value_need, &l_value_transfer); if (!l_list_used_out) { log_it(L_WARNING,"Not enough funds to transfer"); @@ -567,7 +693,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx_new, l_tx_size); dap_chain_datum_tx_delete(l_tx_new); - //dap_chain_ledger_tx_add( a_chain->ledger, l_tx); + //dap_ledger_tx_add( a_chain->ledger, l_tx); l_objs[i].key = dap_chain_hash_fast_to_str_new(&l_tx_new_hash); //continue; @@ -621,7 +747,7 @@ char* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h const dap_chain_addr_t *a_addr_to, dap_enc_key_t *a_key_tx_sign, dap_chain_datum_tx_receipt_t *a_receipt, const char *a_hash_out_type, int *a_ret_status) { - dap_ledger_t * l_ledger = a_net ? dap_chain_ledger_by_net_name( a_net->pub.name ) : NULL; + dap_ledger_t * l_ledger = a_net ? dap_ledger_by_net_name( a_net->pub.name ) : NULL; if ( ! a_net || ! l_ledger || ! a_addr_to ){ if (a_ret_status) *a_ret_status = DAP_CHAIN_MEMPOOL_RET_STATUS_BAD_ARGUMENTS; @@ -634,20 +760,20 @@ char* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_WRONG_ADDR; return NULL; } - dap_chain_hash_fast_t *l_tx_final_hash = dap_chain_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, a_tx_prev_hash); + dap_chain_hash_fast_t *l_tx_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, a_tx_prev_hash); if (!l_tx_final_hash) { log_it(L_WARNING, "Requested conditional transaction is already used out"); if (a_ret_status) *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_CANT_FIND_FINAL_TX_HASH; return NULL; } - if (dap_strcmp(a_net->pub.native_ticker, dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, l_tx_final_hash))) { + if (dap_strcmp(a_net->pub.native_ticker, dap_ledger_tx_get_token_ticker_by_hash(l_ledger, l_tx_final_hash))) { log_it(L_WARNING, "Pay for service should be only in native token ticker"); if (a_ret_status) *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_NATIVE_TOKEN; return NULL; } - dap_chain_datum_tx_t *l_tx_cond = dap_chain_ledger_tx_find_by_hash(l_ledger, l_tx_final_hash); + dap_chain_datum_tx_t *l_tx_cond = dap_ledger_tx_find_by_hash(l_ledger, l_tx_final_hash); int l_out_cond_idx = 0; dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_cond, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, &l_out_cond_idx); if (!l_out_cond) { @@ -752,7 +878,7 @@ char *dap_chain_mempool_tx_create_cond(dap_chain_net_t *a_net, uint256_t a_value_fee, const void *a_cond, size_t a_cond_size, const char *a_hash_out_type) { - dap_ledger_t * l_ledger = a_net ? dap_chain_ledger_by_net_name( a_net->pub.name ) : NULL; + dap_ledger_t * l_ledger = a_net ? dap_ledger_by_net_name( a_net->pub.name ) : NULL; // check valid param if (!a_net || !l_ledger || !a_key_from || !a_key_cond || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size || IS_ZERO_256(a_value)) @@ -774,7 +900,7 @@ char *dap_chain_mempool_tx_create_cond(dap_chain_net_t *a_net, dap_chain_addr_t l_addr_from; dap_chain_addr_fill_from_key(&l_addr_from, a_key_from, a_net->pub.id); // list of transaction with 'out' items - dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker, + dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker, &l_addr_from, l_value_need, &l_value_transfer); if(!l_list_used_out) { log_it( L_ERROR, "Nothing to transfer (not enough funds)"); @@ -885,7 +1011,7 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast } dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger; // list of transaction with 'out' items - l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, + l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, &l_addr_from_fee, l_total_fee, &l_value_transfer); if (!l_list_used_out) { log_it(L_WARNING,"Not enough funds to transfer"); @@ -1000,7 +1126,7 @@ dap_chain_datum_token_emission_t *dap_chain_mempool_datum_emission_extract(dap_c dap_chain_net_t *l_net = dap_chain_net_by_name(a_chain->net_name); if (!l_net) return NULL; - dap_chain_datum_token_t *l_token = dap_chain_ledger_token_ticker_check(l_net->pub.ledger, l_ticker); + dap_chain_datum_token_t *l_token = dap_ledger_token_ticker_check(l_net->pub.ledger, l_ticker); if (!l_token) return NULL; if (l_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE && l_token->type == DAP_CHAIN_DATUM_TOKEN_DECL) diff --git a/modules/mempool/include/dap_chain_mempool.h b/modules/mempool/include/dap_chain_mempool.h index 97a3042c19..7e436c23f2 100644 --- a/modules/mempool/include/dap_chain_mempool.h +++ b/modules/mempool/include/dap_chain_mempool.h @@ -104,5 +104,7 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast dap_chain_datum_token_emission_t *dap_chain_mempool_emission_get(dap_chain_t *a_chain, const char *a_emission_hash_str); dap_chain_datum_token_emission_t *dap_chain_mempool_datum_emission_extract(dap_chain_t *a_chain, byte_t *a_data, size_t a_size); -char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from, const dap_chain_addr_t* a_addr_to, dap_list_t *a_block_list, +char *dap_chain_mempool_tx_coll_fee_create(dap_chain_cs_blocks_t *a_blocks, dap_enc_key_t *a_key_from, const dap_chain_addr_t* a_addr_to, dap_list_t *a_block_list, uint256_t a_value_fee, const char *a_hash_out_type); +char *dap_chain_mempool_tx_reward_create(dap_chain_cs_blocks_t *a_blocks, dap_enc_key_t *a_sign_key, dap_chain_addr_t *a_addr_to, dap_list_t *a_block_list, + uint256_t a_value_fee, const char *a_hash_out_type); diff --git a/modules/chain/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c similarity index 75% rename from modules/chain/dap_chain_ledger.c rename to modules/net/dap_chain_ledger.c index 5472dd7928..5ebbb90e5b 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -58,107 +58,107 @@ #include "dap_notify_srv.h" -#define LOG_TAG "dap_chain_ledger" +#define LOG_TAG "dap_ledger" -typedef struct dap_chain_ledger_verificator { +typedef struct dap_ledger_verificator { int subtype; // hash key - dap_chain_ledger_verificator_callback_t callback; - dap_chain_ledger_updater_callback_t callback_added; + dap_ledger_verificator_callback_t callback; + dap_ledger_updater_callback_t callback_added; UT_hash_handle hh; -} dap_chain_ledger_verificator_t; +} dap_ledger_verificator_t; -static dap_chain_ledger_verificator_t *s_verificators; +static dap_ledger_verificator_t *s_verificators; static pthread_rwlock_t s_verificators_rwlock; #define MAX_OUT_ITEMS 10 -static const char *s_ledger_tx_check_err_str[] = { - [DAP_CHAIN_LEDGER_TX_CHECK_OK] = "DAP_CHAIN_LEDGER_TX_CHECK_OK", - [DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX] = "DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX", - [DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE] = "DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE", - [DAP_CHAIN_LEDGER_TX_ALREADY_CACHED] = "DAP_CHAIN_LEDGER_TX_ALREADY_CACHED", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN", - [DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED] = "DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED", - [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND", - [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN", - [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS", - [DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE] = "DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS", - [DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX] = "DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY", - [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE", - [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND", - [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET", - [DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE] = "DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND", - [DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED] = "DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED", - [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS" +static const char * const s_ledger_tx_check_err_str[] = { + [DAP_LEDGER_TX_CHECK_OK] = "DAP_LEDGER_TX_CHECK_OK", + [DAP_LEDGER_TX_CHECK_NULL_TX] = "DAP_LEDGER_TX_CHECK_NULL_TX", + [DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE] = "DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE", + [DAP_LEDGER_TX_ALREADY_CACHED] = "DAP_LEDGER_TX_ALREADY_CACHED", + [DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN] = "DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN", + [DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED", + [DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED", + [DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND", + [DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS] = "DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS", + [DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND", + [DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN", + [DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS", + [DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE] = "DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE", + [DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS] = "DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS", + [DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX] = "DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX", + [DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY] = "DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY", + [DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE", + [DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND", + [DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED", + [DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED", + [DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND", + [DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND", + [DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH] = "DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH", + [DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX] = "DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX", + [DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET] = "DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET", + [DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE] = "DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE", + [DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND", + [DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND", + [DAP_LEDGER_PERMISSION_CHECK_FAILED] = "DAP_LEDGER_PERMISSION_CHECK_FAILED", + [DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS] = "DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS", + [DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED", + [DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL] = "DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL" }; -static const char *s_ledger_emission_add_err_str[] = { - [DAP_CHAIN_LEDGER_EMISSION_ADD_OK] = "DAP_CHAIN_LEDGER_EMISSION_ADD_OK", - [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL", - [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED", - [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW", - [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY", - [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS", - [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN", - [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE", - [DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED] = "DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED" +static const char * const s_ledger_emission_add_err_str[] = { + [DAP_LEDGER_EMISSION_ADD_OK] = "DAP_LEDGER_EMISSION_ADD_OK", + [DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL] = "DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL", + [DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED] = "DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED", + [DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW] = "DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW", + [DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY] = "DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY", + [DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS] = "DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS", + [DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN] = "DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN", + [DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE] = "DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE", + [DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED] = "DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED" }; -static const char *s_ledger_token_decl_err_str[] = { - [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK", - [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL", - [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE", - [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK", - [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN", - [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN", - [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS" +static const char * const s_ledger_token_decl_err_str[] = { + [DAP_LEDGER_TOKEN_DECL_ADD_OK] = "DAP_LEDGER_TOKEN_DECL_ADD_OK", + [DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL", + [DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE", + [DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK", + [DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN", + [DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN", + [DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS" }; -char *dap_chain_ledger_tx_check_err_str(int a_code) { - return (a_code >= DAP_CHAIN_LEDGER_TX_CHECK_OK) && (a_code < DAP_CHAIN_LEDGER_TX_CHECK_UNKNOWN) - ? (char*)s_ledger_tx_check_err_str[(dap_chain_ledger_tx_check_t)a_code] +char *dap_ledger_tx_check_err_str(int a_code) { + return (a_code >= DAP_LEDGER_TX_CHECK_OK) && (a_code < DAP_LEDGER_TX_CHECK_UNKNOWN) + ? (char*)s_ledger_tx_check_err_str[(dap_ledger_tx_check_t)a_code] : dap_itoa(a_code); } -typedef struct dap_chain_ledger_stake_lock_item { +typedef struct dap_ledger_stake_lock_item { dap_chain_hash_fast_t tx_for_stake_lock_hash; dap_chain_hash_fast_t tx_used_out; - uint256_t ems_value; UT_hash_handle hh; -} dap_chain_ledger_stake_lock_item_t; +} dap_ledger_stake_lock_item_t; -typedef struct dap_chain_ledger_token_emission_item { +typedef struct dap_ledger_token_emission_item { dap_chain_hash_fast_t datum_token_emission_hash; dap_chain_datum_token_emission_t *datum_token_emission; size_t datum_token_emission_size; dap_chain_hash_fast_t tx_used_out; dap_nanotime_t ts_added; UT_hash_handle hh; -} dap_chain_ledger_token_emission_item_t; +} dap_ledger_token_emission_item_t; -typedef struct dap_chain_ledger_token_update_item { +typedef struct dap_ledger_token_update_item { dap_hash_fast_t update_token_hash; dap_chain_datum_token_t *datum_token_update; size_t datum_token_update_size; time_t updated_time; UT_hash_handle hh; -} dap_chain_ledger_token_update_item_t; +} dap_ledger_token_update_item_t; -typedef struct dap_chain_ledger_token_item { +typedef struct dap_ledger_token_item { uint16_t version; char ticker[DAP_CHAIN_TICKER_SIZE_MAX]; uint16_t type; @@ -170,10 +170,10 @@ typedef struct dap_chain_ledger_token_item { uint256_t current_supply; pthread_rwlock_t token_emissions_rwlock; - dap_chain_ledger_token_emission_item_t * token_emissions; + dap_ledger_token_emission_item_t * token_emissions; pthread_rwlock_t token_ts_updated_rwlock; - dap_chain_ledger_token_update_item_t * token_ts_updated; + dap_ledger_token_update_item_t * token_ts_updated; time_t last_update_token_time; // for auth operations @@ -193,10 +193,10 @@ typedef struct dap_chain_ledger_token_item { char *description_token; size_t description_token_size; UT_hash_handle hh; -} dap_chain_ledger_token_item_t; +} dap_ledger_token_item_t; // ledger cache item - one of unspent outputs -typedef struct dap_chain_ledger_tx_item { +typedef struct dap_ledger_tx_item { dap_chain_hash_fast_t tx_hash_fast; dap_chain_datum_tx_t *tx; dap_nanotime_t ts_added; @@ -213,35 +213,44 @@ typedef struct dap_chain_ledger_tx_item { dap_chain_hash_fast_t tx_hash_spent_fast[MAX_OUT_ITEMS]; // spent outs list } DAP_ALIGN_PACKED cache_data; UT_hash_handle hh; -} dap_chain_ledger_tx_item_t; +} dap_ledger_tx_item_t; -typedef struct dap_chain_ledger_tokenizer { +typedef struct dap_ledger_tokenizer { char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; uint256_t sum; UT_hash_handle hh; -} dap_chain_ledger_tokenizer_t; +} dap_ledger_tokenizer_t; -typedef struct dap_chain_ledger_tx_bound { - dap_chain_hash_fast_t tx_prev_hash; - dap_chain_datum_tx_t *tx_prev; - union { - dap_chain_tx_in_t *tx_cur_in; - dap_chain_tx_in_cond_t *tx_cur_in_cond; - dap_chain_tx_in_ems_t *tx_cur_in_ems; - } in; +typedef struct dap_ledger_reward_key { + dap_hash_fast_t block_hash; + dap_hash_fast_t sign_pkey_hash; +} DAP_ALIGN_PACKED dap_ledger_reward_key_t; + +typedef struct dap_ledger_reward_item { + dap_ledger_reward_key_t key; + dap_hash_fast_t spender_tx; + UT_hash_handle hh; +} dap_ledger_reward_item_t; + +typedef struct dap_ledger_tx_bound { + uint8_t type; + uint16_t prev_out_idx; + uint256_t value; union { - dap_chain_tx_out_old_t *tx_prev_out; - // 256 - dap_chain_tx_out_t *tx_prev_out_256; - dap_chain_tx_out_ext_t *tx_prev_out_ext_256; - dap_chain_tx_out_cond_t *tx_prev_out_cond_256; - } out; + dap_ledger_token_item_t *token_item; // For current_supply update on emissions + dap_chain_tx_out_cond_t *cond; // For conditional output + struct { + char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; + dap_chain_addr_t addr_from; + } in; + }; union { - dap_chain_ledger_tx_item_t *item_out; - dap_chain_ledger_token_emission_item_t *item_emission; - dap_chain_ledger_stake_lock_item_t *stake_lock_item; + dap_ledger_tx_item_t *prev_item; // For not emission TX + dap_ledger_token_emission_item_t *emission_item; + dap_ledger_stake_lock_item_t *stake_lock_item; + dap_ledger_reward_key_t reward_key; }; -} dap_chain_ledger_tx_bound_t; +} dap_ledger_tx_bound_t; // in-memory wallet balance typedef struct dap_ledger_wallet_balance { @@ -261,32 +270,29 @@ typedef struct dap_ledger_cache_str_item { bool found; } dap_ledger_cache_str_item_t; -typedef struct dap_chain_ledger_tx_notifier { - dap_chain_ledger_tx_add_notify_t callback; +typedef struct dap_ledger_tx_notifier { + dap_ledger_tx_add_notify_t callback; void *arg; -} dap_chain_ledger_tx_notifier_t; +} dap_ledger_tx_notifier_t; -typedef struct dap_chain_ledger_bridged_tx_notifier { - dap_chain_ledger_bridged_tx_notify_t callback; +typedef struct dap_ledger_bridged_tx_notifier { + dap_ledger_bridged_tx_notify_t callback; void *arg; -} dap_chain_ledger_bridged_tx_notifier_t; +} dap_ledger_bridged_tx_notifier_t; // dap_ledget_t private section typedef struct dap_ledger_private { - const char *net_native_ticker; - uint256_t fee_value; - dap_chain_addr_t fee_addr; - dap_list_t *poa_certs; // List of ledger - unspent transactions cache - dap_chain_ledger_tx_item_t *threshold_txs; - dap_chain_ledger_token_emission_item_t * threshold_emissions; + dap_ledger_tx_item_t *threshold_txs; + dap_ledger_token_emission_item_t * threshold_emissions; - dap_chain_ledger_tx_item_t *ledger_items; - dap_chain_ledger_token_item_t *tokens; - dap_chain_ledger_stake_lock_item_t *emissions_for_stake_lock; + dap_ledger_tx_item_t *ledger_items; + dap_ledger_token_item_t *tokens; + dap_ledger_stake_lock_item_t *emissions_for_stake_lock; + dap_ledger_reward_item_t *rewards; dap_ledger_wallet_balance_t *balance_accounts; - // for separate access to ledger + // for separate access to transactions pthread_rwlock_t ledger_rwlock; // for separate access to tokens pthread_rwlock_t tokens_rwlock; @@ -294,16 +300,19 @@ typedef struct dap_ledger_private { pthread_rwlock_t threshold_txs_rwlock; pthread_rwlock_t threshold_emissions_rwlock; pthread_rwlock_t balance_accounts_rwlock; + pthread_rwlock_t rewards_rwlock; // Save/load operations condition pthread_mutex_t load_mutex; pthread_cond_t load_cond; bool load_end; - uint16_t flags; + // Ledger flags bool check_ds; bool check_cells_ds; bool check_token_emission; + bool cached; + dap_chain_cell_id_t local_cell_id; //notifiers @@ -311,8 +320,7 @@ typedef struct dap_ledger_private { dap_list_t *tx_add_notifiers; bool load_mode; - bool cached; - dap_chain_ledger_cache_tx_check_callback_t cache_tx_check_callback; + dap_ledger_cache_tx_check_callback_t cache_tx_check_callback; // TPS section dap_timerfd_t *tps_timer; struct timespec tps_start_time; @@ -331,25 +339,17 @@ typedef struct dap_ledger_hal_item { static dap_ledger_hal_item_t *s_hal_items = NULL; -static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, +static dap_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash); static void s_threshold_emissions_proc( dap_ledger_t * a_ledger); static void s_threshold_txs_proc( dap_ledger_t * a_ledger); static void s_threshold_txs_free(dap_ledger_t *a_ledger); static void s_threshold_emission_free(dap_ledger_t *a_ledger); -static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size); -static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t *a_token, size_t a_token_size); -static int s_ledger_permissions_check(dap_chain_ledger_token_item_t * a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size ); +static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size); +static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_token_item , dap_chain_datum_token_t *a_token, size_t a_token_size); +static int s_ledger_permissions_check(dap_ledger_token_item_t * a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size ); static bool s_ledger_tps_callback(void *a_arg); -static int s_sort_ledger_tx_item(dap_chain_ledger_tx_item_t* a, dap_chain_ledger_tx_item_t* b); - -static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold, bool a_safe_call); -static int s_tx_add_unsafe(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold); - -static int s_token_emission_add_unsafe(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, - dap_hash_fast_t *a_emission_hash, bool a_from_threshold); -static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, - dap_hash_fast_t *a_emission_hash, bool a_from_threshold, bool a_safe_call); +static int s_sort_ledger_tx_item(dap_ledger_tx_item_t* a, dap_ledger_tx_item_t* b); static size_t s_threshold_emissions_max = 1000; static size_t s_threshold_txs_max = 10000; @@ -359,11 +359,11 @@ static size_t s_threshold_free_timer_tick = 900000; // 900000 ms = 15 minutes. struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_wallet_balance_t* a_bal); /** - * @brief dap_chain_ledger_init + * @brief dap_ledger_init * current function version set s_debug_more parameter, if it define in config, and returns 0 * @return */ -int dap_chain_ledger_init() +int dap_ledger_init() { s_debug_more = dap_config_get_item_bool_default(g_config,"ledger","debug_more",false); pthread_rwlock_init(&s_verificators_rwlock, NULL); @@ -371,27 +371,20 @@ int dap_chain_ledger_init() } /** - * @brief dap_chain_ledger_deinit + * @brief dap_ledger_deinit * nothing do */ -void dap_chain_ledger_deinit() +void dap_ledger_deinit() { - // TODO write correct deinit of all net ledgers -/* uint16_t l_net_count = 0; - dap_chain_net_t **l_net_list = dap_chain_net_list(&l_net_count); - for(uint16_t i =0; i < l_net_count; i++) { - dap_chain_ledger_purge(l_net_list[i]->pub.ledger, true); - } - DAP_DELETE(l_net_list); */ pthread_rwlock_destroy(&s_verificators_rwlock); } /** - * @brief dap_chain_ledger_handle_new + * @brief dap_ledger_handle_new * Create empty dap_ledger_t structure * @return dap_ledger_t* */ -static dap_ledger_t * dap_chain_ledger_handle_new(void) +static dap_ledger_t * dap_ledger_handle_new(void) { dap_ledger_t *l_ledger = DAP_NEW_Z(dap_ledger_t); if ( !l_ledger ) { @@ -412,6 +405,7 @@ static dap_ledger_t * dap_chain_ledger_handle_new(void) pthread_rwlock_init(&l_ledger_pvt->threshold_emissions_rwlock , NULL); pthread_rwlock_init(&l_ledger_pvt->balance_accounts_rwlock , NULL); pthread_rwlock_init(&l_ledger_pvt->stake_lock_rwlock, NULL); + pthread_rwlock_init(&l_ledger_pvt->rewards_rwlock, NULL); l_ledger_pvt->threshold_txs_free_timer = dap_interval_timer_create(s_threshold_free_timer_tick, (dap_timer_callback_t)s_threshold_txs_free, l_ledger); l_ledger_pvt->threshold_emissions_free_timer = dap_interval_timer_create(s_threshold_free_timer_tick, @@ -420,15 +414,15 @@ static dap_ledger_t * dap_chain_ledger_handle_new(void) } /** - * @brief dap_chain_ledger_handle_free + * @brief dap_ledger_handle_free * Remove dap_ledger_t structure * @param a_ledger */ -void dap_chain_ledger_handle_free(dap_ledger_t *a_ledger) +void dap_ledger_handle_free(dap_ledger_t *a_ledger) { if(!a_ledger) return; - log_it(L_INFO,"Ledger %s destroyed", a_ledger->net_name); + log_it(L_INFO,"Ledger for network %s destroyed", a_ledger->net->pub.name); // Destroy Read/Write Lock pthread_rwlock_destroy(&PVT(a_ledger)->ledger_rwlock); pthread_rwlock_destroy(&PVT(a_ledger)->tokens_rwlock); @@ -436,12 +430,13 @@ void dap_chain_ledger_handle_free(dap_ledger_t *a_ledger) pthread_rwlock_destroy(&PVT(a_ledger)->threshold_emissions_rwlock); pthread_rwlock_destroy(&PVT(a_ledger)->balance_accounts_rwlock); pthread_rwlock_destroy(&PVT(a_ledger)->stake_lock_rwlock); + pthread_rwlock_destroy(&PVT(a_ledger)->rewards_rwlock); DAP_DELETE(PVT(a_ledger)); DAP_DELETE(a_ledger); } -void dap_chain_ledger_load_end(dap_ledger_t *a_ledger) +void dap_ledger_load_end(dap_ledger_t *a_ledger) { PVT(a_ledger)->load_mode = false; } @@ -450,7 +445,7 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_ struct json_object *l_json = json_object_new_object(); json_object_object_add(l_json, "class", json_object_new_string("Wallet")); struct json_object *l_network = json_object_new_object(); - json_object_object_add(l_network, "name", json_object_new_string(a_ledger->net_name)); + json_object_object_add(l_network, "name", json_object_new_string(a_ledger->net->pub.name)); char *pos = strrchr(a_bal->key, ' '); if (pos) { size_t l_addr_len = pos - a_bal->key; @@ -477,18 +472,18 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_ } /** - * @brief s_chain_ledger_token_update_check + * @brief s_ledger_token_update_check * @param a_cur_token_item * @param a_token_update * @param a_token_update_size * @return true or false */ -static bool s_ledger_token_update_check(dap_chain_ledger_token_item_t *a_cur_token_item, dap_chain_datum_token_t *a_token_update, size_t a_token_update_size) +static bool s_ledger_token_update_check(dap_ledger_token_item_t *a_cur_token_item, dap_chain_datum_token_t *a_token_update, size_t a_token_update_size) { dap_sign_t **l_signs_upd_token; size_t auth_signs_total = 0; size_t auth_signs_valid = 0; - dap_chain_ledger_token_update_item_t *l_token_update_item; + dap_ledger_token_update_item_t *l_token_update_item; dap_hash_fast_t l_hash_token_update; dap_hash_fast(a_token_update, a_token_update_size, &l_hash_token_update); @@ -531,7 +526,7 @@ static bool s_ledger_token_update_check(dap_chain_ledger_token_item_t *a_cur_tok if(auth_signs_total) { size_t l_valid_pkeys = 0; for(uint16_t i = 0; i < auth_signs_total; i++){ - dap_pkey_t *l_pkey_upd_token = dap_pkey_get_from_sign_deserialization(l_signs_upd_token[i]); + dap_pkey_t *l_pkey_upd_token = dap_pkey_get_from_sign(l_signs_upd_token[i]); for (size_t j = 0; j < a_cur_token_item->auth_signs_total; j++) { if (dap_pkey_match(a_cur_token_item->auth_pkeys[j], l_pkey_upd_token)) { l_valid_pkeys++; @@ -710,41 +705,41 @@ static bool s_ledger_token_update_check(dap_chain_ledger_token_item_t *a_cur_tok } +inline static dap_ledger_token_item_t *s_ledger_find_token(dap_ledger_t *a_ledger, const char *a_token_ticker) +{ + dap_ledger_token_item_t *l_token_item; + pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); + HASH_FIND_STR(PVT(a_ledger)->tokens, a_token_ticker, l_token_item); + pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + return l_token_item; +} + /** - * @brief dap_chain_ledger_token_check + * @brief dap_ledger_token_check * @param a_ledger * @param a_token * @param a_token_size * @return */ -int dap_chain_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size) +int dap_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size) { if ( !a_ledger){ if(s_debug_more) log_it(L_ERROR, "NULL ledger, can't add datum with token declaration!"); - return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL; + return DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL; } - - bool update_token = false; - dap_chain_ledger_token_item_t *l_token_item; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_FIND_STR(PVT(a_ledger)->tokens, a_token->ticker, l_token_item); - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - if (a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) - update_token = true; - + bool l_update_token = a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE; + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token->ticker); if (l_token_item != NULL) { - if (update_token == false) { - log_it(L_WARNING,"Duplicate token declaration for ticker '%s' ", a_token->ticker); - return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE; - } else if (s_ledger_token_update_check(l_token_item, a_token, a_token_size) == false) { - return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK; - } - } - else if (l_token_item == NULL && update_token == true) { - log_it(L_WARNING,"Can't update token that doesn't exist for ticker '%s' ", a_token->ticker); - return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN; + if (!l_update_token) { + log_it(L_WARNING, "Duplicate token declaration for ticker '%s'", a_token->ticker); + return DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE; + } else if (!s_ledger_token_update_check(l_token_item, a_token, a_token_size)) + return DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK; + } else if (!l_token_item && l_update_token) { + log_it(L_WARNING, "Can't update token that doesn't exist for ticker '%s'", a_token->ticker); + return DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN; } // Check signs size_t l_signs_unique = 0; @@ -778,43 +773,39 @@ int dap_chain_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datu l_signs_approve++; a_token->signs_total = l_tmp_auth_signs; if (l_signs_approve == a_token->signs_total){ - return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK; + return DAP_LEDGER_TOKEN_DECL_ADD_OK; } else { log_it(L_WARNING, "The token declaration has %zu valid signatures out of %hu.", l_signs_approve, a_token->signs_total); - return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN; + return DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN; } } else { log_it(L_WARNING, "The number of unique token signs %zu is less than total token signs set to %hu.", l_signs_unique, a_token->signs_total); - return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS; + return DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS; } // Checks passed - return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK; + return DAP_LEDGER_TOKEN_DECL_ADD_OK; } -char *dap_chain_ledger_token_decl_add_err_code_to_str(int a_code) { - return (a_code >= DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK) && (a_code < DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_UNKNOWN) - ? (char*)s_ledger_token_decl_err_str[(dap_chain_ledger_token_decl_add_err_t)a_code] +char *dap_ledger_token_decl_add_err_code_to_str(int a_code) { + return (a_code >= DAP_LEDGER_TOKEN_DECL_ADD_OK) && (a_code < DAP_LEDGER_TOKEN_DECL_ADD_UNKNOWN) + ? (char*)s_ledger_token_decl_err_str[(dap_ledger_token_decl_add_err_t)a_code] : dap_itoa(a_code); } /** - * @brief dap_chain_ledger_token_ticker_check + * @brief dap_ledger_token_ticker_check * @param a_ledger * @param a_token_ticker * @return */ -dap_chain_datum_token_t *dap_chain_ledger_token_ticker_check(dap_ledger_t * a_ledger, const char *a_token_ticker) +dap_chain_datum_token_t *dap_ledger_token_ticker_check(dap_ledger_t *a_ledger, const char *a_token_ticker) { - if ( !a_ledger){ - if(s_debug_more) - log_it(L_WARNING, "NULL ledger, can't find token ticker"); + if (!a_ledger) { + debug_if(s_debug_more, L_WARNING, "NULL ledger, can't find token ticker"); return NULL; } - dap_chain_ledger_token_item_t *l_token_item; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_FIND_STR(PVT(a_ledger)->tokens, a_token_ticker, l_token_item); - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token_ticker); return l_token_item ? l_token_item->datum_token : NULL; } @@ -844,7 +835,7 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_datum_tx_t *a_t DAP_DELETE(l_tx_hash_str); } -static void s_dump_datum_tx_for_addr(dap_chain_ledger_tx_item_t *a_item, bool a_unspent, dap_ledger_t *a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, dap_string_t *a_str_out) { +static void s_dump_datum_tx_for_addr(dap_ledger_tx_item_t *a_item, bool a_unspent, dap_ledger_t *a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, dap_string_t *a_str_out) { if (a_unspent && a_item->cache_data.ts_spent) { // With 'unspent' flag spent ones are ignored return; @@ -882,7 +873,7 @@ static void s_dump_datum_tx_for_addr(dap_chain_ledger_tx_item_t *a_item, bool a_ l_src_token = l_token->header.ticker; break; } - l_tx_prev = dap_chain_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash); + l_tx_prev = dap_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash); if (l_tx_prev) { uint8_t *l_prev_out_union = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_tx_prev_out_idx); if (!l_prev_out_union) @@ -943,7 +934,7 @@ static void s_dump_datum_tx_for_addr(dap_chain_ledger_tx_item_t *a_item, bool a_ s_tx_header_print(a_str_out, l_tx, a_hash_out_type, l_tx_hash); l_header_printed = true; } - //const char *l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash); + //const char *l_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash); const char *l_dst_addr_str = l_dst_addr ? dap_chain_addr_to_str(l_dst_addr) : dap_chain_tx_out_cond_subtype_to_str( ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.subtype); @@ -985,16 +976,16 @@ char *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a { dap_string_t *l_str_out = dap_string_new(NULL); if (!l_str_out) { - log_it(L_CRITICAL, "Memory allocation error"); + log_it(L_CRITICAL, "Memory allocation error"); return NULL; } //dap_chain_tx_hash_processed_ht_t *l_tx_data_ht = NULL; - dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp; + dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp; dap_ledger_private_t * l_ledger_pvt = PVT(a_ledger); pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); - //unsigned test = dap_chain_ledger_count(a_ledger); + //unsigned test = dap_ledger_count(a_ledger); HASH_ITER(hh, l_ledger_pvt->ledger_items, l_tx_item, l_tx_tmp) { s_dump_datum_tx_for_addr(l_tx_item, a_unspent_only, a_ledger, a_addr, a_hash_out_type, l_str_out); } @@ -1013,9 +1004,11 @@ char *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a * @param a_ledger ledger object * @param l_token_item token item object */ -void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_t *l_token_item) +void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_ledger_token_item_t *l_token_item) { - char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR); + if (!PVT(a_ledger)->cached) + return; + char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TOKENS_STR); size_t l_cache_size = l_token_item->datum_token_size + sizeof(uint256_t); uint8_t *l_cache = DAP_NEW_STACK_SIZE(uint8_t, l_cache_size); if ( !l_cache ) { @@ -1032,6 +1025,43 @@ void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_token_ DAP_DELETE(l_gdb_group); } +static bool s_ledger_token_supply_check_unsafe(dap_ledger_token_item_t *a_token_item, uint256_t a_value) +{ + if (compare256(a_token_item->current_supply, a_value) >= 0) + return true; + char *l_supply_str = dap_chain_balance_print(a_token_item->current_supply); + char *l_value_str = dap_chain_balance_print(a_value); + log_it(L_WARNING, "Token current supply %s < emission value %s", l_supply_str, l_value_str); + DAP_DEL_Z(l_supply_str); + DAP_DEL_Z(l_value_str); + return false; +} + +static bool s_ledger_token_supply_check(dap_ledger_token_item_t *a_token_item, uint256_t a_value) +{ + assert(a_token_item); + if (IS_ZERO_256(a_token_item->total_supply) || IS_ZERO_256(a_value)) + return true; + return s_ledger_token_supply_check_unsafe(a_token_item, a_value); +} + +static bool s_ledger_token_supply_check_update(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_token_item, uint256_t a_value) +{ + assert(a_token_item); + if (IS_ZERO_256(a_token_item->total_supply) || IS_ZERO_256(a_value)) + return true; + if (!s_ledger_token_supply_check_unsafe(a_token_item, a_value)) + return false; + int l_overflow = SUBTRACT_256_256(a_token_item->current_supply, a_value, &a_token_item->current_supply); + assert(!l_overflow); + char *l_balance = dap_chain_balance_to_coins(a_token_item->current_supply); + log_it(L_NOTICE, "New current supply %s for token %s", l_balance, a_token_item->ticker); + DAP_DELETE(l_balance); + s_ledger_token_cache_update(a_ledger, a_token_item); + return true; +} + + /** * @brief s_ledger_update_token_add_in_hash_table * @param a_cur_token_item @@ -1039,9 +1069,9 @@ void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_token_ * @param a_token_update_size * @return true or false */ -static bool s_ledger_update_token_add_in_hash_table(dap_chain_ledger_token_item_t *a_cur_token_item, dap_chain_datum_token_t *a_token_update, size_t a_token_update_size) +static bool s_ledger_update_token_add_in_hash_table(dap_ledger_token_item_t *a_cur_token_item, dap_chain_datum_token_t *a_token_update, size_t a_token_update_size) { - dap_chain_ledger_token_update_item_t *l_token_update_item; + dap_ledger_token_update_item_t *l_token_update_item; dap_hash_fast_t l_hash_token_update; bool new_item = false; @@ -1053,17 +1083,17 @@ static bool s_ledger_update_token_add_in_hash_table(dap_chain_ledger_token_item_ if (l_token_update_item && a_cur_token_item->last_update_token_time == l_token_update_item->updated_time) { if (s_debug_more) - log_it(L_WARNING, "Error: item 'dap_chain_ledger_token_update_item_t' already exist in hash-table"); + log_it(L_WARNING, "Error: item 'dap_ledger_token_update_item_t' already exist in hash-table"); return false; } else if (!l_token_update_item){ new_item = true; - l_token_update_item = DAP_NEW(dap_chain_ledger_token_update_item_t); + l_token_update_item = DAP_NEW(dap_ledger_token_update_item_t); if (!l_token_update_item) { if (s_debug_more) - log_it(L_ERROR, "Error: memory allocation when try adding item 'dap_chain_ledger_token_update_item_t' to hash-table"); + log_it(L_ERROR, "Error: memory allocation when try adding item 'dap_ledger_token_update_item_t' to hash-table"); return false; } - *l_token_update_item = (dap_chain_ledger_token_update_item_t) { + *l_token_update_item = (dap_ledger_token_update_item_t) { .update_token_hash = l_hash_token_update, .datum_token_update = a_token_update, .datum_token_update_size = a_token_update_size @@ -1090,24 +1120,20 @@ static bool s_ledger_update_token_add_in_hash_table(dap_chain_ledger_token_item_ } /** - * @brief dap_chain_ledger_token_add + * @brief dap_ledger_token_add * @param a_token * @param a_token_size * @return */ -int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size) { +int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size) +{ if (!a_ledger || !a_token) { debug_if(s_debug_more, L_ERROR, "NULL ledger, can't add datum with token declaration!"); return -1; } dap_chain_datum_token_t *l_token = a_token; - - dap_chain_ledger_token_item_t *l_token_item; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_FIND_STR(PVT(a_ledger)->tokens, l_token->ticker, l_token_item); - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token->ticker); if (l_token_item) { if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE @@ -1149,13 +1175,13 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * DAP_DEL_Z(l_token); return -7; } - l_token_item = DAP_NEW_Z(dap_chain_ledger_token_item_t); + l_token_item = DAP_NEW_Z(dap_ledger_token_item_t); if ( !l_token_item ) { DAP_DEL_Z(l_token); - log_it(L_CRITICAL, "Memory allocation error"); + log_it(L_CRITICAL, "Memory allocation error"); return -8; } - *l_token_item = (dap_chain_ledger_token_item_t) { + *l_token_item = (dap_ledger_token_item_t) { .version = l_token->version, .type = l_token->type, .subtype = l_token->subtype, @@ -1173,7 +1199,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * if (l_token) DAP_DELETE(l_token); DAP_DELETE(l_token_item); - log_it(L_CRITICAL, "Memory allocation error"); + log_it(L_CRITICAL, "Memory allocation error"); return -6; }; if ( !l_token_item->auth_pkeys ) { @@ -1181,12 +1207,12 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * DAP_DELETE(l_token); DAP_DEL_Z(l_token_item->auth_pkeys); DAP_DELETE(l_token_item); - log_it(L_CRITICAL, "Memory allocation error"); + log_it(L_CRITICAL, "Memory allocation error"); return -6; } dap_stpcpy(l_token_item->ticker, l_token->ticker); for (uint16_t k = 0; k < l_token_item->auth_signs_total; k++) { - l_token_item->auth_pkeys[k] = dap_pkey_get_from_sign_deserialization(l_signs[k]); + l_token_item->auth_pkeys[k] = dap_pkey_get_from_sign(l_signs[k]); dap_pkey_get_hash(l_token_item->auth_pkeys[k], &l_token_item->auth_pkeys_hash[k]); } DAP_DELETE(l_signs); @@ -1290,8 +1316,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * #undef CLEAN_UP DAP_DELETE(l_balance_dbg); s_threshold_emissions_proc(a_ledger); /* TODO process thresholds only for no-consensus chains */ - if (PVT(a_ledger)->cached) - s_ledger_token_cache_update(a_ledger, l_token_item); + s_ledger_token_cache_update(a_ledger, l_token_item); return 0; } @@ -1304,7 +1329,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * * @param a_token_size * @return int */ -static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size) +static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size) { UNUSED(a_ledger); dap_tsd_t * l_tsd= dap_chain_datum_token_tsd_get(a_token,a_token_size); @@ -1709,7 +1734,7 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite return 0; } -static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t *a_token, size_t a_token_size){ +static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_token_item , dap_chain_datum_token_t *a_token, size_t a_token_size){ dap_tsd_t * l_tsd= dap_chain_datum_token_tsd_get(a_token,a_token_size); size_t l_tsd_size=0; size_t l_tsd_total_size = a_token->header_native_decl.tsd_total_size; @@ -1783,15 +1808,12 @@ static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_ return 0; } -int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size) +int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size) { dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(a_token, &a_token_size); if (PVT(a_ledger)->load_mode) { - dap_chain_ledger_token_item_t *l_token_item; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_FIND_STR(PVT(a_ledger)->tokens, l_token->ticker, l_token_item); - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token->ticker); if (l_token_item && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE @@ -1800,13 +1822,13 @@ int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t return 0; } } - return dap_chain_ledger_token_add(a_ledger, l_token, a_token_size); + return dap_ledger_token_add(a_ledger, l_token, a_token_size); } -dap_string_t *dap_chain_ledger_threshold_info(dap_ledger_t *a_ledger) +dap_string_t *dap_ledger_threshold_info(dap_ledger_t *a_ledger) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp; + dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp; dap_string_t *l_str_ret = dap_string_new(""); uint32_t l_counter = 0; pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); @@ -1832,7 +1854,7 @@ dap_string_t *dap_chain_ledger_threshold_info(dap_ledger_t *a_ledger) pthread_rwlock_rdlock(&l_ledger_pvt->threshold_emissions_rwlock); l_counter = 0; - dap_chain_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp; + dap_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp; HASH_ITER(hh, l_ledger_pvt->threshold_emissions, l_emission_item, l_emission_tmp){ char l_emission_hash_str[70]={0}; char l_item_size[70] = {0}; @@ -1851,10 +1873,10 @@ dap_string_t *dap_chain_ledger_threshold_info(dap_ledger_t *a_ledger) return l_str_ret; } -dap_string_t *dap_chain_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_threshold_hash) +dap_string_t *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_threshold_hash) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp; + dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp; dap_string_t *l_str_ret = dap_string_new(""); pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){ @@ -1871,7 +1893,7 @@ dap_string_t *dap_chain_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_c pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); pthread_rwlock_rdlock(&l_ledger_pvt->threshold_emissions_rwlock); - dap_chain_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp; + dap_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp; HASH_ITER(hh, l_ledger_pvt->threshold_emissions, l_emission_item, l_emission_tmp){ if (!memcmp(&l_emission_item->datum_token_emission_hash,l_threshold_hash, sizeof(dap_chain_hash_fast_t))){ char l_emission_hash_str[70]={0}; @@ -1888,7 +1910,7 @@ dap_string_t *dap_chain_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_c return l_str_ret; } -dap_string_t *dap_chain_ledger_balance_info(dap_ledger_t *a_ledger) +dap_string_t *dap_ledger_balance_info(dap_ledger_t *a_ledger) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); dap_string_t *l_str_ret = dap_string_new(""); @@ -1916,14 +1938,14 @@ dap_string_t *dap_chain_ledger_balance_info(dap_ledger_t *a_ledger) } /** - * @breif dap_chain_ledger_token_auth_signs_valid + * @breif dap_ledger_token_auth_signs_valid * @param a_ledger * @param a_token_ticker * @return 0 if no ticker found */ -size_t dap_chain_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker) +size_t dap_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker) { - dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item; + dap_ledger_token_item_t *l_token_item, *l_tmp_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); size_t l_res = 0; HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { @@ -1937,14 +1959,14 @@ size_t dap_chain_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const cha } /** - * @breif dap_chain_ledger_token_auth_signs_total + * @breif dap_ledger_token_auth_signs_total * @param a_ledger * @param a_token_ticker * @return */ -size_t dap_chain_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker) +size_t dap_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker) { - dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item; + dap_ledger_token_item_t *l_token_item, *l_tmp_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); size_t l_res = 0; HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { @@ -1958,15 +1980,15 @@ size_t dap_chain_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const cha } /** - * @breif dap_chain_ledger_token_auth_signs_hashes + * @breif dap_ledger_token_auth_signs_hashes * @param a_ledger * @param a_token_ticker * @return */ -dap_list_t * dap_chain_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker) +dap_list_t * dap_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker) { dap_list_t * l_ret = NULL; - dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item; + dap_ledger_token_item_t *l_token_item, *l_tmp_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { if (!dap_strcmp(l_token_item->ticker, a_token_ticker)) { @@ -1986,11 +2008,11 @@ dap_list_t * dap_chain_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, co * @param a_ledger * @return */ -dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger) +dap_list_t *dap_ledger_token_info(dap_ledger_t *a_ledger) { dap_list_t *l_ret_list = NULL; dap_string_t *l_str_tmp;// = dap_string_new(""); - dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item; + dap_ledger_token_item_t *l_token_item, *l_tmp_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { l_str_tmp = dap_string_new(""); @@ -2081,10 +2103,10 @@ dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger) * @param a_ledger * @return */ -dap_list_t* dap_chain_ledger_token_decl_all(dap_ledger_t *a_ledger) +dap_list_t* dap_ledger_token_decl_all(dap_ledger_t *a_ledger) { dap_list_t * l_ret = NULL; - dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item; + dap_ledger_token_item_t *l_token_item, *l_tmp_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { @@ -2105,10 +2127,10 @@ static void s_threshold_emissions_proc(dap_ledger_t * a_ledger) bool l_success; do { l_success = false; - dap_chain_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp; + dap_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp; pthread_rwlock_wrlock(&PVT(a_ledger)->threshold_emissions_rwlock); HASH_ITER(hh, PVT(a_ledger)->threshold_emissions, l_emission_item, l_emission_tmp) { - int l_res = s_token_emission_add_unsafe(a_ledger, (byte_t *)l_emission_item->datum_token_emission, + int l_res = dap_ledger_token_emission_add(a_ledger, (byte_t *)l_emission_item->datum_token_emission, l_emission_item->datum_token_emission_size, &l_emission_item->datum_token_emission_hash, true); if (l_res != DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE) { @@ -2135,9 +2157,9 @@ static void s_threshold_txs_proc( dap_ledger_t *a_ledger) pthread_rwlock_wrlock(&l_ledger_pvt->threshold_txs_rwlock); do { l_success = false; - dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp; + dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp; HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp) { - int l_res = s_tx_add_unsafe(a_ledger, l_tx_item->tx, &l_tx_item->tx_hash_fast, true); + int l_res = dap_ledger_tx_add(a_ledger, l_tx_item->tx, &l_tx_item->tx_hash_fast, true); if (l_res != DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION && l_res != DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS) { HASH_DEL(l_ledger_pvt->threshold_txs, l_tx_item); @@ -2157,7 +2179,7 @@ static void s_threshold_txs_proc( dap_ledger_t *a_ledger) static void s_threshold_txs_free(dap_ledger_t *a_ledger){ log_it(L_DEBUG, "Start free threshold txs"); dap_ledger_private_t *l_pvt = PVT(a_ledger); - dap_chain_ledger_tx_item_t *l_current = NULL, *l_tmp = NULL; + dap_ledger_tx_item_t *l_current = NULL, *l_tmp = NULL; dap_nanotime_t l_time_cut_off = dap_nanotime_now() - dap_nanotime_from_sec(7200); //7200 sec = 2 hours. pthread_rwlock_wrlock(&l_pvt->threshold_txs_rwlock); HASH_ITER(hh, l_pvt->threshold_txs, l_current, l_tmp) { @@ -2180,7 +2202,7 @@ static void s_threshold_txs_free(dap_ledger_t *a_ledger){ static void s_threshold_emission_free(dap_ledger_t *a_ledger){ log_it(L_DEBUG, "Start free threshold emission"); dap_ledger_private_t *l_pvt = PVT(a_ledger); - dap_chain_ledger_token_emission_item_t *l_current = NULL, *l_tmp = NULL; + dap_ledger_token_emission_item_t *l_current = NULL, *l_tmp = NULL; dap_nanotime_t l_time_cut_off = dap_nanotime_now() - dap_nanotime_from_sec(7200); //7200 sec = 2 hours. pthread_rwlock_wrlock(&l_pvt->threshold_emissions_rwlock); HASH_ITER(hh, l_pvt->threshold_emissions, l_current, l_tmp) { @@ -2218,12 +2240,12 @@ static bool s_load_cache_gdb_loaded_balances_callback(dap_global_db_instance_t * for (size_t i = 0; i < a_values_count; i++) { dap_ledger_wallet_balance_t *l_balance_item = DAP_NEW_Z(dap_ledger_wallet_balance_t); if (!l_balance_item) { - log_it(L_CRITICAL, "Memory allocation error"); + log_it(L_CRITICAL, "Memory allocation error"); return false; } l_balance_item->key = DAP_NEW_Z_SIZE(char, strlen(a_values[i].key) + 1); if (!l_balance_item->key) { - log_it(L_CRITICAL, "Memory allocation error"); + log_it(L_CRITICAL, "Memory allocation error"); DAP_DEL_Z(l_balance_item); return false; } @@ -2267,7 +2289,7 @@ static bool s_load_cache_gdb_loaded_txs_callback(dap_global_db_instance_t *a_dbi dap_ledger_t * l_ledger = (dap_ledger_t*) a_arg; dap_ledger_private_t * l_ledger_pvt = PVT(l_ledger); for (size_t i = 0; i < a_values_count; i++) { - dap_chain_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_chain_ledger_tx_item_t); + dap_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_ledger_tx_item_t); if ( !l_tx_item ) { log_it(L_CRITICAL, "Memory allocation error"); return false; @@ -2298,9 +2320,9 @@ static bool s_load_cache_gdb_loaded_stake_lock_callback(dap_global_db_instance_t for (size_t i = 0; i < a_values_count; i++) { if (a_values[i].value_len != sizeof(dap_hash_fast_t)) continue; - dap_chain_ledger_stake_lock_item_t *l_new_stake_lock_emission = DAP_NEW(dap_chain_ledger_stake_lock_item_t); + dap_ledger_stake_lock_item_t *l_new_stake_lock_emission = DAP_NEW(dap_ledger_stake_lock_item_t); if (!l_new_stake_lock_emission) { - debug_if(s_debug_more, L_ERROR, "Error: memory allocation when try adding item 'dap_chain_ledger_stake_lock_item_t' to hash-table"); + debug_if(s_debug_more, L_ERROR, "Error: memory allocation when try adding item 'dap_ledger_stake_lock_item_t' to hash-table"); continue; } dap_chain_hash_fast_from_str(a_values[i].key, &l_new_stake_lock_emission->tx_for_stake_lock_hash); @@ -2308,7 +2330,7 @@ static bool s_load_cache_gdb_loaded_stake_lock_callback(dap_global_db_instance_t HASH_ADD(hh, l_ledger_pvt->emissions_for_stake_lock, tx_for_stake_lock_hash, sizeof(dap_chain_hash_fast_t), l_new_stake_lock_emission); } - char* l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_LEDGER_TXS_STR); + char* l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_LEDGER_TXS_STR); dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_txs_callback, l_ledger); DAP_DELETE(l_gdb_group); return true; @@ -2341,13 +2363,13 @@ static bool s_load_cache_gdb_loaded_emissions_callback(dap_global_db_instance_t continue; const char *c_token_ticker = ((dap_chain_datum_token_emission_t *) (a_values[i].value + sizeof(dap_hash_fast_t)))->hdr.ticker; - dap_chain_ledger_token_item_t *l_token_item = NULL; + dap_ledger_token_item_t *l_token_item = NULL; HASH_FIND_STR(l_ledger_pvt->tokens, c_token_ticker, l_token_item); if (!l_token_item) { log_it(L_WARNING, "Not found token with ticker [%s], need to 'ledger reload' to update cache", c_token_ticker); continue; } - dap_chain_ledger_token_emission_item_t *l_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t); + dap_ledger_token_emission_item_t *l_emission_item = DAP_NEW_Z(dap_ledger_token_emission_item_t); if ( !l_emission_item ) { log_it(L_CRITICAL, "Memory allocation error"); return false; @@ -2361,7 +2383,7 @@ static bool s_load_cache_gdb_loaded_emissions_callback(dap_global_db_instance_t sizeof(dap_chain_hash_fast_t), l_emission_item); } - char* l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_LEDGER_STAKE_LOCK_STR); + char* l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_LEDGER_STAKE_LOCK_STR); dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_stake_lock_callback, l_ledger); DAP_DELETE(l_gdb_group); return true; @@ -2405,8 +2427,8 @@ static bool s_load_cache_gdb_loaded_tokens_callback(dap_global_db_instance_t *a_ continue; } // TODO: rework! Old token types may be passed unchecked! - dap_chain_ledger_token_add(l_ledger, l_token, l_token_size); - dap_chain_ledger_token_item_t *l_token_item = NULL; + dap_ledger_token_add(l_ledger, l_token, l_token_size); + dap_ledger_token_item_t *l_token_item = NULL; HASH_FIND_STR(l_ledger_pvt->tokens, l_token->ticker, l_token_item); if (!l_token_item) { log_it(L_WARNING, "Can't load token with ticker [%s], need to 'ledger reload' to update cache", l_token->ticker); @@ -2415,7 +2437,7 @@ static bool s_load_cache_gdb_loaded_tokens_callback(dap_global_db_instance_t *a_ l_token_item->current_supply = *(uint256_t*)a_values[i].value; } - char *l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR); + char *l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_LEDGER_EMISSIONS_STR); dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_emissions_callback, l_ledger); DAP_DELETE(l_gdb_group); return true; @@ -2425,10 +2447,10 @@ static bool s_load_cache_gdb_loaded_tokens_callback(dap_global_db_instance_t *a_ * @brief Load ledger from cache (stored in GDB) * @param a_ledger */ -void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger) +void dap_ledger_load_cache(dap_ledger_t *a_ledger) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR); + char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TOKENS_STR); pthread_mutex_lock(& l_ledger_pvt->load_mutex); dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_tokens_callback, a_ledger); @@ -2445,34 +2467,30 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger) * create ledger for specific net * load ledger cache * @param a_check_flags checking flags - * DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION - * DAP_CHAIN_LEDGER_CHECK_CELLS_DS - * DAP_CHAIN_LEDGER_CHECK_CELLS_DS + * DAP_LEDGER_CHECK_TOKEN_EMISSION + * DAP_LEDGER_CHECK_CELLS_DS + * DAP_LEDGER_CHECK_CELLS_DS * @param a_net_name char * network name, for example "kelvin-testnet" * @return dap_ledger_t* */ -dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, dap_chain_net_id_t a_net_id, char *a_net_name, const char *a_net_native_ticker, dap_list_t *a_poa_certs) +dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags) { - dap_ledger_t *l_ledger = dap_chain_ledger_handle_new(); + dap_ledger_t *l_ledger = dap_ledger_handle_new(); if (!l_ledger) { log_it(L_CRITICAL, "Memory allocation error"); return NULL; } - l_ledger->net_name = a_net_name; - l_ledger->net_id = a_net_id; + l_ledger->net = a_net; dap_ledger_private_t *l_ledger_pvt = PVT(l_ledger); - l_ledger_pvt->net_native_ticker = a_net_native_ticker; - l_ledger_pvt->poa_certs = a_poa_certs; - l_ledger_pvt->flags = a_flags; - l_ledger_pvt->check_ds = a_flags & DAP_CHAIN_LEDGER_CHECK_LOCAL_DS; - l_ledger_pvt->check_cells_ds = a_flags & DAP_CHAIN_LEDGER_CHECK_CELLS_DS; - l_ledger_pvt->check_token_emission = a_flags & DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION; - l_ledger_pvt->cached = a_flags & DAP_CHAIN_LEDGER_CACHE_ENABLED; + l_ledger_pvt->check_ds = a_flags & DAP_LEDGER_CHECK_LOCAL_DS; + l_ledger_pvt->check_cells_ds = a_flags & DAP_LEDGER_CHECK_CELLS_DS; + l_ledger_pvt->check_token_emission = a_flags & DAP_LEDGER_CHECK_TOKEN_EMISSION; + l_ledger_pvt->cached = a_flags & DAP_LEDGER_CACHE_ENABLED; pthread_cond_init(&l_ledger_pvt->load_cond, NULL); pthread_mutex_init(&l_ledger_pvt->load_mutex, NULL); -#ifndef DAP_CHAIN_LEDGER_TEST - char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), a_net_name); +#ifndef DAP_LEDGER_TEST + char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), a_net->pub.name); DIR * l_chains_dir = opendir(l_chains_path); DAP_DEL_Z(l_chains_path); @@ -2485,7 +2503,7 @@ dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, dap_chain_net_id_t a_net if ( strncmp (l_entry_name + strlen(l_entry_name)-4,".cfg",4) == 0 ) { // its .cfg file l_entry_name [strlen(l_entry_name)-4] = 0; log_it(L_DEBUG,"Open chain config \"%s\"...",l_entry_name); - l_chains_path = dap_strdup_printf("network/%s/%s", a_net_name, l_entry_name); + l_chains_path = dap_strdup_printf("network/%s/%s", a_net->pub.name, l_entry_name); dap_config_t * l_cfg = dap_config_open(l_chains_path); uint16_t l_whitelist_size; char **l_whitelist = dap_config_get_array_str(l_cfg, "ledger", "hard_accept_list", &l_whitelist_size); @@ -2513,38 +2531,28 @@ dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, dap_chain_net_id_t a_net if ( l_ledger_pvt->cached ) // load ledger cache from GDB - dap_chain_ledger_load_cache(l_ledger); + dap_ledger_load_cache(l_ledger); #endif return l_ledger; } -void dap_chain_ledger_set_fee(dap_ledger_t *a_ledger, uint256_t a_fee, dap_chain_addr_t a_fee_addr) -{ - PVT(a_ledger)->fee_value = a_fee; - PVT(a_ledger)->fee_addr = a_fee_addr; -} - -int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash) +int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash) { if (!a_token_emission || !a_token_emission_size) - return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL; + return DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL; - int l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_OK; + int l_ret = DAP_LEDGER_EMISSION_ADD_OK; dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); const char *l_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker; - dap_chain_ledger_token_item_t * l_token_item = NULL; - pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock); - HASH_FIND_STR(l_ledger_pvt->tokens, l_token_ticker, l_token_item); - pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock); - + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token_ticker); if (!l_token_item) { log_it(L_ERROR, "Check emission: token %s was not found", l_token_ticker); - return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN; + return DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN; } - dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL; + dap_ledger_token_emission_item_t * l_token_emission_item = NULL; // check if such emission is already present in table pthread_rwlock_rdlock(l_token_item ? &l_token_item->token_emissions_rwlock : &l_ledger_pvt->threshold_emissions_rwlock); @@ -2553,25 +2561,24 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ unsigned long long l_threshold_emissions_count = HASH_COUNT( l_ledger_pvt->threshold_emissions); pthread_rwlock_unlock(l_token_item ? &l_token_item->token_emissions_rwlock : &l_ledger_pvt->threshold_emissions_rwlock); - if(l_token_emission_item ) { + if (l_token_emission_item) { if(s_debug_more) { char l_token_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(a_emission_hash, l_token_hash_str, sizeof(l_token_hash_str)); if ( l_token_emission_item->datum_token_emission->hdr.version >= 2 ) { - char *l_balance = dap_chain_balance_print(l_token_emission_item->datum_token_emission->hdr.value_256); + char *l_balance = dap_chain_balance_print(l_token_emission_item->datum_token_emission->hdr.value); log_it(L_ERROR, "Can't add token emission datum of %s %s ( %s ): already present in cache", l_balance, l_token_ticker, l_token_hash_str); DAP_DELETE(l_balance); - } - else + } else log_it(L_ERROR, "Can't add token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s ): already present in cache", - l_token_emission_item->datum_token_emission->hdr.value, l_token_ticker, l_token_hash_str); + l_token_emission_item->datum_token_emission->hdr.value64, l_token_ticker, l_token_hash_str); } - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED; + l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED; }else if ( (! l_token_item) && ( l_threshold_emissions_count >= s_threshold_emissions_max)) { if(s_debug_more) log_it(L_WARNING,"Emissions threshold overflow, max %zu items", s_threshold_emissions_max); - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW; + l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW; } if (l_ret || !PVT(a_ledger)->check_token_emission) return l_ret; @@ -2591,25 +2598,14 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ size_t l_emission_size = a_token_emission_size; dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_token_emission, &l_emission_size); - if (IS_ZERO_256((l_emission->hdr.value_256))) { + if (IS_ZERO_256((l_emission->hdr.value))) { log_it(L_ERROR, "Emission check: zero %s emission value", l_token_item->ticker); DAP_DELETE(l_emission); - return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE; + return DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE; } - // if total_supply > 0 we can check current_supply - if (!IS_ZERO_256(l_token_item->total_supply)){ - if(compare256(l_token_item->current_supply, l_emission->hdr.value_256) < 0) { - char *l_balance_cur = dap_chain_balance_print(l_token_item->current_supply); - char *l_balance_em = dap_chain_balance_print(l_emission->hdr.value_256); - log_it(L_ERROR, "Emission check: current_supply %s < emission value %s", - l_balance_cur, l_balance_em); - DAP_DELETE(l_balance_cur); - DAP_DELETE(l_balance_em); - DAP_DELETE(l_emission); - return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY; - } - } + if (!s_ledger_token_supply_check(l_token_item, l_emission->hdr.value)) + return DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY; //additional check for private tokens if ((l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE) @@ -2620,11 +2616,8 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ } switch (l_emission->hdr.type){ case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH:{ - dap_chain_ledger_token_item_t *l_token_item=NULL; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_FIND_STR(PVT(a_ledger)->tokens, l_emission->hdr.ticker, l_token_item); - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - if (l_token_item){ + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_emission->hdr.ticker); + if (l_token_item) { assert(l_token_item->datum_token); dap_sign_t *l_sign = (dap_sign_t *)(l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size); size_t l_offset = (byte_t *)l_sign - (byte_t *)l_emission; @@ -2665,20 +2658,20 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ } if (l_aproves < l_aproves_valid ){ if(s_debug_more) { - char *l_balance = dap_chain_balance_print(l_emission->hdr.value_256); + char *l_balance = dap_chain_balance_print(l_emission->hdr.value); log_it(L_WARNING, "Emission of %s datoshi of %s:%s is wrong: only %u valid aproves when %u need", - l_balance, a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid); + l_balance, a_ledger->net->pub.name, l_emission->hdr.ticker, l_aproves, l_aproves_valid); DAP_DELETE(l_balance); } - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS; + l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS; char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str)); log_it(L_MSG, "!!! Datum hash for HAL: %s", l_hash_str); } }else{ if(s_debug_more) - log_it(L_WARNING,"Can't find token declaration %s:%s thats pointed in token emission datum", a_ledger->net_name, l_emission->hdr.ticker); - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN; + log_it(L_WARNING,"Can't find token declaration %s:%s thats pointed in token emission datum", a_ledger->net->pub.name, l_emission->hdr.ticker); + l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN; } }break; default:{} @@ -2687,7 +2680,7 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ return l_ret; } -bool s_chain_ledger_token_address_check(dap_chain_addr_t * a_addrs, dap_chain_datum_token_emission_t *a_token_emission, size_t a_addrs_count) +bool s_ledger_token_address_check(dap_chain_addr_t * a_addrs, dap_chain_datum_token_emission_t *a_token_emission, size_t a_addrs_count) { // if l_addrs is empty - nothing to check dap_return_val_if_pass(!a_addrs, true); @@ -2701,7 +2694,7 @@ bool s_chain_ledger_token_address_check(dap_chain_addr_t * a_addrs, dap_chain_da return false; } -bool s_chain_ledger_token_tsd_check(dap_chain_ledger_token_item_t * a_token_item, dap_chain_datum_token_emission_t *a_token_emission) +bool s_ledger_token_tsd_check(dap_ledger_token_item_t * a_token_item, dap_chain_datum_token_emission_t *a_token_emission) { if (!a_token_item){ log_it(L_WARNING, "Token object is null. Probably, you set unknown token ticker in -token parameter"); @@ -2712,7 +2705,7 @@ bool s_chain_ledger_token_tsd_check(dap_chain_ledger_token_item_t * a_token_item if ((a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED) || (a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN)) { // in white list - if (!s_chain_ledger_token_address_check(a_token_item->tx_recv_allow, a_token_emission, a_token_item->tx_recv_allow_size)){ + if (!s_ledger_token_address_check(a_token_item->tx_recv_allow, a_token_emission, a_token_item->tx_recv_allow_size)){ log_it(L_WARNING, "Address %s is not in tx_recv_allow for emission for token %s", dap_chain_addr_to_str(&a_token_emission->hdr.address), a_token_item->ticker); return false; @@ -2721,7 +2714,7 @@ bool s_chain_ledger_token_tsd_check(dap_chain_ledger_token_item_t * a_token_item } if (a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED) { - if (s_chain_ledger_token_address_check(a_token_item->tx_recv_block, a_token_emission, a_token_item->tx_recv_block_size)){ + if (s_ledger_token_address_check(a_token_item->tx_recv_block, a_token_emission, a_token_item->tx_recv_block_size)){ log_it(L_WARNING, "Address %s is in tx_recv_block for emission for token %s", dap_chain_addr_to_str(&a_token_emission->hdr.address), a_token_item->ticker); return false; @@ -2731,9 +2724,11 @@ bool s_chain_ledger_token_tsd_check(dap_chain_ledger_token_item_t * a_token_item return true; } -static void s_ledger_emission_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_token_emission_item_t *a_emission_item) +static void s_ledger_emission_cache_update(dap_ledger_t *a_ledger, dap_ledger_token_emission_item_t *a_emission_item) { - char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR); + if (!PVT(a_ledger)->cached) + return; + char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_EMISSIONS_STR); size_t l_cache_size = a_emission_item->datum_token_emission_size + sizeof(dap_hash_fast_t); uint8_t *l_cache = DAP_NEW_STACK_SIZE(uint8_t, l_cache_size); memcpy(l_cache, &a_emission_item->tx_used_out, sizeof(dap_hash_fast_t)); @@ -2747,64 +2742,33 @@ static void s_ledger_emission_cache_update(dap_ledger_t *a_ledger, dap_chain_led } /** - * @brief dap_chain_ledger_token_emission_add + * @brief dap_ledger_token_emission_add * @param a_token_emission * @param a_token_emision_size * @return */ -int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, +int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_hash_fast_t *a_emission_hash, bool a_from_threshold) -{ - return s_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, a_emission_hash, a_from_threshold, true); -} - -/** - * @brief s_token_emission_add_unsafe - * @param a_ledger - * @param a_token_emission - * @param a_token_emission_size - * @param a_emission_hash - * @param a_from_threshold - * @return - */ -static int s_token_emission_add_unsafe(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, - dap_hash_fast_t *a_emission_hash, bool a_from_threshold) -{ - return s_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, a_emission_hash, a_from_threshold, false); -} - -/** - * @brief s_token_emission_add - * @param a_ledger - * @param a_token_emission - * @param a_token_emission_size - * @param a_emission_hash - * @param a_from_threshold - * @param a_safe_call - * @return - */ -static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, - dap_hash_fast_t *a_emission_hash, bool a_from_threshold, bool a_safe_call) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL; + dap_ledger_token_emission_item_t * l_token_emission_item = NULL; char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str)); - int l_ret = dap_chain_ledger_token_emission_add_check(a_ledger, a_token_emission, a_token_emission_size, a_emission_hash); + int l_ret = dap_ledger_token_emission_add_check(a_ledger, a_token_emission, a_token_emission_size, a_emission_hash); if (l_ret) { if (l_ret == DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE) { // TODO remove emissions threshold if (HASH_COUNT(l_ledger_pvt->threshold_emissions) < s_threshold_emissions_max) { - l_token_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t); + l_token_emission_item = DAP_NEW_Z(dap_ledger_token_emission_item_t); if ( !l_token_emission_item ) { - log_it(L_CRITICAL, "Memory allocation error"); - return DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; + log_it(L_CRITICAL, "Memory allocation error"); + return DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; } l_token_emission_item->datum_token_emission = DAP_DUP_SIZE(a_token_emission, a_token_emission_size); if ( !l_token_emission_item->datum_token_emission ) { DAP_DELETE(l_token_emission_item); - log_it(L_CRITICAL, "Memory allocation error"); - return DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; + log_it(L_CRITICAL, "Memory allocation error"); + return DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; } l_token_emission_item->datum_token_emission_size = a_token_emission_size; dap_hash_fast_t l_emi_hash = {0}; @@ -2823,26 +2787,23 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e } return l_ret; } - const char * c_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker; - dap_chain_ledger_token_item_t * l_token_item = NULL; - pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock); - HASH_FIND_STR(l_ledger_pvt->tokens, c_token_ticker, l_token_item); - pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock); + const char *c_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker; + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, c_token_ticker); if (!l_token_item && a_from_threshold) - return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN; + return DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN; // check if such emission is already present in table - if(a_safe_call) pthread_rwlock_rdlock( l_token_item ? &l_token_item->token_emissions_rwlock + pthread_rwlock_rdlock( l_token_item ? &l_token_item->token_emissions_rwlock : &l_ledger_pvt->threshold_emissions_rwlock); HASH_FIND(hh,l_token_item ? l_token_item->token_emissions : l_ledger_pvt->threshold_emissions, a_emission_hash, sizeof(*a_emission_hash), l_token_emission_item); - if(a_safe_call) pthread_rwlock_unlock(l_token_item ? &l_token_item->token_emissions_rwlock + pthread_rwlock_unlock(l_token_item ? &l_token_item->token_emissions_rwlock : &l_ledger_pvt->threshold_emissions_rwlock); if (!l_token_emission_item) { - l_token_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t); + l_token_emission_item = DAP_NEW_Z(dap_ledger_token_emission_item_t); if ( !l_token_emission_item ) { - log_it(L_CRITICAL, "Memory allocation error"); - return DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; + log_it(L_CRITICAL, "Memory allocation error"); + return DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; } l_token_emission_item->datum_token_emission_size = a_token_emission_size; l_token_emission_item->datum_token_emission_hash = *a_emission_hash; @@ -2853,46 +2814,29 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e //additional check for private tokens if((l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE) || (l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE)) { - if (!s_chain_ledger_token_tsd_check(l_token_item, (dap_chain_datum_token_emission_t *)a_token_emission)) { + if (!s_ledger_token_tsd_check(l_token_item, (dap_chain_datum_token_emission_t *)a_token_emission)) { DAP_DELETE(l_token_emission_item->datum_token_emission); DAP_DELETE(l_token_emission_item); - return DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED; + return DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED; } } //Update value in ledger memory object - if (!IS_ZERO_256(l_token_item->total_supply)) { - uint256_t l_emission_value = l_token_emission_item->datum_token_emission->hdr.value_256; - if (compare256(l_token_item->current_supply, l_emission_value) >= 0){ - SUBTRACT_256_256(l_token_item->current_supply, l_emission_value, &l_token_item->current_supply); - char *l_balance = dap_chain_balance_print(l_token_item->current_supply); - log_it(L_DEBUG,"New current supply %s for token %s", l_balance, l_token_item->ticker); - DAP_DELETE(l_balance); - } else { - char *l_balance = dap_chain_balance_print(l_token_item->current_supply); - char *l_value = dap_chain_balance_print(l_emission_value); - - log_it(L_WARNING,"Token %s current supply %s < emission value %s", - l_token_item->ticker, l_balance, l_value); - DAP_DELETE(l_balance); - DAP_DELETE(l_value); - DAP_DELETE(l_token_emission_item->datum_token_emission); - DAP_DELETE(l_token_emission_item); - return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY; - } - if (PVT(a_ledger)->cached) - s_ledger_token_cache_update(a_ledger, l_token_item); + if (!s_ledger_token_supply_check_update(a_ledger, l_token_item, + l_token_emission_item->datum_token_emission->hdr.value)) { + DAP_DELETE(l_token_emission_item->datum_token_emission); + DAP_DELETE(l_token_emission_item); + return DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY; } pthread_rwlock_wrlock(&l_token_item->token_emissions_rwlock); HASH_ADD(hh, l_token_item->token_emissions, datum_token_emission_hash, sizeof(*a_emission_hash), l_token_emission_item); pthread_rwlock_unlock(&l_token_item->token_emissions_rwlock); - if (PVT(a_ledger)->cached) - // Add it to cache - s_ledger_emission_cache_update(a_ledger, l_token_emission_item); - if(s_debug_more) { + // Add it to cache + s_ledger_emission_cache_update(a_ledger, l_token_emission_item); + if (s_debug_more) { char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_emission_item->datum_token_emission->hdr.address)); - char *l_balance = dap_chain_balance_to_coins(l_token_emission_item->datum_token_emission->hdr.value_256); + char *l_balance = dap_chain_balance_to_coins(l_token_emission_item->datum_token_emission->hdr.value); log_it(L_NOTICE, "Added token emission datum to emissions cache: type=%s value=%s token=%s to_addr=%s ", c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type], l_balance, c_token_ticker, l_token_emission_address_str); @@ -2903,22 +2847,23 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e } else if (HASH_COUNT(l_ledger_pvt->threshold_emissions) < s_threshold_emissions_max) { l_token_emission_item->datum_token_emission = DAP_DUP_SIZE(a_token_emission, a_token_emission_size); l_token_emission_item->datum_token_emission_size = a_token_emission_size; - if(a_safe_call) pthread_rwlock_wrlock(&l_ledger_pvt->threshold_emissions_rwlock); + pthread_rwlock_wrlock(&l_ledger_pvt->threshold_emissions_rwlock); l_token_emission_item->ts_added = dap_nanotime_now(); dap_chain_hash_fast_t l_emi_hash = {0}; dap_hash_fast(a_token_emission, a_token_emission_size, &l_emi_hash); l_token_emission_item->datum_token_emission_hash = l_emi_hash; HASH_ADD(hh, l_ledger_pvt->threshold_emissions, datum_token_emission_hash, sizeof(*a_emission_hash), l_token_emission_item); - if(a_safe_call) pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock); + pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock); l_ret = -5; - if(s_debug_more) { + if (s_debug_more) { char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_emission_item->datum_token_emission->hdr.address)); - log_it(L_NOTICE, "Added token emission datum to emissions threshold: type=%s value=%.1Lf token=%s to_addr=%s ", + char *l_balance = dap_chain_balance_to_coins(l_token_emission_item->datum_token_emission->hdr.value); + log_it(L_NOTICE, "Added token emission datum to emissions threshold: type=%s value=%s token=%s to_addr=%s ", c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type], - dap_chain_datoshi_to_coins(l_token_emission_item->datum_token_emission->hdr.value), - c_token_ticker, l_token_emission_address_str); + l_balance, c_token_ticker, l_token_emission_address_str); DAP_DELETE(l_token_emission_address_str); + DAP_DELETE(l_balance); } } else { DAP_DELETE(l_token_emission_item->datum_token_emission); @@ -2926,7 +2871,7 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e if(s_debug_more) log_it(L_WARNING,"threshold for emissions is overfulled (%zu max), dropping down new data, added nothing", s_threshold_emissions_max); - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW; + l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW; } } else { if (l_token_item) { @@ -2934,34 +2879,35 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str)); if ( ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.version == 2 ) { - char *l_balance = dap_chain_balance_print(((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value_256); + char *l_balance = dap_chain_balance_print(((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value); log_it(L_ERROR, "Duplicate token emission datum of %s %s ( %s )", l_balance, c_token_ticker, l_hash_str); DAP_DELETE(l_balance); - } - else + } else log_it(L_ERROR, "Duplicate token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s )", - ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value, c_token_ticker, l_hash_str); + ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value64, c_token_ticker, l_hash_str); } } - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED; + l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED; } return l_ret; } -void s_ledger_stake_lock_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_stake_lock_item_t *a_stake_lock_item) +void s_ledger_stake_lock_cache_update(dap_ledger_t *a_ledger, dap_ledger_stake_lock_item_t *a_stake_lock_item) { + if (!PVT(a_ledger)->cached) + return; char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&a_stake_lock_item->tx_for_stake_lock_hash, l_hash_str, sizeof(l_hash_str)); - char *l_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_STAKE_LOCK_STR); + char *l_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_STAKE_LOCK_STR); if (dap_global_db_set(l_group, l_hash_str, &a_stake_lock_item->tx_used_out, sizeof(dap_hash_fast_t), false, NULL, NULL)) log_it(L_WARNING, "Ledger cache mismatch"); DAP_DEL_Z(l_group); } -int dap_chain_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash) +int dap_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_stake_lock_item_t *l_new_stake_lock_emission; + dap_ledger_stake_lock_item_t *l_new_stake_lock_emission; pthread_rwlock_rdlock(&l_ledger_pvt->stake_lock_rwlock); HASH_FIND(hh, l_ledger_pvt->emissions_for_stake_lock, a_tx_hash, sizeof(dap_hash_fast_t), l_new_stake_lock_emission); @@ -2969,10 +2915,10 @@ int dap_chain_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, co if (l_new_stake_lock_emission) { return -1; } - l_new_stake_lock_emission = DAP_NEW_Z(dap_chain_ledger_stake_lock_item_t); + l_new_stake_lock_emission = DAP_NEW_Z(dap_ledger_stake_lock_item_t); if (!l_new_stake_lock_emission) { if (s_debug_more) { - log_it(L_ERROR, "Error: memory allocation when try adding item 'dap_chain_ledger_stake_lock_item_t' to hash-table"); + log_it(L_ERROR, "Error: memory allocation when try adding item 'dap_ledger_stake_lock_item_t' to hash-table"); } return -13; } @@ -2981,19 +2927,16 @@ int dap_chain_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, co HASH_ADD(hh, l_ledger_pvt->emissions_for_stake_lock, tx_for_stake_lock_hash, sizeof(dap_chain_hash_fast_t), l_new_stake_lock_emission); pthread_rwlock_unlock(&l_ledger_pvt->stake_lock_rwlock); - if (!l_new_stake_lock_emission) - debug_if(s_debug_more, L_ERROR, "Error: adding to hash-table. Be careful, there may be leaks"); - else if (PVT(a_ledger)->cached) - s_ledger_stake_lock_cache_update(a_ledger, l_new_stake_lock_emission); + s_ledger_stake_lock_cache_update(a_ledger, l_new_stake_lock_emission); return 0; } -dap_chain_ledger_stake_lock_item_t *s_emissions_for_stake_lock_item_find(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_token_emission_hash) +dap_ledger_stake_lock_item_t *s_emissions_for_stake_lock_item_find(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_token_emission_hash) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_stake_lock_item_t *l_new_stake_lock_emission; + dap_ledger_stake_lock_item_t *l_new_stake_lock_emission; pthread_rwlock_rdlock(&l_ledger_pvt->stake_lock_rwlock); HASH_FIND(hh, l_ledger_pvt->emissions_for_stake_lock, a_token_emission_hash, sizeof(dap_chain_hash_fast_t), l_new_stake_lock_emission); @@ -3002,12 +2945,12 @@ dap_chain_ledger_stake_lock_item_t *s_emissions_for_stake_lock_item_find(dap_led } -int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, +int dap_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_hash_fast_t *a_token_emission_hash) { if (PVT(a_ledger)->load_mode) { - dap_chain_ledger_token_emission_item_t *l_token_emission_item; - dap_chain_ledger_token_item_t *l_token_item, *l_item_tmp; + dap_ledger_token_emission_item_t *l_token_emission_item; + dap_ledger_token_item_t *l_token_item, *l_item_tmp; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_item_tmp) { pthread_rwlock_rdlock(&l_token_item->token_emissions_rwlock); @@ -3028,63 +2971,59 @@ int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token return -5; } } - return dap_chain_ledger_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, a_token_emission_hash, false); + return dap_ledger_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, a_token_emission_hash, false); } -char *dap_chain_ledger_token_emission_err_code_to_str(int a_code) { - return (a_code >= DAP_CHAIN_LEDGER_EMISSION_ADD_OK && a_code < DAP_CHAIN_LEDGER_EMISSION_ADD_UNKNOWN) - ? (char*)s_ledger_emission_add_err_str[(dap_chain_ledger_emission_err_code_t)a_code] +char *dap_ledger_token_emission_err_code_to_str(int a_code) { + return (a_code >= DAP_LEDGER_EMISSION_ADD_OK && a_code < DAP_LEDGER_EMISSION_ADD_UNKNOWN) + ? (char*)s_ledger_emission_add_err_str[(dap_ledger_emission_err_code_t)a_code] : dap_itoa(a_code); } -dap_chain_ledger_token_emission_item_t *s_emission_item_find(dap_ledger_t *a_ledger, - const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash) +dap_ledger_token_emission_item_t *s_emission_item_find(dap_ledger_t *a_ledger, + const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash, dap_ledger_token_item_t **a_token_item) { - dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_token_item_t * l_token_item = NULL; - pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock); - HASH_FIND_STR(l_ledger_pvt->tokens, a_token_ticker, l_token_item); - pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock); - + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token_ticker); if (!l_token_item) return NULL; - dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL; + else if (a_token_item) + *a_token_item = l_token_item; + dap_ledger_token_emission_item_t *l_token_emission_item = NULL; pthread_rwlock_rdlock(&l_token_item->token_emissions_rwlock); - HASH_FIND(hh, l_token_item->token_emissions, a_token_emission_hash, sizeof(*a_token_emission_hash), - l_token_emission_item); + HASH_FIND(hh, l_token_item->token_emissions, a_token_emission_hash, sizeof(*a_token_emission_hash), l_token_emission_item); pthread_rwlock_unlock(&l_token_item->token_emissions_rwlock); return l_token_emission_item; } /** - * @brief dap_chain_ledger_token_emission_find + * @brief dap_ledger_token_emission_find * @param a_token_ticker * @param a_token_emission_hash * @return */ -dap_chain_datum_token_emission_t *dap_chain_ledger_token_emission_find(dap_ledger_t *a_ledger, +dap_chain_datum_token_emission_t *dap_ledger_token_emission_find(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash) { - dap_chain_ledger_token_emission_item_t *l_emission_item = s_emission_item_find(a_ledger, a_token_ticker, a_token_emission_hash); + dap_ledger_token_emission_item_t *l_emission_item = s_emission_item_find(a_ledger, a_token_ticker, a_token_emission_hash, NULL); return l_emission_item ? l_emission_item->datum_token_emission : NULL; } /** - * @brief dap_chain_ledger_set_local_cell_id + * @brief dap_ledger_set_local_cell_id * @param a_local_cell_id */ -void dap_chain_ledger_set_local_cell_id(dap_ledger_t *a_ledger, dap_chain_cell_id_t a_local_cell_id) +void dap_ledger_set_local_cell_id(dap_ledger_t *a_ledger, dap_chain_cell_id_t a_local_cell_id) { PVT(a_ledger)->local_cell_id.uint64 = a_local_cell_id.uint64; } /** - * @brief dap_chain_ledger_tx_get_token_ticker_by_hash + * @brief dap_ledger_tx_get_token_ticker_by_hash * @param a_ledger * @param a_tx_hash * @return */ -const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_chain_hash_fast_t *a_tx_hash) +const char* dap_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_chain_hash_fast_t *a_tx_hash) { if(!a_ledger || !a_tx_hash) return NULL; @@ -3093,7 +3032,7 @@ const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger, if ( dap_hash_fast_is_blank(a_tx_hash) ) return NULL; - dap_chain_ledger_tx_item_t *l_item; + dap_ledger_tx_item_t *l_item; unsigned l_hash_value; HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value); pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); @@ -3103,16 +3042,16 @@ const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger, } /** - * @brief dap_chain_ledger_addr_get_token_ticker_all_depricated + * @brief dap_ledger_addr_get_token_ticker_all_depricated * @param a_addr * @param a_tickers * @param a_tickers_size */ -void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, +void dap_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, char *** a_tickers, size_t * a_tickers_size) { dap_chain_hash_fast_t l_tx_first_hash = { 0 }; - const dap_chain_ledger_tx_item_t * l_tx_item = tx_item_find_by_addr(a_ledger, a_addr,NULL, &l_tx_first_hash); + const dap_ledger_tx_item_t * l_tx_item = tx_item_find_by_addr(a_ledger, a_addr,NULL, &l_tx_first_hash); char ** l_tickers = NULL; size_t l_tickers_size = 10; size_t l_tickers_pos = 0; @@ -3138,7 +3077,7 @@ void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledge l_tickers_size += (l_tickers_size / 2); l_tickers = DAP_REALLOC(l_tickers, l_tickers_size); if ( !l_tickers ) { - log_it(L_CRITICAL, "Memory allocation error"); + log_it(L_CRITICAL, "Memory allocation error"); return; } } @@ -3168,14 +3107,14 @@ void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledge * @param a_tickers * @param a_tickers_size */ -void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, +void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, char *** a_tickers, size_t * a_tickers_size) { if (a_addr == NULL){ // Get all tockens pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); size_t l_count = HASH_COUNT(PVT(a_ledger)->tokens); if (l_count && a_tickers){ - dap_chain_ledger_token_item_t * l_token_item, *l_tmp; + dap_ledger_token_item_t * l_token_item, *l_tmp; char **l_tickers = DAP_NEW_Z_SIZE(char*, l_count * sizeof(char*)); if (!l_tickers) { log_it(L_CRITICAL, "Memory allocation error"); @@ -3229,7 +3168,7 @@ void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chai * return transaction, or NULL if transaction not found in the cache */ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger, - dap_chain_hash_fast_t *a_tx_hash, dap_chain_ledger_tx_item_t **a_item_out, bool a_unspent_only) + dap_chain_hash_fast_t *a_tx_hash, dap_ledger_tx_item_t **a_item_out, bool a_unspent_only) { if(!a_tx_hash) return NULL; @@ -3238,7 +3177,7 @@ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger, dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); dap_chain_datum_tx_t *l_tx_ret = NULL; - dap_chain_ledger_tx_item_t *l_tx_item; + dap_ledger_tx_item_t *l_tx_item; pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); HASH_FIND(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item); pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); @@ -3253,27 +3192,27 @@ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger, } /** - * @brief dap_chain_ledger_tx_find_by_hash + * @brief dap_ledger_tx_find_by_hash * @param a_tx_hash * @return */ -dap_chain_datum_tx_t *dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash) +dap_chain_datum_tx_t *dap_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash) { return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, true); } -dap_chain_datum_tx_t *dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash) +dap_chain_datum_tx_t *dap_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash) { return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, false); } -dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash) +dap_hash_fast_t *dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash) { if (!a_ledger || !a_tx_hash || dap_hash_fast_is_blank(a_tx_hash)) return NULL; dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_tx_item_t *l_item; + dap_ledger_tx_item_t *l_item; unsigned l_hash_value; dap_chain_hash_fast_t *l_tx_hash = a_tx_hash; pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); @@ -3299,7 +3238,7 @@ dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger /** * Check whether used 'out' items (local function) */ -static bool s_ledger_tx_hash_is_used_out_item(dap_chain_ledger_tx_item_t *a_item, int a_idx_out, dap_hash_fast_t *a_out_spender_hash) +static bool s_ledger_tx_hash_is_used_out_item(dap_ledger_tx_item_t *a_item, int a_idx_out, dap_hash_fast_t *a_out_spender_hash) { if (!a_item || !a_item->cache_data.n_outs) { //log_it(L_DEBUG, "list_cached_item is NULL"); @@ -3319,15 +3258,30 @@ static bool s_ledger_tx_hash_is_used_out_item(dap_chain_ledger_tx_item_t *a_item return false; } +static dap_ledger_reward_item_t *s_find_reward(dap_ledger_t *a_ledger, dap_ledger_reward_key_t *a_search_key) +{ + dap_ledger_reward_item_t *l_reward_item = NULL; + pthread_rwlock_rdlock(&PVT(a_ledger)->rewards_rwlock); + HASH_FIND(hh, PVT(a_ledger)->rewards, a_search_key, sizeof(*a_search_key), l_reward_item); + pthread_rwlock_unlock(&PVT(a_ledger)->rewards_rwlock); + return l_reward_item; +} + +bool dap_ledger_is_used_reward(dap_ledger_t *a_ledger, dap_hash_fast_t *a_block_hash, dap_hash_fast_t *a_sign_pkey_hash) +{ + dap_ledger_reward_key_t l_search_key = { .block_hash = *a_block_hash, .sign_pkey_hash = *a_sign_pkey_hash }; + return s_find_reward(a_ledger, &l_search_key); +} + /** - * @brief dap_chain_ledger_permissions_check + * @brief dap_ledger_permissions_check * @param a_token_item * @param a_permission_id * @param a_data * @param a_data_size * @return */ -static int s_ledger_permissions_check(dap_chain_ledger_token_item_t * a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size ) +static int s_ledger_permissions_check(dap_ledger_token_item_t * a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size ) { dap_chain_addr_t * l_addrs = NULL; size_t l_addrs_count =0; @@ -3402,8 +3356,8 @@ bool s_tx_match_sign(dap_chain_datum_token_emission_t *a_datum_emission, dap_cha // For each emission signs for(int l_sign_em_num = 0; l_sign_em_num < l_emission_sign_num && l_emission_sign_offset < l_emission_size; l_sign_em_num++) { // For each tx signs - for(dap_list_t *l_list_tmp = l_list_sig; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp)) { - dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) l_list_tmp->data; + for(dap_list_t *it = l_list_sig; it; it = dap_list_next(it)) { + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) it->data; // Get sign from sign item dap_sign_t *l_tx_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*) l_tx_sig); // Compare signs @@ -3432,13 +3386,21 @@ static int s_callback_sign_compare(dap_list_t *a_list_elem, dap_list_t *a_sign_e return !dap_pkey_match_sign(l_key, l_sign); } -bool dap_chain_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) +bool dap_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) { dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL); dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); - return dap_list_find(PVT(a_ledger)->poa_certs, l_sign, s_callback_sign_compare); + return dap_list_find(a_ledger->net->pub.keys, l_sign, s_callback_sign_compare); } +inline static bool s_ledger_check_token_ticker(const char *a_ticker) +{ + const char *c = a_ticker; + for (int i = 0; i < DAP_CHAIN_TICKER_SIZE_MAX; i++, c++) + if (*c == '\0') + return true; + return false; +} /** * Checking a new transaction before adding to the cache @@ -3446,11 +3408,15 @@ bool dap_chain_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t * return 0 OK, otherwise error */ // Checking a new transaction before adding to the cache -int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, +int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker) { + if (!a_tx) { + log_it(L_DEBUG, "NULL transaction, check broken"); + return DAP_LEDGER_TX_CHECK_NULL_TX; + } if (!PVT(a_ledger)->load_mode && !a_from_threshold) { - dap_chain_ledger_tx_item_t *l_ledger_item; + dap_ledger_tx_item_t *l_ledger_item; pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock); HASH_FIND(hh, PVT(a_ledger)->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_ledger_item); pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); @@ -3460,16 +3426,16 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); log_it(L_WARNING, "Transaction %s already present in the cache", l_tx_hash_str); } - return DAP_CHAIN_LEDGER_TX_ALREADY_CACHED; + return DAP_LEDGER_TX_ALREADY_CACHED; } } /* * Steps of checking for current transaction tx2 and every previous transaction tx1: * 1. valid(tx2.dap_chain_datum_tx_sig.pkey) * && - * 2. !is_used_out(tx1.dap_chain_datum_tx_out) + * 2. tx2.input != tx2.inputs.used * && - * 3. tx1.output != tx2.bound_items.outputs.used + * 3. !is_used_out(tx1.dap_chain_datum_tx_out) * && * 4. tx1.dap_chain_datum_tx_out.addr.data.key == tx2.dap_chain_datum_tx_sig.pkey for unconditional output * \\ @@ -3479,117 +3445,78 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t * && * 7. valid(fee) */ - dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - if(!a_tx){ - log_it(L_DEBUG, "NULL transaction, check broken"); - return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX; - } dap_list_t *l_list_bound_items = NULL; - - dap_list_t* l_list_tx_out = NULL; - if (a_list_tx_out) - *a_list_tx_out = l_list_tx_out; + dap_list_t *l_list_tx_out = NULL; // sum of values in 'out' items from the previous transactions - dap_chain_ledger_tokenizer_t *l_values_from_prev_tx = NULL, *l_values_from_cur_tx = NULL, + dap_ledger_tokenizer_t *l_values_from_prev_tx = NULL, *l_values_from_cur_tx = NULL, *l_value_cur = NULL, *l_tmp = NULL, *l_res = NULL; const char *l_token = NULL, *l_main_ticker = NULL; - dap_chain_ledger_token_item_t * l_token_item = NULL; - dap_chain_hash_fast_t *l_emission_hash = NULL; - // check all previous transactions - int l_err_num = DAP_CHAIN_LEDGER_TX_CHECK_OK; + int l_err_num = DAP_LEDGER_TX_CHECK_OK; int l_prev_tx_count = 0; // 1. Verify signature in current transaction if (!a_from_threshold && dap_chain_datum_tx_verify_sign(a_tx) != 1) - return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN; + return DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN; // ---------------------------------------------------------------- - // find all 'in' & conditional 'in' items in current transaction - dap_list_t *l_list_in = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_IN_ALL, - &l_prev_tx_count); + // find all 'in' && 'in_cond' && 'in_ems' && 'in_reward' items in current transaction + dap_list_t *l_list_in = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_IN_ALL, &l_prev_tx_count); if (!l_list_in) { log_it(L_WARNING, "Tx check: no valid inputs found"); - return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS; + return DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS; } - dap_chain_ledger_tx_bound_t *bound_item; - dap_chain_hash_fast_t l_hash_pkey = {}; + dap_chain_hash_fast_t l_tx_first_sign_pkey_hash = {}; + dap_pkey_t *l_tx_first_sign_pkey = NULL; bool l_girdled_ems_used = false; - // find all previous transactions - dap_list_t *l_list_tmp = l_list_in; - for (int l_list_tmp_num = 0; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_list_tmp_num++) { - bound_item = DAP_NEW_Z(dap_chain_ledger_tx_bound_t); - if (!bound_item) { - log_it(L_CRITICAL, "Memory allocation error"); - if ( l_list_bound_items ) - dap_list_free_full(l_list_bound_items, NULL); - if (l_list_tx_out) - dap_list_free(l_list_tx_out); - HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { - HASH_DEL(l_values_from_prev_tx, l_value_cur); - DAP_DELETE(l_value_cur); - } - HASH_ITER(hh, l_values_from_cur_tx, l_value_cur, l_tmp) { - HASH_DEL(l_values_from_cur_tx, l_value_cur); - DAP_DELETE(l_value_cur); - } - return -1; - } - dap_chain_tx_in_t *l_tx_in = NULL; - dap_chain_addr_t l_tx_in_from={0}; - dap_chain_tx_in_cond_t *l_tx_in_cond = NULL; - dap_chain_tx_in_ems_t * l_tx_in_ems = NULL; - dap_chain_hash_fast_t l_tx_prev_hash={0}; - uint8_t l_cond_type = *(uint8_t *)l_list_tmp->data; - // one of the previous transaction - switch (l_cond_type) { - case TX_ITEM_TYPE_IN: - l_tx_in = (dap_chain_tx_in_t *)l_list_tmp->data; - l_tx_prev_hash = l_tx_in->header.tx_prev_hash; - bound_item->in.tx_cur_in = l_tx_in; - if (dap_hash_fast_is_blank(&l_tx_prev_hash)) - continue; // old base tx compliance - break; - case TX_ITEM_TYPE_IN_COND: - l_tx_in_cond = (dap_chain_tx_in_cond_t *)l_list_tmp->data; - l_tx_prev_hash = l_tx_in_cond->header.tx_prev_hash; - bound_item->in.tx_cur_in_cond = l_tx_in_cond; - break; - case TX_ITEM_TYPE_IN_EMS: - l_tx_in_ems = (dap_chain_tx_in_ems_t *)l_list_tmp->data; - l_tx_prev_hash =l_tx_in_ems->header.token_emission_hash; - bound_item->in.tx_cur_in_ems = l_tx_in_ems; - break; - default: + + // find all previous transactions + for (dap_list_t *it = l_list_in; it; it = it->next) { + dap_ledger_tx_bound_t *l_bound_item = DAP_NEW_Z(dap_ledger_tx_bound_t); + if (!l_bound_item) { + log_it(L_CRITICAL, "Memory allocation error"); + l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM; break; } - bound_item->tx_prev_hash = l_tx_prev_hash; + l_list_bound_items = dap_list_append(l_list_bound_items, l_bound_item); - char l_tx_prev_hash_str[70]={[0]='\0'}; - dap_chain_hash_fast_to_str(&l_tx_prev_hash, l_tx_prev_hash_str, sizeof(l_tx_prev_hash_str)); - uint256_t l_value; + uint8_t l_cond_type = *(uint8_t *)it->data; + l_bound_item->type = l_cond_type; + uint256_t l_value = uint256_0; void *l_tx_prev_out = NULL; dap_chain_datum_tx_t *l_tx_prev = NULL; - dap_chain_ledger_token_emission_item_t *l_emission_item = NULL; - dap_chain_ledger_stake_lock_item_t *l_stake_lock_emission = NULL; + dap_ledger_token_emission_item_t *l_emission_item = NULL; + dap_ledger_stake_lock_item_t *l_stake_lock_emission = NULL; bool l_girdled_ems = false; - if (l_cond_type == TX_ITEM_TYPE_IN_EMS) { // It's the emission (base) TX + + switch (l_cond_type) { + case TX_ITEM_TYPE_IN_EMS: { // It's the emission (base) TX + dap_chain_tx_in_ems_t *l_tx_in_ems = it->data; l_token = l_tx_in_ems->header.ticker; - l_emission_hash = &l_tx_in_ems->header.token_emission_hash; - if ( (l_emission_item = s_emission_item_find(a_ledger, l_token, l_emission_hash)) ) { - // check AUTH token emission - if (!dap_hash_fast_is_blank(&l_emission_item->tx_used_out)) { - debug_if(s_debug_more, L_WARNING, "Emission for IN_EMS [%s] is already used", l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED; + if (!s_ledger_check_token_ticker(l_token)) { + l_err_num = DAP_LEDGER_TX_CHECK_INVALID_TICKER; + break; + } + dap_hash_fast_t *l_emission_hash = &l_tx_in_ems->header.token_emission_hash; + // 2. Check current transaction for doubles in input items list + for (dap_list_t *l_iter = l_list_in; l_iter; l_iter = l_iter->next) { + dap_chain_tx_in_ems_t *l_in_ems_check = l_iter->data; + if (l_tx_in_ems != l_in_ems_check && + l_in_ems_check->header.type == TX_ITEM_TYPE_IN_EMS && + dap_hash_fast_compare(&l_in_ems_check->header.token_emission_hash, l_emission_hash)) { + debug_if(s_debug_more, L_ERROR, "Emission output already used in current tx"); + l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX; break; } - bound_item->item_emission = l_emission_item; - } else if ((l_girdled_ems = dap_hash_fast_is_blank(l_emission_hash)) || - (l_stake_lock_emission = s_emissions_for_stake_lock_item_find(a_ledger, l_emission_hash))) { + } + if (l_err_num) + break; + if ((l_girdled_ems = dap_hash_fast_is_blank(l_emission_hash)) || + (l_stake_lock_emission = s_emissions_for_stake_lock_item_find(a_ledger, l_emission_hash))) { dap_chain_datum_tx_t *l_tx_stake_lock = a_tx; - // check emission for STAKE_LOCK + // 3. Check emission for STAKE_LOCK if (!dap_hash_fast_is_blank(l_emission_hash)) { dap_hash_fast_t cur_tx_hash; dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &cur_tx_hash); @@ -3598,14 +3525,15 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t debug_if(s_debug_more, L_WARNING, "stake_lock_emission already present in cache for IN_EMS [%s]", l_token); else debug_if(s_debug_more, L_WARNING, "stake_lock_emission is used out for IN_EMS [%s]", l_token); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED; + l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED; break; } - l_tx_stake_lock = dap_chain_ledger_tx_find_by_hash(a_ledger, l_emission_hash); + l_tx_stake_lock = dap_ledger_tx_find_by_hash(a_ledger, l_emission_hash); } else { - if (l_girdled_ems_used) { // Only one allowed item with girdled emission + // 2. The only allowed item with girdled emission + if (l_girdled_ems_used) { debug_if(s_debug_more, L_WARNING, "stake_lock_emission is used out for IN_EMS [%s]", l_token); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED; + l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED; break; } else l_girdled_ems_used = true; @@ -3616,13 +3544,10 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t break; } dap_tsd_t *l_tsd; - dap_chain_ledger_token_item_t *l_delegated_item = NULL; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_FIND_STR(PVT(a_ledger)->tokens, l_token, l_delegated_item); - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + dap_ledger_token_item_t *l_delegated_item = s_ledger_find_token(a_ledger, l_token); if (!l_delegated_item) { debug_if(s_debug_more, L_WARNING, "Token [%s] not found", l_token); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND; + l_err_num = DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND; break; } dap_chain_datum_token_t *l_datum_token = l_delegated_item->datum_token; @@ -3631,13 +3556,13 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_datum_token->header_native_decl.tsd_total_size, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK))) { debug_if(s_debug_more, L_WARNING, "Token [%s] not valid for stake_lock transaction", l_token); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN; + l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN; break; } dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section = _dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t); - if (!dap_chain_ledger_token_ticker_check(a_ledger, (char*)l_tsd_section->ticker_token_from)) { + if (!dap_ledger_token_ticker_check(a_ledger, (char*)l_tsd_section->ticker_token_from)) { debug_if(s_debug_more, L_WARNING, "Token [%s] not found", l_tsd_section->ticker_token_from); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND; + l_err_num = DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND; break; } @@ -3647,7 +3572,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_chain_tx_out_cond_t *l_tx_stake_lock_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_stake_lock, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, NULL); if (!l_tx_stake_lock_out_cond) { debug_if(s_debug_more, L_WARNING, "No OUT_COND of stake_lock subtype for IN_EMS [%s]", l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS; + l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS; break; } uint256_t l_value_expected ={}; @@ -3660,7 +3585,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t DAP_DEL_Z(l_emission_rate_str); DAP_DEL_Z(l_locked_value_str); } - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE; + l_err_num = DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE; break; } dap_chain_tx_out_ext_t *l_tx_out_ext = NULL; @@ -3671,7 +3596,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t if (!l_tx_out_ext) { if (l_girdled_ems) { debug_if(s_debug_more, L_WARNING, "No OUT_EXT for girdled IN_EMS [%s]", l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS; + l_err_num = DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS; } break; } @@ -3681,21 +3606,14 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_OUT, NULL); if (!l_tx_out) { debug_if(true, L_WARNING, "Can't find OUT nor OUT_EXT item for base TX with IN_EMS [%s]", l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX; + l_err_num = DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX; break; } else l_stake_lock_ems_value = l_tx_out->header.value; } else l_stake_lock_ems_value = l_tx_out_ext->header.value; - if (!IS_ZERO_256(l_delegated_item->total_supply) && - compare256(l_delegated_item->current_supply, l_stake_lock_ems_value) < 0) { - char *l_balance = dap_chain_balance_print(l_delegated_item->current_supply); - char *l_value_ch = dap_chain_balance_print(l_stake_lock_ems_value); - log_it(L_WARNING, "Token current supply %s < emission value %s", - l_balance, l_value_ch); - DAP_DEL_Z(l_balance); - DAP_DEL_Z(l_value_ch); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY; + if (!s_ledger_token_supply_check(l_delegated_item, l_stake_lock_ems_value)) { + l_err_num = DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY; break; } if (!EQUAL_256(l_value_expected, l_stake_lock_ems_value)) { @@ -3710,58 +3628,189 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t DAP_DEL_Z(l_value_expected_str); DAP_DEL_Z(l_locked_value_str); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE; + l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE; break; } } if (!l_girdled_ems) { // check tiker - const char *l_tx_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, l_emission_hash); + const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_emission_hash); if (!l_tx_ticker) { debug_if(s_debug_more, L_WARNING, "No ticker found for stake_lock tx [expected '%s']", l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND; + l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND; break; } if (strcmp(l_tx_ticker, (char *)l_tsd_section->ticker_token_from)) { debug_if(s_debug_more, L_WARNING, "Ticker '%s' != expected '%s'", l_tx_ticker, l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED; + l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED; break; } } debug_if(s_debug_more, L_NOTICE, "Check emission passed for IN_EMS [%s]", l_tx_in_ems->header.ticker); - bound_item->tx_prev = l_tx_stake_lock; if (l_stake_lock_emission) { - bound_item->stake_lock_item = l_stake_lock_emission; - bound_item->stake_lock_item->ems_value = l_value_expected; + l_bound_item->stake_lock_item = l_stake_lock_emission; + l_value = l_stake_lock_ems_value; } else // girdled emission - bound_item->out.tx_prev_out_ext_256 = l_tx_out_ext; + l_value = l_tx_out_ext->header.value; + l_bound_item->token_item = l_delegated_item; + l_bound_item->type = TX_ITEM_TYPE_IN_EMS_LOCK; + } else if ( (l_emission_item = s_emission_item_find(a_ledger, l_token, l_emission_hash, &l_bound_item->token_item)) ) { + // 3. Check AUTH token emission + if (!dap_hash_fast_is_blank(&l_emission_item->tx_used_out)) { + debug_if(s_debug_more, L_WARNING, "Emission for IN_EMS [%s] is already used", l_tx_in_ems->header.ticker); + l_err_num = DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED; + break; + } + l_value = l_emission_item->datum_token_emission->hdr.value; + l_bound_item->emission_item = l_emission_item; } else { l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION; break; } - } else { //It's not the emission TX + } break; + + case TX_ITEM_TYPE_IN_REWARD: { + dap_chain_tx_in_reward_t *l_tx_in_reward = it->data; + dap_hash_fast_t *l_block_hash = &l_tx_in_reward->block_hash; + // 2. Check current transaction for doubles in input items list + for (dap_list_t *l_iter = l_list_in; l_iter; l_iter = l_iter->next) { + dap_chain_tx_in_reward_t *l_in_reward_check = l_iter->data; + if (l_tx_in_reward != l_in_reward_check && + l_in_reward_check->type == TX_ITEM_TYPE_IN_REWARD && + dap_hash_fast_compare(&l_in_reward_check->block_hash, l_block_hash)) { + debug_if(s_debug_more, L_ERROR, "Reward for this block sign already used in current tx"); + l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX; + break; + } + } + if (l_err_num) + break; + if (!l_tx_first_sign_pkey) { + // Get sign item + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL, + TX_ITEM_TYPE_SIG, NULL); + assert(l_tx_sig); + // Get sign from sign item + dap_sign_t *l_tx_first_sign = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig); + assert(l_tx_first_sign); + // calculate hash from sign public key + dap_sign_get_pkey_hash(l_tx_first_sign, &l_tx_first_sign_pkey_hash); + l_tx_first_sign_pkey = dap_pkey_get_from_sign(l_tx_first_sign); + } + // 3. Check if already spent reward + dap_ledger_reward_key_t l_search_key = { .block_hash = *l_block_hash, .sign_pkey_hash = l_tx_first_sign_pkey_hash }; + dap_ledger_reward_item_t *l_reward_item = s_find_reward(a_ledger, &l_search_key); + if (l_reward_item) { + l_err_num = DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED; + char l_block_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE], + l_sign_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE], + l_spender_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_chain_hash_fast_to_str(l_block_hash, l_block_hash_str, sizeof(l_block_hash_str)); + dap_chain_hash_fast_to_str(&l_tx_first_sign_pkey_hash, l_sign_hash_str, sizeof(l_sign_hash_str)); + dap_chain_hash_fast_to_str(&l_reward_item->spender_tx, l_spender_hash_str, sizeof(l_spender_hash_str)); + debug_if(s_debug_more, L_WARNING, "Reward for block %s sign %s already spent by %s", l_block_hash_str, l_sign_hash_str, l_spender_hash_str); + break; + } + // Check reward legitimacy & amount + dap_chain_t *l_chain; + DL_FOREACH(a_ledger->net->pub.chains, l_chain) { + if (l_chain->callback_calc_reward) { + l_value = l_chain->callback_calc_reward(l_chain, l_block_hash, l_tx_first_sign_pkey); + break; + } + } + if (IS_ZERO_256(l_value)) { + l_err_num = DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL; + char l_block_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE], + l_sign_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_chain_hash_fast_to_str(l_block_hash, l_block_hash_str, sizeof(l_block_hash_str)); + dap_chain_hash_fast_to_str(&l_tx_first_sign_pkey_hash, l_sign_hash_str, sizeof(l_sign_hash_str)); + debug_if(s_debug_more, L_DEBUG, "Can't find block %s with sign %s", l_block_hash_str, l_sign_hash_str); + break; + } + // Reward nominated in net native ticker only + l_token = l_main_ticker = a_ledger->net->pub.native_ticker; + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token); + if (!l_token_item) { + debug_if(s_debug_more, L_ERROR, "Native token ticker not found"); + l_err_num = DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND; + break; + } + if (!s_ledger_token_supply_check(l_token_item, l_value)) { + l_err_num = DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY; + break; + } + l_bound_item->token_item = l_token_item; + l_bound_item->reward_key = l_search_key; + } break; + + case TX_ITEM_TYPE_IN: + case TX_ITEM_TYPE_IN_COND: { // Not emission types + uint32_t l_idx = (uint32_t)-1; + dap_hash_fast_t *l_tx_prev_hash; + if (l_cond_type == TX_ITEM_TYPE_IN) { + dap_chain_tx_in_t *l_tx_in = it->data; + l_tx_prev_hash = &l_tx_in->header.tx_prev_hash; + if (dap_hash_fast_is_blank(l_tx_prev_hash)) { + DAP_DELETE(l_bound_item); + continue; // old base tx compliance + } + l_idx = l_tx_in->header.tx_out_prev_idx; + // 2. Check current transaction for doubles in input items list + for (dap_list_t *l_iter = l_list_in; l_iter; l_iter = l_iter->next) { + dap_chain_tx_in_t *l_in_check = l_iter->data; + if (l_tx_in != l_in_check && + l_in_check->header.type == TX_ITEM_TYPE_IN && + l_in_check->header.tx_out_prev_idx == l_idx && + dap_hash_fast_compare(&l_in_check->header.tx_prev_hash, l_tx_prev_hash)) { + debug_if(s_debug_more, L_ERROR, "This previous tx output already used in current tx"); + l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX; + break; + } + } + if (l_err_num) + break; + } else { + dap_chain_tx_in_cond_t *l_tx_in_cond = it->data; + l_tx_prev_hash = &l_tx_in_cond->header.tx_prev_hash; + l_idx = l_tx_in_cond->header.tx_out_prev_idx; + // 2. Check current transaction for doubles in input items list + for (dap_list_t *l_iter = l_list_in; l_iter; l_iter = l_iter->next) { + dap_chain_tx_in_cond_t *l_in_cond_check = l_iter->data; + if (l_tx_in_cond != l_in_cond_check && + l_in_cond_check->header.type == TX_ITEM_TYPE_IN_COND && + l_in_cond_check->header.tx_out_prev_idx == l_idx && + dap_hash_fast_compare(&l_in_cond_check->header.tx_prev_hash, l_tx_prev_hash)) { + debug_if(s_debug_more, L_ERROR, "This previous tx output already used in current tx"); + l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX; + break; + } + } + if (l_err_num) + break; + } // Get previous transaction in the cache by hash - dap_chain_ledger_tx_item_t *l_item_out = NULL; - l_tx_prev = s_find_datum_tx_by_hash(a_ledger, &l_tx_prev_hash, &l_item_out, false); + dap_ledger_tx_item_t *l_item_out = NULL; + l_tx_prev = s_find_datum_tx_by_hash(a_ledger, l_tx_prev_hash, &l_item_out, false); + char l_tx_prev_hash_str[DAP_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(l_tx_prev_hash, l_tx_prev_hash_str, DAP_HASH_FAST_STR_SIZE); if (!l_tx_prev) { // Unchained transaction or previous TX was already spent and removed from ledger debug_if(s_debug_more && !a_from_threshold, L_DEBUG, "No previous transaction was found for hash %s", l_tx_prev_hash_str); l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS; break; } else if (l_item_out->cache_data.ts_spent) { - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED; - debug_if(s_debug_more, L_INFO, "All 'out' items of previous tx %s were already spent", l_tx_prev_hash_str); + l_err_num = DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED; + debug_if(s_debug_more, L_WARNING, "All 'out' items of previous tx %s were already spent", l_tx_prev_hash_str); break; } - bound_item->item_out = l_item_out; + l_bound_item->prev_item = l_item_out; l_token = l_item_out->cache_data.token_ticker; debug_if(s_debug_more && !a_from_threshold, L_INFO, "Previous transaction was found for hash %s",l_tx_prev_hash_str); - bound_item->tx_prev = l_tx_prev; // 2. Check if out in previous transaction has spent - int l_idx = (l_cond_type == TX_ITEM_TYPE_IN) ? l_tx_in->header.tx_out_prev_idx : l_tx_in_cond->header.tx_out_prev_idx; dap_hash_fast_t l_spender; if (s_ledger_tx_hash_is_used_out_item(l_item_out, l_idx, &l_spender)) { - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED; + l_err_num = DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED; char l_hash[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&l_spender, l_hash, sizeof(l_hash)); debug_if(s_debug_more, L_INFO, "'Out' item of previous tx %s already spent by %s", l_tx_prev_hash_str, l_hash); @@ -3771,191 +3820,166 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // Get one 'out' item in previous transaction bound with current 'in' item l_tx_prev_out = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_idx); if(!l_tx_prev_out) { - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND; + l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND; break; } - // 3. Compare out in previous transaction with currently used out - dap_list_t *l_bound_item; - DL_FOREACH(l_list_bound_items, l_bound_item) { - if (l_tx_prev_out == ((dap_chain_ledger_tx_bound_t*)l_bound_item->data)->out.tx_prev_out) { - debug_if(s_debug_more, L_ERROR, "Previous transaction output already used in current tx"); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX; + + if (l_cond_type == TX_ITEM_TYPE_IN) { + dap_chain_addr_t *l_addr_from = NULL; + dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_prev_out; + switch (l_type) { + case TX_ITEM_TYPE_OUT_OLD: // Deprecated + l_addr_from = &((dap_chain_tx_out_old_t *)l_tx_prev_out)->addr; + l_value = dap_chain_uint256_from(((dap_chain_tx_out_old_t *)l_tx_prev_out)->header.value); + break; + case TX_ITEM_TYPE_OUT: + l_addr_from = &((dap_chain_tx_out_t *)l_tx_prev_out)->addr; + l_value = ((dap_chain_tx_out_t *)l_tx_prev_out)->header.value; + break; + case TX_ITEM_TYPE_OUT_EXT: + l_addr_from = &((dap_chain_tx_out_ext_t *)l_tx_prev_out)->addr; + l_value = ((dap_chain_tx_out_ext_t *)l_tx_prev_out)->header.value; + l_token = ((dap_chain_tx_out_ext_t *)l_tx_prev_out)->token; + break; + default: + l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_MISSTYPED; + break; + } + if (l_err_num) + break; + l_bound_item->in.addr_from = *l_addr_from; + strncpy(l_bound_item->in.token_ticker, l_token, DAP_CHAIN_TICKER_SIZE_MAX - 1); + // 4. compare public key hashes in the signature of the current transaction and in the 'out' item of the previous transaction + if (dap_hash_fast_is_blank(&l_tx_first_sign_pkey_hash)) { + // Get sign item + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL, + TX_ITEM_TYPE_SIG, NULL); + assert(l_tx_sig); + // Get sign from sign item + dap_sign_t *l_tx_first_sign = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig); + assert(l_tx_first_sign); + // calculate hash from sign public key + dap_sign_get_pkey_hash(l_tx_first_sign, &l_tx_first_sign_pkey_hash); + } + if (!dap_hash_fast_compare(&l_tx_first_sign_pkey_hash, &l_addr_from->data.hash_fast)) { + l_err_num = DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH; break; } - } - } - if (l_err_num) - break; - - if (l_cond_type == TX_ITEM_TYPE_IN) { - dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_prev_out; - dap_hash_fast_t *l_prev_out_addr_key = NULL; - switch (l_type) { - case TX_ITEM_TYPE_OUT_OLD: - bound_item->out.tx_prev_out = l_tx_prev_out; - l_tx_in_from = bound_item->out.tx_prev_out->addr; - l_prev_out_addr_key = &bound_item->out.tx_prev_out->addr.data.hash_fast; - l_value = dap_chain_uint256_from(bound_item->out.tx_prev_out->header.value); - break; - case TX_ITEM_TYPE_OUT: // 256 - bound_item->out.tx_prev_out_256 = l_tx_prev_out; - l_tx_in_from = bound_item->out.tx_prev_out_256->addr; - l_prev_out_addr_key = &bound_item->out.tx_prev_out_256->addr.data.hash_fast; - l_value = bound_item->out.tx_prev_out_256->header.value; - break; - case TX_ITEM_TYPE_OUT_EXT: // 256 - bound_item->out.tx_prev_out_ext_256 = l_tx_prev_out; - l_tx_in_from = bound_item->out.tx_prev_out_ext_256->addr; - l_prev_out_addr_key = &bound_item->out.tx_prev_out_ext_256->addr.data.hash_fast; - l_value = bound_item->out.tx_prev_out_ext_256->header.value; - l_token = bound_item->out.tx_prev_out_ext_256->token; - break; - default: - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND; - break; - } - if (l_err_num) - break; - // 4. compare public key hashes in the signature of the current transaction and in the 'out' item of the previous transaction - if (dap_hash_fast_is_blank(&l_hash_pkey)) { - // Get sign item - dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL, - TX_ITEM_TYPE_SIG, NULL); - // Get sign from sign item - dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig); - // calculate hash from sign public key - dap_sign_get_pkey_hash(l_sign, &l_hash_pkey); - } - if (!dap_hash_fast_compare(&l_hash_pkey, l_prev_out_addr_key)) { - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH; - break; - } - } else if(l_cond_type == TX_ITEM_TYPE_IN_COND) { // TX_ITEM_TYPE_IN_COND - if(*(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT_COND) { - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND; - break; - } - // 5a. Check for condition owner - dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_tx_prev, NULL, TX_ITEM_TYPE_SIG, NULL); - dap_sign_t *l_prev_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_prev_sig); - dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL); - dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); - - dap_chain_tx_out_cond_t *l_tx_prev_out_cond = NULL; - l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out; - if (l_tx_prev_out_cond->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) + if ( !l_token || !*l_token ) { + log_it(L_WARNING, "No token ticker found in previous transaction"); + l_err_num = DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND; + break; + } + // Get permissions + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token); + if (!l_token_item) { + debug_if(s_debug_more, L_WARNING, "Token with ticker %s not found", l_token); + l_err_num = DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND; + break; + } + // Check permissions + if ( (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED ) || // If all is blocked - check if we're + (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN) ){ // in white list + + if (!dap_chain_addr_is_blank(l_addr_from) && s_ledger_permissions_check(l_token_item, + DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD, l_addr_from, + sizeof(*l_addr_from)) != 0 ){ + char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from); + debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)"); + DAP_DEL_Z(l_tmp_tx_in_from); + l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED; + break; + } + } + if ((l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED ) || // If all is allowed - check if we're + (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN ) ){ // in black list + if (s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD, l_addr_from, + sizeof(*l_addr_from)) == 0 ){ + char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from); + debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)"); + DAP_DEL_Z(l_tmp_tx_in_from); + l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED; + break; + } + } + } else { // l_cond_type == TX_ITEM_TYPE_IN_COND + if(*(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT_COND) { + l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_MISSTYPED; + break; + } + // 5a. Check for condition owner + dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_tx_prev, NULL, TX_ITEM_TYPE_SIG, NULL); + dap_sign_t *l_prev_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_prev_sig); + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL); + dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); + + dap_chain_tx_out_cond_t *l_tx_prev_out_cond = NULL; + l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out; + if (l_tx_prev_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) + l_token = a_ledger->net->pub.native_ticker; l_main_ticker = l_token; - else - l_token = l_main_ticker = l_ledger_pvt->net_native_ticker; - - bool l_owner = false; - l_owner = dap_sign_match_pkey_signs(l_prev_sign,l_sign); - - // 5b. Call verificator for conditional output - dap_chain_ledger_verificator_t *l_verificator; - int l_sub_tmp = l_tx_prev_out_cond->header.subtype; - - pthread_rwlock_rdlock(&s_verificators_rwlock); - HASH_FIND_INT(s_verificators, &l_sub_tmp, l_verificator); - pthread_rwlock_unlock(&s_verificators_rwlock); - if (!l_verificator || !l_verificator->callback) { - debug_if(s_debug_more, L_ERROR, "No verificator set for conditional output subtype %d", l_sub_tmp); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET; - break; - } - if (l_verificator->callback(a_ledger, l_tx_prev_out_cond, a_tx, l_owner) == false) { - debug_if(s_debug_more, L_WARNING, "Verificator check error for conditional output %s", - dap_chain_tx_out_cond_subtype_to_str(l_sub_tmp)); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE; - break; - } - // calculate sum of values from previous transactions - bound_item->out.tx_prev_out_cond_256 = l_tx_prev_out_cond; - l_value = l_tx_prev_out_cond->header.value; - } else if(l_cond_type == TX_ITEM_TYPE_IN_EMS) { - if (l_stake_lock_emission) { - l_token = bound_item->in.tx_cur_in_ems->header.ticker; - l_value = bound_item->stake_lock_item->ems_value; - } else if (l_girdled_ems) { - l_token = bound_item->in.tx_cur_in_ems->header.ticker; - l_value = bound_item->out.tx_prev_out_ext_256->header.value; - } else { - l_token = bound_item->item_emission->datum_token_emission->hdr.ticker; - l_value = bound_item->item_emission->datum_token_emission->hdr.value_256; + bool l_owner = false; + l_owner = dap_sign_match_pkey_signs(l_prev_sign, l_sign); + + // 5b. Call verificator for conditional output + dap_ledger_verificator_t *l_verificator; + int l_sub_tmp = l_tx_prev_out_cond->header.subtype; + + pthread_rwlock_rdlock(&s_verificators_rwlock); + HASH_FIND_INT(s_verificators, &l_sub_tmp, l_verificator); + pthread_rwlock_unlock(&s_verificators_rwlock); + if (!l_verificator || !l_verificator->callback) { + debug_if(s_debug_more, L_ERROR, "No verificator set for conditional output subtype %d", l_sub_tmp); + l_err_num = DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET; + break; + } + if (l_verificator->callback(a_ledger, l_tx_prev_out_cond, a_tx, l_owner) == false) { + debug_if(s_debug_more, L_WARNING, "Verificator check error for conditional output %s", + dap_chain_tx_out_cond_subtype_to_str(l_sub_tmp)); + l_err_num = DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE; + break; + } + l_bound_item->cond = l_tx_prev_out_cond; + l_value = l_tx_prev_out_cond->header.value; } - } - if (! l_token || !*l_token ) { - log_it(L_WARNING, "No token ticker found in previous transaction"); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND; + } break; + + default: break; } - // Get permissions - l_token_item = NULL; - pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock); - HASH_FIND_STR(l_ledger_pvt->tokens, l_token, l_token_item); - pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock); - if (! l_token_item){ - if(s_debug_more) - log_it(L_WARNING, "No token item found for token %s", l_token); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND; + if (l_err_num) break; - } - // Check permissions - if ( (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED ) || // If all is blocked - check if we're - (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN) ){ // in white list - if(!dap_chain_addr_is_blank(&l_tx_in_from) && s_ledger_permissions_check(l_token_item, - DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD,&l_tx_in_from, - sizeof (l_tx_in_from)) != 0 ){ - char * l_tmp_tx_in_from = dap_chain_addr_to_str(&l_tx_in_from); - if(s_debug_more) - log_it(L_WARNING, "No permission for addr %s", l_tmp_tx_in_from?l_tmp_tx_in_from:"(null)"); - DAP_DELETE(l_tmp_tx_in_from); - l_err_num = DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED; - break; - } - } - if ((l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED ) || // If all is allowed - check if we're - (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN ) ){ // in black list - if(s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD ,&l_tx_in_from, - sizeof (l_tx_in_from)) == 0 ){ - char * l_tmp_tx_in_from = dap_chain_addr_to_str(&l_tx_in_from); - if(s_debug_more) - log_it(L_WARNING, "No permission for addr %s", l_tmp_tx_in_from?l_tmp_tx_in_from:"(null)"); - DAP_DELETE(l_tmp_tx_in_from); - l_err_num = DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED; + l_bound_item->value = l_value; + + if (l_cond_type != TX_ITEM_TYPE_IN) { + // If not checked earlier + if (!l_token || !*l_token) { + log_it(L_WARNING, "No token ticker found in previous transaction"); + l_err_num = DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND; break; } } - HASH_FIND_STR(l_values_from_prev_tx, l_token, l_value_cur); if (!l_value_cur) { - l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); + l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t); if ( !l_value_cur ) { - log_it(L_CRITICAL, "Memory allocation error"); - if (bound_item) - DAP_DELETE(bound_item); - if ( l_list_bound_items ) - dap_list_free_full(l_list_bound_items, NULL); - if (l_list_tx_out) - dap_list_free(l_list_tx_out); - return -1; + log_it(L_CRITICAL, "Memory allocation error"); + l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM; + break; } strcpy(l_value_cur->token_ticker, l_token); HASH_ADD_STR(l_values_from_prev_tx, token_ticker, l_value_cur); } // calculate from previous transactions per each token SUM_256_256(l_value_cur->sum, l_value, &l_value_cur->sum); - - l_list_bound_items = dap_list_append(l_list_bound_items, bound_item); } if (l_list_in) dap_list_free(l_list_in); - + DAP_DEL_Z(l_tx_first_sign_pkey); if (l_err_num) { - DAP_DELETE(bound_item); if ( l_list_bound_items ) dap_list_free_full(l_list_bound_items, NULL); HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { @@ -3971,23 +3995,24 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t if (HASH_COUNT(l_values_from_prev_tx) > 1) { l_multichannel = true; if (HASH_COUNT(l_values_from_prev_tx) == 2 && !l_main_ticker) { - HASH_FIND_STR(l_values_from_prev_tx, PVT(a_ledger)->net_native_ticker, l_value_cur); + HASH_FIND_STR(l_values_from_prev_tx, a_ledger->net->pub.native_ticker, l_value_cur); if (l_value_cur) { l_value_cur = l_value_cur->hh.next ? l_value_cur->hh.next : l_value_cur->hh.prev; l_main_ticker = l_value_cur->token_ticker; } } } else { - l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); + l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t); if ( !l_value_cur ) { - log_it(L_CRITICAL, "Memory allocation error"); - if (bound_item) - DAP_DELETE(bound_item); + log_it(L_CRITICAL, "Memory allocation error"); + l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM; if ( l_list_bound_items ) dap_list_free_full(l_list_bound_items, NULL); - if (l_list_tx_out) - dap_list_free(l_list_tx_out); - return -1; + HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { + HASH_DEL(l_values_from_prev_tx, l_value_cur); + DAP_DELETE(l_value_cur); + } + return l_err_num; } dap_stpcpy(l_value_cur->token_ticker, l_token); if (!l_main_ticker) @@ -3998,14 +4023,14 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // find 'out' items dap_list_t *l_list_out = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx, TX_ITEM_TYPE_OUT_ALL, NULL); uint256_t l_value = {}, l_fee_sum = {}; - bool l_fee_check = !IS_ZERO_256(l_ledger_pvt->fee_value) && !dap_chain_addr_is_blank(&l_ledger_pvt->fee_addr); + bool l_fee_check = !IS_ZERO_256(a_ledger->net->pub.fee_value) && !dap_chain_addr_is_blank(&a_ledger->net->pub.fee_addr); int l_item_idx = 0; - for (l_list_tmp = l_list_out; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_item_idx++) { - dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data; + for (dap_list_t *it = l_list_out; it; it = it->next, l_item_idx++) { + dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data; dap_chain_addr_t l_tx_out_to={0}; switch (l_type) { case TX_ITEM_TYPE_OUT_OLD: { - dap_chain_tx_out_old_t *l_tx_out = (dap_chain_tx_out_old_t *)l_list_tmp->data; + dap_chain_tx_out_old_t *l_tx_out = (dap_chain_tx_out_old_t *)it->data; if (l_multichannel) { // token ticker is mandatory for multichannel transactions l_err_num = -16; break; @@ -4015,7 +4040,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); } break; case TX_ITEM_TYPE_OUT: { // 256 - dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)l_list_tmp->data; + dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)it->data; if (l_multichannel) { // token ticker is mandatory for multichannel transactions if (l_main_ticker) l_token = l_main_ticker; @@ -4029,7 +4054,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); } break; case TX_ITEM_TYPE_OUT_EXT: { // 256 - dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)l_list_tmp->data; + dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)it->data; if (!l_multichannel) { // token ticker is depricated for single-channel transactions l_err_num = -16; break; @@ -4040,10 +4065,10 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); } break; case TX_ITEM_TYPE_OUT_COND: { - dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)l_list_tmp->data; + dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)it->data; if (l_multichannel) { if (l_tx_out->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) - l_token = (char *)PVT(a_ledger)->net_native_ticker; + l_token = (char *)a_ledger->net->pub.native_ticker; else if (l_main_ticker) l_token = l_main_ticker; else { @@ -4057,19 +4082,16 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } break; default: {} } + if (l_err_num) + break; if (l_multichannel) { HASH_FIND_STR(l_values_from_cur_tx, l_token, l_value_cur); if (!l_value_cur) { - l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); + l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t); if ( !l_value_cur ) { log_it(L_CRITICAL, "Memory allocation error"); - if (bound_item) - DAP_DELETE(bound_item); - if ( l_list_bound_items ) - dap_list_free_full(l_list_bound_items, NULL); - if (l_list_tx_out) - dap_list_free(l_list_tx_out); - return -1; + l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM; + break; } strcpy(l_value_cur->token_ticker, l_token); HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); @@ -4083,14 +4105,9 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } // Get permissions for token - l_token_item = NULL; - pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock); - if(l_ledger_pvt->tokens) - HASH_FIND_STR(l_ledger_pvt->tokens,l_token, l_token_item); - pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock); - if (! l_token_item){ - if(s_debug_more) - log_it(L_WARNING, "No token item found for token %s", l_token); + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token); + if (!l_token_item) { + debug_if(s_debug_more, L_WARNING, "Token with ticker %s not found", l_token); l_err_num = -15; break; } @@ -4122,8 +4139,8 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } } - if (l_fee_check && dap_chain_addr_compare(&l_tx_out_to, &l_ledger_pvt->fee_addr) && - !dap_strcmp(l_value_cur->token_ticker, PVT(a_ledger)->net_native_ticker)) { + if (l_fee_check && dap_chain_addr_compare(&l_tx_out_to, &a_ledger->net->pub.fee_addr) && + !dap_strcmp(l_value_cur->token_ticker, a_ledger->net->pub.native_ticker)) { SUM_256_256(l_fee_sum, l_value, &l_fee_sum); } } @@ -4139,23 +4156,23 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t if (s_debug_more) { char *l_balance = dap_chain_balance_to_coins(l_res ? l_res->sum : uint256_0); char *l_balance_cur = dap_chain_balance_to_coins(l_value_cur->sum); - log_it(L_ERROR, "Sum of values of out items from current tx (%s) is not equal outs from previous tx (%s) for token %s", + log_it(L_ERROR, "Sum of values of out items from current tx (%s) is not equal outs from previous txs (%s) for token %s", l_balance, l_balance_cur, l_value_cur->token_ticker); DAP_DELETE(l_balance); DAP_DELETE(l_balance_cur); } - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS; + l_err_num = DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS; break; } } } // 7. Check the network fee - if (l_fee_check && compare256(l_fee_sum, l_ledger_pvt->fee_value) == -1) { + if (!l_err_num && l_fee_check && compare256(l_fee_sum, a_ledger->net->pub.fee_value) == -1) { // Check for PoA-cert-signed "service" no-tax tx - if (!dap_chain_ledger_tx_poa_signed(a_ledger, a_tx)) { + if (!dap_ledger_tx_poa_signed(a_ledger, a_tx)) { char *l_current_fee = dap_chain_balance_to_coins(l_fee_sum); - char *l_expected_fee = dap_chain_balance_to_coins(l_ledger_pvt->fee_value); + char *l_expected_fee = dap_chain_balance_to_coins(a_ledger->net->pub.fee_value); log_it(L_ERROR, "Fee value is invalid, expected %s pointed %s", l_expected_fee, l_current_fee); l_err_num = -55; DAP_DEL_Z(l_current_fee); @@ -4190,30 +4207,30 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } /** - * @brief dap_chain_ledger_tx_check + * @brief dap_ledger_tx_check * @param a_ledger * @param a_tx * @return */ -int dap_chain_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash) +int dap_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash) { if (!a_tx) - return DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX; + return DAP_LEDGER_TX_CHECK_NULL_TX; size_t l_tx_size = dap_chain_datum_tx_get_size(a_tx); if (l_tx_size != a_datum_size) { log_it (L_WARNING, "Inconsistent datum TX: datum size %zu != tx size %zu", a_datum_size, l_tx_size); - return DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE; + return DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE; } - int l_ret_check = dap_chain_ledger_tx_cache_check(a_ledger, a_tx, a_datum_hash, + int l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_datum_hash, false, NULL, NULL, NULL); if(s_debug_more) { char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(a_datum_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); if (l_ret_check) log_it(L_NOTICE, "Ledger TX adding check not passed for TX %s: error %s", - l_tx_hash_str, dap_chain_ledger_tx_check_err_str(l_ret_check)); + l_tx_hash_str, dap_ledger_tx_check_err_str(l_ret_check)); else log_it(L_INFO, "Ledger TX adding check passed for TX %s", l_tx_hash_str); } @@ -4230,7 +4247,7 @@ int dap_chain_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t * static int s_balance_cache_update(dap_ledger_t *a_ledger, dap_ledger_wallet_balance_t *a_balance) { if (PVT(a_ledger)->cached) { - char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_BALANCES_STR); + char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_BALANCES_STR); if (dap_global_db_set(l_gdb_group, a_balance->key, &a_balance->balance, sizeof(uint256_t), false, NULL, NULL)) { debug_if(s_debug_more, L_WARNING, "Ledger cache mismatch"); return -1; @@ -4244,40 +4261,13 @@ static int s_balance_cache_update(dap_ledger_t *a_ledger, dap_ledger_wallet_bala return 0; } -static int s_sort_ledger_tx_item(dap_chain_ledger_tx_item_t* a, dap_chain_ledger_tx_item_t* b) +static int s_sort_ledger_tx_item(dap_ledger_tx_item_t* a, dap_ledger_tx_item_t* b) { return a->tx->header.ts_created == b->tx->header.ts_created ? 0 : a->tx->header.ts_created < b->tx->header.ts_created ? -1 : 1; } - -/** - * @brief Add new transaction to the cache list - * @param a_ledger - * @param a_tx - * @param a_tx_hash - * @param a_from_threshold - * @return return 1 OK, -1 error - */ -int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold) -{ - return s_tx_add(a_ledger,a_tx,a_tx_hash,a_from_threshold,true); -} - -/** - * @brief Add new transaction to the cache list, without rwlocks lock - * @param a_ledger - * @param a_tx - * @param a_tx_hash - * @param a_from_threshold - * @return return 1 OK, -1 error - */ -static int s_tx_add_unsafe(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold) -{ - return s_tx_add(a_ledger,a_tx,a_tx_hash,a_from_threshold,false); -} - -void dap_chain_ledger_set_tps_start_time(dap_ledger_t *a_ledger) +void dap_ledger_set_tps_start_time(dap_ledger_t *a_ledger) { clock_gettime(CLOCK_REALTIME, &PVT(a_ledger)->tps_start_time); } @@ -4288,10 +4278,9 @@ void dap_chain_ledger_set_tps_start_time(dap_ledger_t *a_ledger) * @param a_tx * @param a_tx_hash * @param a_from_threshold - * @param a_safe_call True if we need to lock rwlock, false if not * @return return 1 OK, -1 error */ -static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold, bool a_safe_call) +int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold) { if(!a_tx) { debug_if(s_debug_more, L_ERROR, "NULL tx detected"); @@ -4301,12 +4290,12 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); dap_list_t *l_list_bound_items = NULL; dap_list_t *l_list_tx_out = NULL; - dap_chain_ledger_tx_item_t *l_item_tmp = NULL; + dap_ledger_tx_item_t *l_item_tmp = NULL; char *l_main_token_ticker = NULL; if (!l_ledger_pvt->tps_timer) { #ifndef DAP_TPS_TEST - dap_chain_ledger_set_tps_start_time(a_ledger); + dap_ledger_set_tps_start_time(a_ledger); #endif l_ledger_pvt->tps_current_time.tv_sec = l_ledger_pvt->tps_start_time.tv_sec; l_ledger_pvt->tps_current_time.tv_nsec = l_ledger_pvt->tps_start_time.tv_nsec; @@ -4322,7 +4311,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d int l_ret_check; l_item_tmp = NULL; - if( (l_ret_check = dap_chain_ledger_tx_cache_check(a_ledger, a_tx, a_tx_hash, a_from_threshold, + if( (l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_tx_hash, a_from_threshold, &l_list_bound_items, &l_list_tx_out, &l_main_token_ticker))) { if (l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS || @@ -4339,7 +4328,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d log_it(L_WARNING, "Threshold for tranactions is overfulled (%zu max), dropping down new data, added nothing", s_threshold_txs_max); } else { - l_item_tmp = DAP_NEW_Z(dap_chain_ledger_tx_item_t); + l_item_tmp = DAP_NEW_Z(dap_ledger_tx_item_t); if ( !l_item_tmp ) { log_it(L_CRITICAL, "Memory allocation error"); return -1; @@ -4360,13 +4349,12 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); } } else { - debug_if(s_debug_more, L_WARNING, "dap_chain_ledger_tx_add() tx %s not passed the check: %s ", l_tx_hash_str, - dap_chain_ledger_tx_check_err_str(l_ret_check)); + debug_if(s_debug_more, L_WARNING, "dap_ledger_tx_add() tx %s not passed the check: %s ", l_tx_hash_str, + dap_ledger_tx_check_err_str(l_ret_check)); } return l_ret_check; } - if(s_debug_more) - log_it ( L_DEBUG, "dap_chain_ledger_tx_add() check passed for tx %s",l_tx_hash_str); + debug_if(s_debug_more, L_DEBUG, "dap_ledger_tx_add() check passed for tx %s", l_tx_hash_str); // Mark 'out' items in cache if they were used & delete previous transactions from cache if it need // find all bound pairs 'in' and 'out' @@ -4377,113 +4365,75 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d if (PVT(a_ledger)->cached) { dap_store_obj_t *l_cache_used_outs = DAP_NEW_Z_SIZE(dap_store_obj_t, sizeof(dap_store_obj_t) * (l_outs_used + 1)); if ( !l_cache_used_outs ) { - if (l_item_tmp) { - DAP_DEL_Z(l_item_tmp->tx); - DAP_DELETE(l_item_tmp); - } - dap_list_free(l_list_bound_items); log_it(L_CRITICAL, "Memory allocation error"); - return -1; + l_ret = -1; + goto FIN; } - l_ledger_cache_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR); + l_ledger_cache_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TXS_STR); } const char *l_cur_token_ticker = NULL; - dap_list_t *l_list_tmp = l_list_bound_items; + // Update balance: deducts - for (int i = 1; l_list_tmp; i++) { - dap_chain_ledger_tx_bound_t *bound_item = l_list_tmp->data; - void *l_item_in = *(void **)&bound_item->in; - dap_chain_tx_item_type_t l_type = *(uint8_t *)l_item_in; - if (l_type == TX_ITEM_TYPE_IN_EMS) { + int l_spent_idx = 0; + for (dap_list_t *it = l_list_bound_items; it; it = it->next) { + dap_ledger_tx_bound_t *l_bound_item = it->data; + dap_chain_tx_item_type_t l_type = l_bound_item->type; + if (l_type == TX_ITEM_TYPE_IN || l_type == TX_ITEM_TYPE_IN_COND) { + if (l_bound_item->prev_item->cache_data.n_outs <= l_bound_item->prev_item->cache_data.n_outs_used) { + log_it(L_ERROR, "[!] Irrelevant prev tx: out items mismatch %d <= %d", + l_bound_item->prev_item->cache_data.n_outs, l_bound_item->prev_item->cache_data.n_outs_used); + l_outs_used--; + continue; + } + l_spent_idx++; + } + + switch (l_type) { + case TX_ITEM_TYPE_IN_EMS: + case TX_ITEM_TYPE_IN_EMS_LOCK: + case TX_ITEM_TYPE_IN_REWARD: { // It's the emission behind - dap_chain_tx_in_ems_t *l_in_ems = bound_item->in.tx_cur_in_ems; - const char *l_delegated_ticker_str = l_in_ems->header.ticker; - if (bound_item->tx_prev) { // It's the stake lock emission - dap_chain_ledger_token_item_t *l_token_item = NULL; - pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock); - HASH_FIND_STR(l_ledger_pvt->tokens, l_delegated_ticker_str, l_token_item); - pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock); - if (l_token_item) { - if (!IS_ZERO_256(l_token_item->total_supply)) { - uint256_t *l_value = bound_item->stake_lock_item ? - &bound_item->stake_lock_item->ems_value : - &bound_item->out.tx_prev_out_ext_256->header.value; - SUBTRACT_256_256(l_token_item->current_supply, *l_value, - &l_token_item->current_supply); - char *l_balance = dap_chain_balance_print(l_token_item->current_supply); - log_it(L_DEBUG, "New current supply %s for token %s", l_balance, l_token_item->ticker); - DAP_DEL_Z(l_balance); - if (PVT(a_ledger)->cached) - s_ledger_token_cache_update(a_ledger, l_token_item); - } - } else - log_it(L_ERROR, "No token item found for token %s", l_delegated_ticker_str); - if (bound_item->stake_lock_item) { - bound_item->stake_lock_item->tx_used_out = *a_tx_hash; - if (PVT(a_ledger)->cached) - // Mirror it in cache - s_ledger_stake_lock_cache_update(a_ledger, bound_item->stake_lock_item); + if (!s_ledger_token_supply_check_update(a_ledger, l_bound_item->token_item, l_bound_item->value)) + log_it(L_ERROR, "Insufficient supply for token %s", l_bound_item->token_item->ticker); + if (l_type == TX_ITEM_TYPE_IN_EMS_LOCK) { + // Mark it as used with current tx hash + l_bound_item->stake_lock_item->tx_used_out = *a_tx_hash; + s_ledger_stake_lock_cache_update(a_ledger, l_bound_item->stake_lock_item); + } else if (l_type == TX_ITEM_TYPE_IN_EMS) { + // Mark it as used with current tx hash + l_bound_item->emission_item->tx_used_out = *a_tx_hash; + s_ledger_emission_cache_update(a_ledger, l_bound_item->emission_item); + } else { // l_type == TX_ITEM_TYPE_IN_REWARD + dap_ledger_reward_item_t *l_item = DAP_NEW_Z(dap_ledger_reward_item_t); + if (!l_item) { + log_it(L_CRITICAL, "Memory allocation error"); + l_ret = -1; + goto FIN; } - } else { // It's the general emission - // Mark it as used with base tx hash - bound_item->item_emission->tx_used_out = *a_tx_hash; - if (PVT(a_ledger)->cached) - // Mirror it in cache - s_ledger_emission_cache_update(a_ledger, bound_item->item_emission); + l_item->key = l_bound_item->reward_key; + l_item->spender_tx = *a_tx_hash; + pthread_rwlock_wrlock(&l_ledger_pvt->rewards_rwlock); + HASH_ADD(hh, l_ledger_pvt->rewards, key, sizeof(l_item->key), l_item); + pthread_rwlock_unlock(&l_ledger_pvt->rewards_rwlock); } - l_list_tmp = dap_list_next(l_list_tmp); - i--; // Do not calc this output with tx used items - l_outs_used--; - continue; - } - dap_chain_ledger_tx_item_t *l_prev_item_out = bound_item->item_out; - if (l_prev_item_out->cache_data.n_outs <= l_prev_item_out->cache_data.n_outs_used) { - log_it(L_ERROR, "[!] Irrelevant prev tx: out items mismatch %d <= %d", - l_prev_item_out->cache_data.n_outs, l_prev_item_out->cache_data.n_outs_used); - l_list_tmp = dap_list_next(l_list_tmp); - i--; - l_outs_used--; - continue; - } - l_cur_token_ticker = l_prev_item_out->cache_data.token_ticker; - int l_tx_prev_out_used_idx = 0; - if (l_type == TX_ITEM_TYPE_IN) { - dap_chain_tx_in_t *l_tx_in = bound_item->in.tx_cur_in; + l_outs_used--; // Do not calc this output with tx used items + } continue; + + case TX_ITEM_TYPE_IN: { dap_ledger_wallet_balance_t *wallet_balance = NULL; - uint256_t l_value = {}; - dap_chain_addr_t *l_addr = NULL; - void *l_item_out = *(void **)&bound_item->out; - dap_chain_tx_item_type_t l_out_type = *(uint8_t *)l_item_out; - switch (l_out_type) { - case TX_ITEM_TYPE_OUT: - l_addr = &bound_item->out.tx_prev_out_256->addr; - l_value = bound_item->out.tx_prev_out_256->header.value; - break; - case TX_ITEM_TYPE_OUT_OLD: - l_addr = &bound_item->out.tx_prev_out->addr; - l_value = GET_256_FROM_64(bound_item->out.tx_prev_out->header.value); - break; - case TX_ITEM_TYPE_OUT_EXT: - l_addr = &bound_item->out.tx_prev_out_ext_256->addr; - l_value = bound_item->out.tx_prev_out_ext_256->header.value; - l_cur_token_ticker = bound_item->out.tx_prev_out_ext_256->token; - break; - default: - log_it(L_DEBUG, "Unknown item type %d", l_out_type); - break; - } - char *l_addr_str = dap_chain_addr_to_str(l_addr); + l_cur_token_ticker = l_bound_item->in.token_ticker; + char *l_addr_str = dap_chain_addr_to_str(&l_bound_item->in.addr_from); char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_cur_token_ticker, (char*)NULL); pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock); HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance); pthread_rwlock_unlock(&PVT(a_ledger)->balance_accounts_rwlock); if (wallet_balance) { if(s_debug_more) { - char *l_balance = dap_chain_balance_print(l_value); + char *l_balance = dap_chain_balance_print(l_bound_item->value); log_it(L_DEBUG,"SPEND %s from addr: %s", l_balance, l_wallet_balance_key); DAP_DELETE(l_balance); } - SUBTRACT_256_256(wallet_balance->balance, l_value, &wallet_balance->balance); + SUBTRACT_256_256(wallet_balance->balance, l_bound_item->value, &wallet_balance->balance); // Update the cache s_balance_cache_update(a_ledger, wallet_balance); } else { @@ -4492,28 +4442,27 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d } DAP_DELETE(l_addr_str); DAP_DELETE(l_wallet_balance_key); - /// Mark 'out' item in cache because it used - l_tx_prev_out_used_idx = l_tx_in->header.tx_out_prev_idx; - } else {//TX_ITEM_TYPE_IN_COND - // all balance deducts performed with previous conditional transaction - dap_chain_tx_in_cond_t *l_tx_in_cond = bound_item->in.tx_cur_in_cond; - /// Mark 'out' item in cache because it used - l_tx_prev_out_used_idx = l_tx_in_cond->header.tx_out_prev_idx; - dap_chain_tx_out_cond_t *l_cond = bound_item->out.tx_prev_out_cond_256; - if (l_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) - l_cur_token_ticker = (char *)PVT(a_ledger)->net_native_ticker; + } break; + + case TX_ITEM_TYPE_IN_COND: { // all balance deducts performed with previous conditional transaction // Update service items if any - dap_chain_ledger_verificator_t *l_verificator; - int l_tmp = l_cond->header.subtype; + dap_ledger_verificator_t *l_verificator; + int l_tmp = l_bound_item->cond->header.subtype; pthread_rwlock_rdlock(&s_verificators_rwlock); HASH_FIND_INT(s_verificators, &l_tmp, l_verificator); pthread_rwlock_unlock(&s_verificators_rwlock); if (l_verificator && l_verificator->callback_added) - l_verificator->callback_added(a_ledger, a_tx, l_cond); + l_verificator->callback_added(a_ledger, a_tx, l_bound_item->cond); + } break; + + default: + log_it(L_ERROR, "Unknown item type %d in ledger TX bound for IN part", l_type); + break; } // add a used output - l_prev_item_out->cache_data.tx_hash_spent_fast[l_tx_prev_out_used_idx] = *a_tx_hash; + dap_ledger_tx_item_t *l_prev_item_out = l_bound_item->prev_item; + l_prev_item_out->cache_data.tx_hash_spent_fast[l_bound_item->prev_out_idx] = *a_tx_hash; l_prev_item_out->cache_data.n_outs_used++; if (PVT(a_ledger)->cached) { // mirror it in the cache @@ -4523,22 +4472,18 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d memcpy(l_tx_cache, &l_prev_item_out->cache_data, sizeof(l_prev_item_out->cache_data)); memcpy(l_tx_cache + sizeof(l_prev_item_out->cache_data), l_prev_item_out->tx, l_tx_size); char *l_tx_i_hash = dap_chain_hash_fast_to_str_new(&l_prev_item_out->tx_hash_fast); - l_cache_used_outs[i] = (dap_store_obj_t) { + l_cache_used_outs[l_spent_idx] = (dap_store_obj_t) { .key = l_tx_i_hash, .value = l_tx_cache, .value_len = l_tx_cache_sz, .group = l_ledger_cache_group, .type = DAP_GLOBAL_DB_OPTYPE_ADD }; - l_cache_used_outs[i].timestamp = dap_nanotime_now(); + l_cache_used_outs[l_spent_idx].timestamp = dap_nanotime_now(); } - // mark previous transactions as used with the extra timestamp if(l_prev_item_out->cache_data.n_outs_used == l_prev_item_out->cache_data.n_outs) l_prev_item_out->cache_data.ts_spent = a_tx->header.ts_created; - - // go to next previous transaction - l_list_tmp = dap_list_next(l_list_tmp); } @@ -4554,7 +4499,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d if (l_type == TX_ITEM_TYPE_OUT_COND) { // Update service items if any dap_chain_tx_out_cond_t *l_cond = (dap_chain_tx_out_cond_t *)l_tx_out->data; - dap_chain_ledger_verificator_t *l_verificator; + dap_ledger_verificator_t *l_verificator; int l_tmp = l_cond->header.subtype; pthread_rwlock_rdlock(&s_verificators_rwlock); HASH_FIND_INT(s_verificators, &l_tmp, l_verificator); @@ -4592,7 +4537,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d } if (!l_addr) continue; - else if (l_addr->net_id.uint64 != a_ledger->net_id.uint64 && + else if (l_addr->net_id.uint64 != a_ledger->net->pub.id.uint64 && !dap_chain_addr_is_blank(l_addr)) l_cross_network = true; char *l_addr_str = dap_chain_addr_to_str(l_addr); @@ -4616,7 +4561,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d } else { wallet_balance = DAP_NEW_Z(dap_ledger_wallet_balance_t); if (!wallet_balance) { - log_it(L_ERROR, "Memoru allocation error in s_load_cache_gdb_loaded_txs_callback"); + log_it(L_CRITICAL, "Memory allocation error in s_load_cache_gdb_loaded_txs_callback"); l_ret = -1; goto FIN; } @@ -4636,7 +4581,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d } // add transaction to the cache list - dap_chain_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_chain_ledger_tx_item_t); + dap_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_ledger_tx_item_t); if ( !l_tx_item ) { log_it(L_CRITICAL, "Memory allocation error"); l_ret = -1; @@ -4647,30 +4592,30 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d l_tx_item->tx = DAP_DUP_SIZE(a_tx, l_tx_size); l_tx_item->cache_data.ts_created = dap_time_now(); // Time of transasction added to ledger int l_outs_count = 0; - dap_list_t *l_list_tmp2 = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_outs_count); + dap_list_t *l_list_tmp = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_outs_count); l_tx_item->cache_data.n_outs = l_outs_count; // TODO: dump the UTXO in debug mode if need - if(l_list_tmp2) - dap_list_free(l_list_tmp2); + if(l_list_tmp) + dap_list_free(l_list_tmp); dap_stpcpy(l_tx_item->cache_data.token_ticker, l_main_token_ticker); l_tx_item->cache_data.multichannel = l_multichannel; - if(a_safe_call) pthread_rwlock_wrlock(&l_ledger_pvt->ledger_rwlock); + pthread_rwlock_wrlock(&l_ledger_pvt->ledger_rwlock); l_tx_item->ts_added = dap_nanotime_now(); HASH_ADD_INORDER(hh, l_ledger_pvt->ledger_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_tx_item, s_sort_ledger_tx_item); // tx_hash_fast: name of key field - if(a_safe_call) pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); + pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); // Callable callback dap_list_t *l_notifier; DL_FOREACH(PVT(a_ledger)->tx_add_notifiers, l_notifier) { - dap_chain_ledger_tx_notifier_t *l_notify = (dap_chain_ledger_tx_notifier_t*)l_notifier->data; + dap_ledger_tx_notifier_t *l_notify = (dap_ledger_tx_notifier_t*)l_notifier->data; l_notify->callback(l_notify->arg, a_ledger, l_tx_item->tx); } if (l_cross_network) { dap_list_t *l_notifier; DL_FOREACH(PVT(a_ledger)->bridged_tx_notifiers, l_notifier) { - dap_chain_ledger_bridged_tx_notifier_t *l_notify = l_notifier->data; + dap_ledger_bridged_tx_notifier_t *l_notify = l_notifier->data; l_notify->callback(a_ledger, a_tx, a_tx_hash, l_notify->arg); } } @@ -4708,8 +4653,8 @@ FIN: DAP_DEL_Z(l_cache_used_outs[i].key); DAP_DEL_Z(l_cache_used_outs[i].value); } - DAP_DELETE(l_cache_used_outs); - DAP_DELETE(l_ledger_cache_group); + DAP_DEL_Z(l_cache_used_outs); + DAP_DEL_Z(l_ledger_cache_group); } return l_ret; } @@ -4727,19 +4672,19 @@ static bool s_ledger_tps_callback(void *a_arg) return false; } -int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_hash_fast_t *a_tx_hash) +int dap_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_hash_fast_t *a_tx_hash) { if (PVT(a_ledger)->load_mode) { if (PVT(a_ledger)->cache_tx_check_callback) PVT(a_ledger)->cache_tx_check_callback(a_tx_hash); - dap_chain_ledger_tx_item_t *l_tx_item; + dap_ledger_tx_item_t *l_tx_item; unsigned l_hash_value; HASH_VALUE(a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value); pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock); HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_item); if (l_tx_item) { pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); - return DAP_CHAIN_LEDGER_TX_ALREADY_CACHED; + return DAP_LEDGER_TX_ALREADY_CACHED; } HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->threshold_txs, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_item); if (l_tx_item) { @@ -4747,13 +4692,13 @@ int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, return DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS; } } - return dap_chain_ledger_tx_add(a_ledger, a_tx, a_tx_hash, false); + return dap_ledger_tx_add(a_ledger, a_tx, a_tx_hash, false); } /** * Delete all transactions from the cache */ -void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) +void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); pthread_rwlock_wrlock(&l_ledger_pvt->ledger_rwlock); @@ -4764,7 +4709,7 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) pthread_rwlock_wrlock(&l_ledger_pvt->stake_lock_rwlock); /* Delete regular transactions */ - dap_chain_ledger_tx_item_t *l_item_current, *l_item_tmp; + dap_ledger_tx_item_t *l_item_current, *l_item_tmp; char *l_gdb_group; HASH_ITER(hh, l_ledger_pvt->ledger_items , l_item_current, l_item_tmp) { HASH_DEL(l_ledger_pvt->ledger_items, l_item_current); @@ -4772,13 +4717,13 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) DAP_DEL_Z(l_item_current); } if (!a_preserve_db) { - l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR); + l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TXS_STR); dap_global_db_del(l_gdb_group, NULL, NULL, NULL); DAP_DELETE(l_gdb_group); } if (!a_preserve_db) { - l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR); + l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_SPENT_TXS_STR); dap_global_db_del(l_gdb_group, NULL, NULL, NULL); DAP_DELETE(l_gdb_group); } @@ -4791,14 +4736,14 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) DAP_DELETE(l_balance_current); } if (!a_preserve_db) { - l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_BALANCES_STR); + l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_BALANCES_STR); dap_global_db_del(l_gdb_group, NULL, NULL, NULL); DAP_DELETE(l_gdb_group); } /* Delete tokens and their emissions */ - dap_chain_ledger_token_item_t *l_token_current, *l_token_tmp; - dap_chain_ledger_token_emission_item_t *l_emission_current, *l_emission_tmp; + dap_ledger_token_item_t *l_token_current, *l_token_tmp; + dap_ledger_token_emission_item_t *l_emission_current, *l_emission_tmp; HASH_ITER(hh, l_ledger_pvt->tokens, l_token_current, l_token_tmp) { HASH_DEL(l_ledger_pvt->tokens, l_token_current); pthread_rwlock_wrlock(&l_token_current->token_emissions_rwlock); @@ -4819,22 +4764,22 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) DAP_DELETE(l_token_current); } if (!a_preserve_db) { - l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR); + l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TOKENS_STR); dap_global_db_del(l_gdb_group, NULL, NULL, NULL); DAP_DELETE(l_gdb_group); - l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR); + l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_EMISSIONS_STR); dap_global_db_del(l_gdb_group, NULL, NULL, NULL); DAP_DELETE(l_gdb_group); } /* Delete stake-lock items */ - dap_chain_ledger_stake_lock_item_t *l_stake_item_current, *l_stake_item_tmp; + dap_ledger_stake_lock_item_t *l_stake_item_current, *l_stake_item_tmp; HASH_ITER(hh, l_ledger_pvt->emissions_for_stake_lock, l_stake_item_current, l_stake_item_tmp) { HASH_DEL(l_ledger_pvt->emissions_for_stake_lock, l_stake_item_current); DAP_DELETE(l_stake_item_current); } if (!a_preserve_db) { - l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_STAKE_LOCK_STR); + l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_STAKE_LOCK_STR); dap_global_db_del(l_gdb_group, NULL, NULL, NULL); DAP_DELETE(l_gdb_group); } @@ -4872,7 +4817,7 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) * Return number transactions from the cache * According to UT_hash_handle size of return value is sizeof(unsigned int) */ -unsigned dap_chain_ledger_count(dap_ledger_t *a_ledger) +unsigned dap_ledger_count(dap_ledger_t *a_ledger) { pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock); unsigned long ret = HASH_COUNT(PVT(a_ledger)->ledger_items); @@ -4881,17 +4826,17 @@ unsigned dap_chain_ledger_count(dap_ledger_t *a_ledger) } /** - * @brief dap_chain_ledger_count_from_to + * @brief dap_ledger_count_from_to * @param a_ledger * @param a_ts_from * @param a_ts_to * @return */ -uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts_from, dap_time_t a_ts_to) +uint64_t dap_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts_from, dap_time_t a_ts_to) { uint64_t l_ret = 0; dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_tx_item_t *l_iter_current, *l_item_tmp; + dap_ledger_tx_item_t *l_iter_current, *l_item_tmp; pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); if ( a_ts_from && a_ts_to) { HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp){ @@ -4918,7 +4863,7 @@ uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts return l_ret; } -size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to) +size_t dap_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to) { if (!a_ledger) return 0; @@ -4937,9 +4882,9 @@ size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_ /** * Check whether used 'out' items */ -bool dap_chain_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, int a_idx_out, dap_hash_fast_t *a_out_spender) +bool dap_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, int a_idx_out, dap_hash_fast_t *a_out_spender) { - dap_chain_ledger_tx_item_t *l_item_out = NULL; + dap_ledger_tx_item_t *l_item_out = NULL; /*dap_chain_datum_tx_t *l_tx =*/ s_find_datum_tx_by_hash(a_ledger, a_tx_hash, &l_item_out, false); return l_item_out ? s_ledger_tx_hash_is_used_out_item(l_item_out, a_idx_out, a_out_spender) : true; } @@ -4948,7 +4893,7 @@ bool dap_chain_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain * Calculate balance of addr * */ -uint256_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, +uint256_t dap_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, const char *a_token_ticker) { uint256_t l_ret = uint256_0; @@ -4975,7 +4920,7 @@ uint256_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_ return l_ret; } -uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, +uint256_t dap_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, const char *a_token_ticker) { uint256_t balance = uint256_0; @@ -4984,7 +4929,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c return balance; dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_tx_item_t *l_iter_current, *l_item_tmp; + dap_ledger_tx_item_t *l_iter_current, *l_item_tmp; pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp) { @@ -5007,14 +4952,13 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c } } int l_out_idx_tmp = 0; - for (dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_out_idx_tmp++) { - assert(l_list_tmp->data); - dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data; - if (l_type == TX_ITEM_TYPE_OUT_COND_OLD || (l_type == TX_ITEM_TYPE_OUT_COND)) { + for (dap_list_t *it = l_list_out_items; it; it = it->next, l_out_idx_tmp++) { + assert(it->data); + dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data; + if (l_type == TX_ITEM_TYPE_OUT_COND) continue; - } - if (l_type == TX_ITEM_TYPE_OUT_OLD) { - const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t*) l_list_tmp->data; + if (l_type == TX_ITEM_TYPE_OUT_OLD) { // 64 + const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t*) it->data; // Check for token name if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_ticker)) { // if transaction has the out item with requested addr @@ -5022,8 +4966,6 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c // if 'out' item not used & transaction is valid if(!s_ledger_tx_hash_is_used_out_item(l_iter_current, l_out_idx_tmp, NULL) && dap_chain_datum_tx_verify_sign(l_cur_tx)) { - // uint128_t l_add = dap_chain_uint128_from(l_tx_out->header.value); - // balance = dap_uint128_add(balance, l_add); uint256_t l_add = dap_chain_uint256_from(l_tx_out->header.value); SUM_256_256(balance, l_add, &balance); } @@ -5031,8 +4973,8 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c } } if (l_type == TX_ITEM_TYPE_OUT) { // 256 - const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data; - // const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t*) l_list_tmp->data; + const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) it->data; + // const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t*) it->data; // Check for token name if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_ticker)) { // if transaction has the out item with requested addr @@ -5046,8 +4988,8 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c } } if (l_type == TX_ITEM_TYPE_OUT_EXT) { // 256 - const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) l_list_tmp->data; - // const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) l_list_tmp->data; + const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) it->data; + // const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) it->data; // Check for token name if (!strcmp(a_token_ticker, l_tx_out->token)) { // if transaction has the out item with requested addr @@ -5074,7 +5016,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c * a_public_key_size[in] public key size * a_tx_first_hash [in/out] hash of the initial transaction/ found transaction, if 0 start from the beginning */ -static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, +static dap_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash) { if(!a_addr || !a_tx_first_hash) @@ -5083,7 +5025,7 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, bool is_tx_found = false; bool is_null_hash = dap_hash_fast_is_blank(a_tx_first_hash); bool is_search_enable = is_null_hash; - dap_chain_ledger_tx_item_t *l_iter_current, *l_item_tmp; + dap_ledger_tx_item_t *l_iter_current, *l_item_tmp; pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp) { @@ -5103,14 +5045,13 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, } // Get 'out' items from transaction dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL); - for(dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp)) { - assert(l_list_tmp->data); - dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data; - if (l_type == TX_ITEM_TYPE_OUT_COND || l_type == TX_ITEM_TYPE_OUT_COND_OLD) { + for(dap_list_t *it = l_list_out_items; it; it = dap_list_next(it)) { + assert(it->data); + dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data; + if (l_type == TX_ITEM_TYPE_OUT_COND) continue; - } if (l_type == TX_ITEM_TYPE_OUT) { - const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t *)l_list_tmp->data; + const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t *)it->data; // if transaction has the out item with requested addr if(!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) { memcpy(a_tx_first_hash, l_tx_hash, sizeof(dap_chain_hash_fast_t)); @@ -5119,7 +5060,7 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, } } if (l_type == TX_ITEM_TYPE_OUT_OLD) { - const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t *)l_list_tmp->data; + const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t *)it->data; // if transaction has the out item with requested addr if(!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) { memcpy(a_tx_first_hash, l_tx_hash, sizeof(dap_chain_hash_fast_t)); @@ -5128,7 +5069,7 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, } } if (l_type == TX_ITEM_TYPE_OUT_EXT) { - const dap_chain_tx_out_ext_t *l_tx_out_ext = (const dap_chain_tx_out_ext_t *)l_list_tmp->data; + const dap_chain_tx_out_ext_t *l_tx_out_ext = (const dap_chain_tx_out_ext_t *)it->data; // If a_token is setup we check if its not our token - miss it if (a_token && dap_strcmp(l_tx_out_ext->token, a_token)) { continue; @@ -5154,15 +5095,15 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, } /** - * @brief dap_chain_ledger_tx_find_by_addr + * @brief dap_ledger_tx_find_by_addr * @param a_addr * @param a_tx_first_hash * @return */ - dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_addr(dap_ledger_t *a_ledger , const char * a_token , + dap_chain_datum_tx_t* dap_ledger_tx_find_by_addr(dap_ledger_t *a_ledger , const char * a_token , const dap_chain_addr_t *a_addr, dap_chain_hash_fast_t *a_tx_first_hash) { - dap_chain_ledger_tx_item_t* l_tx_item = tx_item_find_by_addr(a_ledger, a_addr, a_token, a_tx_first_hash); + dap_ledger_tx_item_t* l_tx_item = tx_item_find_by_addr(a_ledger, a_addr, a_token, a_tx_first_hash); return (l_tx_item) ? l_tx_item->tx : NULL; } @@ -5176,7 +5117,7 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, * a_public_key_size[in] public key size * a_tx_first_hash [in/out] hash of the initial transaction/ found transaction, if 0 start from the beginning */ -const dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger, +const dap_chain_datum_tx_t* dap_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger, char *a_public_key, size_t a_public_key_size, dap_chain_hash_fast_t *a_tx_first_hash) { if(!a_public_key || !a_tx_first_hash) @@ -5185,7 +5126,7 @@ const dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_pkey(dap_ledger_t *a_led dap_chain_datum_tx_t *l_cur_tx = NULL; bool is_null_hash = dap_hash_fast_is_blank(a_tx_first_hash); bool is_search_enable = is_null_hash; - dap_chain_ledger_tx_item_t *l_iter_current, *l_item_tmp; + dap_ledger_tx_item_t *l_iter_current, *l_item_tmp; pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp) { dap_chain_datum_tx_t *l_tx_tmp = l_iter_current->tx; @@ -5221,11 +5162,11 @@ const dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_pkey(dap_ledger_t *a_led * @param a_srv_uid * @return */ -dap_list_t* dap_chain_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_chain_net_srv_uid_t a_srv_uid) +dap_list_t* dap_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_chain_net_srv_uid_t a_srv_uid) { dap_list_t * l_ret = NULL; dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_tx_item_t *l_iter_current = NULL, *l_item_tmp = NULL; + dap_ledger_tx_item_t *l_iter_current = NULL, *l_item_tmp = NULL; HASH_ITER(hh, l_ledger_pvt->ledger_items, l_iter_current, l_item_tmp) { dap_chain_datum_tx_t *l_tx = l_iter_current->tx; dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_COND, NULL), *l_out_item; @@ -5244,7 +5185,7 @@ dap_list_t* dap_chain_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, * * a_addr[in] wallet address, whose owner can use the service */ -dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, +dap_chain_datum_tx_t* dap_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_hash_fast_t *a_tx_first_hash, dap_chain_tx_out_cond_t **a_out_cond, int *a_out_cond_idx, char *a_token_ticker) { if (!a_tx_first_hash) @@ -5253,7 +5194,7 @@ dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_le dap_chain_datum_tx_t *l_cur_tx = NULL; bool is_null_hash = dap_hash_fast_is_blank(a_tx_first_hash); bool is_search_enable = is_null_hash; - dap_chain_ledger_tx_item_t *l_iter_current = NULL, *l_item_tmp = NULL; + dap_ledger_tx_item_t *l_iter_current = NULL, *l_item_tmp = NULL; dap_chain_tx_out_cond_t *l_tx_out_cond = NULL; int l_tx_out_cond_idx = 0; pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); @@ -5298,7 +5239,7 @@ dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_le * a_public_key[in] public key that signed the transaction * a_public_key_size[in] public key size */ -uint256_t dap_chain_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, +uint256_t dap_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_addr_t *a_addr, dap_chain_tx_out_cond_t **tx_out_cond) { @@ -5311,7 +5252,7 @@ uint256_t dap_chain_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, d dap_chain_tx_out_cond_t *l_tx_out_cond; // Find all transactions do { - l_tx_tmp = dap_chain_ledger_tx_cache_find_out_cond(a_ledger, a_cond_type, &l_tx_first_hash, &l_tx_out_cond, NULL, NULL); + l_tx_tmp = dap_ledger_tx_cache_find_out_cond(a_ledger, a_cond_type, &l_tx_first_hash, &l_tx_out_cond, NULL, NULL); // Get out_cond item from transaction if(l_tx_tmp) { UNUSED(a_addr); @@ -5327,7 +5268,7 @@ uint256_t dap_chain_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, d } /** - * @brief dap_chain_ledger_get_list_tx_outs_with_val + * @brief dap_ledger_get_list_tx_outs_with_val * @param a_ledger * @param a_token_ticker * @param a_addr_from @@ -5335,7 +5276,7 @@ uint256_t dap_chain_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, d * @param a_value_transfer * @return list of dap_chain_tx_used_out_item_t */ -dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from, +dap_list_t *dap_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from, uint256_t a_value_need, uint256_t *a_value_transfer) { dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items @@ -5344,7 +5285,7 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c while(compare256(l_value_transfer, a_value_need) == -1) { // Get the transaction in the cache by the addr in out item - dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, + dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash); if(!l_tx) break; @@ -5352,26 +5293,26 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL); uint32_t l_out_idx_tmp = 0; // current index of 'out' item - for (dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_out_idx_tmp++) { - dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data; + for (dap_list_t *it = l_list_out_items; it; it = dap_list_next(it), l_out_idx_tmp++) { + dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data; uint256_t l_value = {}; switch (l_type) { case TX_ITEM_TYPE_OUT_OLD: { - dap_chain_tx_out_old_t *l_out = (dap_chain_tx_out_old_t *)l_list_tmp->data; + dap_chain_tx_out_old_t *l_out = (dap_chain_tx_out_old_t *)it->data; if (!l_out->header.value || memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t))) continue; l_value = GET_256_FROM_64(l_out->header.value); } break; case TX_ITEM_TYPE_OUT: { - dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)l_list_tmp->data; + dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)it->data; if (memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t)) || - dap_strcmp(dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_cur_hash), a_token_ticker) || + dap_strcmp(dap_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_cur_hash), a_token_ticker) || IS_ZERO_256(l_out->header.value)) continue; l_value = l_out->header.value; } break; case TX_ITEM_TYPE_OUT_EXT: { - dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)l_list_tmp->data; + dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)it->data; if (memcmp(a_addr_from, &l_out_ext->addr, sizeof(dap_chain_addr_t)) || strcmp((char *)a_token_ticker, l_out_ext->token) || IS_ZERO_256(l_out_ext->header.value) ) { @@ -5379,13 +5320,12 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c } l_value = l_out_ext->header.value; } break; - case TX_ITEM_TYPE_OUT_COND_OLD: case TX_ITEM_TYPE_OUT_COND: default: continue; } // Check whether used 'out' items - if (!dap_chain_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp, NULL)) { + if (!dap_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp, NULL)) { dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t); if ( !l_item ) { log_it(L_CRITICAL, "Out of memory"); @@ -5421,9 +5361,9 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c } // Add new verificator callback with associated subtype. Returns 1 if callback replaced, -1 error, overwise returns 0 -int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_chain_ledger_verificator_callback_t a_callback, dap_chain_ledger_updater_callback_t a_callback_added) +int dap_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_ledger_verificator_callback_t a_callback, dap_ledger_updater_callback_t a_callback_added) { - dap_chain_ledger_verificator_t *l_new_verificator; + dap_ledger_verificator_t *l_new_verificator; int l_tmp = (int)a_subtype; pthread_rwlock_rdlock(&s_verificators_rwlock); HASH_FIND_INT(s_verificators, &l_tmp, l_new_verificator); @@ -5432,7 +5372,7 @@ int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, l_new_verificator->callback = a_callback; return 1; } - l_new_verificator = DAP_NEW(dap_chain_ledger_verificator_t); + l_new_verificator = DAP_NEW(dap_ledger_verificator_t); if (!l_new_verificator) { log_it(L_CRITICAL, "Memory allocation error"); return -1; @@ -5446,7 +5386,7 @@ int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, return 0; } -dap_list_t *dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only) +dap_list_t *dap_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock); @@ -5457,7 +5397,7 @@ dap_list_t *dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, siz dap_list_t *l_list = NULL; size_t l_counter = 0; size_t l_end = l_offset + a_count; - dap_chain_ledger_tx_item_t *l_item_current, *l_item_tmp; + dap_ledger_tx_item_t *l_item_current, *l_item_tmp; HASH_ITER(hh, l_ledger_pvt->ledger_items, l_item_current, l_item_tmp) { if (l_counter++ >= l_offset) { if (!a_unspent_only || !l_item_current->cache_data.ts_spent) @@ -5471,7 +5411,7 @@ dap_list_t *dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, siz } /** - * @brief dap_chain_ledger_get_list_tx_cond_outs_with_val + * @brief dap_ledger_get_list_tx_cond_outs_with_val * @param a_ledger * @param a_token_ticker * @param a_addr_from @@ -5480,7 +5420,7 @@ dap_list_t *dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, siz * @param a_value_transfer * @return */ -dap_list_t *dap_chain_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from, +dap_list_t *dap_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from, dap_chain_tx_out_cond_subtype_t a_subtype, uint256_t a_value_need, uint256_t *a_value_transfer) { dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items @@ -5489,19 +5429,19 @@ dap_list_t *dap_chain_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledg while(compare256(l_value_transfer, a_value_need) == -1) { // Get the transaction in the cache by the addr in out item - dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash); + dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash); if(!l_tx) break; // Get all item from transaction by type dap_list_t *l_list_out_cond_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_COND, NULL); uint32_t l_out_idx_tmp = 0; // current index of 'out' item - for(dap_list_t *l_list_tmp = l_list_out_cond_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_out_idx_tmp++) { - dap_chain_tx_item_type_t l_type = *(uint8_t*) l_list_tmp->data; + for(dap_list_t *it = l_list_out_cond_items; it; it = dap_list_next(it), l_out_idx_tmp++) { + dap_chain_tx_item_type_t l_type = *(uint8_t*) it->data; uint256_t l_value = { }; switch (l_type) { case TX_ITEM_TYPE_OUT_COND: { - dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*) l_list_tmp->data; + dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*) it->data; if(IS_ZERO_256(l_out_cond->header.value) || a_subtype != l_out_cond->header.subtype) { continue; } @@ -5545,18 +5485,18 @@ dap_list_t *dap_chain_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledg return l_list_used_out; } -void dap_chain_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_ledger_tx_add_notify_t a_callback, void *a_arg) { +void dap_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_ledger_tx_add_notify_t a_callback, void *a_arg) { if (!a_ledger) { - log_it(L_ERROR, "NULL ledger passed to dap_chain_ledger_tx_add_notify()"); + log_it(L_ERROR, "NULL ledger passed to dap_ledger_tx_add_notify()"); return; } if (!a_callback) { - log_it(L_ERROR, "NULL callback passed to dap_chain_ledger_tx_add_notify()"); + log_it(L_ERROR, "NULL callback passed to dap_ledger_tx_add_notify()"); return; } - dap_chain_ledger_tx_notifier_t *l_notifier = DAP_NEW(dap_chain_ledger_tx_notifier_t); + dap_ledger_tx_notifier_t *l_notifier = DAP_NEW(dap_ledger_tx_notifier_t); if (!l_notifier){ - log_it(L_ERROR, "Can't allocate memory for notifier in dap_chain_ledger_tx_add_notify()"); + log_it(L_ERROR, "Can't allocate memory for notifier in dap_ledger_tx_add_notify()"); return; } l_notifier->callback = a_callback; @@ -5564,13 +5504,13 @@ void dap_chain_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_ledger_tx_ PVT(a_ledger)->tx_add_notifiers = dap_list_append(PVT(a_ledger)->tx_add_notifiers, l_notifier); } -void dap_chain_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_chain_ledger_bridged_tx_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) { if (!a_ledger || !a_callback) return; - dap_chain_ledger_bridged_tx_notifier_t *l_notifier = DAP_NEW_Z(dap_chain_ledger_bridged_tx_notifier_t); + dap_ledger_bridged_tx_notifier_t *l_notifier = DAP_NEW_Z(dap_ledger_bridged_tx_notifier_t); if (!l_notifier) { - log_it(L_ERROR, "Can't allocate memory for notifier in dap_chain_ledger_tx_add_notify()"); + log_it(L_ERROR, "Can't allocate memory for notifier in dap_ledger_tx_add_notify()"); return; } l_notifier->callback = a_callback; @@ -5578,12 +5518,12 @@ void dap_chain_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_chain_le PVT(a_ledger)->bridged_tx_notifiers = dap_list_append(PVT(a_ledger)->bridged_tx_notifiers , l_notifier); } -bool dap_chain_ledger_cache_enabled(dap_ledger_t *a_ledger) +bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger) { return PVT(a_ledger)->cached; } -void dap_chain_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_chain_ledger_cache_tx_check_callback_t a_callback) +void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_cache_tx_check_callback_t a_callback) { PVT(a_ledger)->cache_tx_check_callback = a_callback; } diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 88481d80d1..24ab71f8ae 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -257,6 +257,7 @@ static bool s_new_balancer_link_request(dap_chain_net_t *a_net, int a_link_repla */ int dap_chain_net_init() { + dap_ledger_init(); dap_stream_ch_chain_init(); dap_stream_ch_chain_net_init(); dap_chain_node_client_init(); @@ -1373,7 +1374,7 @@ const char* dap_chain_net_get_type(dap_chain_t *l_chain) */ static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net) { - dap_chain_ledger_purge(l_net->pub.ledger, false); + dap_ledger_purge(l_net->pub.ledger, false); dap_chain_net_srv_stake_purge(l_net); dap_chain_net_decree_purge(l_net); dap_chain_t *l_chain = NULL; @@ -1382,7 +1383,8 @@ static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net) l_chain->callback_purge(l_chain); if (l_chain->callback_set_min_validators_count) l_chain->callback_set_min_validators_count(l_chain, 0); - dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); + l_net->pub.fee_value = uint256_0; + l_net->pub.fee_addr = c_dap_chain_addr_blank; dap_chain_load_all(l_chain); } DL_FOREACH(l_net->pub.chains, l_chain) { @@ -1413,7 +1415,7 @@ static bool s_chain_net_reload_ledger_cache_once(dap_chain_net_t *l_net) return false; } // Check the file with provided UUID. Change this UUID to automatically reload cache on next node startup - char *l_cache_file = dap_strdup_printf( "%s/%s.cache", l_cache_dir, DAP_CHAIN_LEDGER_CACHE_RELOAD_ONCE_UUID); + char *l_cache_file = dap_strdup_printf( "%s/%s.cache", l_cache_dir, DAP_LEDGER_CACHE_RELOAD_ONCE_UUID); DAP_DELETE(l_cache_dir); // create file, if it not presented. If file exists, ledger cache operation is stopped if (dap_file_simple_test(l_cache_file)) { @@ -1622,7 +1624,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) dap_string_t * l_ret_str = dap_string_new("Transactions statistics:\n"); dap_string_append_printf( l_ret_str, "\tFrom: %s\tTo: %s\n", l_from_str_new, l_to_str_new); log_it(L_INFO, "Calc TPS from %s to %s", l_from_str_new, l_to_str_new); - uint64_t l_tx_count = dap_chain_ledger_count_from_to ( l_net->pub.ledger, l_from_ts, l_to_ts); + uint64_t l_tx_count = dap_ledger_count_from_to ( l_net->pub.ledger, l_from_ts, l_to_ts); long double l_tps = l_to_ts == l_from_ts ? 0 : (long double) l_tx_count / (long double) ( l_to_ts - l_from_ts ); dap_string_append_printf( l_ret_str, "\tSpeed: %.3Lf TPS\n", l_tps ); @@ -1632,7 +1634,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) } else if (strcmp(l_stats_str, "tps") == 0) { struct timespec l_from_time_acc = {}, l_to_time_acc = {}; dap_string_t * l_ret_str = dap_string_new("Transactions per second peak values:\n"); - size_t l_tx_num = dap_chain_ledger_count_tps(l_net->pub.ledger, &l_from_time_acc, &l_to_time_acc); + size_t l_tx_num = dap_ledger_count_tps(l_net->pub.ledger, &l_from_time_acc, &l_to_time_acc); if (l_tx_num) { localtime_r(&l_from_time_acc.tv_sec, &l_from_tm); strftime(l_from_str_new, sizeof(l_from_str_new), c_time_fmt, &l_from_tm); @@ -2029,6 +2031,8 @@ void dap_chain_net_delete(dap_chain_net_t *a_net) DAP_DEL_Z(PVT(a_net)->seed_nodes_ipv4); DAP_DEL_Z(PVT(a_net)->seed_nodes_ipv6); DAP_DEL_Z(PVT(a_net)->node_info); + dap_ledger_purge(a_net->pub.ledger, true); + dap_ledger_handle_free(a_net->pub.ledger); DAP_DELETE(a_net); } @@ -2198,34 +2202,6 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx) l_net_pvt->seed_nodes_ipv4[j] = tmp; } - l_net_pvt->node_info = dap_chain_node_info_read(l_net, &g_node_addr); - if ( !l_net_pvt->node_info ) { // If not present - create it - l_net_pvt->node_info = DAP_NEW_Z(dap_chain_node_info_t); - if (!l_net_pvt->node_info) { - log_it(L_CRITICAL, "Memory allocation error"); - dap_chain_net_delete(l_net); - return -6; - } - l_net_pvt->node_info->hdr.address = g_node_addr; - if (dap_config_get_item_bool_default(g_config, "server", "enabled", false)) { - const char *l_ext_addr_v4 = dap_config_get_item_str_default(g_config, "server", "ext_address", NULL); - const char *l_ext_addr_v6 = dap_config_get_item_str_default(g_config, "server", "ext_address6", NULL); - uint16_t l_node_info_port = dap_config_get_item_uint16_default(g_config, "server", "ext_port_tcp", - dap_config_get_item_uint16_default(g_config, "server", "listen_port_tcp", 8079)); - if (l_ext_addr_v4) - inet_pton(AF_INET, l_ext_addr_v4, &l_net_pvt->node_info->hdr.ext_addr_v4); - if (l_ext_addr_v6) - inet_pton(AF_INET6, l_ext_addr_v6, &l_net_pvt->node_info->hdr.ext_addr_v6); - l_net_pvt->node_info->hdr.ext_port = l_node_info_port; - } else - log_it(L_INFO, "Server is disabled, add only node address in nodelist"); - } - - log_it(L_NOTICE, "Net load information: node_addr " NODE_ADDR_FP_STR ", balancers links %u, cell_id 0x%016"DAP_UINT64_FORMAT_X, - NODE_ADDR_FP_ARGS_S(g_node_addr), - l_net_pvt->seed_nodes_count, - l_net_pvt->node_info->hdr.cell_id.uint64); - /* *** Chains init by configs *** */ char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), l_net->pub.name); DIR * l_chains_dir = opendir(l_chains_path); @@ -2323,11 +2299,11 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx) case NODE_ROLE_LIGHT: break; case NODE_ROLE_FULL: - l_ledger_flags |= DAP_CHAIN_LEDGER_CHECK_LOCAL_DS; + l_ledger_flags |= DAP_LEDGER_CHECK_LOCAL_DS; if (dap_config_get_item_bool_default(g_config, "ledger", "cache_enabled", false)) - l_ledger_flags |= DAP_CHAIN_LEDGER_CACHE_ENABLED; + l_ledger_flags |= DAP_LEDGER_CACHE_ENABLED; default: - l_ledger_flags |= DAP_CHAIN_LEDGER_CHECK_CELLS_DS | DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION; + l_ledger_flags |= DAP_LEDGER_CHECK_CELLS_DS | DAP_LEDGER_CHECK_TOKEN_EMISSION; } for (dap_chain_t *l_chain = l_net->pub.chains; l_chain; l_chain = l_chain->next) { if (!l_chain->callback_get_poa_certs) @@ -2339,7 +2315,7 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx) if (!l_net->pub.keys) log_it(L_WARNING, "PoA certificates for net %s not found", l_net->pub.name); // init LEDGER model - l_net->pub.ledger = dap_chain_ledger_create(l_ledger_flags, l_net->pub.id, l_net->pub.name, l_net->pub.native_ticker, l_net->pub.keys); + l_net->pub.ledger = dap_ledger_create(l_net, l_ledger_flags); return 0; } @@ -2363,7 +2339,7 @@ int s_net_load(dap_chain_net_t *a_net) // reload ledger cache at once if (s_chain_net_reload_ledger_cache_once(l_net)) { log_it(L_WARNING,"Start one time ledger cache reloading"); - dap_chain_ledger_purge(l_net->pub.ledger, false); + dap_ledger_purge(l_net->pub.ledger, false); dap_chain_net_srv_stake_purge(l_net); } else dap_chain_net_srv_stake_load_cache(l_net); @@ -2373,7 +2349,8 @@ int s_net_load(dap_chain_net_t *a_net) // load chains dap_chain_t *l_chain = l_net->pub.chains; while(l_chain){ - dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); + l_net->pub.fee_value = uint256_0; + l_net->pub.fee_addr = c_dap_chain_addr_blank; if (!dap_chain_load_all(l_chain)) { log_it (L_NOTICE, "Loaded chain files"); if (DAP_CHAIN_PVT(l_chain)->need_reorder) { @@ -2385,8 +2362,9 @@ int s_net_load(dap_chain_net_t *a_net) DAP_CHAIN_PVT(l_chain)->need_reorder = false; if (l_chain->callback_purge) { l_chain->callback_purge(l_chain); - dap_chain_ledger_purge(l_net->pub.ledger, false); - dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); + dap_ledger_purge(l_net->pub.ledger, false); + l_net->pub.fee_value = uint256_0; + l_net->pub.fee_addr = c_dap_chain_addr_blank; dap_chain_net_decree_purge(l_net); dap_chain_load_all(l_chain); } else @@ -2468,7 +2446,7 @@ int s_net_load(dap_chain_net_t *a_net) l_net_pvt->load_mode = false; if (l_net->pub.ledger) - dap_chain_ledger_load_end(l_net->pub.ledger); + dap_ledger_load_end(l_net->pub.ledger); l_net_pvt->balancer_http = !dap_config_get_item_bool_default(l_cfg, "general", "use_dns_links", false); @@ -2526,6 +2504,34 @@ int s_net_load(dap_chain_net_t *a_net) if (l_chain->callback_created) l_chain->callback_created(l_chain, l_cfg); + l_net_pvt->node_info = dap_chain_node_info_read(l_net, &g_node_addr); + if ( !l_net_pvt->node_info ) { // If not present - create it + l_net_pvt->node_info = DAP_NEW_Z(dap_chain_node_info_t); + if (!l_net_pvt->node_info) { + log_it(L_CRITICAL, "Memory allocation error"); + dap_chain_net_delete(l_net); + return -6; + } + l_net_pvt->node_info->hdr.address = g_node_addr; + if (dap_config_get_item_bool_default(g_config, "server", "enabled", false)) { + const char *l_ext_addr_v4 = dap_config_get_item_str_default(g_config, "server", "ext_address", NULL); + const char *l_ext_addr_v6 = dap_config_get_item_str_default(g_config, "server", "ext_address6", NULL); + uint16_t l_node_info_port = dap_config_get_item_uint16_default(g_config, "server", "ext_port_tcp", + dap_config_get_item_uint16_default(g_config, "server", "listen_port_tcp", 8079)); + if (l_ext_addr_v4) + inet_pton(AF_INET, l_ext_addr_v4, &l_net_pvt->node_info->hdr.ext_addr_v4); + if (l_ext_addr_v6) + inet_pton(AF_INET6, l_ext_addr_v6, &l_net_pvt->node_info->hdr.ext_addr_v6); + l_net_pvt->node_info->hdr.ext_port = l_node_info_port; + } else + log_it(L_INFO, "Server is disabled, add only node address in nodelist"); + } + + log_it(L_NOTICE, "Net load information: node_addr " NODE_ADDR_FP_STR ", balancers links %u, cell_id 0x%016"DAP_UINT64_FORMAT_X, + NODE_ADDR_FP_ARGS_S(g_node_addr), + l_net_pvt->seed_nodes_count, + l_net_pvt->node_info->hdr.cell_id.uint64); + // TODO rework alias concept const char * l_node_addr_type = dap_config_get_item_str_default(l_cfg , "general", "node_addr_type", "auto"); if (!dap_strcmp(l_node_addr_type, "static")) { @@ -2667,11 +2673,11 @@ dap_chain_net_t *dap_chain_net_by_name(const char *a_name) } /** - * @brief dap_chain_ledger_by_net_name + * @brief dap_ledger_by_net_name * @param a_net_name * @return */ -dap_ledger_t * dap_chain_ledger_by_net_name( const char * a_net_name) +dap_ledger_t * dap_ledger_by_net_name( const char * a_net_name) { dap_chain_net_t *l_net = dap_chain_net_by_name(a_net_name); return l_net ? l_net->pub.ledger : NULL; @@ -2914,9 +2920,9 @@ void dap_chain_net_proc_mempool(dap_chain_net_t *a_net) /** * @brief dap_chain_net_verify_datum_for_add * process datum verification process. Can be: - * if DAP_CHAIN_DATUM_TX, called dap_chain_ledger_tx_add_check - * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_chain_ledger_token_decl_add_check - * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_chain_ledger_token_emission_add_check + * if DAP_CHAIN_DATUM_TX, called dap_ledger_tx_add_check + * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_ledger_token_decl_add_check + * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_ledger_token_emission_add_check * if DAP_CHAIN_DATUM_DECREE * @param a_net * @param a_datum @@ -2931,15 +2937,18 @@ int dap_chain_net_verify_datum_for_add(dap_chain_t *a_chain, dap_chain_datum_t * dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); switch (a_datum->header.type_id) { case DAP_CHAIN_DATUM_TX: - return dap_chain_ledger_tx_add_check(l_net->pub.ledger, (dap_chain_datum_tx_t *)a_datum->data, a_datum->header.data_size, a_datum_hash); + return dap_ledger_tx_add_check(l_net->pub.ledger, (dap_chain_datum_tx_t *)a_datum->data, a_datum->header.data_size, a_datum_hash); case DAP_CHAIN_DATUM_TOKEN_DECL: - return dap_chain_ledger_token_decl_add_check(l_net->pub.ledger, (dap_chain_datum_token_t *)a_datum->data, a_datum->header.data_size); + return dap_ledger_token_decl_add_check(l_net->pub.ledger, (dap_chain_datum_token_t *)a_datum->data, a_datum->header.data_size); case DAP_CHAIN_DATUM_TOKEN_EMISSION: - return dap_chain_ledger_token_emission_add_check(l_net->pub.ledger, a_datum->data, a_datum->header.data_size, a_datum_hash); + return dap_ledger_token_emission_add_check(l_net->pub.ledger, a_datum->data, a_datum->header.data_size, a_datum_hash); case DAP_CHAIN_DATUM_DECREE: return dap_chain_net_decree_verify((dap_chain_datum_decree_t *)a_datum->data, l_net, a_datum->header.data_size, a_datum_hash); - case DAP_CHAIN_DATUM_ANCHOR: - return dap_chain_net_anchor_verify((dap_chain_datum_anchor_t *)a_datum->data, a_datum->header.data_size); + case DAP_CHAIN_DATUM_ANCHOR: { + int l_result = dap_chain_net_anchor_verify((dap_chain_datum_anchor_t *)a_datum->data, a_datum->header.data_size); + if (l_result) + return l_result; + } default: if (a_chain->callback_datum_find_by_hash && a_chain->callback_datum_find_by_hash(a_chain, a_datum_hash, NULL, NULL)) @@ -2951,11 +2960,11 @@ int dap_chain_net_verify_datum_for_add(dap_chain_t *a_chain, dap_chain_datum_t * char *dap_chain_net_verify_datum_err_code_to_str(dap_chain_datum_t *a_datum, int a_code){ switch (a_datum->header.type_id) { case DAP_CHAIN_DATUM_TX: - return dap_chain_ledger_tx_check_err_str(a_code); + return dap_ledger_tx_check_err_str(a_code); case DAP_CHAIN_DATUM_TOKEN_DECL: - return dap_chain_ledger_token_decl_add_err_code_to_str(a_code); + return dap_ledger_token_decl_add_err_code_to_str(a_code); case DAP_CHAIN_DATUM_TOKEN_EMISSION: - return dap_chain_ledger_token_emission_err_code_to_str(a_code); + return dap_ledger_token_emission_err_code_to_str(a_code); default: return !a_code ? "DAP_CHAIN_DATUM_VERIFY_OK" : dap_itoa(a_code); @@ -3161,10 +3170,10 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t return dap_chain_net_anchor_load(l_anchor, a_chain); } case DAP_CHAIN_DATUM_TOKEN_DECL: - return dap_chain_ledger_token_load(l_ledger, a_datum->data, a_datum->header.data_size); + return dap_ledger_token_load(l_ledger, a_datum->data, a_datum->header.data_size); case DAP_CHAIN_DATUM_TOKEN_EMISSION: - return dap_chain_ledger_token_emission_load(l_ledger, a_datum->data, a_datum->header.data_size, a_datum_hash); + return dap_ledger_token_emission_load(l_ledger, a_datum->data, a_datum->header.data_size, a_datum_hash); case DAP_CHAIN_DATUM_TX: { dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)a_datum->data; @@ -3173,7 +3182,7 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t log_it(L_WARNING, "Corrupted trnsaction, datum size %zd is not equal to size of TX %zd", l_datum_data_size, l_tx_size); return -102; } - return dap_chain_ledger_tx_load(l_ledger, l_tx, a_datum_hash); + return dap_ledger_tx_load(l_ledger, l_tx, a_datum_hash); } case DAP_CHAIN_DATUM_CA: return dap_cert_chain_file_save(a_datum, a_chain->net_name); diff --git a/modules/net/dap_chain_net_anchor.c b/modules/net/dap_chain_net_anchor.c index 4e8ac387c3..dfa2bb8e58 100644 --- a/modules/net/dap_chain_net_anchor.c +++ b/modules/net/dap_chain_net_anchor.c @@ -28,6 +28,7 @@ #include "dap_cert.h" #include "dap_pkey.h" #include "dap_chain_common.h" +#include "dap_chain_ledger.h" #include "dap_chain_net.h" #include "dap_chain_datum_decree.h" diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c index bef168e6f6..119ce7317a 100644 --- a/modules/net/dap_chain_net_decree.c +++ b/modules/net/dap_chain_net_decree.c @@ -106,7 +106,6 @@ int dap_chain_net_decree_deinit(dap_chain_net_t *a_net) { dap_chain_net_decree_t *l_decree = a_net->pub.decree; dap_list_free_full(l_decree->pkeys, NULL); - DAP_DELETE(l_decree->fee_addr); DAP_DELETE(l_decree); struct decree_hh *l_decree_hh, *l_tmp; HASH_ITER(hh, s_decree_hh, l_decree_hh, l_tmp) { @@ -185,6 +184,11 @@ int dap_chain_net_decree_verify(dap_chain_datum_decree_t *a_decree, dap_chain_ne size_t l_num_of_unique_signs = 0; dap_sign_t **l_unique_signs = dap_sign_get_unique_signs(l_signs_block, l_signs_size, &l_num_of_unique_signs); + if (!a_net->pub.decree) { + log_it(L_ERROR, "Decree module hasn't been initialized yet"); + return -404; + } + uint16_t l_min_signs = a_net->pub.decree->min_num_of_owners; if (l_num_of_unique_signs < l_min_signs) { log_it(L_WARNING, "Not enough unique signatures, get %zu from %hu", l_num_of_unique_signs, l_min_signs); @@ -369,37 +373,21 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai switch (a_decree->header.sub_type) { case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_FEE: - if(dap_chain_datum_decree_get_fee_addr(a_decree, &l_addr)){ - if(l_net->pub.decree->fee_addr != NULL) - { - l_addr = *l_net->pub.decree->fee_addr; - } else - { + if (dap_chain_datum_decree_get_fee_addr(a_decree, &l_addr)) { + if (dap_chain_addr_is_blank(&l_net->pub.fee_addr)) { log_it(L_WARNING, "Fee wallet address not set."); return -111; - } - } else{ - dap_chain_addr_t *l_decree_addr = DAP_NEW_Z_SIZE(dap_chain_addr_t, sizeof(dap_chain_addr_t)); - if (!l_decree_addr) { - log_it(L_CRITICAL, "Memory allocation error"); - return -1; - } - memcpy(l_decree_addr, &l_addr, sizeof(dap_chain_addr_t)); - l_net->pub.decree->fee_addr = l_decree_addr; + } else + l_addr = l_net->pub.fee_addr; } - - if (!dap_chain_datum_decree_get_fee(a_decree, &l_uint256_buffer)){ - if (!a_apply) - break; - - if (!dap_chain_net_tx_add_fee(a_chain->net_id, l_uint256_buffer, l_addr)) { - log_it(L_WARNING,"Can't add/replace fee value."); - return -102; - } - }else{ + if (dap_chain_datum_decree_get_fee(a_decree, &l_uint256_buffer)) { log_it(L_WARNING,"Can't get fee value from decree."); return -103; } + if (!a_apply) + break; + if (!dap_chain_net_tx_set_fee(a_chain->net_id, l_uint256_buffer, l_addr)) + log_it(L_ERROR, "Can't set fee value for network %s", a_chain->net_name); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS: l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_uint16_buffer); @@ -550,7 +538,17 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai l_tsd_offset += l_tsd_size; } } break; - default: return -1; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD: { + if (dap_chain_datum_decree_get_value(a_decree, &l_uint256_buffer)) { + log_it(L_WARNING,"Can't get value from decree."); + return -103; + } + if (!a_apply) + break; + a_net->pub.base_reward = l_uint256_buffer; + } break; + default: + return -1; } return 0; diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index 3a47bb05b7..ecc2fe7917 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -26,6 +26,7 @@ #include "dap_chain_net_tx.h" #include "dap_chain_cell.h" #include "dap_chain_common.h" +#include "dap_chain_ledger.h" #include "dap_chain_datum_tx_in_cond.h" #include "dap_chain_tx.h" #include "dap_list.h" @@ -93,7 +94,7 @@ dap_chain_datum_tx_spends_items_t * dap_chain_net_get_tx_cond_all_with_spends_by if(a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT ){ dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx); - bool l_is_spent = !!dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash); + bool l_is_spent = !!dap_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash); DAP_DELETE(l_tx_hash); if(!l_is_spent) continue; @@ -399,7 +400,7 @@ static void s_get_tx_cond_all_for_addr_callback(dap_chain_net_t* a_net, dap_chai // dap_chain_tx_t * l_tx = dap_chain_tx_hh_find( l_args->tx_all_hh, &l_in->header.tx_prev_hash); if( dap_chain_tx_hh_find( l_args->tx_all_hh, &l_in->header.tx_prev_hash) ){ // Its input thats closing output for target address - we note it l_tx_from_addr = true; - //l_tx_from_addr_token = dap_chain_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx->hash); + //l_tx_from_addr_token = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx->hash); } }break; case TX_ITEM_TYPE_IN_COND:{ @@ -537,7 +538,7 @@ dap_list_t * dap_chain_net_get_tx_cond_all_by_srv_uid(dap_chain_net_t * a_net, c if(a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT ){ dap_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx); - bool l_is_spent = !!dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash); + bool l_is_spent = !!dap_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash); DAP_DELETE(l_tx_hash); if(!l_is_spent) continue; @@ -566,7 +567,7 @@ dap_list_t * dap_chain_net_get_tx_cond_all_by_srv_uid(dap_chain_net_t * a_net, c case TX_SEARCH_TYPE_NET_UNSPENT: case TX_SEARCH_TYPE_CELL_UNSPENT: - l_ret = dap_chain_ledger_tx_cache_find_out_cond_all(l_ledger, a_srv_uid); + l_ret = dap_ledger_tx_cache_find_out_cond_all(l_ledger, a_srv_uid); break; } return l_ret; @@ -637,70 +638,43 @@ dap_chain_datum_tx_t *dap_chain_net_get_tx_by_hash(dap_chain_net_t *a_net, dap_c continue; if ((a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT) && - (!dap_chain_ledger_tx_spent_find_by_hash(l_ledger, a_tx_hash))) + (!dap_ledger_tx_spent_find_by_hash(l_ledger, a_tx_hash))) return NULL; return (dap_chain_datum_tx_t *)l_datum->data; } case TX_SEARCH_TYPE_NET_UNSPENT: case TX_SEARCH_TYPE_CELL_UNSPENT: - return dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_hash); + return dap_ledger_tx_find_by_hash(l_ledger, a_tx_hash); default: break; } return NULL; } -static struct net_fee { - dap_chain_net_id_t net_id; - uint256_t value; // Network fee value - dap_chain_addr_t fee_addr; // Addr collector - UT_hash_handle hh; -} *s_net_fees = NULL; // Governance statements for networks - bool dap_chain_net_tx_get_fee(dap_chain_net_id_t a_net_id, uint256_t *a_value, dap_chain_addr_t *a_addr) { - struct net_fee *l_net_fee; dap_chain_net_t *l_net = dap_chain_net_by_id(a_net_id); - if (!l_net){ log_it(L_WARNING, "Can't find net with id 0x%016"DAP_UINT64_FORMAT_x"", a_net_id.uint64); return false; } - - HASH_FIND(hh, s_net_fees, &a_net_id, sizeof(dap_chain_net_id_t), l_net_fee); - if (!l_net_fee || IS_ZERO_256(l_net_fee->value)) + if (IS_ZERO_256(l_net->pub.fee_value)) return false; if (a_value) - *a_value = l_net_fee->value; + *a_value = l_net->pub.fee_value; if (a_addr) - *a_addr = l_net_fee->fee_addr; + *a_addr = l_net->pub.fee_addr; return true; } -bool dap_chain_net_tx_add_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, dap_chain_addr_t a_addr) +bool dap_chain_net_tx_set_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, dap_chain_addr_t a_addr) { - struct net_fee *l_net_fee = NULL; - bool l_found = false; dap_chain_net_t *l_net = dap_chain_net_by_id(a_net_id); - if (!l_net){ log_it(L_WARNING, "Can't find net with id 0x%016"DAP_UINT64_FORMAT_x"", a_net_id.uint64); return false; } - - HASH_FIND(hh, s_net_fees, &a_net_id, sizeof(dap_chain_net_id_t), l_net_fee); - - if (l_net_fee) - l_found = true; - else - l_net_fee = DAP_NEW(struct net_fee); - l_net_fee->net_id = a_net_id; - l_net_fee->value = a_value; - l_net_fee->fee_addr = a_addr; - - if (!l_found) - HASH_ADD(hh, s_net_fees, net_id, sizeof(dap_chain_net_id_t), l_net_fee); - - dap_chain_ledger_set_fee(l_net->pub.ledger, a_value, a_addr); + l_net->pub.fee_value = a_value; + l_net->pub.fee_addr = a_addr; return true; } diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c index 6519c1026c..8de6289a3b 100644 --- a/modules/net/dap_chain_node.c +++ b/modules/net/dap_chain_node.c @@ -46,6 +46,7 @@ #include "dap_global_db.h" #include "dap_chain_node.h" #include "dap_chain_cell.h" +#include "dap_chain_ledger.h" #define LOG_TAG "chain_node" @@ -227,7 +228,7 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force) dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data; if (dap_chain_datum_tx_get_fee_value (l_tx, &l_tx_fee) || IS_ZERO_256(l_tx_fee)) { - if (!dap_chain_ledger_tx_poa_signed(l_net->pub.ledger, l_tx)) { + if (!dap_ledger_tx_poa_signed(l_net->pub.ledger, l_tx)) { log_it(L_WARNING, "Can't get fee value from tx %s", l_objs[i].key); continue; } else diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 360c3f2a1f..595e06cde4 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -569,7 +569,7 @@ void s_dap_chain_net_purge(dap_chain_net_t * a_net) if (!a_net) return; dap_chain_t *l_chain = NULL; - dap_chain_ledger_purge(a_net->pub.ledger, false); + dap_ledger_purge(a_net->pub.ledger, false); dap_chain_net_srv_stake_purge(a_net); dap_chain_net_decree_purge(a_net); DL_FOREACH(a_net->pub.chains, l_chain) { @@ -579,7 +579,8 @@ void s_dap_chain_net_purge(dap_chain_net_t * a_net) l_chain->callback_set_min_validators_count(l_chain, 0); const char *l_chains_rm_path = dap_chain_get_path(l_chain); dap_rm_rf(l_chains_rm_path); - dap_chain_ledger_set_fee(a_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); + a_net->pub.fee_value = uint256_0; + a_net->pub.fee_addr = c_dap_chain_addr_blank; dap_chain_load_all(l_chain); } } @@ -1478,7 +1479,7 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply) l_decree->header.signs_size = 0; memcpy(l_decree->data_n_signs, l_addr_tsd, dap_tsd_size(l_addr_tsd)); size_t l_total_signs_success = 0; - l_decree = dap_chain_datum_decree_in_cycle(l_certs, l_decree, l_certs_count, &l_total_signs_success); + l_decree = dap_chain_datum_decree_sign_in_cycle(l_certs, l_decree, l_certs_count, &l_total_signs_success); if (!l_decree || !l_total_signs_success) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Decree creation failed. Successful count of certificate signing is 0"); @@ -1539,7 +1540,7 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply) l_decree->header.signs_size = 0; memcpy(l_decree->data_n_signs, l_addr_tsd, dap_tsd_size(l_addr_tsd)); size_t l_total_signs_success = 0; - l_decree = dap_chain_datum_decree_in_cycle(l_certs, l_decree, l_certs_count, &l_total_signs_success); + l_decree = dap_chain_datum_decree_sign_in_cycle(l_certs, l_decree, l_certs_count, &l_total_signs_success); if (!l_decree || !l_total_signs_success) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Decree creation failed. Successful count of certificate signing is 0"); @@ -2048,7 +2049,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; size_t l_l_addr_tokens_size = 0; char **l_l_addr_tokens = NULL; - dap_chain_ledger_addr_get_token_ticker_all(l_ledger, l_addr, &l_l_addr_tokens, &l_l_addr_tokens_size); + dap_ledger_addr_get_token_ticker_all(l_ledger, l_addr, &l_l_addr_tokens, &l_l_addr_tokens_size); if(l_l_addr_tokens_size > 0) dap_string_append_printf(l_string_ret, "balance:\n"); else @@ -2056,7 +2057,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; for(size_t i = 0; i < l_l_addr_tokens_size; i++) { if(l_l_addr_tokens[i]) { - uint256_t l_balance = dap_chain_ledger_calc_balance(l_ledger, l_addr, l_l_addr_tokens[i]); + uint256_t l_balance = dap_ledger_calc_balance(l_ledger, l_addr, l_l_addr_tokens[i]); char *l_balance_coins = dap_chain_balance_to_coins(l_balance); char *l_balance_datoshi = dap_chain_balance_print(l_balance); dap_string_append_printf(l_string_ret, "\t%s (%s) %s\n", l_balance_coins, @@ -2642,12 +2643,12 @@ dap_list_t *s_tickers_list_created(dap_chain_datum_tx_t *a_tx, dap_chain_net_t * case TX_ITEM_TYPE_IN: l_parent_hash = ((dap_chain_tx_in_t*)l_item_in)->header.tx_prev_hash; l_parrent_tx_out_idx = ((dap_chain_tx_in_t*)l_item_in)->header.tx_out_prev_idx; - l_tx_parent = dap_chain_ledger_tx_find_by_hash(a_net->pub.ledger, &((dap_chain_tx_in_t*)l_item_in)->header.tx_prev_hash); + l_tx_parent = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &((dap_chain_tx_in_t*)l_item_in)->header.tx_prev_hash); break; case TX_ITEM_TYPE_IN_COND: l_parent_hash = ((dap_chain_tx_in_cond_t*)l_item_in)->header.tx_prev_hash; l_parrent_tx_out_idx = ((dap_chain_tx_in_cond_t*)l_item_in)->header.tx_out_prev_idx; - l_tx_parent = dap_chain_ledger_tx_find_by_hash(a_net->pub.ledger, &((dap_chain_tx_in_cond_t*)l_item_in)->header.tx_prev_hash); + l_tx_parent = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &((dap_chain_tx_in_cond_t*)l_item_in)->header.tx_prev_hash); break; } if (!l_tx_parent) { @@ -2659,7 +2660,7 @@ dap_list_t *s_tickers_list_created(dap_chain_datum_tx_t *a_tx, dap_chain_net_t * l_tx_parent, TX_ITEM_TYPE_OUT_ALL, l_parrent_tx_out_idx); switch(dap_chain_datum_tx_item_get_type(l_out_unknown)) { case TX_ITEM_TYPE_OUT: - l_current_token = dap_chain_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_parent_hash); + l_current_token = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_parent_hash); l_tickers = dap_list_append(l_tickers, (void *)l_current_token); break; case TX_ITEM_TYPE_OUT_EXT: @@ -2668,7 +2669,7 @@ dap_list_t *s_tickers_list_created(dap_chain_datum_tx_t *a_tx, dap_chain_net_t * break; case TX_ITEM_TYPE_OUT_COND: if(((dap_chain_tx_out_cond_t*)l_out_unknown)->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) { - l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_parent_hash); + l_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_parent_hash); } break; } @@ -2714,7 +2715,7 @@ const char* s_tx_get_main_ticker(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *a_ static bool dap_chain_mempool_find_addr_ledger(dap_ledger_t* a_ledger, dap_chain_hash_fast_t* a_tx_prev_hash, dap_chain_addr_t *a_addr) { dap_chain_datum_tx_t *l_tx; - l_tx = dap_chain_ledger_tx_find_by_hash (a_ledger,a_tx_prev_hash); + l_tx = dap_ledger_tx_find_by_hash (a_ledger,a_tx_prev_hash); dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL), *l_item; if(!l_list_out_items) return false; @@ -3074,7 +3075,7 @@ int com_mempool_check(int a_argc, char **a_argv, char ** a_str_reply) char l_atom_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&l_atom_hash, l_atom_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); dap_string_append_printf(l_str_reply, "Atom hash is %s return code is %d (%s)\n", - l_atom_hash_str, l_ret_code, dap_chain_ledger_tx_check_err_str(l_ret_code)); + l_atom_hash_str, l_ret_code, dap_ledger_tx_check_err_str(l_ret_code)); } dap_chain_datum_dump(l_str_reply, l_datum, l_hash_out_type, l_net->pub.id); if (!l_found_in_chains) @@ -3238,7 +3239,7 @@ int com_mempool_proc_all(int argc, char ** argv, char ** a_str_reply) { } #ifdef DAP_TPS_TEST - dap_chain_ledger_set_tps_start_time(l_net->pub.ledger); + dap_ledger_set_tps_start_time(l_net->pub.ledger); #endif dap_chain_node_mempool_process_all(l_chain, true); dap_cli_server_cmd_set_reply_text(a_str_reply, "The entire mempool has been processed in %s.%s.", @@ -3469,7 +3470,7 @@ static int s_parse_additional_token_decl_arg(int a_argc, char ** a_argv, char ** a_params->ext.parsed_flags = l_flags; if (a_params->ext.delegated_token_from) { dap_chain_datum_token_t* l_delegated_token_from; - if (NULL == (l_delegated_token_from = dap_chain_ledger_token_ticker_check(a_params->net->pub.ledger, a_params->ext.delegated_token_from))) { + if (NULL == (l_delegated_token_from = dap_ledger_token_ticker_check(a_params->net->pub.ledger, a_params->ext.delegated_token_from))) { dap_cli_server_cmd_set_reply_text(a_str_reply, "To create a delegated token %s, can't find token by ticker %s", a_params->ticker, a_params->ext.delegated_token_from); return -91; } @@ -3802,7 +3803,7 @@ int com_token_decl(int a_argc, char ** a_argv, char ** a_str_reply) } if (l_params->ext.delegated_token_from){ dap_chain_datum_token_t *l_delegated_token_from; - if (NULL == (l_delegated_token_from = dap_chain_ledger_token_ticker_check(l_net->pub.ledger, l_params->ext.delegated_token_from))) { + if (NULL == (l_delegated_token_from = dap_ledger_token_ticker_check(l_net->pub.ledger, l_params->ext.delegated_token_from))) { dap_cli_server_cmd_set_reply_text(a_str_reply,"To create a delegated token %s, can't find token by ticket %s", l_ticker, l_params->ext.delegated_token_from); DAP_DEL_Z(l_params); return -91; @@ -5367,7 +5368,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, char **a_str_reply) if (!dap_strcmp(l_native_token, l_main_token)) { SUM_256_256(l_value_need_check, l_value_need, &l_value_need_check); SUM_256_256(l_value_need_check, l_value_need_fee, &l_value_need_check); - l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_json_item_token, + l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_json_item_token, l_addr_from, l_value_need_check, &l_value_transfer); if(!l_list_used_out) { log_it(L_WARNING, "Not enough funds in previous tx to transfer"); @@ -5379,7 +5380,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, char **a_str_reply) } } else { //CHECK value need - l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_json_item_token, + l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_json_item_token, l_addr_from, l_value_need, &l_value_transfer); if(!l_list_used_out) { log_it(L_WARNING, "Not enough funds in previous tx to transfer"); @@ -5390,7 +5391,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, char **a_str_reply) continue; } //CHECK value fee - l_list_used_out_fee = dap_chain_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_native_token, + l_list_used_out_fee = dap_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_native_token, l_addr_from, l_value_need_fee, &l_value_transfer_fee); if(!l_list_used_out_fee) { log_it(L_WARNING, "Not enough funds in previous tx to transfer"); @@ -5616,12 +5617,12 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply) } dap_chain_net_t * l_net = dap_chain_net_by_name(l_net_name); dap_ledger_t *l_ledger = l_net ? l_net->pub.ledger : NULL; - if(l_net == NULL || (l_ledger = dap_chain_ledger_by_net_name(l_net_name)) == NULL) { + if(l_net == NULL || (l_ledger = dap_ledger_by_net_name(l_net_name)) == NULL) { dap_cli_server_cmd_set_reply_text(a_str_reply, "not found net by name '%s'", l_net_name); return -7; } - if(!dap_chain_ledger_token_ticker_check(l_ledger, l_token_ticker)) { + if(!dap_ledger_token_ticker_check(l_ledger, l_token_ticker)) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Ticker '%s' is not declared on network '%s'.", l_token_ticker, l_net_name); return -16; @@ -5829,7 +5830,7 @@ int com_tx_verify(int a_argc, char **a_argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified tx not found"); return -3; } - int l_ret = dap_chain_ledger_tx_add_check(l_net->pub.ledger, l_tx, l_tx_size, &l_tx_hash); + int l_ret = dap_ledger_tx_add_check(l_net->pub.ledger, l_tx, l_tx_size, &l_tx_hash); if (l_ret) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified tx verify fail with return code=%d", l_ret); return -4; @@ -5997,7 +5998,7 @@ int com_tx_history(int a_argc, char ** a_argv, char **a_str_reply) dap_hash_fast_t l_ttx_hash = {0}; dap_hash_fast(l_tx, l_datums[i]->header.data_size, &l_ttx_hash); const char *l_token_ticker = NULL; - if ((l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_ttx_hash))) { + if ((l_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_ttx_hash))) { dap_string_append_printf(l_tx_all_str, "\t\t↓↓↓ Ledger accepted ↓↓↓\n"); l_tx_ledger_accepted++; } else { diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index a0f72850f3..349a3e485d 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -101,11 +101,11 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, dap_chain_hash_fast_t *a_tx_hash) { const char *l_ticker = a_ledger - ? dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash) + ? dap_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash) : NULL; if (!l_ticker) return false; - dap_chain_datum_dump_tx(a_datum, l_ticker, a_str_out, a_hash_out_type, a_tx_hash, a_ledger->net_id); + dap_chain_datum_dump_tx(a_datum, l_ticker, a_str_out, a_hash_out_type, a_tx_hash, a_ledger->net->pub.id); dap_list_t *l_out_items = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_OUT_ALL, NULL); int l_out_idx = 0; dap_string_append_printf(a_str_out, "Spent OUTs:\r\n"); @@ -115,10 +115,9 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, case TX_ITEM_TYPE_OUT: case TX_ITEM_TYPE_OUT_OLD: case TX_ITEM_TYPE_OUT_EXT: - case TX_ITEM_TYPE_OUT_COND_OLD: case TX_ITEM_TYPE_OUT_COND: { dap_hash_fast_t l_spender = { }; - if (dap_chain_ledger_tx_hash_is_used_out_item(a_ledger, a_tx_hash, l_out_idx, &l_spender)) { + if (dap_ledger_tx_hash_is_used_out_item(a_ledger, a_tx_hash, l_out_idx, &l_spender)) { char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; dap_hash_fast_to_str(&l_spender, l_hash_str, sizeof(l_hash_str)); dap_string_append_printf(a_str_out, @@ -165,9 +164,9 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, ? dap_enc_base58_encode_hash_to_str(&l_atom_hash) : dap_chain_hash_fast_to_str_new(&l_atom_hash); dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger; - const char *l_tx_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash); + const char *l_tx_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash); dap_string_append_printf(l_str_out, "%s TX with atom %s (ret_code %d - %s)\n", l_tx_token_ticker ? "ACCEPTED" : "DECLINED", - l_atom_hash_str, l_ret_code, dap_chain_ledger_tx_check_err_str(l_ret_code)); + l_atom_hash_str, l_ret_code, dap_ledger_tx_check_err_str(l_ret_code)); DAP_DELETE(l_atom_hash_str); dap_chain_datum_dump_tx(l_tx, l_tx_token_ticker, l_str_out, a_hash_out_type, a_tx_hash, a_chain->net_id); } else { @@ -204,7 +203,7 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_tx_hash_process } l_tx_data->hash = *a_tx_hash; HASH_ADD(hh, *a_tx_data_ht, hash, sizeof(*a_tx_hash), l_tx_data); - const char *l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash); + const char *l_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash); if (!l_token_ticker) l_declined = true; } @@ -218,7 +217,7 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_tx_hash_process } dap_string_append_printf(a_str_out, "%s TX hash %s with atom %s (ret code %d - %s) \n\t%s", l_declined ? "DECLINED" : "ACCEPTED", l_tx_hash_str, l_atom_hash_str, a_ret_code, - dap_chain_ledger_tx_check_err_str(a_ret_code), l_time_str); + dap_ledger_tx_check_err_str(a_ret_code), l_time_str); DAP_DELETE(l_tx_hash_str); DAP_DELETE(l_atom_hash_str); } @@ -279,7 +278,7 @@ char* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, const dap_hash_fast_t l_tx_hash; dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); - const char *l_src_token = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash); + const char *l_src_token = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash); int l_src_subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED; for (dap_list_t *it = l_list_in_items; it; it = it->next) { @@ -768,15 +767,15 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_string_t *l_str_ret = dap_string_new(NULL); char *l_str_out = NULL; - dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str); + dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net_str); if(l_is_all) { - size_t l_tx_count = dap_chain_ledger_count(l_ledger), l_tx_count_spent_count = 0; + size_t l_tx_count = dap_ledger_count(l_ledger), l_tx_count_spent_count = 0; if (!l_tx_count) { - dap_string_append_printf(l_str_ret, "Network ledger %s contains no transactions.\n", l_ledger->net_name); + dap_string_append_printf(l_str_ret, "Network ledger %s contains no transactions.\n", l_ledger->net->pub.name); } else { dap_string_append_printf(l_str_ret, "There are %zu transactions in the network ledger %s:\n", - l_tx_count, l_ledger->net_name); - dap_list_t *l_txs_list = dap_chain_ledger_get_txs(l_ledger, l_tx_count, 1, true, l_unspent_flag); + l_tx_count, l_ledger->net->pub.name); + dap_list_t *l_txs_list = dap_ledger_get_txs(l_ledger, l_tx_count, 1, true, l_unspent_flag); for (dap_list_t *iter = l_txs_list; iter; iter = dap_list_next(iter)) { dap_chain_datum_tx_t *l_tx = iter->data; dap_hash_fast_t l_tx_hash = { }; @@ -794,9 +793,9 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) l_str_out ? l_str_out : " empty"); DAP_DELETE(l_addr_str); } else if(l_tx_hash_str) { - dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &l_tx_hash); + dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_tx_hash); if (!l_tx && !l_unspent_flag) { - l_tx = dap_chain_ledger_tx_spent_find_by_hash(l_ledger, &l_tx_hash); + l_tx = dap_ledger_tx_spent_find_by_hash(l_ledger, &l_tx_hash); } if(l_tx) { size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); @@ -847,13 +846,13 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'list' requires key -net"); return -1; } - dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str); + dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net_str); if (l_ledger == NULL){ dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get ledger for net %s", l_net_str); return -2; } if (l_sub_cmd == SUB_CMD_LIST_LEDGER_THRESHOLD){ - dap_string_t *l_str_ret = dap_chain_ledger_threshold_info(l_ledger); + dap_string_t *l_str_ret = dap_ledger_threshold_info(l_ledger); if (l_str_ret){ dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str); dap_string_free(l_str_ret, true); @@ -862,7 +861,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) return 0; } if (l_sub_cmd == SUB_CMD_LIST_LEDGER_THRESHOLD_WITH_HASH){ - dap_string_t *l_str_ret = dap_chain_ledger_threshold_hash_info(l_ledger, &l_tx_threshold_hash); + dap_string_t *l_str_ret = dap_ledger_threshold_hash_info(l_ledger, &l_tx_threshold_hash); if (l_str_ret){ dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str); dap_string_free(l_str_ret, true); @@ -871,7 +870,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) return 0; } if (l_sub_cmd == SUB_CMD_LIST_LEDGER_BALANCE){ - dap_string_t *l_str_ret = dap_chain_ledger_balance_info(l_ledger); + dap_string_t *l_str_ret = dap_ledger_balance_info(l_ledger); if (l_str_ret){ dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str); dap_string_free(l_str_ret, true); @@ -880,7 +879,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) return 0; } dap_string_t *l_str_ret = dap_string_new(""); - dap_list_t *l_token_list = dap_chain_ledger_token_info(l_ledger); + dap_list_t *l_token_list = dap_ledger_token_info(l_ledger); dap_string_append_printf(l_str_ret, "Found %lu tokens in %s ledger\n", dap_list_length(l_token_list), l_net_str); for (dap_list_t *l_list = l_token_list; l_list; l_list = dap_list_next(l_list)) { dap_string_append(l_str_ret, (char *)l_list->data); @@ -1062,7 +1061,7 @@ int com_token(int a_argc, char ** a_argv, char **a_str_reply) // only selected net if(l_net->pub.id.uint64 == l_chain_cur->net_id.uint64) { long l_chain_datum = l_cur_datum; - dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str); + dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net_str); char *l_datum_list_str = dap_db_history_filter(l_chain_cur, l_ledger, l_token_name_str, NULL, l_hash_out_type, l_page_start * l_page_size, (l_page_start+l_page)*l_page_size, &l_chain_datum, l_list_tx_hash_processd); if(l_datum_list_str) { @@ -1336,9 +1335,8 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &l_param_value_str)){ l_subtype = SUBTYPE_FEE; if (!dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_addr", &l_param_addr_str)){ - if(!l_net->pub.decree->fee_addr) - { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Net fee add needed. Use -to_addr parameter"); + if (dap_chain_addr_is_blank(&l_net->pub.fee_addr)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Use -to_addr parameter to set net fee"); return -111; } }else{ @@ -1473,7 +1471,7 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) // Sign decree size_t l_total_signs_success = 0; if (l_certs_count) - l_datum_decree = dap_chain_datum_decree_in_cycle(l_certs, l_datum_decree, l_certs_count, &l_total_signs_success); + l_datum_decree = dap_chain_datum_decree_sign_in_cycle(l_certs, l_datum_decree, l_certs_count, &l_total_signs_success); if (!l_datum_decree || l_total_signs_success == 0){ dap_cli_server_cmd_set_reply_text(a_str_reply, @@ -1567,7 +1565,7 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) // Sign decree size_t l_total_signs_success = 0; if (l_certs_count) - l_datum_decree = dap_chain_datum_decree_in_cycle(l_certs, l_datum_decree, l_certs_count, &l_total_signs_success); + l_datum_decree = dap_chain_datum_decree_sign_in_cycle(l_certs, l_datum_decree, l_certs_count, &l_total_signs_success); if (!l_datum_decree || l_total_signs_success == 0){ dap_cli_server_cmd_set_reply_text(a_str_reply, diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h new file mode 100644 index 0000000000..2f1d084ca9 --- /dev/null +++ b/modules/net/include/dap_chain_ledger.h @@ -0,0 +1,357 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * Alexander Lysikov <alexander.lysikov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * DeM Labs Open source community https://github.com/demlabsinc + * Copyright (c) 2017-2019 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once +#include <stdint.h> +#include <stdbool.h> +#include "dap_common.h" +#include "dap_hash.h" +#include "dap_list.h" +#include "dap_math_ops.h" +#include "dap_chain_common.h" +#include "dap_chain_datum_token.h" +#include "dap_chain_datum_tx.h" +#include "dap_chain_datum_tx_in_ems.h" +#include "dap_chain_datum_tx_items.h" +#include "dap_chain_net.h" + +typedef struct dap_ledger { + dap_chain_net_t *net; + void *_internal; +} dap_ledger_t; + +/** + * @brief Error codes for accepting a transaction to the ledger. + */ +typedef enum dap_ledger_tx_check{ + DAP_LEDGER_TX_CHECK_OK = 0, + DAP_LEDGER_TX_CHECK_NULL_TX, + DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE, + DAP_LEDGER_TX_ALREADY_CACHED, + DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN, + DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED, + DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED, + DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND, + DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS, + DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND, + DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN, + DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS, + DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE, + DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS, + DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX, + DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY, + DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE, + DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND, + DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED, + DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED, + DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND, + DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND, + DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_MISSTYPED, + DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH, + DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX, + DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET, + DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE, + DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND, + DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND, + DAP_LEDGER_PERMISSION_CHECK_FAILED, + DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS, + DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED, + DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL, + DAP_LEDGER_TX_CHECK_INVALID_TICKER, + DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM, + /* add custom codes here */ + + DAP_LEDGER_TX_CHECK_UNKNOWN /* MAX */ +} dap_ledger_tx_check_t; + +typedef enum dap_ledger_emission_err{ + DAP_LEDGER_EMISSION_ADD_OK = 0, + DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL, + DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED, + DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW, + DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY, + DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS, + DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN, + DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE, + DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED, + /* add custom codes here */ + DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM, + DAP_LEDGER_EMISSION_ADD_UNKNOWN /* MAX */ +} dap_ledger_emission_err_code_t; + +typedef enum dap_ledger_token_decl_add_err{ + DAP_LEDGER_TOKEN_DECL_ADD_OK = 0, + DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL, + DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE, + DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK, + DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN, + DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN, + DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS, + /* add custom codes here */ + + DAP_LEDGER_TOKEN_DECL_ADD_UNKNOWN /* MAX */ +} dap_ledger_token_decl_add_err_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); +typedef void (* dap_ledger_bridged_tx_notify_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg); +typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_hash_fast_t *a_tx_hash); +typedef struct dap_chain_net dap_chain_net_t; + +//Change this UUID to automatically reload ledger cache on next node startup +#define DAP_LEDGER_CACHE_RELOAD_ONCE_UUID "0c92b759-a565-448f-b8bd-99103dacf7fc" + +// Checks the emission of the token, usualy on zero chain +#define DAP_LEDGER_CHECK_TOKEN_EMISSION 0x0001 + +// Check double spending in local cell +#define DAP_LEDGER_CHECK_LOCAL_DS 0x0002 + +// Check the double spending in all cells +#define DAP_LEDGER_CHECK_CELLS_DS 0x0100 + +#define DAP_LEDGER_CACHE_ENABLED 0x0200 + +// Error code for no previous transaction (for stay in mempool) +#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND +// Error code for no emission for a transaction (for stay in mempoold) +#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND +// Error code for no decree for anchor (for stay in mempool) +#define DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE -1113 + +#define DAP_LEDGER_TOKENS_STR "tokens" +#define DAP_LEDGER_EMISSIONS_STR "emissions" +#define DAP_LEDGER_STAKE_LOCK_STR "stake_lock" +#define DAP_LEDGER_TXS_STR "txs" +#define DAP_LEDGER_SPENT_TXS_STR "spent_txs" +#define DAP_LEDGER_BALANCES_STR "balances" + +int dap_ledger_init(); +void dap_ledger_deinit(); + +dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags); + +// Remove dap_ledger_t structure +void dap_ledger_handle_free(dap_ledger_t *a_ledger); + +// Load ledger from mempool +//int dap_ledger_load(const char *a_net_name, const char *a_chain_name); + +void dap_ledger_set_local_cell_id(dap_ledger_t *a_ledger, dap_chain_cell_id_t a_local_cell_id); + +/** + * @brief dap_chain_node_datum_tx_calc_hash + * @param a_tx + * @return + */ +DAP_STATIC_INLINE dap_chain_hash_fast_t* dap_chain_node_datum_tx_calc_hash(dap_chain_datum_tx_t *a_tx) +{ + dap_chain_hash_fast_t *tx_hash = DAP_NEW_Z(dap_chain_hash_fast_t); + if (!tx_hash) { + return NULL; + } + dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), tx_hash); + return tx_hash; +} + +DAP_STATIC_INLINE char *dap_ledger_get_gdb_group(dap_ledger_t *a_ledger, const char *a_suffix) +{ + return a_ledger && a_ledger->net->pub.name && a_suffix + ? dap_strdup_printf("local.ledger-cache.%s.%s", a_ledger->net->pub.name, a_suffix) + : NULL; +} + +/** + * Add new transaction to the cache + * + * return 1 OK, -1 error + */ +int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold); +int dap_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_hash_fast_t *a_tx_hash); + + +int dap_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash); + +char* dap_ledger_tx_check_err_str(int a_code); + +/** + * Print list transaction from ledger + * + */ + +char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only); + +/** + * Check token ticker existance + * + */ + +dap_chain_datum_token_t *dap_ledger_token_ticker_check(dap_ledger_t * a_ledger, const char *a_token_ticker); + +/** + * Add new token datum + * + */ + +int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); +int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size); +int dap_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); +char *dap_ledger_token_decl_add_err_code_to_str(int a_code); +dap_list_t *dap_ledger_token_info(dap_ledger_t *a_ledger); + +// Get all token-declarations +dap_list_t* dap_ledger_token_decl_all(dap_ledger_t *a_ledger); + +dap_string_t *dap_ledger_threshold_info(dap_ledger_t *a_ledger); +dap_string_t *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_tx_treshold_hash); +dap_string_t *dap_ledger_balance_info(dap_ledger_t *a_ledger); + +size_t dap_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker); +size_t dap_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker); +dap_list_t * dap_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker); + +/** + * Add token emission datum + */ +int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, + dap_hash_fast_t *a_emission_hash, bool a_from_threshold); +int dap_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_hash_fast_t *a_token_emission_hash); +char *dap_ledger_token_emission_err_code_to_str(int a_code); + +// Check if it addable +int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash); + +/* Add stake-lock item */ +int dap_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash); + +dap_chain_datum_token_emission_t *dap_ledger_token_emission_find(dap_ledger_t *a_ledger, + const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash); + +const char* dap_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_chain_hash_fast_t *a_tx_hash); + +void dap_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, + char *** a_tickers, size_t * a_tickers_size); + +void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, + char *** a_tickers, size_t * a_tickers_size); + +bool dap_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx); + +// Checking a new transaction before adding to the cache +int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, + bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker); + +/** + * Delete all transactions from the cache + */ +void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db); + +/** + * End of load mode with no chackes for incoming datums + */ +void dap_ledger_load_end(dap_ledger_t *a_ledger); + +/** + * Return number transactions from the cache + */ +unsigned dap_ledger_count(dap_ledger_t *a_ledger); +uint64_t dap_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts_from, dap_time_t a_ts_to); +size_t dap_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to); +void dap_ledger_set_tps_start_time(dap_ledger_t *a_ledger); + +/** + * Check whether used 'out' items + */ +bool dap_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, int a_idx_out, dap_hash_fast_t *a_out_spender); + +/** + * Retun true if reward was collected before + */ +bool dap_ledger_is_used_reward(dap_ledger_t *a_ledger, dap_hash_fast_t *a_block_hash, dap_hash_fast_t *a_sign_pkey_hash); + +/** + * Calculate balance of addr + * + */ +uint256_t dap_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, + const char *a_token_ticker); + +uint256_t dap_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, + const char *a_token_ticker); + +/** + * Get transaction in the cache by hash + * + * return transaction, or NULL if transaction not found in the cache + */ +dap_chain_datum_tx_t* dap_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); +dap_chain_datum_tx_t* dap_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); +dap_hash_fast_t *dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash); + + // Get the transaction in the cache by the addr in out item +dap_chain_datum_tx_t* dap_ledger_tx_find_by_addr(dap_ledger_t *a_ledger, const char * a_token, + const dap_chain_addr_t *a_addr, dap_chain_hash_fast_t *a_tx_first_hash); + +// Get the transaction in the cache by the public key that signed the transaction, starting with a_tx_first_hash +const dap_chain_datum_tx_t* dap_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger, + char *a_public_key, size_t a_public_key_size, dap_chain_hash_fast_t *a_tx_first_hash); + +// Get the transaction in the cache with the out_cond item +dap_chain_datum_tx_t* dap_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, + dap_chain_hash_fast_t *a_tx_first_hash, dap_chain_tx_out_cond_t **a_out_cond, + int *a_out_cond_idx, char *a_token_ticker); + +// Get all transactions from the cache with the specified out_cond items +dap_list_t* dap_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_chain_net_srv_uid_t a_srv_uid); + +// Get the value from all transactions in the cache with out_cond item +uint256_t dap_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_addr_t *a_addr, + dap_chain_tx_out_cond_t **tx_out_cond); + +// Get the list of 'out' items from previous transactions with summary value >= than a_value_need +// Put this summary value to a_value_transfer +dap_list_t *dap_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from, + uint256_t a_value_need, uint256_t *a_value_transfer); + +// Get the list of 'out_cond' items with summary value >= than a_value_need +dap_list_t *dap_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from, + dap_chain_tx_out_cond_subtype_t a_subtype, uint256_t a_value_need, uint256_t *a_value_transfer); + +// Add new verificator callback with associated subtype. Returns 1 if callback replaced, overwise returns 0 +int dap_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_ledger_verificator_callback_t a_callback, + dap_ledger_updater_callback_t a_callback_added); + +// Getting a list of transactions from the ledger. +dap_list_t * dap_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only); + +//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); + +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); + + +bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger); +void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_cache_tx_check_callback_t a_callback); diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 523b3e4717..b82409b423 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -37,7 +37,6 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "dap_chain_common.h" #include "dap_chain.h" #include "dap_chain_node.h" -#include "dap_chain_ledger.h" #include "dap_chain_net_decree.h" #include "dap_chain_net_tx.h" #include "dap_chain_datum_decree.h" @@ -50,6 +49,7 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic struct dap_chain_node_info; typedef struct dap_chain_node_client dap_chain_node_client_t; +typedef struct dap_ledger dap_ledger_t; typedef enum dap_chain_net_state{ NET_STATE_OFFLINE = 0, @@ -74,10 +74,15 @@ typedef struct dap_chain_net{ bool mempool_autoproc; - dap_chain_t * chains; // double-linked list of chains + dap_chain_t *chains; // double-linked list of chains const char *native_ticker; - dap_ledger_t *ledger; + dap_ledger_t *ledger; dap_chain_net_decree_t *decree; + // 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; @@ -138,7 +143,7 @@ dap_chain_net_t * dap_chain_net_by_name( const char * a_name); dap_chain_net_t * dap_chain_net_by_id( dap_chain_net_id_t a_id); uint16_t dap_chain_net_get_acl_idx(dap_chain_net_t *a_net); dap_chain_net_id_t dap_chain_net_id_by_name( const char * a_name); -dap_ledger_t * dap_chain_ledger_by_net_name( const char * a_net_name); +dap_ledger_t * dap_ledger_by_net_name( const char * a_net_name); dap_string_t* dap_cli_list_net(); dap_chain_t * dap_chain_net_get_chain_by_name( dap_chain_net_t * l_net, const char * a_name); diff --git a/modules/net/include/dap_chain_net_decree.h b/modules/net/include/dap_chain_net_decree.h index 255ab44326..4a1720c7df 100644 --- a/modules/net/include/dap_chain_net_decree.h +++ b/modules/net/include/dap_chain_net_decree.h @@ -29,7 +29,6 @@ typedef struct decree_params { dap_list_t *pkeys; uint16_t num_of_owners; uint16_t min_num_of_owners; - dap_chain_addr_t *fee_addr; } dap_chain_net_decree_t; int dap_chain_net_decree_init(dap_chain_net_t *a_net); diff --git a/modules/net/include/dap_chain_net_tx.h b/modules/net/include/dap_chain_net_tx.h index 8fccb5f4e9..74aa1d9aeb 100644 --- a/modules/net/include/dap_chain_net_tx.h +++ b/modules/net/include/dap_chain_net_tx.h @@ -24,6 +24,7 @@ #pragma once #include "dap_chain_net.h" +#include "dap_chain_datum_tx_items.h" typedef enum dap_chain_net_tx_search_type { /// Search local, in memory, possible load data from drive to memory @@ -88,4 +89,4 @@ void dap_chain_datum_tx_spends_item_free(dap_chain_datum_tx_spends_item_t * a_it void dap_chain_datum_tx_spends_items_free(dap_chain_datum_tx_spends_items_t * a_items); bool dap_chain_net_tx_get_fee(dap_chain_net_id_t a_net_id, uint256_t *a_value, dap_chain_addr_t *a_addr); -bool dap_chain_net_tx_add_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, dap_chain_addr_t a_addr); +bool dap_chain_net_tx_set_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, dap_chain_addr_t a_addr); diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c index 8f38736980..4950f4e3d5 100644 --- a/modules/net/srv/dap_chain_net_srv.c +++ b/modules/net/srv/dap_chain_net_srv.c @@ -93,8 +93,8 @@ static int s_str_to_price_unit(const char *a_price_unit_str, dap_chain_net_srv_p */ int dap_chain_net_srv_init() { - dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, s_pay_verificator_callback, NULL); - dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE, s_fee_verificator_callback, NULL); + dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, s_pay_verificator_callback, NULL); + dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE, s_fee_verificator_callback, NULL); dap_stream_ch_chain_net_srv_init(); dap_cli_server_cmd_add ("net_srv", s_cli_net_srv, "Network services managment", @@ -661,12 +661,11 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply) * @param a_owner * @return */ -static bool s_fee_verificator_callback(dap_ledger_t *a_ledger, UNUSED_ARG dap_chain_tx_out_cond_t *a_cond, - dap_chain_datum_tx_t *a_tx_in, UNUSED_ARG bool a_owner) +static bool s_fee_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t UNUSED_ARG *a_cond, + dap_chain_datum_tx_t *a_tx_in, bool UNUSED_ARG a_owner) { - dap_chain_net_t *l_net = dap_chain_net_by_name(a_ledger->net_name); - if (!l_net) - return false; + dap_chain_net_t *l_net = a_ledger->net; + assert(l_net); dap_chain_t *l_chain; DL_FOREACH(l_net->pub.chains, l_chain) { if (!l_chain->callback_block_find_by_tx_hash) @@ -778,7 +777,7 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out // Check price is less than maximum dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0); - dap_chain_datum_tx_t *l_tx_prev = dap_chain_ledger_tx_find_by_hash(a_ledger , &l_tx_in_cond->header.tx_prev_hash); + dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash(a_ledger , &l_tx_in_cond->header.tx_prev_hash); dap_chain_tx_out_cond_t *l_prev_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_prev, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL); uint256_t l_unit_price = {}; @@ -800,7 +799,7 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out uint256_t l_value = l_receipt->receipt_info.value_datoshi; uint256_t l_cond_out_value = {}; dap_chain_addr_t l_network_fee_addr = {}; - dap_chain_net_tx_get_fee(a_ledger->net_id, NULL, &l_network_fee_addr); + dap_chain_net_tx_get_fee(a_ledger->net->pub.id, NULL, &l_network_fee_addr); int l_item_idx = 0; for (dap_list_t * l_list_tmp = l_list_out; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_item_idx++) { dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data; @@ -1163,7 +1162,7 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid, // dap_chain_net_srv_parse_pricelist(l_srv, a_config_section); HASH_ADD(hh, s_srv_list, uid, sizeof(l_srv->uid), l_sdata); if (l_srv->pricelist) - dap_chain_ledger_tx_add_notify(l_srv->pricelist->net->pub.ledger, dap_stream_ch_chain_net_srv_tx_cond_added_cb, NULL); + dap_ledger_tx_add_notify(l_srv->pricelist->net->pub.ledger, dap_stream_ch_chain_net_srv_tx_cond_added_cb, NULL); }else{ log_it(L_ERROR, "Already present service with 0x%016"DAP_UINT64_FORMAT_X, a_uid.uint64); } diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c index 07c316c94b..30a8335e8c 100644 --- a/modules/net/srv/dap_chain_net_srv_order.c +++ b/modules/net/srv/dap_chain_net_srv_order.c @@ -550,7 +550,7 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d DAP_DELETE(l_balance); if( a_order->price_unit.uint32 ) dap_string_append_printf(a_str_out, " price_unit: %s\n", dap_chain_net_srv_price_unit_uid_to_str(a_order->price_unit) ); - if(a_order->price_ticker) + if (*a_order->price_ticker) dap_string_append_printf(a_str_out, " price_token: %s\n", a_order->price_ticker); if ( a_order->node_addr.uint64) dap_string_append_printf(a_str_out, " node_addr: "NODE_ADDR_FP_STR"\n", NODE_ADDR_FP_ARGS_S(a_order->node_addr) ); diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c index 87db2ea544..ef7885414f 100644 --- a/modules/service/datum/dap_chain_net_srv_datum.c +++ b/modules/service/datum/dap_chain_net_srv_datum.c @@ -248,7 +248,7 @@ void s_order_notficator(dap_store_obj_t *a_obj, void *a_arg) if (l_datum) l_tx_cond = (dap_chain_datum_tx_t *)l_datum->data; else - l_tx_cond = dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order->tx_cond_hash); + l_tx_cond = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order->tx_cond_hash); if (!l_tx_cond) { log_it(L_DEBUG, "Invalid tx cond datum hash"); return; diff --git a/modules/service/stake/dap_chain_net_srv_stake_lock.c b/modules/service/stake/dap_chain_net_srv_stake_lock.c index 4e3d065313..7a7f365a73 100644 --- a/modules/service/stake/dap_chain_net_srv_stake_lock.c +++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c @@ -22,16 +22,15 @@ along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. */ -#include "dap_chain_net_srv.h" -#include "dap_chain_net_srv_stake_lock.h" -#include "dap_chain_net_tx.h" -#include "dap_chain_node_cli.h" -#include "dap_chain_mempool.h" -#include "dap_chain_wallet.h" -#include "dap_chain_ledger.h" #include "dap_common.h" #include "dap_hash.h" #include "dap_time.h" +#include "dap_chain_ledger.h" +#include "dap_chain_net_srv_stake_lock.h" +#include "dap_chain_node_cli.h" +#include "dap_chain_wallet.h" +#include "dap_chain_mempool.h" +#include "dap_chain_net_srv.h" static bool s_debug_more = false; @@ -81,12 +80,12 @@ enum error_code { FEE_FORMAT_ERROR = 43, }; -typedef struct dap_chain_ledger_token_emission_for_stake_lock_item { +typedef struct dap_ledger_token_emission_for_stake_lock_item { dap_chain_hash_fast_t datum_token_emission_for_stake_lock_hash; dap_chain_hash_fast_t tx_used_out; // const char datum_token_emission_hash[DAP_CHAIN_HASH_FAST_STR_SIZE]; UT_hash_handle hh; -} dap_chain_ledger_token_emission_for_stake_lock_item_t; +} dap_ledger_token_emission_for_stake_lock_item_t; #define LOG_TAG "dap_chain_net_stake_lock" #define MONTH_INDEX 8 @@ -115,7 +114,7 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_ */ int dap_chain_net_srv_stake_lock_init() { - dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, s_stake_lock_callback_verificator, s_stake_lock_callback_updater); + dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, s_stake_lock_callback_verificator, s_stake_lock_callback_updater); dap_cli_server_cmd_add("stake_lock", s_cli_stake_lock, "Stake lock service commands", "Command:" "stake_lock hold\n" @@ -200,7 +199,7 @@ static enum error_code s_cli_hold(int a_argc, char **a_argv, int a_arg_index, da l_ledger = l_net->pub.ledger; - if (NULL == dap_chain_ledger_token_ticker_check(l_ledger, l_ticker_str)) { + if (NULL == dap_ledger_token_ticker_check(l_ledger, l_ticker_str)) { dap_string_append_printf(output_line, "'%s'", l_ticker_str); return TOKEN_ERROR; } @@ -214,7 +213,7 @@ static enum error_code s_cli_hold(int a_argc, char **a_argv, int a_arg_index, da dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker_str, l_ticker_str); - if (NULL == (l_delegated_token = dap_chain_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str)) + if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str)) || (l_delegated_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE) || !l_delegated_token->header_native_decl.tsd_total_size || NULL == (l_tsd = dap_tsd_find(l_delegated_token->data_n_tsd, l_delegated_token->header_native_decl.tsd_total_size, @@ -399,7 +398,7 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da l_ledger = l_net->pub.ledger; - l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &l_tx_hash); + l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_tx_hash); if (NULL == (l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_cond_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, &l_prev_cond_idx))) @@ -408,11 +407,11 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da if (l_tx_out_cond->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK) return NO_VALID_SUBTYPE_ERROR; - if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, &l_tx_hash, l_prev_cond_idx, NULL)) { + if (dap_ledger_tx_hash_is_used_out_item(l_ledger, &l_tx_hash, l_prev_cond_idx, NULL)) { return IS_USED_OUT_ERROR; } - if (NULL == (l_ticker_str = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash))) + if (NULL == (l_ticker_str = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash))) return TX_TICKER_ERROR; if (l_tx_out_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_CREATE_BASE_TX || @@ -420,7 +419,7 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker_str, l_ticker_str); - if (NULL == (l_delegated_token = dap_chain_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str)) + if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str)) || (l_delegated_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE) || !l_delegated_token->header_native_decl.tsd_total_size || NULL == (l_tsd = dap_tsd_find(l_delegated_token->data_n_tsd, @@ -905,7 +904,7 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_ return false; if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash)) return false; - if (NULL == (l_prev_tx_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash( + if (NULL == (l_prev_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash( a_ledger, &l_tx_in_cond->header.tx_prev_hash))) return false; @@ -913,7 +912,7 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_ if (a_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_CREATE_BASE_TX || a_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_EMIT) { - if (NULL == (l_delegated_token = dap_chain_ledger_token_ticker_check(a_ledger, l_delegated_ticker_str)) + if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(a_ledger, l_delegated_ticker_str)) || (l_delegated_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE) || !l_delegated_token->header_native_decl.tsd_total_size || NULL == (l_tsd = dap_tsd_find(l_delegated_token->data_n_tsd, @@ -939,7 +938,7 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_ l_burning_tx_hash = *(dap_hash_fast_t*)l_receipt->exts_n_signs; if (dap_hash_fast_is_blank(&l_burning_tx_hash)) return false; - l_burning_tx = dap_chain_ledger_tx_find_by_hash(a_ledger, &l_burning_tx_hash); + l_burning_tx = dap_ledger_tx_find_by_hash(a_ledger, &l_burning_tx_hash); if (!l_burning_tx) { char l_burning_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; dap_hash_fast_to_str(&l_burning_tx_hash, l_burning_tx_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); @@ -1018,7 +1017,7 @@ static void s_stake_lock_callback_updater(dap_ledger_t *a_ledger, dap_chain_datu if (l_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_CREATE_BASE_TX) { dap_chain_hash_fast_t l_tx_cond_hash; dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_tx_cond_hash); - dap_chain_ledger_emission_for_stake_lock_item_add(a_ledger, &l_tx_cond_hash); + dap_ledger_emission_for_stake_lock_item_add(a_ledger, &l_tx_cond_hash); } } @@ -1029,7 +1028,7 @@ static dap_chain_datum_t *s_stake_lock_datum_create(dap_chain_net_t *a_net, dap_ const char *a_delegated_ticker_str, uint256_t a_delegated_value) { dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_LOCK_ID }; - dap_ledger_t * l_ledger = a_net ? dap_chain_ledger_by_net_name( a_net->pub.name ) : NULL; + dap_ledger_t * l_ledger = a_net ? dap_ledger_by_net_name( a_net->pub.name ) : NULL; // check valid param if (!a_net || !l_ledger || !a_key_from || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size || IS_ZERO_256(a_value)) @@ -1049,7 +1048,7 @@ static dap_chain_datum_t *s_stake_lock_datum_create(dap_chain_net_t *a_net, dap_ if (l_main_native) SUM_256_256(l_value_need, l_total_fee, &l_value_need); else if (!IS_ZERO_256(l_total_fee)) { - l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker, + l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker, &l_addr, l_total_fee, &l_fee_transfer); if (!l_list_fee_out) { log_it(L_WARNING, "Not enough funds to pay fee"); @@ -1057,7 +1056,7 @@ static dap_chain_datum_t *s_stake_lock_datum_create(dap_chain_net_t *a_net, dap_ } } // list of transaction with 'out' items - dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_main_ticker, + dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_main_ticker, &l_addr, l_value_need, &l_value_transfer); if(!l_list_used_out) { log_it( L_ERROR, "Nothing to transfer (not enough funds)"); @@ -1192,7 +1191,7 @@ dap_chain_datum_t *s_stake_unlock_datum_create(dap_chain_net_t *a_net, dap_enc_k SUM_256_256(l_net_fee, a_value_fee, &l_total_fee); if (!IS_ZERO_256(l_total_fee)) { - l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker, + l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker, &l_addr, l_total_fee, &l_fee_transfer); if (!l_list_fee_out) { log_it(L_WARNING, "Not enough funds to pay fee"); @@ -1200,7 +1199,7 @@ dap_chain_datum_t *s_stake_unlock_datum_create(dap_chain_net_t *a_net, dap_enc_k } } if (!IS_ZERO_256(a_delegated_value)) { - l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, a_delegated_ticker_str, + l_list_used_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, a_delegated_ticker_str, &l_addr, a_delegated_value, &l_value_transfer); if(!l_list_used_out) { log_it( L_ERROR, "Nothing to transfer (not enough delegated tokens)"); 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 9bb320251b..44ecfb56b8 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 @@ -63,7 +63,7 @@ static dap_chain_net_srv_stake_t *s_srv_stake = NULL; */ int dap_chain_net_srv_stake_pos_delegate_init() { - dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, s_stake_verificator_callback, s_stake_updater_callback); + dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, s_stake_verificator_callback, s_stake_updater_callback); dap_cli_server_cmd_add("srv_stake", s_cli_srv_stake, "Delegated stake service commands", "\t\t=== Commands for work with orders ===\n" "srv_stake order create -net <net_name> -value <value> -cert <priv_cert_name> \n" @@ -361,9 +361,9 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net) log_it(L_ERROR, "Invalid arguments l_ledger in dap_chain_net_srv_stake_load_cache"); return -1; } - if (!dap_chain_ledger_cache_enabled(l_ledger)) + if (!dap_ledger_cache_enabled(l_ledger)) return 0; - char *l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP); + char *l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP); size_t l_objs_count = 0; dap_store_obj_t *l_store_obj = dap_global_db_get_all_raw_sync(l_gdb_group, &l_objs_count); @@ -385,14 +385,14 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net) HASH_ADD(hh, s_srv_stake->cache, tx_hash, sizeof(dap_hash_fast_t), l_cache); } dap_store_obj_free(l_store_obj, l_objs_count); - dap_chain_ledger_set_cache_tx_check_callback(l_ledger, s_stake_cache_check_tx); + dap_ledger_set_cache_tx_check_callback(l_ledger, s_stake_cache_check_tx); return 0; } void dap_chain_net_srv_stake_purge(dap_chain_net_t *a_net) { dap_ledger_t *l_ledger = a_net->pub.ledger; - char *l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP); + char *l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP); dap_global_db_del(l_gdb_group, NULL, NULL, NULL); DAP_DELETE(l_gdb_group); s_stake_net_clear(a_net); @@ -412,7 +412,7 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_chai const char *l_native_ticker = a_net->pub.native_ticker; char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, l_native_ticker); - dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_net->pub.name); + dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name); uint256_t l_value_transfer = {}, l_fee_transfer = {}; // how many coins to transfer // list of transaction with 'out' items to sell dap_chain_addr_t *l_owner_addr = (dap_chain_addr_t *)dap_chain_wallet_get_addr(a_wallet, a_net->pub.id); @@ -421,14 +421,14 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_chai bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr); if (l_net_fee_used) SUM_256_256(l_fee_total, l_net_fee, &l_fee_total); - dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_delegated_ticker, + dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_delegated_ticker, l_owner_addr, a_value, &l_value_transfer); if (!l_list_used_out) { log_it(L_WARNING, "Nothing to pay for delegate (not enough funds)"); DAP_DELETE(l_owner_addr); return NULL; } - dap_list_t *l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, + dap_list_t *l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, l_owner_addr, l_fee_total, &l_fee_transfer); if (!l_list_fee_out) { log_it(L_WARNING, "Nothing to pay for fee (not enough funds)"); @@ -530,9 +530,9 @@ static char *s_stake_tx_put(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *a_net) dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t *a_net, dap_hash_fast_t *a_stake_tx_hash, dap_cert_t *a_cert) { - dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_net->pub.name); + dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name); - dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_stake_tx_hash); + dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, a_stake_tx_hash); if (!l_cond_tx) { log_it(L_WARNING, "Requested conditional transaction not found"); return NULL; @@ -545,7 +545,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t return NULL; } dap_hash_fast_t l_spender_hash = { }; - if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, a_stake_tx_hash, l_prev_cond_idx, &l_spender_hash)) { + if (dap_ledger_tx_hash_is_used_out_item(l_ledger, a_stake_tx_hash, l_prev_cond_idx, &l_spender_hash)) { char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&l_spender_hash, l_hash_str, sizeof(l_hash_str)); log_it(L_WARNING, "Requested conditional transaction is already used out by %s", l_hash_str); @@ -553,7 +553,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t } char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, a_net->pub.native_ticker); - const char *l_tx_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, a_stake_tx_hash); + const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, a_stake_tx_hash); if (dap_strcmp(l_tx_ticker, l_delegated_ticker)) { log_it(L_WARNING, "Requested conditional transaction have another ticker (not %s)", l_delegated_ticker); return NULL; @@ -698,9 +698,9 @@ static char *s_stake_decree_put(dap_chain_datum_decree_t *a_decree, dap_chain_ne static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_hash_fast_t *a_tx_hash, uint256_t a_fee, dap_enc_key_t *a_key) { - dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_net->pub.name); + dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name); - dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_hash); + dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, a_tx_hash); if (!l_cond_tx) { log_it(L_WARNING, "Requested conditional transaction not found"); return NULL; @@ -713,7 +713,7 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h return NULL; } dap_hash_fast_t l_spender_hash = { }; - if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, a_tx_hash, l_prev_cond_idx, &l_spender_hash)) { + if (dap_ledger_tx_hash_is_used_out_item(l_ledger, a_tx_hash, l_prev_cond_idx, &l_spender_hash)) { char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&l_spender_hash, l_hash_str, sizeof(l_hash_str)); log_it(L_WARNING, "Requested conditional transaction is already used out by %s", l_hash_str); @@ -733,7 +733,7 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h return NULL; } const char *l_native_ticker = a_net->pub.native_ticker; - const char *l_delegated_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash); + const char *l_delegated_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash); uint256_t l_fee_transfer = {}; // how many coins to transfer // list of transaction with 'out' items to sell uint256_t l_net_fee, l_fee_total = a_fee; @@ -741,7 +741,7 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr); if (l_net_fee_used) SUM_256_256(l_fee_total, l_net_fee, &l_fee_total); - dap_list_t *l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, + dap_list_t *l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, &l_owner_addr, l_fee_total, &l_fee_transfer); if (!l_list_fee_out) { log_it(L_WARNING, "Nothing to pay for fee (not enough funds)"); @@ -802,10 +802,10 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h static dap_chain_datum_decree_t *s_stake_decree_invalidate(dap_chain_net_t *a_net, dap_hash_fast_t *a_stake_tx_hash, dap_cert_t *a_cert) { - dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_net->pub.name); + dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name); // add 'in' item to buy from conditional transaction - dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_stake_tx_hash); + dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, a_stake_tx_hash); if (!l_cond_tx) { log_it(L_WARNING, "Requested conditional transaction not found"); return NULL; @@ -1304,7 +1304,7 @@ static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_ &l_out_idx_tmp))) { dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_datum_hash); - if (!dap_chain_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_datum_hash, l_out_idx_tmp, NULL)) { + if (!dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_datum_hash, l_out_idx_tmp, NULL)) { dap_chain_net_srv_stake_item_t *l_stake = NULL; HASH_FIND(ht, s_srv_stake->tx_itemlist, &l_datum_hash, sizeof(dap_hash_fast_t), l_stake); if(!l_stake){ @@ -1335,8 +1335,8 @@ int dap_chain_net_srv_stake_check_validator(dap_chain_net_t * a_net, dap_hash_fa uint8_t l_test_data[1024] = {0}; dap_chain_node_client_t *l_node_client = NULL; dap_chain_node_info_t *l_remote_node_info = NULL; - dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_net->pub.name); - dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_hash); + dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name); + dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_ledger, a_tx_hash); dap_chain_node_addr_t *l_signer_node_addr = NULL; int l_overall_correct = false; @@ -1939,7 +1939,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) if (l_tx_hash_str) { l_final_tx_hash = DAP_NEW(dap_hash_fast_t); dap_chain_hash_fast_from_str(l_tx_hash_str, l_final_tx_hash); - if(!dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, l_final_tx_hash)) { + if(!dap_ledger_tx_find_by_hash(l_net->pub.ledger, l_final_tx_hash)) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is not found.", l_tx_hash_str); return -20; } @@ -2182,14 +2182,14 @@ void dap_chain_net_srv_stake_get_fee_validators_str(dap_chain_net_t *a_net, dap_ static void s_cache_data(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_addr_t *a_signing_addr) { - if (!dap_chain_ledger_cache_enabled(a_ledger)) + if (!dap_ledger_cache_enabled(a_ledger)) return; dap_chain_net_srv_stake_cache_data_t l_cache_data; dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_cache_data.tx_hash); char l_data_key[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&l_cache_data.tx_hash, l_data_key, sizeof(l_data_key)); l_cache_data.signing_addr = *a_signing_addr; - char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP); + char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP); if (dap_global_db_set(l_gdb_group, l_data_key, &l_cache_data, sizeof(l_cache_data), false, NULL, NULL)) log_it(L_WARNING, "Stake service cache mismatch"); } diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index 1afa7e9519..62c029e9cb 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -82,7 +82,7 @@ static bool s_debug_more = true; */ int dap_chain_net_srv_xchange_init() { - dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, s_xchange_verificator_callback, NULL); + dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, s_xchange_verificator_callback, NULL); dap_cli_server_cmd_add("srv_xchange", s_cli_srv_xchange, "eXchange service commands", "srv_xchange order create -net <net_name> -token_sell <token_ticker> -token_buy <token_ticker> -w <wallet_name>" @@ -171,7 +171,7 @@ static bool s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_ return false; if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash)) return false; - const char *l_sell_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_in_cond->header.tx_prev_hash); + const char *l_sell_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_in_cond->header.tx_prev_hash); if (!l_sell_ticker) return false; const char *l_buy_ticker = a_tx_out_cond->subtype.srv_xchange.buy_token; @@ -183,7 +183,7 @@ static bool s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_ dap_chain_addr_t l_service_fee_addr, *l_seller_addr = &a_tx_out_cond->subtype.srv_xchange.seller_addr; uint16_t l_service_fee_type; - dap_chain_net_t *l_net = dap_chain_net_by_name(a_ledger->net_name); + dap_chain_net_t *l_net = a_ledger->net; bool l_service_fee_used = s_srv_xchange_get_fee(l_net->pub.id, &l_service_fee_val, &l_service_fee_addr, &l_service_fee_type); const char *l_native_ticker = l_net->pub.native_ticker; const char *l_service_ticker = (l_service_fee_type == SERVICE_FEE_OWN_FIXED || l_service_fee_type == SERVICE_FEE_OWN_PERCENT) ? @@ -374,7 +374,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_request(dap_chain_net_srv_xchan if (l_single_channel) SUM_256_256(l_value_need, l_total_fee, &l_value_need); else { - l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, + l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, l_seller_addr, l_total_fee, &l_fee_transfer); if (!l_list_fee_out) { log_it(L_WARNING, "Not enough funds to pay fee"); @@ -382,7 +382,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_request(dap_chain_net_srv_xchan } } // list of transaction with 'out' items to sell - dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_sell, + dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_sell, l_seller_addr, l_value_need, &l_value_transfer); if(!l_list_used_out) { DAP_DELETE(l_seller_addr); @@ -533,7 +533,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha if (l_pay_with_native) SUM_256_256(l_value_need, l_total_fee, &l_value_need); else { - l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, + l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, l_buyer_addr, l_total_fee, &l_fee_transfer); if (!l_list_fee_out) { log_it(L_WARNING, "Not enough funds to pay fee"); @@ -541,7 +541,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha } } // list of transaction with 'out' items to sell - dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_buy, + dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_buy, l_buyer_addr, l_value_need, &l_value_transfer); if(!l_list_used_out) { DAP_DELETE(l_buyer_addr); @@ -582,7 +582,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha } } // add 'in' item to buy from conditional transaction - dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &a_price->tx_hash); + dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, &a_price->tx_hash); if (!l_cond_tx) { log_it(L_WARNING, "Requested conditional transaction not found"); return NULL; @@ -594,7 +594,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha log_it(L_WARNING, "Requested transaction has no conditional output"); return NULL; } - if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, &a_price->tx_hash, l_prev_cond_idx, NULL)) { + if (dap_ledger_tx_hash_is_used_out_item(l_ledger, &a_price->tx_hash, l_prev_cond_idx, NULL)) { log_it(L_WARNING, "Requested conditional transaction is already used out"); return NULL; } @@ -766,7 +766,7 @@ static bool s_xchange_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price, // create empty transaction dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); - dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_price->net->pub.name); + dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_price->net->pub.name); dap_chain_addr_t *l_seller_addr = (dap_chain_addr_t *)dap_chain_wallet_get_addr(a_wallet, a_price->net->pub.id); // create and add reciept @@ -780,18 +780,18 @@ static bool s_xchange_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price, DAP_DELETE(l_receipt); // add 'in' item to buy from conditional transaction - dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &a_price->tx_hash); + dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, &a_price->tx_hash); if (!l_cond_tx) { log_it(L_WARNING, "Requested conditional transaction not found"); dap_chain_datum_tx_delete(l_tx); return false; } - const char *l_tx_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &a_price->tx_hash); + const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &a_price->tx_hash); bool l_single_channel = !dap_strcmp(l_tx_ticker, l_native_ticker); int l_prev_cond_idx = 0; dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_cond_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_prev_cond_idx); - if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, &a_price->tx_hash, l_prev_cond_idx, NULL)) { + if (dap_ledger_tx_hash_is_used_out_item(l_ledger, &a_price->tx_hash, l_prev_cond_idx, NULL)) { log_it(L_WARNING, "Requested conditional transaction is already used out"); dap_chain_datum_tx_delete(l_tx); return false; @@ -811,7 +811,7 @@ static bool s_xchange_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price, uint256_t l_total_fee = {}; SUM_256_256(a_price->fee, l_net_fee, &l_total_fee); // list of transaction with 'out' items to get net fee - dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, + dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, l_seller_addr, l_total_fee, &l_transfer_fee); if(!l_list_used_out) { dap_chain_datum_tx_delete(l_tx); @@ -940,7 +940,7 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a dap_hash_fast_t l_tx_hash = {}; dap_hash_fast(a_order, dap_chain_datum_tx_get_size(a_order), &l_tx_hash); - const char *l_token_sell = dap_chain_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx_hash); + const char *l_token_sell = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx_hash); strcpy(l_price->token_sell, l_token_sell); @@ -948,7 +948,7 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a l_price->net = a_net; if (!IS_ZERO_256(l_price->datoshi_buy)) { l_price->rate = l_out_cond->subtype.srv_xchange.rate; - dap_hash_fast_t *l_final_hash = dap_chain_ledger_get_final_chain_tx_hash(a_net->pub.ledger, + dap_hash_fast_t *l_final_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_tx_hash); if (l_final_hash) { l_price->tx_hash = *l_final_hash; @@ -1015,7 +1015,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'price create' requires parameter -token_sell"); return -5; } - if (!dap_chain_ledger_token_ticker_check(l_net->pub.ledger, l_token_sell_str)) { + if (!dap_ledger_token_ticker_check(l_net->pub.ledger, l_token_sell_str)) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_sell_str); return -6; } @@ -1024,7 +1024,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'price create' requires parameter -token_buy"); return -5; } - if (!dap_chain_ledger_token_ticker_check(l_net->pub.ledger, l_token_buy_str)) { + if (!dap_ledger_token_ticker_check(l_net->pub.ledger, l_token_buy_str)) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_buy_str); return -6; } @@ -1287,7 +1287,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c dap_hash_fast_t l_tx_hash = {}; dap_chain_hash_fast_from_str(l_order_hash_str, &l_tx_hash); - dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash); + dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash); if (!l_cond_tx) { dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nSpecified order not found", l_sign_str); return -13; @@ -1341,14 +1341,14 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified order not found"); return -13; } - dap_hash_fast_t *l_final_hash = dap_chain_ledger_get_final_chain_tx_hash(l_net->pub.ledger, + dap_hash_fast_t *l_final_hash = dap_ledger_get_final_chain_tx_hash(l_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_order->tx_cond_hash); if (!l_final_hash) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified order have no active tx (copmleted)"); DAP_DELETE(l_order); return -18; } - dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, l_final_hash); + dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, l_final_hash); if (!l_tx) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Internal error"); DAP_DELETE(l_order); @@ -1441,7 +1441,7 @@ static int s_tx_check_for_open_close(dap_chain_net_t * a_net, dap_chain_datum_tx dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_out_cond_get(a_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_cond_idx); if (l_out_cond_item) { - if(dap_chain_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL)) + if(dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL)) return 2; // If its SRV_XCHANGE and spent its closed else return 1; // If its SRV_XCHANGE and not spent its open @@ -1467,7 +1467,7 @@ static void s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_ // dap_string_append_printf(l_reply_str, "Hash: %s\n", l_hash_str); // Get input token ticker - const char * l_tx_input_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash( + const char * l_tx_input_ticker = dap_ledger_tx_get_token_ticker_by_hash( a_net->pub.ledger, &l_tx_hash); // Find SRV_XCHANGE out_cond item @@ -1477,7 +1477,7 @@ static void s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_ bool l_is_cond_out = false; if ( l_out_cond_item && (l_out_cond_item->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE) ) { - bool l_is_closed = dap_chain_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL); + bool l_is_closed = dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL); uint256_t l_value_from = l_out_cond_item->header.value; uint256_t l_rate = l_out_cond_item->subtype.srv_xchange.rate; @@ -1543,7 +1543,7 @@ dap_chain_tx_out_cond_t *l_out_cond_item; for (l_tx_total = 0; - (l_datum_tx = dap_chain_ledger_tx_find_by_addr(a_net->pub.ledger, NULL, a_addr, &l_tx_first_hash)); + (l_datum_tx = dap_ledger_tx_find_by_addr(a_net->pub.ledger, NULL, a_addr, &l_tx_first_hash)); l_tx_total++) { /* Check time range (if need ) */ @@ -1575,7 +1575,7 @@ dap_chain_tx_out_cond_t *l_out_cond_item; if (a_opt_status) /* 1 - closed, 2 - open */ { - l_rc = dap_chain_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_hash, l_item_idx, NULL); + l_rc = dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_hash, l_item_idx, NULL); if ( a_opt_status ) { @@ -1590,7 +1590,7 @@ dap_chain_tx_out_cond_t *l_out_cond_item; dap_string_append_printf(l_reply_str, "Hash: %s\n", l_hash_str); - const char *l_tx_input_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_hash); + const char *l_tx_input_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_hash); uint256_t l_rate = l_out_cond_item->subtype.srv_xchange.rate; uint256_t l_tx_input_values = dap_chain_net_get_tx_total_value(a_net, l_datum_tx); @@ -1803,7 +1803,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply) // dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_str); dap_hash_fast_t l_tx_hash = {}; dap_chain_hash_fast_from_str(l_order_hash_str, &l_tx_hash); - dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash); + dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash); if (l_cond_tx) { dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_cond_tx, false); @@ -1937,7 +1937,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply) // dap_string_append_printf(l_reply_str, "Hash: %s\n", l_hash_str); // Get input token ticker - const char * l_tx_input_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash( + const char * l_tx_input_ticker = dap_ledger_tx_get_token_ticker_by_hash( l_net->pub.ledger, &l_tx_hash); // Find SRV_XCHANGE out_cond item @@ -1950,7 +1950,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply) char *l_rate_str = dap_chain_balance_to_coins(l_rate); char *l_value_from_str = dap_chain_balance_to_coins(l_value_from); - l_rc = dap_chain_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, &l_tx_hash, l_prev_cond_idx, NULL); + l_rc = dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, &l_tx_hash, l_prev_cond_idx, NULL); if ((l_opt_status == 1 && !l_rc) || /* Select close only */ (l_opt_status == 2 && l_rc)) /* Select open only */ @@ -2009,7 +2009,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply,"No argument '-token_from'"); return -5; } - dap_chain_datum_token_t * l_token_from_datum = dap_chain_ledger_token_ticker_check( l_net->pub.ledger, l_token_from_str); + dap_chain_datum_token_t * l_token_from_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_from_str); if(!l_token_from_datum){ dap_cli_server_cmd_set_reply_text(a_str_reply,"Can't find \"%s\" token in network \"%s\" for argument '-token_from' ", l_token_from_str, l_net->pub.name); return -6; @@ -2022,7 +2022,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply,"No argument '-token_to'"); return -5; } - dap_chain_datum_token_t * l_token_to_datum = dap_chain_ledger_token_ticker_check( l_net->pub.ledger, l_token_to_str); + dap_chain_datum_token_t * l_token_to_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_to_str); if(!l_token_to_datum){ dap_cli_server_cmd_set_reply_text(a_str_reply,"Can't find \"%s\" token in network \"%s\" for argument '-token2' ", l_token_to_str, l_net->pub.name); return -6; @@ -2053,13 +2053,13 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply) while(l_cur){ dap_chain_datum_tx_t * l_tx =(dap_chain_datum_tx_t *) l_cur->data; if(l_tx){ + // TODO find another way to get current tx hash dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx); - int l_cond_idx = 0; dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, - &l_cond_idx); + &l_cond_idx); if (l_out_cond_item && - dap_chain_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, l_tx_hash, l_cond_idx, NULL)) { + dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, l_tx_hash, l_cond_idx, NULL)) { uint256_t l_value_sell = l_out_cond_item->header.value; l_rate = l_out_cond_item->subtype.srv_xchange.rate; if (!IS_ZERO_256(l_value_sell)) { @@ -2069,8 +2069,8 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply) }else{ log_it(L_ERROR, "Sell value is 0 in avarage price calculation (summing)"); } - DAP_DEL_Z(l_tx_hash); } + DAP_DEL_Z(l_tx_hash); } l_cur = dap_list_next(l_cur); } @@ -2101,7 +2101,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply) dap_hash_fast_t * l_tx_hash = &l_cur->tx_hash; // Get input token ticker - const char * l_tx_input_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash( + const char * l_tx_input_ticker = dap_ledger_tx_get_token_ticker_by_hash( l_net->pub.ledger, l_tx_hash); // Check if output is spent @@ -2173,7 +2173,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply) dap_string_t *l_reply_str = dap_string_new(""); char ** l_tickers = NULL; size_t l_tickers_count = 0; - dap_chain_ledger_addr_get_token_ticker_all( l_net->pub.ledger,NULL,&l_tickers,&l_tickers_count); + dap_ledger_addr_get_token_ticker_all( l_net->pub.ledger,NULL,&l_tickers,&l_tickers_count); size_t l_pairs_count = 0; if(l_tickers){ diff --git a/modules/test/CMakeLists.txt b/modules/test/CMakeLists.txt deleted file mode 100644 index 0f12e79311..0000000000 --- a/modules/test/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -if(TARGET dap_test) - return() # The project has already been built. -endif() -project(dap_test) - -add_library(${PROJECT_NAME} STATIC dap_test.h dap_test.c dap_test_generator.h dap_test_generator.c) - -target_include_directories(${PROJECT_NAME} INTERFACE .) diff --git a/modules/test/dap_test.c b/modules/test/dap_test.c deleted file mode 100644 index 55517435e1..0000000000 --- a/modules/test/dap_test.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "dap_test.h" - -#include <sys/time.h> - -/* - How to use benchmark_xxx() functions: - - void mytest_func() - { - // doing something ... - } - - // Repeat mytest_func() 5 time - int dt = benchmark_test_time(mytest_func, 5); - // Display result, sample 'Encode and decode PASS. (4 msec.)' - benchmark_mgs_time("Encode and decode", dt); - - // Repeat mytest_func() within 2 second - float rate = benchmark_test_rate(mytest_func, 2); - // Display result, sample 'Encode and decode PASS. (703 times/sec.)' - benchmark_mgs_rate("Encode and decode", rate); - - */ - -#define dap_pass_msg_benchmark(testname, benchmark_text) \ - printf("\t%s%s PASS. %s%s\n", TEXT_COLOR_GRN, testname, benchmark_text, TEXT_COLOR_RESET); \ - fflush(stdout); \ - -/** - * Display time in the format 'x.xx sec.' or 'xx msec.' - */ -void benchmark_mgs_time(const char *test_name, int dt) -{ - char buf[120]; - if(abs(dt) >= 1000) { - snprintf(buf, 120, "(%.3lf sec.)", dt * 1. / 1000); - } - else { - - snprintf(buf, 120, "(%d msec.)", dt); - } - dap_pass_msg_benchmark(test_name, buf); -} - -/** - * Display rate in the format 'xx times/sec.' - */ -void benchmark_mgs_rate(const char *test_name, float rate) -{ - char buf[120]; - if(rate > 100) { - snprintf(buf, 120, "(%.0lf times/sec.)", rate); - } - else if(rate > 10) { - snprintf(buf, 120, "%.1lf times/sec.", rate); - } - else { - snprintf(buf, 120, "%.2lf times/sec.", rate); - } - dap_pass_msg_benchmark(test_name, buf); -} - -/** - * @return current time in milliseconds - */ -int get_cur_time_msec(void) -{ - struct timespec time; - clock_gettime(CLOCK_MONOTONIC, &time); - int msec = time.tv_sec * 1000 + (time.tv_nsec + 500000) / 1000000; - return msec; -} - -/** - * Calculate the runtime of a function that repeat several times - * @func_name function for repeats - * @repeat how many times repeats - * @return time in milliseconds - */ -int benchmark_test_time(void (*func_name)(void), int repeat) -{ - int t1 = get_cur_time_msec(); - for(int i = 0; i < repeat; i++) - func_name(); - int t2 = get_cur_time_msec(); - return t2 - t1; -} - -/** - * Calculate the rate of a function that repeat at a minimum specified number of seconds - * @func_name function for repeats - * @repeat how many times repeats - * @return function rate, i.e. count per second - */ -float benchmark_test_rate(void (*func_name)(void), float sec) -{ - if(sec < 0.1f) { - dap_test_msg("undefined times/sec."); - return 0; - } - int t1 = get_cur_time_msec(); - int repeat = 0, dt; - do { - func_name(); - dt = (get_cur_time_msec() - t1); - repeat++; - } - while(dt < sec * 1000); - float rate = repeat * 1000.f / dt; - return rate; -} - diff --git a/modules/test/dap_test.h b/modules/test/dap_test.h deleted file mode 100644 index 4a6445d82f..0000000000 --- a/modules/test/dap_test.h +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once -#include <assert.h> -#include <stdbool.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <time.h> - -#define TEXT_COLOR_RED "\x1B[31m" -#define TEXT_COLOR_GRN "\x1B[32m" -#define TEXT_COLOR_YEL "\x1B[33m" -#define TEXT_COLOR_BLU "\x1B[34m" -#define TEXT_COLOR_MAG "\x1B[35m" -#define TEXT_COLOR_CYN "\x1B[36m" -#define TEXT_COLOR_WHT "\x1B[37m" -#define TEXT_COLOR_RESET "\x1B[0m" - -/* Can be used like debug info during write test*/ -/** - * @brief Can be used like debug info during write test - */ -#define dap_test_msg(...) { \ - printf("\t%s", TEXT_COLOR_WHT); \ - printf(__VA_ARGS__); \ - printf("%s\n", TEXT_COLOR_RESET); \ - fflush(stdout); } - -#define dap_fail(msg) {\ - printf("\t%s%s!%s\n", TEXT_COLOR_RED, msg, TEXT_COLOR_RESET); \ - abort();} - -/* PIF - print if failed. For checking value in loop, for don't repeat output */ -/** - * @brief PIF - print if failed. For checking value in loop, for don't repeat output - */ -#define dap_assert_PIF(expr, msg) { \ - if(expr) {} \ - else { \ - printf("\t%s%s FAILED!%s\n", TEXT_COLOR_RED, msg, TEXT_COLOR_RESET); \ - abort(); } } - -/** - * @brief -*/ -#define dap_assert(expr, testname) { \ - if(expr) { \ - printf("\t%s%s PASS.%s\n", TEXT_COLOR_GRN, testname, TEXT_COLOR_RESET); \ - fflush(stdout); \ - } else { \ - printf("\t%s%s FAILED!%s\n", TEXT_COLOR_RED, testname, TEXT_COLOR_RESET); \ - abort(); } } \ - -/** - * @brief Display the name test -*/ -#define dap_pass_msg(testname) { \ - printf("\t%s%s PASS.%s\n", TEXT_COLOR_GRN, testname, TEXT_COLOR_RESET); \ - fflush(stdout); } \ - -/** - * @brief Display the name of the test module -*/ -#define dap_print_module_name(module_name) { \ - printf("%s%s passing the tests... %s\n", TEXT_COLOR_CYN, module_name, TEXT_COLOR_RESET); \ - fflush(stdout); } - -#define dap_str_equals(str1, str2) strcmp(str1, str2) == 0 -#define dap_strn_equals(str1, str2, count) strncmp(str1, str2, count) == 0 -int get_cur_time_msec(void); - -/* - How to use benchmark_xxx() functions: - - void mytest_func() - { - // doing something ... - } - - // Repeat mytest_func() 5 time - int dt = benchmark_test_time(mytest_func, 5); - // Display result, sample 'Encode and decode PASS. (4 msec.)' - benchmark_mgs_time("Encode and decode", dt); - - // Repeat mytest_func() within 2 second - float rate = benchmark_test_rate(mytest_func, 2); - // Display result, sample 'Encode and decode PASS. (703 times/sec.)' - benchmark_mgs_rate("Encode and decode", rate); - - */ - -/** - * Display time in the format 'x.xx sec.' or 'xx msec.' - */ -void benchmark_mgs_time(const char *text, int dt); - -/** - * Display rate in the format 'xx times/sec.' - */ -void benchmark_mgs_rate(const char *test_name, float rate); -/** - * Calculate the runtime of a function that repeat several times - * @func_name function for repeats - * @repeat how many times repeats - * @return time in milliseconds - */ -int benchmark_test_time(void (*func_name)(void), int repeat); -/** - * Calculate the rate of a function that repeat at a minimum specified number of seconds - * @func_name function for repeats - * @repeat how many times repeats - * @return function rate, i.e. count per second - */ -float benchmark_test_rate(void (*func_name)(void), float sec); diff --git a/modules/test/dap_test_generator.c b/modules/test/dap_test_generator.c deleted file mode 100644 index 6a540f6928..0000000000 --- a/modules/test/dap_test_generator.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "dap_test_generator.h" - -#define BYTE_SIZE 255 - -/** - * @brief The function fills an array with random numbers - * @param[out] array Takes a pointer to an array - * @param[in] size Size of the array passed in the array parameter - * - * The function fills an array with random integer non-negative values -*/ -void generate_random_byte_array(uint8_t* array, const size_t size) { - srand((uint32_t)time(NULL)); - for(size_t i = 0; i < size; i++) { - array[i] = (uint8_t)rand() % BYTE_SIZE; - } - - // Last byte not should be 0 - if (array[size - 1] == 0) - array[size - 1] = 1; -} diff --git a/modules/test/dap_test_generator.h b/modules/test/dap_test_generator.h deleted file mode 100644 index 4c74064744..0000000000 --- a/modules/test/dap_test_generator.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include <stdint.h> -#include <stdlib.h> -#include <time.h> - -void generate_random_byte_array(uint8_t* array, const size_t size); - diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c index 20420c7471..2b64edb253 100644 --- a/modules/type/blocks/dap_chain_block.c +++ b/modules/type/blocks/dap_chain_block.c @@ -91,10 +91,11 @@ dap_chain_block_t *dap_chain_block_new(dap_chain_hash_fast_t *a_prev_block, size * @param a_block_size * @return */ -size_t s_block_get_datum_offset (dap_chain_block_t * a_block, size_t a_block_size) +size_t s_block_get_datum_offset(const dap_chain_block_t *a_block, size_t a_block_size) { if( a_block_size < sizeof(a_block->hdr) ){ log_it(L_ERROR, "Can't get datum offset: corrupted block size %zu / header size %zu", a_block_size, sizeof (a_block->hdr)); + return 0; } size_t l_offset = 0; dap_chain_block_meta_t * l_meta=NULL; @@ -278,7 +279,7 @@ size_t dap_chain_block_datum_del_by_hash(dap_chain_block_t ** a_block_ptr, size_ * @param a_block_size * @return */ -size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_block_size) +size_t dap_chain_block_get_sign_offset(const dap_chain_block_t *a_block, size_t a_block_size) { assert(a_block); assert(a_block_size); @@ -287,7 +288,7 @@ size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_bloc return 0; } - size_t l_offset = s_block_get_datum_offset(a_block,a_block_size); + 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); // Pass all datums to the end for(size_t n=0; n<a_block->hdr.datum_count && l_offset< (a_block_size-sizeof (a_block->hdr)) ; n++){ @@ -296,12 +297,12 @@ size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_bloc // Check if size 0 if(! l_datum_size){ log_it(L_ERROR,"Datum size is 0, smth is corrupted in block"); - return a_block_size; + return 0; } // Check if size of of block size if ( (l_datum_size+l_offset) > (a_block_size-sizeof (a_block->hdr)) ){ log_it(L_ERROR,"Datum size is too big %zu thats with offset %zu is bigger than block size %zu", l_datum_size, l_offset, a_block_size); - return a_block_size; + return 0; } l_offset += l_datum_size; // Updae current datum pointer, if it was deleted - we also need to update it after realloc @@ -309,7 +310,7 @@ size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_bloc } if (l_offset> (a_block_size-sizeof (a_block->hdr))){ log_it(L_ERROR,"Offset %zd with block header %zu is bigger than block size %zu", l_offset,sizeof (a_block->hdr),a_block_size); - return a_block_size; + return 0; } return l_offset; @@ -344,14 +345,13 @@ size_t dap_chain_block_sign_add(dap_chain_block_t **a_block_ptr, size_t a_block_ * @param a_sign_num * @return */ -dap_sign_t *dap_chain_block_sign_get ( dap_chain_block_t * a_block, size_t a_block_size, uint16_t a_sign_num ) +dap_sign_t *dap_chain_block_sign_get(const dap_chain_block_t *a_block, size_t a_block_size, uint16_t a_sign_num) { assert(a_block); size_t l_offset = dap_chain_block_get_sign_offset(a_block, a_block_size); uint16_t l_sign_cur = 0; dap_sign_t *l_sign = (dap_sign_t *)(a_block->meta_n_datum_n_sign + l_offset); while (l_sign_cur < a_sign_num) { - size_t l_sign_size = dap_sign_get_size(l_sign); if (!l_sign_size){ log_it(L_ERROR, "Empty sign #%u", l_sign_cur ); @@ -368,7 +368,7 @@ dap_sign_t *dap_chain_block_sign_get ( dap_chain_block_t * a_block, size_t a_blo return l_sign_cur == a_sign_num ? l_sign : NULL; } -size_t dap_chain_block_get_signs_count(dap_chain_block_t * a_block, size_t a_block_size) +size_t dap_chain_block_get_signs_count(const dap_chain_block_t * a_block, size_t a_block_size) { assert(a_block); assert(a_block_size); @@ -390,6 +390,25 @@ size_t dap_chain_block_get_signs_count(dap_chain_block_t * a_block, size_t a_blo return l_sign_count; } +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); + return false; + } + if (dap_pkey_match_sign(a_sign_pkey, l_sign)) + return true; + l_offset += l_sign_size; + } + return false; +} + /** * @brief dap_chain_block_get_datums * @param a_block @@ -397,7 +416,7 @@ size_t dap_chain_block_get_signs_count(dap_chain_block_t * a_block, size_t a_blo * @param a_datums_count * @return */ -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_datum_t** dap_chain_block_get_datums(const dap_chain_block_t *a_block, size_t a_block_size, size_t * a_datums_count ) { assert(a_block); assert(a_block_size); @@ -448,13 +467,14 @@ dap_chain_datum_t** dap_chain_block_get_datums(dap_chain_block_t * a_block, size * @param a_meta_count * @return */ -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 ) +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 ) { + 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; } - if (a_meta_count) - *a_meta_count = 0; if (a_block->hdr.meta_count == 0) // no meta - nothing to return return NULL; size_t l_offset = 0; @@ -482,6 +502,37 @@ dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, s return l_ret; } +dap_hash_fast_t *dap_chain_block_get_prev_hash(const dap_chain_block_t *a_block, size_t a_block_size) +{ + 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; + } + if (a_block->hdr.meta_count == 0) // no meta - nothing to return + return NULL; + + dap_chain_block_meta_t *l_meta = 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 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; + } + } + return NULL; +} + /** * @brief dap_chain_block_meta_extract_generals * @param a_meta diff --git a/modules/type/blocks/dap_chain_block_cache.c b/modules/type/blocks/dap_chain_block_cache.c index 90a0d2467f..c5994830db 100644 --- a/modules/type/blocks/dap_chain_block_cache.c +++ b/modules/type/blocks/dap_chain_block_cache.c @@ -54,8 +54,7 @@ void dap_chain_block_cache_deinit() * @return */ -dap_chain_block_cache_t *dap_chain_block_cache_new(dap_chain_cs_blocks_t *a_blocks, 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) { if (! a_block) return NULL; @@ -67,7 +66,6 @@ dap_chain_block_cache_t *dap_chain_block_cache_new(dap_chain_cs_blocks_t *a_bloc } l_block_cache->block = a_block; l_block_cache->block_size= a_block_size; - l_block_cache->_inheritor = a_blocks; 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)) { @@ -177,10 +175,10 @@ dap_list_t * dap_chain_block_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledg //Check whether used 'out' items dap_hash_fast_t *l_tx_hash = a_block_cache->datum_hash + i; - if (!dap_chain_ledger_tx_hash_is_used_out_item (a_ledger, l_tx_hash, l_out_idx_tmp, NULL)) { + if (!dap_ledger_tx_hash_is_used_out_item (a_ledger, l_tx_hash, l_out_idx_tmp, NULL)) { dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t); if (!l_item) { - log_it(L_CRITICAL, "Memory allocation error"); + log_it(L_CRITICAL, "Memory allocation error"); if (l_list_used_out) dap_list_free_full(l_list_used_out, NULL); return NULL; diff --git a/modules/type/blocks/dap_chain_block_chunk.c b/modules/type/blocks/dap_chain_block_chunk.c index fd5578c968..0e9d2aa3cd 100644 --- a/modules/type/blocks/dap_chain_block_chunk.c +++ b/modules/type/blocks/dap_chain_block_chunk.c @@ -49,8 +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(a_blocks, &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); 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 1dc1d60663..88cb1a7ad1 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -98,8 +98,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); static dap_chain_atom_iter_t *s_callback_atom_iter_create(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, bool a_with_treshold); -static dap_chain_atom_iter_t* s_callback_atom_iter_create_from(dap_chain_t * , - dap_chain_atom_ptr_t , size_t); +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); 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_t *s_callback_datum_find_by_hash(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_datum_hash, @@ -109,6 +108,7 @@ static dap_chain_atom_ptr_t s_callback_block_find_by_tx_hash(dap_chain_t * a_cha 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); static dap_time_t s_chain_callback_atom_get_timestamp(dap_chain_atom_ptr_t a_atom) { return ((dap_chain_block_t *)a_atom)->hdr.ts_created; } +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); // 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 @@ -117,7 +117,7 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_links( dap_chain_atom_iter static dap_chain_atom_ptr_t *s_callback_atom_iter_get_lasts( dap_chain_atom_iter_t * a_atom_iter ,size_t *a_links_size, size_t ** a_lasts_size_ptr ); // Get list of linked blocks //Get list of hashes -static dap_list_t *s_block_parse_str_list(const char * a_hash_str,size_t * a_hash_size, dap_chain_t * a_chain, dap_cert_t * a_cert); +static dap_list_t *s_block_parse_str_list(char *a_hash_str, size_t * a_hash_size, dap_chain_t * a_chain); // Delete iterator static void s_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter ); // Get the fisrt block @@ -177,11 +177,24 @@ int dap_chain_cs_blocks_init() "block -net <net_name> -chain <chain_name> list [-from_hash <block_hash>] [-to_hash <block_hash>]" "[-from_dt <in YYMMDD>] [-to_dt <in YYMMDD>] [-cert <priv_cert_name> -unspent]\n" "\t\t List blocks\n\n" + "Commission collect:\n" "block -net <net_name> -chain <chain_name> fee collect\n" "-cert <priv_cert_name> -addr <addr> -hashes <hashes list> -fee <value>\n" "\t\t Take the whole commission\n\n" + "Reward for block signs:\n" + "block -net <net_name> -chain <chain_name> reward set\n" + "-cert <poa_cert_name> -value <value>\n" + "\t\t Set base reward for sign for one block at one minute\n\n" + + "block -net <net_name> -chain <chain_name> reward show\n" + "-cert <poa_cert_name> -value <value>\n" + "\t\t Show base reward for sign for one block at one minute\n\n" + + "block -net <net_name> -chain <chain_name> reward collect\n" + "-cert <priv_cert_name> -addr <addr> -hashes <hashes list> -fee <value>\n" + "\t\t Take reward\n\n" ); if( dap_chain_block_cache_init() ) { log_it(L_WARNING, "Can't init blocks cache"); @@ -238,6 +251,7 @@ static int s_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_c a_chain->callback_datum_find_by_hash = s_callback_datum_find_by_hash; a_chain->callback_block_find_by_tx_hash = s_callback_block_find_by_tx_hash; + a_chain->callback_calc_reward = s_callback_calc_reward; a_chain->callback_add_datums = s_callback_add_datums; a_chain->callback_purge = s_callback_cs_blocks_purge; @@ -295,12 +309,12 @@ static int s_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_c } /** - * @brief dap_chain_block_cs_cache_get_by_hash + * @brief dap_chain_block_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 * dap_chain_block_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); @@ -309,6 +323,70 @@ dap_chain_block_cache_t * dap_chain_block_cs_cache_get_by_hash(dap_chain_cs_bloc return l_ret; } +static char *s_blocks_decree_set_reward(dap_chain_net_t *a_net, dap_chain_t *a_chain, uint256_t a_value, dap_cert_t *a_cert) +{ + dap_return_val_if_fail(a_net && a_cert && a_cert->enc_key && + a_cert->enc_key->priv_key_data && a_cert->enc_key->priv_key_data_size, NULL); + dap_chain_t *l_chain_anchor = a_chain ? a_chain : dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR); + if (!l_chain_anchor) { + log_it(L_ERROR, "Can't find chain with anchor support"); + return NULL; + } + dap_chain_t *l_chain_decree = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_DECREE); + if (!l_chain_decree) { + log_it(L_ERROR, "Can't find chain with decree support"); + return NULL; + } + // Create decree + size_t l_tsd_total_size = sizeof(dap_tsd_t) + sizeof(uint256_t); + size_t l_decree_size = sizeof(dap_chain_datum_decree_t) + l_tsd_total_size; + dap_chain_datum_decree_t *l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, l_decree_size); + if (!l_decree) { + log_it(L_CRITICAL, "Memory allocation error"); + return NULL; + } + // Fill the header + l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION; + l_decree->header.ts_created = dap_time_now(); + l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON; + l_decree->header.common_decree_params.net_id = a_net->pub.id; + l_decree->header.common_decree_params.chain_id = l_chain_anchor->id; + l_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(a_net); + l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD; + l_decree->header.data_size = l_tsd_total_size; + // Fill a TSD section + dap_tsd_t *l_tsd = (dap_tsd_t *)l_decree->data_n_signs; + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE; + l_tsd->size = sizeof(uint256_t); + *(uint256_t*)(l_tsd->data) = a_value; + // Sign it + dap_sign_t *l_sign = dap_cert_sign(a_cert, l_decree, l_decree_size, 0); + if (!l_sign) { + log_it(L_ERROR, "Decree signing failed"); + DAP_DELETE(l_decree); + return NULL; + } + log_it(L_NOTICE, "<-- Signed with '%s'", a_cert->name); + size_t l_sign_size = dap_sign_get_size(l_sign); + l_decree_size += l_sign_size; + l_decree->header.signs_size = l_sign_size; + void *l_decree_rl = DAP_REALLOC(l_decree, l_decree_size); + if (!l_decree_rl) { + log_it(L_CRITICAL, "Memory reallocation error"); + DAP_DELETE(l_decree); + return NULL; + } else + l_decree = l_decree_rl; + memcpy(l_decree->data_n_signs + l_tsd_total_size, l_sign, l_sign_size); + DAP_DELETE(l_sign); + + dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_DECREE, l_decree, l_decree_size); + // Processing will be made according to autoprocess policy + char *l_ret = dap_chain_mempool_datum_add(l_datum, l_chain_decree, "hex"); + DAP_DELETE(l_datum); + return l_ret; +} + /** * @brief s_cli_parse_cmd_hash * @param a_argv @@ -384,7 +462,8 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) SUBCMD_DUMP, SUBCMD_LIST, SUBCMD_FEE, - SUBCMD_DROP + SUBCMD_DROP, + SUBCMD_REWARD } l_subcmd={0}; const char* l_subcmd_strs[]={ @@ -397,6 +476,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) [SUBCMD_LIST]="list", [SUBCMD_FEE]="fee", [SUBCMD_DROP]="drop", + [SUBCMD_REWARD] = "reward", [SUBCMD_UNDEFINED]=NULL }; const size_t l_subcmd_str_count=sizeof(l_subcmd_strs)/sizeof(*l_subcmd_strs); @@ -437,7 +517,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) l_subcmd_str_arg = l_subcmd_str_args[i]; } } - int ret=-1000; + int ret = 0; // Do subcommand action switch ( l_subcmd ){ // Flush memory for the new block @@ -491,11 +571,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Error! Datum %s doesn't pass verifications, examine node log files", l_subcmd_str_arg); ret = -9; - } else { + } else log_it(L_INFO, "Pass datum %s from mempool to block in the new forming round ", l_subcmd_str_arg); - ret = 0; - } if (l_err) break; } @@ -518,7 +596,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_hash_fast_from_str( 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_cs_cache_get_by_hash(l_blocks, &l_block_hash); + dap_chain_block_cache_t *l_block_cache = dap_chain_block_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]; @@ -598,7 +676,6 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) } dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str); dap_string_free(l_str_tmp, true); - ret=0; } }else { dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find block %s ", l_subcmd_str_arg); @@ -701,7 +778,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) int l_out_idx_tmp = 0; if (NULL == dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE, &l_out_idx_tmp)) continue; - if (!dap_chain_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, l_block_cache->datum_hash + i, l_out_idx_tmp, NULL)) { + if (!dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, l_block_cache->datum_hash + i, l_out_idx_tmp, NULL)) { fl_found = true; break; } @@ -743,8 +820,10 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) dap_string_free(l_str_tmp, true); }break; - case SUBCMD_FEE:{ - const char * str_tmp = NULL; + + case SUBCMD_FEE: + case SUBCMD_REWARD: { + const char * l_fee_value_str = NULL; const char * l_cert_name = NULL; const char * l_addr_str = NULL; const char * l_hash_out_type = NULL; @@ -755,12 +834,58 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) dap_list_t *l_block_list = NULL; dap_chain_addr_t *l_addr = NULL; - //arg_index++; + if (l_subcmd == SUBCMD_FEE) { + if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "collect") >= 0) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee' requires subcommand 'collect'"); + return -14; + } + } else { // l_sumcmd == SUBCMD_REWARD + if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "set") >= 0) { + const char *l_value_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-poa_cert", &l_cert_name); + if(!l_cert_name) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block reward set' requires parameter '-poa_cert'"); + return -17; + } + dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name); + if (!l_cert) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name); + return -18; + } + if (!l_cert->enc_key || !l_cert->enc_key->priv_key_data || !l_cert->enc_key->priv_key_data_size) { + dap_cli_server_cmd_set_reply_text(a_str_reply, + "Certificate \"%s\" doesn't contains private key", l_cert_name); + return -19; + } - if(!dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "collect", NULL)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee' requires parameter 'collect'"); - return -14; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-value", &l_value_str); + uint256_t l_value = dap_chain_balance_scan(l_value_str); + if (!l_value_str || IS_ZERO_256(l_value)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, + "Command 'block reward set' requires parameter '-value' to be valid 256-bit unsigned integer"); + return -20; + } + char *l_decree_hash_str = s_blocks_decree_set_reward(l_net, l_chain, l_value, l_cert); + if (l_decree_hash_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Decree with hash %s created to set basic block sign reward", l_decree_hash_str); + DAP_DELETE(l_decree_hash_str); + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Basic block sign reward setting failed. Examine log file for details"); + return -21; + } + 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); + 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'"); + return -14; + } } + + // Fee or reward collect handler dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); if(!l_hash_out_type) l_hash_out_type = "hex"; @@ -774,124 +899,109 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) // The address of the wallet to which the commission is received dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_str); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-hashes", &l_hash_str); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &str_tmp); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &l_fee_value_str); - if(!l_addr_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-addr'"); + if (!l_addr_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block %s collect' requires parameter '-addr'", l_subcmd_str); return -16; } l_addr = dap_chain_addr_from_str(l_addr_str); - if(!l_cert_name) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-cert'"); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block %s collect' requires parameter '-cert'", l_subcmd_str); return -17; } - dap_cert_t * l_cert = dap_cert_find_by_name( l_cert_name ); - - if( l_cert == NULL ){ - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Can't find \"%s\" certificate", l_cert_name ); + dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name); + if (!l_cert) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name); return -18; } - - l_fee_value = dap_chain_balance_scan(str_tmp); - if(!str_tmp||IS_ZERO_256(l_fee_value)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-fee' to be valid uint256"); + if (!l_cert->enc_key || !l_cert->enc_key->priv_key_data || !l_cert->enc_key->priv_key_data_size) { + dap_cli_server_cmd_set_reply_text(a_str_reply, + "Certificate \"%s\" doesn't contains private key", l_cert_name); return -19; } - if( l_cert->enc_key == NULL ){ + l_fee_value = dap_chain_balance_scan(l_fee_value_str); + if (!l_fee_value_str || IS_ZERO_256(l_fee_value)) { dap_cli_server_cmd_set_reply_text(a_str_reply, - "Corrupted certificate \"%s\" without keys certificate", l_cert_name ); + "Command 'block %s collect' requires parameter '-fee' to be valid uint256", l_subcmd_str); return -20; } - if(!l_hash_str){ + if (!l_hash_str) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-hashes'"); return -21; } - l_block_list = s_block_parse_str_list(l_hash_str, &l_hashes_count,l_chain,l_cert); - - if(!l_hashes_count){ + // NOTE: This call will modify source string + l_block_list = s_block_parse_str_list((char *)l_hash_str, &l_hashes_count, l_chain); + if (!l_block_list || !l_hashes_count) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Block fee collection requires at least one hash to create a transaction"); return -22; } - char * l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_cert->enc_key,l_addr,l_block_list,l_fee_value,l_hash_out_type); + char *l_hash_tx = NULL; + if (l_subcmd == SUBCMD_FEE) + l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_blocks, l_cert->enc_key, l_addr, l_block_list, l_fee_value, l_hash_out_type); + else + l_hash_tx = dap_chain_mempool_tx_reward_create(l_blocks, l_cert->enc_key, l_addr, l_block_list, l_fee_value, l_hash_out_type); if (l_hash_tx) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Fee collect TX created succefully, hash=%s\n", l_hash_tx); - ret = 0; + dap_cli_server_cmd_set_reply_text(a_str_reply, "TX for %s collection created succefully, hash=%s\n", l_subcmd_str, l_hash_tx); + DAP_DELETE(l_hash_tx); + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create %s collect TX\n", l_subcmd_str); + ret = -24; } - else - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create fee collect TX\n"); - ret = -24; - - DAP_DELETE(l_hash_tx); - dap_list_free(l_block_list); + dap_list_free_full(l_block_list, NULL); }break; + + default: case SUBCMD_UNDEFINED: { dap_cli_server_cmd_set_reply_text(a_str_reply, "Undefined block subcommand \"%s\" ", l_subcmd_str); ret=-11; - } + } break; } return ret; } -static dap_list_t * s_block_parse_str_list(const char * a_hash_str,size_t * a_hash_size, dap_chain_t * a_chain, dap_cert_t *a_cert) +static dap_list_t *s_block_parse_str_list(char *a_hash_str, size_t *a_hash_size, dap_chain_t *a_chain) { dap_list_t *l_block_list = NULL; - char * l_hashes_tmp_ptrs = NULL; - char * l_hashes_str_dup = dap_strdup(a_hash_str); - char *l_hashes_str = strtok_r(l_hashes_str_dup, ",", &l_hashes_tmp_ptrs); - dap_chain_hash_fast_t l_hash_block; - dap_chain_block_t *l_block; - dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); - - dap_pkey_t *l_pub_key = NULL; - if(a_cert) { - l_pub_key = dap_pkey_from_enc_key(a_cert->enc_key); - } - // First we just calc items - while(l_hashes_str) { - l_hashes_str = strtok_r(NULL, ",", &l_hashes_tmp_ptrs); - (*a_hash_size)++; - } - strcpy(l_hashes_str_dup, a_hash_str); - l_hashes_str = strtok_r(l_hashes_str_dup, ",", &l_hashes_tmp_ptrs); - + dap_chain_hash_fast_t l_hash_block; + char *l_hashes_tmp_ptrs = NULL; + char *l_hashes_str = strtok_r(a_hash_str, ",", &l_hashes_tmp_ptrs); size_t l_hashes_pos = 0; - while(l_hashes_str) { + while (l_hashes_str) { l_hashes_str = dap_strstrip(l_hashes_str); - if(dap_chain_hash_fast_from_hex_str(l_hashes_str, &l_hash_block)!=0) { - log_it(L_WARNING,"Can't load hash %s",l_hashes_str); - *a_hash_size = 0; - DAP_DELETE(l_hashes_str_dup); - return NULL; + if (!l_hashes_str || dap_chain_hash_fast_from_str(l_hashes_str, &l_hash_block)) { + log_it(L_WARNING, "Can't convert string %s to hash", l_hashes_str ? l_hashes_str : "(null)"); + l_hashes_pos = 0; + break; } - size_t l_block_size = 0; - l_block = (dap_chain_block_t*) dap_chain_get_atom_by_hash( a_chain, &l_hash_block, &l_block_size); - if(!l_block) - { - log_it(L_WARNING,"There aren't any block by this hash"); - *a_hash_size = 0; - DAP_DELETE(l_hashes_str_dup); - return NULL; + dap_chain_block_t *l_block = (dap_chain_block_t *)dap_chain_get_atom_by_hash(a_chain, &l_hash_block, NULL); + if (!l_block) { + log_it(L_WARNING, "There is no block pointed by hash %s", l_hashes_str); + l_hashes_pos = 0; + break; } - dap_chain_block_cache_t *l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_hash_block); - //verification of signatures of all blocks - dap_sign_t * l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0); - if(dap_pkey_compare_with_sign(l_pub_key, l_sign)) - l_block_list = dap_list_append(l_block_list, l_block_cache); - else - log_it(L_WARNING,"Block %s signature does not match certificate key", l_block_cache->block_hash_str); - + dap_hash_fast_t *l_block_hash_new = DAP_DUP(&l_hash_block); + if (!l_block_hash_new) { + log_it(L_CRITICAL, "Memory allocaton error"); + l_hashes_pos = 0; + break; + } + l_block_list = dap_list_append(l_block_list, l_block_hash_new); l_hashes_str = strtok_r(NULL, ",", &l_hashes_tmp_ptrs); l_hashes_pos++; } - DAP_DELETE(l_hashes_str_dup); + if (a_hash_size) + *a_hash_size = l_hashes_pos; + if (!l_hashes_pos && l_block_list) { + dap_list_free_full(l_block_list, NULL); + l_block_list = NULL; + } return l_block_list; } @@ -1023,7 +1133,7 @@ static void s_bft_consensus_setup(dap_chain_cs_blocks_t * a_blocks) // Compare all chunks with chain's tail for (dap_chain_block_chunk_t *l_chunk = PVT(a_blocks)->chunks->chunks_last ; l_chunk; l_chunk=l_chunk->prev ){ size_t l_chunk_length = HASH_COUNT(l_chunk->block_cache_hash); - dap_chain_block_cache_t * l_block_cache_chunk_top_prev = dap_chain_block_cs_cache_get_by_hash(a_blocks,&l_chunk->block_cache_top->prev_hash); + dap_chain_block_cache_t * l_block_cache_chunk_top_prev = dap_chain_block_cache_get_by_hash(a_blocks,&l_chunk->block_cache_top->prev_hash); dap_chain_block_cache_t * l_block_cache= l_block_cache_chunk_top_prev; if ( l_block_cache ){ // we found prev block in main chain size_t l_tail_length = 0; @@ -1103,7 +1213,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_blocks, &l_block_hash, l_block, l_block_size); + l_block_cache = dap_chain_block_cache_new(&l_block_hash, l_block, l_block_size); if (!l_block_cache) { log_it(L_DEBUG, "... corrupted block"); pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); @@ -1169,6 +1279,11 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, } } + if (l_block->hdr.ts_created > dap_time_now() + 60) { + log_it(L_WARNING, "Incorrect block timestamp"); + 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 @@ -1187,7 +1302,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, &l_is_genesis, &l_nonce, &l_nonce2 ) ; - DAP_DELETE(l_meta); + DAP_DEL_Z(l_meta); // 2nd level consensus if(l_blocks->callback_block_verify) @@ -1268,7 +1383,7 @@ static dap_chain_atom_iter_t* s_callback_atom_iter_create_from(dap_chain_t * a_c dap_chain_atom_iter_t * l_atom_iter = s_callback_atom_iter_create(a_chain, a_chain->cells->id, 0); if (l_atom_iter){ dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); - l_atom_iter->cur_item = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_atom_hash); + l_atom_iter->cur_item = dap_chain_block_cache_get_by_hash(l_blocks, &l_atom_hash); l_atom_iter->cur = a_atom; l_atom_iter->cur_size = a_atom_size; return l_atom_iter; @@ -1447,8 +1562,8 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_links(dap_chain_atom_iter_ *a_links_size = l_block_cache->links_hash_count; dap_chain_atom_ptr_t *l_ret = DAP_NEW_Z_SIZE(dap_chain_atom_ptr_t, l_block_cache->links_hash_count * sizeof(dap_chain_atom_ptr_t)); for (size_t i = 0; i < l_block_cache->links_hash_count; ++i){ - dap_chain_cs_blocks_t *l_cs_blocks = (dap_chain_cs_blocks_t *)l_block_cache->_inheritor; - dap_chain_block_cache_t *l_link = dap_chain_block_cs_cache_get_by_hash(l_cs_blocks, &l_block_cache->links_hash[i]); + dap_chain_cs_blocks_t *l_cs_blocks = DAP_CHAIN_CS_BLOCKS(a_atom_iter->chain); + dap_chain_block_cache_t *l_link = dap_chain_block_cache_get_by_hash(l_cs_blocks, &l_block_cache->links_hash[i]); assert(l_link); (*a_links_size_ptr)[i] = l_link->block_size; l_ret[i] = l_link->block; @@ -1712,3 +1827,31 @@ static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, si pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); return l_list; } + +static const dap_time_t s_block_timediff_unit = 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) +{ + uint256_t l_ret = uint256_0; + size_t l_block_size = 0; + const dap_chain_block_t *l_block = dap_chain_get_atom_by_hash(a_chain, a_block_hash, &l_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; + } + 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_time_t l_block_time = l_block->hdr.ts_created; + 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); + } + } + return l_ret; +} diff --git a/modules/type/blocks/include/dap_chain_block.h b/modules/type/blocks/include/dap_chain_block.h index 9beab8cb37..6accd3802d 100644 --- a/modules/type/blocks/include/dap_chain_block.h +++ b/modules/type/blocks/include/dap_chain_block.h @@ -100,16 +100,18 @@ size_t dap_chain_block_datum_del_by_hash(dap_chain_block_t ** a_block_ptr, size_ // Add sign in block size_t dap_chain_block_sign_add(dap_chain_block_t ** a_block_ptr, size_t a_block_size, dap_enc_key_t *a_key); -dap_sign_t *dap_chain_block_sign_get ( dap_chain_block_t * a_block_ptr, size_t a_block_size, uint16_t a_sign_num ); +dap_sign_t *dap_chain_block_sign_get (const dap_chain_block_t *a_block_ptr, size_t a_block_size, uint16_t a_sign_num ); +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); +size_t dap_chain_block_get_signs_count(const dap_chain_block_t *a_block, size_t a_block_size); +size_t dap_chain_block_get_sign_offset(const dap_chain_block_t *a_block, size_t a_block_size); -size_t dap_chain_block_get_signs_count(dap_chain_block_t * a_block, size_t a_block_size); -size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_block_size); +dap_hash_fast_t *dap_chain_block_get_prev_hash(const dap_chain_block_t *a_block, size_t a_block_size); // 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 ); +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(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_meta_count ); +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, diff --git a/modules/type/blocks/include/dap_chain_block_cache.h b/modules/type/blocks/include/dap_chain_block_cache.h index b0cbfdac0c..22cb469d54 100644 --- a/modules/type/blocks/include/dap_chain_block_cache.h +++ b/modules/type/blocks/include/dap_chain_block_cache.h @@ -70,9 +70,6 @@ typedef struct dap_chain_block_cache { struct dap_chain_block_cache * prev; struct dap_chain_block_cache * next; - // Inhertied nested data - void * _inheritor; - // uthash handle UT_hash_handle hh; } dap_chain_block_cache_t; @@ -81,8 +78,7 @@ int dap_chain_block_cache_init(); void dap_chain_block_cache_deinit(); -dap_chain_block_cache_t *dap_chain_block_cache_new(dap_chain_cs_blocks_t *a_blocks, 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); 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 708dd05bba..4889dca957 100644 --- a/modules/type/blocks/include/dap_chain_cs_blocks.h +++ b/modules/type/blocks/include/dap_chain_cs_blocks.h @@ -66,4 +66,4 @@ typedef int (*dap_chain_blocks_block_callback_ptr_t)(dap_chain_cs_blocks_t *, da int dap_chain_cs_blocks_init(); void dap_chain_cs_blocks_deinit(); -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 *dap_chain_block_cache_get_by_hash(dap_chain_cs_blocks_t *a_blocks, dap_chain_hash_fast_t *a_block_hash); diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 93c5224e6a..11382d550d 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -53,10 +53,10 @@ #include "dap_chain_node_cli_cmd.h" #include "dap_chain_cell.h" #include "dap_chain_net.h" +#include "dap_chain_ledger.h" #define LOG_TAG "dap_chain_cs_dag" - typedef struct dap_chain_cs_dag_event_item { dap_chain_hash_fast_t hash; dap_chain_hash_fast_t datum_hash; diff --git a/modules/wallet/dap_chain_wallet.c b/modules/wallet/dap_chain_wallet.c index 2dfd5470fc..b6d6e01f88 100644 --- a/modules/wallet/dap_chain_wallet.c +++ b/modules/wallet/dap_chain_wallet.c @@ -58,6 +58,7 @@ #include "dap_chain_wallet_internal.h" #include "dap_enc_key.h" #include "crc32c_adler.h" +#include "dap_chain_ledger.h" #define LOG_TAG "dap_chain_wallet" @@ -982,7 +983,7 @@ uint256_t dap_chain_wallet_get_balance ( dap_chain_net_t *l_net = dap_chain_net_by_id(a_net_id); dap_chain_addr_t *l_addr = dap_chain_wallet_get_addr(a_wallet, a_net_id); - return (l_net) ? dap_chain_ledger_calc_balance(l_net->pub.ledger, l_addr, a_token_ticker) : uint256_0; + return (l_net) ? dap_ledger_calc_balance(l_net->pub.ledger, l_addr, a_token_ticker) : uint256_0; } /** -- GitLab