From 6c928f8397d9a2c6d3d464b840fe0461fddc1d80 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Thu, 16 Feb 2023 07:32:29 +0000 Subject: [PATCH] Common decrees development --- modules/chain/dap_chain.c | 12 +- modules/chain/dap_chain_ledger.c | 2 +- modules/chain/include/dap_chain.h | 7 +- modules/common/dap_chain_datum.c | 47 +- modules/common/dap_chain_datum_decree.c | 156 +++++- modules/common/include/dap_chain_datum.h | 2 + .../common/include/dap_chain_datum_decree.h | 81 ++- .../block-poa/dap_chain_cs_block_poa.c | 1 + .../consensus/dag-poa/dap_chain_cs_dag_poa.c | 20 +- .../dag-poa/include/dap_chain_cs_dag_poa.h | 2 +- modules/mempool/dap_chain_mempool.c | 10 +- modules/net/dap_chain_net.c | 67 ++- modules/net/dap_chain_net_decree.c | 345 +++++++++++++ modules/net/dap_chain_net_tx.c | 110 +++- modules/net/dap_chain_node_cli.c | 13 + modules/net/dap_chain_node_cli_cmd.c | 7 +- modules/net/dap_chain_node_cli_cmd_tx.c | 477 ++++++++++++++++++ modules/net/include/dap_chain_net.h | 4 + modules/net/include/dap_chain_net_decree.h | 40 ++ modules/net/include/dap_chain_net_tx.h | 4 +- .../net/include/dap_chain_node_cli_cmd_tx.h | 5 + .../stake_lock/dap_chain_net_srv_stake_lock.c | 9 +- .../dap_chain_net_srv_stake_pos_delegate.c | 6 +- .../xchange/dap_chain_net_srv_xchange.c | 88 ++-- 24 files changed, 1400 insertions(+), 115 deletions(-) create mode 100644 modules/net/dap_chain_net_decree.c create mode 100644 modules/net/include/dap_chain_net_decree.h diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index f971680a3c..27dd828169 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -261,6 +261,8 @@ static dap_chain_type_t s_chain_type_from_str(const char *a_type_str) if(!dap_strcmp(a_type_str, "signer")) { return CHAIN_TYPE_SIGNER; } + if (!dap_strcmp(a_type_str, "decree")) + return CHAIN_TYPE_DECREE; return CHAIN_TYPE_LAST; } @@ -287,6 +289,8 @@ static uint16_t s_datum_type_from_str(const char *a_type_str) if (!dap_strcmp(a_type_str, "signer")) { return DAP_CHAIN_DATUM_SIGNER; } + if (!dap_strcmp(a_type_str, "decree")) + return DAP_CHAIN_DATUM_DECREE; return DAP_CHAIN_DATUM_CUSTOM; } @@ -414,12 +418,6 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha if ( dap_config_get_item_path_default(l_cfg , "files","storage_dir",NULL ) ) { DAP_CHAIN_PVT(l_chain)->file_storage_dir = dap_strdup( dap_config_get_item_path( l_cfg , "files","storage_dir" ) ); - if (dap_chain_load_all(l_chain) == 0) - log_it (L_NOTICE, "Loaded chain files"); - else { - dap_chain_save_all( l_chain ); - log_it (L_NOTICE, "Initialized chain files"); - } } else log_it (L_INFO, "Not set file storage path, will not stored in files"); @@ -460,7 +458,7 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha } // add datum types - if (l_datum_types && l_datum_types_count > 0) + if (l_datum_types && l_datum_types_count > 0) { l_chain->datum_types = DAP_NEW_SIZE(dap_chain_type_t, l_datum_types_count * sizeof(dap_chain_type_t)); // TODO: pls check counter for recognized types before memory allocation! l_count_recognized = 0; diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 016a464a66..eaec9d6713 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -3423,7 +3423,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t uint256_t l_value = {}, l_fee_value = {}, l_fee_sum = {}; dap_chain_addr_t l_fee_addr = {}; #ifndef DAP_CHAIN_LEDGER_TEST - bool l_fee_check = dap_chain_net_tx_get_fee(PVT(a_ledger)->net->pub.id, &l_fee_value, &l_fee_addr); + bool l_fee_check = dap_chain_net_tx_get_fee(PVT(a_ledger)->net->pub.id, NULL, &l_fee_value, &l_fee_addr); #else bool l_fee_check = false; #endif diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index 566c15beaf..70dbf5096e 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -32,6 +32,7 @@ #include "dap_chain_common.h" #include "dap_chain_datum.h" #include "dap_chain_datum_tx.h" +#include "dap_cert.h" typedef struct dap_chain dap_chain_t; @@ -95,6 +96,7 @@ typedef void (*dap_chain_callback_notify_t)(void * a_arg, dap_chain_t *a_chain, 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 enum dap_chain_type { @@ -104,7 +106,8 @@ typedef enum dap_chain_type CHAIN_TYPE_TX, CHAIN_TYPE_CA, CHAIN_TYPE_SIGNER, - CHAIN_TYPE_LAST + CHAIN_TYPE_LAST, + CHAIN_TYPE_DECREE } dap_chain_type_t; typedef struct dap_chain { @@ -169,6 +172,8 @@ typedef struct dap_chain { dap_chain_callback_get_count callback_count_atom; dap_chain_callback_get_list callback_get_atoms; + dap_chain_callback_get_poa_certs callback_get_poa_certs; + dap_list_t * atom_notifiers; // dap_chain_callback_notify_t callback_notify; // void *callback_notify_arg; diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c index 71f4cdc95d..9ddec492ea 100644 --- a/modules/common/dap_chain_datum.c +++ b/modules/common/dap_chain_datum.c @@ -29,6 +29,7 @@ #include "dap_chain_datum_tx.h" #include "dap_chain_datum_token.h" #include "dap_chain_datum_tx_items.h" +#include "dap_chain_datum_decree.h" #include "dap_chain_datum_hashtree_roots.h" #include "dap_enc_base58.h" @@ -695,6 +696,50 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)a_datum->data; dap_chain_datum_dump_tx(l_tx, NULL, a_str_out, a_hash_out_type, &l_datum_hash); } break; - } + case DAP_CHAIN_DATUM_DECREE:{ + dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *)a_datum->data; + size_t l_decree_size = sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size + l_decree->header.signs_size; + dap_string_append_printf(a_str_out,"=== Datum decree ===\n"); + dap_string_append_printf(a_str_out, "hash: %s\n", l_hash_str); + dap_string_append_printf(a_str_out, "size: %zd\n", l_decree_size); + char *l_type_str = ""; + switch(l_decree->header.type) + { + case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON: + l_type_str = "DECREE_TYPE_COMMON"; + break; + case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE: + l_type_str = "DECREE_TYPE_SERVICE"; + break; + default: + l_type_str = "DECREE_TYPE_UNKNOWN"; + } + + dap_string_append_printf(a_str_out, "type: %s\n", l_type_str); + + char *l_subtype_str = ""; + switch(l_decree->header.type) + { + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_FEE: + l_subtype_str = "DECREE_COMMON_SUBTYPE_FEE"; + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS: + l_subtype_str = "DECREE_COMMON_SUBTYPE_OWNERS"; + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN: + l_subtype_str = "DECREE_COMMON_SUBTYPE_OWNERS_MIN"; + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_TON_SIGNERS_MIN: + l_subtype_str = "DECREE_COMMON_SUBTYPE_TON_SIGNERS_MIN"; + break; + default: + l_subtype_str = "DECREE_TYPE_UNKNOWN"; + } + + dap_string_append_printf(a_str_out, "subtype: %s\n", l_subtype_str); + + dap_chain_datum_decree_certs_dump(a_str_out, l_decree->data_n_signs + l_decree->header.data_size, l_decree->header.signs_size, a_hash_out_type); + } break; + } DAP_DELETE(l_hash_str); } diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c index f4a72c4c3d..28a8d8b1c0 100644 --- a/modules/common/dap_chain_datum_decree.c +++ b/modules/common/dap_chain_datum_decree.c @@ -1,6 +1,6 @@ /* * Authors: - * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * Frolov Daniil <daniil.frolov@demlabs.net> * DeM Labs Inc. https://demlabs.net * Copyright (c) 2020, All rights reserved. @@ -19,3 +19,157 @@ You should have received a copy of the GNU General Public License along with any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. */ + +#include <memory.h> +#include <assert.h> +#include "dap_tsd.h" +#include "dap_sign.h" +#include "dap_common.h" +#include "dap_chain_datum_decree.h" + + +#define LOG_TAG "dap_chain_datum_decree" + + + +dap_sign_t *dap_chain_datum_decree_get_signs(dap_chain_datum_decree_t *a_decree, size_t* a_signs_size) +{ + if (!a_decree) + return NULL; + + dap_sign_t *l_signs_section = (dap_sign_t *)((byte_t*)a_decree->data_n_signs + a_decree->header.data_size); + + *a_signs_size = a_decree->header.signs_size; + + return l_signs_section; +} + +int dap_chain_datum_decree_get_fee(dap_chain_datum_decree_t *a_decree, uint256_t *a_fee_value) +{ + size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; + + if(!a_decree || !a_fee_value){ + log_it(L_WARNING,"Wrong arguments"); + return -1; + } + while(l_tsd_offset < tsd_data_size){ + dap_tsd_t *l_tsd = (dap_tsd_t*)a_decree->data_n_signs + l_tsd_offset; + size_t l_tsd_size = l_tsd->size + sizeof(dap_tsd_t); + if(l_tsd_size > tsd_data_size){ + log_it(L_WARNING,"TSD size is greater than all data size. It's possible corrupt data."); + return -1; + } + if (l_tsd->type == DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE){ + if(l_tsd->size > sizeof(uint256_t)){ + log_it(L_WARNING,"Wrong fee tsd data size."); + return -1; + } + *a_fee_value = dap_tsd_get_scalar(l_tsd, uint256_t); + return 0; + } + l_tsd_offset += l_tsd_size; + } + return 1; +} + +dap_list_t *dap_chain_datum_decree_get_owners(dap_chain_datum_decree_t *a_decree, uint256_t *a_owners_num) +{ + size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; + uint64_t l_owners_num = 0; + dap_list_t *l_key_list = NULL; + if(!a_decree || !a_owners_num){ + log_it(L_WARNING,"Wrong arguments"); + return NULL; + } + + while(l_tsd_offset < tsd_data_size){ + dap_tsd_t *l_tsd = (dap_tsd_t*)((byte_t*)a_decree->data_n_signs + l_tsd_offset); + size_t l_tsd_size = dap_tsd_size(l_tsd); + if(l_tsd_size > tsd_data_size){ + log_it(L_WARNING,"TSD size is greater than all data size. It's possible corrupt data."); + if (l_key_list) + dap_list_free_full(l_key_list, NULL); + return NULL; + } + if (l_tsd->type == DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER){ + dap_pkey_t *l_owner_pkey = DAP_NEW_Z_SIZE(dap_pkey_t, l_tsd->size); + if (!l_owner_pkey){ + log_it(L_WARNING,"Memory allocate failed."); + dap_list_free_full(l_key_list, NULL); + return NULL; + } + + memcpy(l_owner_pkey, l_tsd->data, l_tsd->size); + l_key_list = dap_list_append(l_key_list, l_owner_pkey); + l_owners_num++; + } + l_tsd_offset += l_tsd_size; + } + *a_owners_num = GET_256_FROM_64(l_owners_num); + return l_key_list; +} + +int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_owners_num) +{ + size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; + + if(!a_decree || !a_min_owners_num){ + log_it(L_WARNING,"Wrong arguments"); + return -1; + } + while(l_tsd_offset < tsd_data_size){ + dap_tsd_t *l_tsd = (dap_tsd_t*)a_decree->data_n_signs + l_tsd_offset; + size_t l_tsd_size = dap_tsd_size(l_tsd); + if(l_tsd_size > tsd_data_size){ + log_it(L_WARNING,"TSD size is greater than all data size. It's possible corrupt data."); + return -1; + } + if (l_tsd->type == DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER){ + if(l_tsd->size > sizeof(uint256_t)){ + log_it(L_WARNING,"Wrong fee tsd data size."); + return -1; + } + *a_min_owners_num = dap_tsd_get_scalar(l_tsd, uint256_t); + return 0; + } + l_tsd_offset += l_tsd_size; + } + return 1; +} + +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) +{ + dap_string_append_printf(a_str_out, "signatures: "); + if (!a_certs_size) { + dap_string_append_printf(a_str_out, "<NONE>\n"); + return; + } + + dap_string_append_printf(a_str_out, "\n"); + + size_t l_offset = 0; + for (int i = 1; l_offset < (a_certs_size); i++) { + dap_sign_t *l_sign = (dap_sign_t *) (a_signs + l_offset); + l_offset += dap_sign_get_size(l_sign); + if (l_sign->header.sign_size == 0) { + dap_string_append_printf(a_str_out, "<CORRUPTED - 0 size signature>\n"); + continue; + } + + dap_chain_hash_fast_t l_pkey_hash = {0}; + if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) { + dap_string_append_printf(a_str_out, "<CORRUPTED - can't calc hash>\n"); + continue; + } + + char *l_hash_str = NULL; + if(!dap_strcmp(a_hash_out_type, "hex")) + l_hash_str = dap_chain_hash_fast_to_str_new(&l_pkey_hash); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(&l_pkey_hash); + + dap_string_append_printf(a_str_out, "%d) %s, %s, %u bytes\n", i, l_hash_str, + dap_sign_type_to_str(l_sign->header.type), l_sign->header.sign_size); + DAP_DEL_Z(l_hash_str); + } +} diff --git a/modules/common/include/dap_chain_datum.h b/modules/common/include/dap_chain_datum.h index 0bfecc72ec..1f88bb8cb1 100644 --- a/modules/common/include/dap_chain_datum.h +++ b/modules/common/include/dap_chain_datum.h @@ -93,6 +93,8 @@ s = "DATUM_TOKEN_DECL"; break; \ case DAP_CHAIN_DATUM_TOKEN_EMISSION:\ s = "DATUM_TOKEN_EMISSION"; break;\ + case DAP_CHAIN_DATUM_DECREE:\ + s = "DATUM_DECREE"; break;\ default: \ s = "DATUM_UNKNOWN"; break; \ } diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h index ebbf67e108..a386badb74 100644 --- a/modules/common/include/dap_chain_datum_decree.h +++ b/modules/common/include/dap_chain_datum_decree.h @@ -1,6 +1,6 @@ /* * Authors: - * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * Frolov Daniil <daniil.frolov@demlabs.net> * DeM Labs Inc. https://demlabs.net * Copyright (c) 2020, All rights reserved. @@ -25,31 +25,86 @@ #include "dap_common.h" #include "dap_math_ops.h" #include "dap_time.h" +#include "dap_list.h" +#include "dap_tsd.h" #include <stdint.h> +#define DAP_CHAIN_DATUM_DECREE_VERSION 0 + // Governance decree typedef struct dap_chain_datum_decree { + uint16_t decree_version; struct { dap_time_t ts_created; uint16_t type; union { dap_chain_net_srv_uid_t srv_id; - dap_chain_net_id_t net_id; - dap_chain_cell_id_t cell_id; - }; - uint16_t action; + struct { + dap_chain_net_id_t net_id; + dap_chain_id_t chain_id; + dap_chain_cell_id_t cell_id; + } DAP_ALIGN_PACKED common_decree_params; + } DAP_ALIGN_PACKED; + uint16_t sub_type; + uint32_t data_size; + uint32_t signs_size; } DAP_ALIGN_PACKED header; - byte_t tsd_sections[]; + byte_t data_n_signs[]; } DAP_ALIGN_PACKED dap_chain_datum_decree_t; -#define DAP_CHAIN_DATUM_DECREE_TYPE_COMMON 0x0001 -#define DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE 0x0002 +// Decree types +#define DAP_CHAIN_DATUM_DECREE_TYPE_COMMON 0x0001 +#define DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE 0x0002 + +// Common decree subtypes +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_FEE 0x0001 +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS 0x0002 +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN 0x0003 +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_TON_SIGNERS_MIN 0x0004 + +// DECREE TSD types +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN 0x0001 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE 0x0002 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER 0x0003 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER 0x0004 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_TON_SIGNERS_MIN 0x0005 +/** + * @brief dap_chain_datum_decree_get_signs + * @param decree pointer to decree + * @param num_of_signs pointer to num of signs buffer. Total + * number of signs will be write to this buffer + * @return pointer to signs + */ +dap_sign_t *dap_chain_datum_decree_get_signs(dap_chain_datum_decree_t *decree, size_t *size_of_signs); +/** + * @brief dap_chain_datum_decree_get_fee gets fee value from decree + * @param a_decree pointer to decree + * @param a_fee_value pointer to fee value buffer + * @return result code + */ +int dap_chain_datum_decree_get_fee(dap_chain_datum_decree_t *a_decree, uint256_t *a_fee_value); -// Create from scratch, reset all previous values -#define DAP_CHAIN_DATUM_DECREE_ACTION_CREATE 0x0001 -#define DAP_CHAIN_DATUM_DECREE_ACTION_UPDATE 0x0002 -#define DAP_CHAIN_DATUM_DECREE_ACTION_DELETE 0x0003 +/** + * @brief dap_chain_datum_decree_get_owners get list of owners certificates + * @param a_decree pointer to decree + * @param a_owners_num pointer to total number of owners buffer + * @return dap_list_t with owners keys in dap_pkey_t format + */ +dap_list_t *dap_chain_datum_decree_get_owners(dap_chain_datum_decree_t *a_decree, uint256_t *a_owners_num); +/** + * @brief dap_chain_datum_decree_get_min_owners get minimum number of owners + * @param a_decree pointer to decree + * @param a_owners_num pointer to minimum number of owners buffer + * @return result code. 0 - success + */ +int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_owners_num); -#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN 0x0001 \ No newline at end of file +/** + * @brief dap_chain_datum_decree_certs_dump compose decree signatures output string + * @param a_str_out pointer to output text buffer + * @param a_data_n_tsd pointer to signs decree section + * @param a_certs_size size of decree signatures + */ +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); diff --git a/modules/consensus/block-poa/dap_chain_cs_block_poa.c b/modules/consensus/block-poa/dap_chain_cs_block_poa.c index 28ecf8f8df..ac93b751c4 100644 --- a/modules/consensus/block-poa/dap_chain_cs_block_poa.c +++ b/modules/consensus/block-poa/dap_chain_cs_block_poa.c @@ -202,6 +202,7 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) } } } + log_it(L_NOTICE,"Initialized Block-PoA consensus with %u/%u minimum consensus",l_poa_pvt->auth_certs_count,l_poa_pvt->auth_certs_count_verify); // Save old callback if present and set the call of its own (chain callbacks) l_poa_pvt->prev_callback_created = l_blocks->chain->callback_created; diff --git a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c index 66e2c52ab2..a598ee20c7 100644 --- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c +++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c @@ -336,6 +336,7 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) l_dag->callback_delete = s_callback_delete; l_dag->callback_cs_verify = s_callback_event_verify; l_dag->callback_cs_event_create = s_callback_event_create; + l_dag->chain->callback_get_poa_certs = dap_chain_cs_dag_poa_get_auth_certs; l_poa->_pvt = DAP_NEW_Z ( dap_chain_cs_dag_poa_pvt_t ); dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(l_poa); pthread_rwlock_init(&l_poa_pvt->rounds_rwlock, NULL); @@ -368,7 +369,7 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) l_dag->chain->callback_created = s_callback_created; if (!l_dag->is_add_directly && l_poa_pvt->auto_round_complete) { - dap_chain_net_t *l_net = dap_chain_net_by_id(l_dag->chain->net_id); + dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); dap_chain_node_role_t l_role = dap_chain_net_get_role(l_net); if (l_role.enums == NODE_ROLE_ROOT_MASTER || l_role.enums == NODE_ROLE_ROOT) { if (!s_poa_round_timer) { @@ -864,13 +865,26 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ } } -dap_cert_t **dap_chain_cs_dag_poa_get_auth_certs(dap_chain_t *a_chain, size_t *a_auth_certs_count) +dap_list_t *dap_chain_cs_dag_poa_get_auth_certs(dap_chain_t *a_chain, size_t *a_auth_certs_count, uint16_t *a_count_verify) { dap_chain_pvt_t *l_chain_pvt = DAP_CHAIN_PVT(a_chain); if (strcmp(l_chain_pvt->cs_name, "dag_poa")) return NULL; + dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(DAP_CHAIN_CS_DAG_POA(DAP_CHAIN_CS_DAG(a_chain))); if (a_auth_certs_count) *a_auth_certs_count = l_poa_pvt->auth_certs_count; - return l_poa_pvt->auth_certs; + + if (a_count_verify) + *a_count_verify = l_poa_pvt->auth_certs_count_verify; + + + dap_list_t *l_keys_list = NULL; + for(size_t i = 0; i < l_poa_pvt->auth_certs_count; i++) + { + dap_pkey_t *l_pkey = dap_cert_to_pkey(l_poa_pvt->auth_certs[i]); + l_keys_list = dap_list_append(l_keys_list, l_pkey); + } + + return l_keys_list; } diff --git a/modules/consensus/dag-poa/include/dap_chain_cs_dag_poa.h b/modules/consensus/dag-poa/include/dap_chain_cs_dag_poa.h index 5e47206823..85ec14a53b 100644 --- a/modules/consensus/dag-poa/include/dap_chain_cs_dag_poa.h +++ b/modules/consensus/dag-poa/include/dap_chain_cs_dag_poa.h @@ -40,6 +40,6 @@ typedef struct dap_chain_cs_dag_poa int dap_chain_cs_dag_poa_init(void); void dap_chain_cs_dag_poa_deinit(void); -dap_cert_t **dap_chain_cs_dag_poa_get_auth_certs(dap_chain_t *a_chain, size_t *a_auth_certs_count); +dap_list_t *dap_chain_cs_dag_poa_get_auth_certs(dap_chain_t *a_chain, size_t *a_auth_certs_count, uint16_t *a_count_verify); void dap_chain_cs_dag_poa_presign_callback_set(dap_chain_t *a_chain, dap_chain_cs_dag_poa_callback_t a_callback, void *a_arg); diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index 66d8de69e3..16ed3ec393 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -145,7 +145,7 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr uint256_t l_value_need = a_value, l_net_fee = {}, l_total_fee = {}, l_fee_transfer = {}; dap_chain_addr_t l_addr_fee = {}; dap_list_t *l_list_fee_out = NULL; - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, &l_net_fee, &l_addr_fee); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, a_chain, &l_net_fee, &l_addr_fee); SUM_256_256(l_net_fee, a_value_fee, &l_total_fee); if (l_single_channel) SUM_256_256(l_value_need, l_total_fee, &l_value_need); @@ -294,7 +294,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a dap_global_db_obj_t * l_objs = DAP_NEW_Z_SIZE(dap_global_db_obj_t, (a_tx_num + 1) * sizeof (dap_global_db_obj_t)); uint256_t l_net_fee = {}, l_total_fee = {}; dap_chain_addr_t l_addr_fee = {}; - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, &l_net_fee, &l_addr_fee); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, a_chain, &l_net_fee, &l_addr_fee); SUM_256_256(l_net_fee, a_value_fee, &l_total_fee); // Search unused out: uint256_t l_single_val = {}; @@ -529,7 +529,7 @@ char *dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h uint256_t l_value_send = a_receipt->receipt_info.value_datoshi; uint256_t l_net_fee = {}; dap_chain_addr_t l_addr_fee = {}; - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_addr_fee); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, NULL, &l_net_fee, &l_addr_fee); SUM_256_256(l_value_send, l_net_fee, &l_value_send); SUM_256_256(l_value_send, l_fee, &l_value_send); if (compare256(l_out_cond->header.value, l_value_send) < 0) { @@ -616,7 +616,7 @@ char *dap_chain_mempool_tx_create_cond(dap_chain_net_t *a_net, uint256_t l_net_fee = {}; dap_chain_addr_t l_addr_fee = {}; - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_addr_fee); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, NULL, &l_net_fee, &l_addr_fee); // find the transactions from which to take away coins uint256_t l_value_transfer = {}; // how many coins to transfer uint256_t l_value_need = {}; @@ -714,7 +714,7 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast dap_list_t *l_list_used_out; const char *l_native_ticker = dap_chain_net_by_id(a_chain->net_id)->pub.native_ticker; bool not_native = dap_strcmp(a_ticker, l_native_ticker); - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, &l_net_fee, &l_addr_fee); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, NULL, &l_net_fee, &l_addr_fee); if(l_net_fee_used) SUM_256_256(l_total_fee,l_net_fee,&l_total_fee); diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 61d28d0d45..bcf8b90f08 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -196,6 +196,7 @@ typedef struct dap_chain_net_pvt{ dap_chain_net_state_t state_target; uint16_t acl_idx; + // Main loop timer dap_interval_timer_t main_timer; @@ -1818,7 +1819,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) // Network fee uint256_t l_network_fee = {}; dap_chain_addr_t l_network_fee_addr = {}; - dap_chain_net_tx_get_fee(l_net->pub.id, &l_network_fee, &l_network_fee_addr); + dap_chain_net_tx_get_fee(l_net->pub.id, NULL, &l_network_fee, &l_network_fee_addr); char *l_network_fee_balance_str = dap_chain_balance_print(l_network_fee); char *l_network_fee_coins_str = dap_chain_balance_to_coins(l_network_fee); char *l_network_fee_addr_str = dap_chain_addr_to_str(&l_network_fee_addr); @@ -2480,6 +2481,8 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx) } + + 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); DAP_DEL_Z(l_chains_path); @@ -2520,7 +2523,8 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx) // sort list with chains names by priority l_prior_list = dap_list_sort(l_prior_list, callback_compare_prioritity_list); - // load chains by priority + + // create and load chains params by priority dap_chain_t *l_chain; dap_list_t *l_list = l_prior_list; while(l_list){ @@ -2528,11 +2532,11 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx) // Create chain object l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name, l_net->pub.id, l_chain_prior->chains_path); + if(l_chain) {//add minimum commission from to which the master node agrees. if present (default = 1.0) l_chain->minimum_commission = dap_chain_coins_to_balance(dap_config_get_item_str_default(l_cfg , "general" ,"minimum_commission","1.0")); DL_APPEND(l_net->pub.chains, l_chain); - if(l_chain->callback_created) - l_chain->callback_created(l_chain, l_cfg); + // add a callback to monitor changes in the chain dap_chain_add_callback_notify(l_chain, s_chain_callback_notify, l_net); } @@ -2541,8 +2545,26 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx) } dap_list_free_full(l_prior_list, NULL); - dap_chain_t *l_chain02; + //load decree + dap_chain_net_decree_init(l_net); + + // load chains + l_chain = l_net->pub.chains; + while(l_chain){ + if (dap_chain_load_all(l_chain) == 0) + log_it (L_NOTICE, "Loaded chain files"); + else { + dap_chain_save_all( l_chain ); + log_it (L_NOTICE, "Initialized chain files"); + } + + if(l_chain->callback_created) + l_chain->callback_created(l_chain, l_cfg); + l_chain = l_chain->next; + } + + dap_chain_t *l_chain02; DL_FOREACH(l_net->pub.chains, l_chain){ DL_FOREACH(l_net->pub.chains, l_chain02){ if (l_chain != l_chain02){ @@ -2792,7 +2814,8 @@ dap_chain_t *dap_chain_net_get_chain_by_chain_type(dap_chain_net_t *a_net, dap_c DL_FOREACH(a_net->pub.chains, l_chain) { for(int i = 0; i < l_chain->datum_types_count; i++) { - if(l_chain->datum_types[i] == a_datum_type) + dap_chain_type_t l_datum_type = l_chain->datum_types[i]; + if(l_datum_type == a_datum_type) return l_chain; } } @@ -3101,6 +3124,7 @@ bool dap_chain_net_get_extra_gdb_group(dap_chain_net_t *a_net, dap_chain_node_ad * 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_DECREE * @param a_net * @param a_datum * @return @@ -3118,7 +3142,9 @@ int dap_chain_net_verify_datum_for_add(dap_chain_net_t *a_net, dap_chain_datum_t return dap_chain_ledger_token_decl_add_check( a_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( a_net->pub.ledger, a_datum->data, a_datum->header.data_size ); - default: return 0; + case DAP_CHAIN_DATUM_DECREE: + return dap_chain_net_decree_verify((dap_chain_datum_decree_t*)a_datum->data, a_net, NULL, NULL); + default: return 0; } } @@ -3299,7 +3325,7 @@ dap_list_t* dap_chain_datum_list(dap_chain_net_t *a_net, dap_chain_t *a_chain, d int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t a_datum_size, dap_hash_fast_t *a_tx_hash) { size_t l_datum_data_size = a_datum->header.data_size; - if ( a_datum_size < l_datum_data_size+ sizeof (a_datum->header) ){ + if (a_datum_size < l_datum_data_size+ sizeof (a_datum->header)){ log_it(L_INFO,"Corrupted datum rejected: wrong size %zd not equel or less datum size %zd",a_datum->header.data_size+ sizeof (a_datum->header), a_datum_size ); return -101; @@ -3307,27 +3333,11 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t switch (a_datum->header.type_id) { case DAP_CHAIN_DATUM_DECREE:{ dap_chain_datum_decree_t * l_decree = (dap_chain_datum_decree_t *) a_datum->data; - if( sizeof(l_decree->header)> l_datum_data_size ){ + if(sizeof(l_decree->header) + l_decree->header.data_size + l_decree->header.signs_size > l_datum_data_size){ log_it(L_WARNING, "Corrupted decree, size %zd is smaller than ever decree header's size %zd", l_datum_data_size, sizeof(l_decree->header)); return -102; } - - - switch(l_decree->header.type){ - case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:{ - dap_chain_net_srv_t * l_srv = dap_chain_net_srv_get(l_decree->header.srv_id); - if(l_srv){ - if(l_srv->callbacks.decree){ - dap_chain_net_t * l_net = dap_chain_net_by_id(a_chain->net_id); - l_srv->callbacks.decree(l_srv,l_net,a_chain,l_decree,l_datum_data_size); - } - }else{ - log_it(L_WARNING,"Decree for unknown srv uid 0x%016"DAP_UINT64_FORMAT_X , l_decree->header.srv_id.uint64); - return -103; - } - } - default:; - } + return dap_chain_net_decree_load(l_decree, a_chain); } break; case DAP_CHAIN_DATUM_TOKEN_DECL: @@ -3357,3 +3367,8 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t return 0; } + +bool dap_chain_net_get_load_mode(dap_chain_net_t * a_net) +{ + return PVT(a_net)->load_mode; +} diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c new file mode 100644 index 0000000000..33fff6eaa2 --- /dev/null +++ b/modules/net/dap_chain_net_decree.c @@ -0,0 +1,345 @@ +/* + * + * Authors: + * Frolov Daniil <daniil.frolov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Copyright (c) 2020, All rights reserved. + + This file is part of CellFrame SDK the open source project + + CellFrame 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. + + CellFrame 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 CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <memory.h> +#include <assert.h> +#include "dap_common.h" +#include "dap_sign.h" +#include "dap_cert.h" +#include "dap_pkey.h" +#include "dap_chain_common.h" +#include "dap_chain_net.h" +#include "dap_chain_net_decree.h" +#include "dap_chain_net_srv.h" +#include "dap_chain_net_tx.h" + + +#define LOG_TAG "chain_net_decree" + +// private types definition + +// Private variable + + +// Private fuctions prototype +static bool s_verify_pkey (dap_sign_t *a_sign, dap_chain_net_t *a_net); +static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain); +static int s_service_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain); + + +// Public functions +int dap_chain_net_decree_init(dap_chain_net_t *a_net) +{ + size_t l_auth_certs_count = 0; + + if (!a_net) + { + log_it(L_WARNING,"Invalid arguments. a_net must be not NULL"); + return -106; + } + + dap_list_t *l_net_keys = NULL; + uint16_t l_count_verify = 0; + for (dap_chain_t *l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next) { + l_net_keys = l_chain->callback_get_poa_certs(l_chain, &l_auth_certs_count, &l_count_verify); + if (l_net_keys) + break; + } + + if (!l_net_keys || !l_auth_certs_count) + { + log_it(L_WARNING,"Certificates for net %s not found.", a_net->pub.name); + return -1; + } + + dap_chain_net_decree_t *l_decree = NULL; + l_decree = DAP_NEW_Z(dap_chain_net_decree_t); + + if (!l_decree) + { + log_it(L_WARNING,"Out of memory."); + return -2; + } + + l_decree->min_num_of_owners = GET_256_FROM_64((uint64_t)l_count_verify); + l_decree->num_of_owners = GET_256_FROM_64((uint64_t)l_auth_certs_count); + l_decree->pkeys = l_net_keys; + + a_net->pub.decree = l_decree; + + return 0; +} + +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); + + return 0; +} + +int dap_chain_net_decree_verify(dap_chain_datum_decree_t * a_decree, dap_chain_net_t *a_net, uint32_t *a_signs_count, uint32_t *a_signs_verify) +{ + dap_chain_datum_decree_t *l_decree = a_decree; + // Get pkeys sign from decree datum + + size_t l_signs_size = 0; + //multiple signs reading from datum + dap_sign_t *l_signs_block = dap_chain_datum_decree_get_signs(l_decree, &l_signs_size); + if (!l_signs_size || !l_signs_block) + { + log_it(L_WARNING,"Decree data sign not found"); + return -100; + } + + // Concate all signs in array + uint32_t l_signs_count = 0; + size_t l_tsd_offset = dap_sign_get_size(l_signs_block); + size_t l_signs_arr_size = 0; + dap_sign_t *l_signs_arr = DAP_NEW_Z_SIZE(dap_sign_t, l_tsd_offset); + memcpy(l_signs_arr, l_signs_block, l_tsd_offset); + l_signs_arr_size += l_tsd_offset; + l_signs_count++; + while (l_tsd_offset < l_signs_size) + { + dap_sign_t *cur_sign = (dap_sign_t *)((byte_t*)l_signs_block + l_tsd_offset); + size_t l_sign_size = dap_sign_get_size(cur_sign); + + if (l_sign_size > a_decree->header.signs_size) + { + log_it(L_WARNING,"Sign size greather than decree datum signs size. May be data is corrupted."); + DAP_DELETE(l_signs_arr); + return -105; + } + + dap_sign_t *l_signs_arr_temp = (dap_sign_t *)DAP_REALLOC(l_signs_arr, l_signs_arr_size + l_sign_size); + + if (!l_signs_arr_temp) + { + log_it(L_WARNING,"Memory allocate fail"); + DAP_DELETE(l_signs_arr); + return -105; + } + + l_signs_arr = l_signs_arr_temp; + memcpy((byte_t *)l_signs_arr + l_signs_arr_size, cur_sign, l_sign_size); + + + l_signs_arr_size += l_sign_size; + l_tsd_offset += l_sign_size; + l_signs_count++; + } + + if (a_signs_count) + *a_signs_count = l_signs_count; + + // Find unique pkeys in pkeys set from previous step and check that number of signs > min + size_t l_num_of_unique_signs = 0; + dap_sign_t **l_unique_signs = dap_sign_get_unique_signs(l_signs_arr, l_signs_arr_size, &l_num_of_unique_signs); + + if (l_num_of_unique_signs != l_signs_count) + { + log_it(L_WARNING,"Signatures contain duplicate signs."); + return -105; + } + + uint256_t l_min_signs = a_net->pub.decree->min_num_of_owners; + uint256_t l_num_of_valid_signs256 = GET_256_FROM_64((uint64_t)l_num_of_unique_signs); + if (compare256(l_num_of_valid_signs256, l_min_signs) < 0) + { + log_it(L_WARNING,"Not enough unique signatures"); + return -106; + } + + // Verify all keys and its signatures + uint16_t l_signs_size_for_current_sign = 0, l_signs_verify_counter = 0; + + for(size_t i = 0; i < l_num_of_unique_signs; i++) + { + size_t l_sign_max_size = dap_sign_get_size(l_unique_signs[i]); + if (s_verify_pkey(l_unique_signs[i], a_net)) + { + // 3. verify sign + size_t l_verify_data_size = l_decree->header.data_size + sizeof(dap_chain_datum_decree_t); + l_decree->header.signs_size = l_signs_size_for_current_sign; + if(!dap_sign_verify_all(l_unique_signs[i], l_sign_max_size, l_decree, l_verify_data_size)) + { + l_signs_verify_counter++; + } + } + // Each sign change the sign_size field by adding its size after signing. So we need to change this field in header for each sign. + l_signs_size_for_current_sign += l_sign_max_size; + } + + l_decree->header.signs_size = l_signs_size_for_current_sign; + + DAP_DELETE(l_signs_arr); + DAP_DELETE(l_unique_signs); + + if (a_signs_verify) + *a_signs_verify = l_signs_verify_counter; + + l_min_signs = a_net->pub.decree->min_num_of_owners; + l_num_of_valid_signs256 = GET_256_FROM_64((uint64_t)l_signs_verify_counter); + if (compare256(l_num_of_valid_signs256, l_min_signs) < 0) + { + log_it(L_WARNING,"Not enough valid signatures"); + return -106; + } + + return 0; +} + +int dap_chain_net_decree_load(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain) +{ + int ret_val = 0; + + if (!a_decree || !a_chain) + { + log_it(L_WARNING,"Invalid arguments. a_decree and a_chain must be not NULL"); + return -107; + } + + dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); + + if (!l_net->pub.decree) + { + log_it(L_WARNING,"Decree is not inited!"); + return -108; + } + + + + uint32_t l_num_of_valid_signs = 0, l_num_of_signs = 0; + if ((ret_val = dap_chain_net_decree_verify(a_decree, l_net, &l_num_of_signs, &l_num_of_valid_signs)) != 0) + return ret_val; + + // Process decree + switch(a_decree->header.type){ + case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON:{ + return s_common_decree_handler(a_decree, a_chain); + break; + } + case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:{ + return s_service_decree_handler(a_decree, a_chain); + } + default:; + } + + return -100; +} + +// Private functions +static bool s_verify_pkey (dap_sign_t *a_sign, dap_chain_net_t *a_net) +{ + bool ret_val = false; + dap_list_t *b_item = a_net->pub.decree->pkeys; + while (b_item && !ret_val) + { + dap_pkey_t *l_pkey = (dap_pkey_t*)(b_item->data); + + if (!memcmp(a_sign->pkey_n_sign, l_pkey->pkey, a_sign->header.sign_pkey_size)) + { + ret_val = true; + } + + b_item = b_item->next; + } + return ret_val; +} + +static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain) +{ + uint256_t l_fee, l_min_owners, l_num_of_owners; + dap_chain_addr_t l_addr; //???????? + dap_chain_net_t *l_net = NULL; + dap_list_t *l_owners_list = NULL; + + + switch (a_decree->header.sub_type) + { + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_FEE: + if (!dap_chain_datum_decree_get_fee(a_decree, &l_fee)){ + if (!dap_chain_net_tx_get_fee(a_chain->net_id, a_chain, NULL, &l_addr)){ + if(!dap_chain_net_tx_add_fee(a_chain->net_id, a_chain, &l_fee, &l_addr)){ + log_it(L_WARNING,"Can't add fee value."); + return -102; + } + }else{ + if(!dap_chain_net_tx_replace_fee(a_chain->net_id, a_chain, &l_fee, &l_addr)){ + log_it(L_WARNING,"Can't replace fee value."); + return -103; + } + } + }else{ + log_it(L_WARNING,"Can't get fee value from decree."); + return -103; + } + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS: + l_net = dap_chain_net_by_id(a_chain->net_id); + l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_num_of_owners); + if (!l_owners_list){ + log_it(L_WARNING,"Can't get ownners from decree."); + return -104; + } + + l_net->pub.decree->num_of_owners = l_num_of_owners; + dap_list_free_full(l_net->pub.decree->pkeys, NULL); + + l_net->pub.decree->pkeys = l_owners_list; + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN: + l_net = dap_chain_net_by_id(a_chain->net_id); + if (dap_chain_datum_decree_get_min_owners(a_decree, &l_min_owners)){ + log_it(L_WARNING,"Can't get min number of ownners from decree."); + return -105; + } + l_net->pub.decree->min_num_of_owners = l_min_owners; + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_TON_SIGNERS_MIN: + + break; + default: return -1; + } + + return 0; +} + +static int s_service_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain) +{ + // size_t l_datum_data_size = ; + // dap_chain_net_srv_t * l_srv = dap_chain_net_srv_get(l_decree->header.srv_id); + // if(l_srv){ + // if(l_srv->callbacks.decree){ + // dap_chain_net_t * l_net = dap_chain_net_by_id(a_chain->net_id); + // l_srv->callbacks.decree(l_srv,l_net,a_chain,l_decree,l_datum_data_size); + // } + // }else{ + // log_it(L_WARNING,"Decree for unknown srv uid 0x%016"DAP_UINT64_FORMAT_X , l_decree->header.srv_id.uint64); + // return -103; + // } + + return 0; +} diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index 95e0c9c44f..146677e180 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -613,18 +613,46 @@ dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap return l_tx; } -static struct net_fee { +typedef struct net_fee_key { dap_chain_net_id_t net_id; + dap_chain_id_t chain_id; +} DAP_ALIGN_PACKED net_fee_key_t; + +static struct net_fee { + net_fee_key_t key; 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 static pthread_rwlock_t s_net_fees_rwlock = PTHREAD_RWLOCK_INITIALIZER; -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_get_fee(dap_chain_net_id_t a_net_id, dap_chain_t *a_chain, uint256_t *a_value, dap_chain_addr_t *a_addr) { struct net_fee *l_net_fee; - HASH_FIND(hh, s_net_fees, &a_net_id, sizeof(a_net_id), l_net_fee); + dap_chain_t *l_chain = NULL; + 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; + } + +// if (dap_chain_net_get_load_mode(l_net) && a_chain){ +// l_chain = a_chain; +// }else{ + l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_TX); + if (!l_chain){ + log_it(L_WARNING, "Can't find default chain for net %s", l_net->pub.name); + return false; + } +// } + + net_fee_key_t l_key = {0}; + l_key.net_id = a_net_id; + l_key.chain_id = l_chain->id; + + + HASH_FIND(hh, s_net_fees, &l_key, sizeof(net_fee_key_t), l_net_fee); if (!l_net_fee || IS_ZERO_256(l_net_fee->value)) return false; if (a_value) @@ -633,3 +661,79 @@ bool dap_chain_net_tx_get_fee(dap_chain_net_id_t a_net_id, uint256_t *a_value, d *a_addr = l_net_fee->fee_addr; return true; } + +bool dap_chain_net_tx_add_fee(dap_chain_net_id_t a_net_id, dap_chain_t *a_chain, uint256_t *a_value, dap_chain_addr_t *a_addr) +{ + struct net_fee *l_net_fee; + dap_chain_t *l_chain = NULL; + 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; + } + +// if (dap_chain_net_get_load_mode(l_net) && a_chain){ +// l_chain = a_chain; +// }else{ + + l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_TX); + if (!l_chain){ + log_it(L_WARNING, "Can't find default chain for net %s", l_net->pub.name); + return false; + } +// } + + l_net_fee = DAP_NEW(struct net_fee); + l_net_fee->key.net_id = a_net_id; + l_net_fee->key.chain_id = l_chain->id; + l_net_fee->value = *a_value; + l_net_fee->fee_addr = *a_addr; + + HASH_ADD(hh, s_net_fees, key, sizeof(net_fee_key_t), l_net_fee); + + return true; +} + +bool dap_chain_net_tx_replace_fee(dap_chain_net_id_t a_net_id, dap_chain_t *a_chain, uint256_t *a_value, dap_chain_addr_t *a_addr) +{ + struct net_fee *l_net_fee; + dap_chain_t *l_chain = NULL; + 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; + } + +// if (dap_chain_net_get_load_mode(l_net) && a_chain){ +// l_chain = a_chain; +// }else{ + + l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_TX); + if (!l_chain){ + log_it(L_WARNING, "Can't find default chain for net %s", l_net->pub.name); + return false; + } +// } + + net_fee_key_t l_key = {0}; + l_key.net_id = a_net_id; + l_key.chain_id = l_chain->id; + + HASH_FIND(hh, s_net_fees, &l_key, sizeof(net_fee_key_t), l_net_fee); + if (!l_net_fee) + return false; + HASH_DEL(s_net_fees, l_net_fee); + DAP_FREE(l_net_fee); + + l_net_fee = DAP_NEW(struct net_fee); + l_net_fee->key.net_id = a_net_id; + l_net_fee->key.chain_id = l_chain->id; + l_net_fee->value = *a_value; + l_net_fee->fee_addr = *a_addr;; + + HASH_ADD(hh, s_net_fees, key, sizeof(net_fee_key_t), l_net_fee); + + return true; +} diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 8d3c2b030a..862cb3826c 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -312,6 +312,19 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "remove -chains [-net <net_name> | -all]\n" "Be careful, the '-all' option for '-chains' will delete all chains and won't ask you for permission!"); + // Decree create command + dap_cli_server_cmd_add ("decree", cmd_decree, "Work with decree", + "decree create common -net <net_name> [-chain <chain_name>] -certs <certs list> -<Subtype param name> <Subtype param Value>\n" + "decree create service -net <net_name> [-chain <chain_name>] -srv_id <service_id> -certs <certs list> -<Subtype param name> <Subtype param Value>\n" + "decree sign -net <net_name> [-chain <chain_name>] -datum <datum_hash> -certs <certs list>\n" + "decree anchor -net <net_name> -anchor_chain <chain_name> -decree?????\n" + "==Subtype Params==\n" + "\t -fee <value>: sets fee for tx in net\n" + "\t -new_certs <certs list>: sets new owners set for net\n" + "\t -signs_verify <value>: sets minimum number of owners needed to sign decree\n" + "\t ton_signs_verify <value>: sets minimum number of TON signers"); + + // Exit - always last! dap_cli_server_cmd_add ("exit", com_exit, "Stop application and exit", "exit\n" ); diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 3f561bedf9..3eb1fdde3c 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -2408,6 +2408,9 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a else l_objs_addr++; break; + case DAP_CHAIN_DATUM_DECREE: + + break; default: continue; break; @@ -3454,7 +3457,7 @@ int com_token_decl(int a_argc, char ** a_argv, char ** a_str_reply) switch (l_tsd->type){ case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: log_it(L_DEBUG,"== TOTAL_SIGNS_VALID: %u", - dap_tsd_get_scalar(l_tsd,uint16_t) ); + dap_tsd_get_scalar(l_tsd, uint16_t) ); break; case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_ADD: log_it(L_DEBUG,"== DATUM_TYPE_ALLOWED_ADD: %s", @@ -4868,7 +4871,7 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-from_wallet", &l_from_wallet_name); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-wallet_fee", &l_wallet_fee_name); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-from_emission", &l_emission_hash_str); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-chain_emission", &l_emission_chain_name); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-emission_chain", &l_emission_chain_name); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_addr", &addr_base58_to); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-token", &l_token_ticker); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_name); diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 882a194c3e..af47162b43 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -33,10 +33,12 @@ #include "dap_string.h" #include "dap_list.h" #include "dap_hash.h" +#include "dap_time.h" #include "dap_chain_cell.h" #include "dap_chain_datum.h" #include "dap_chain_datum_token.h" +#include "dap_chain_datum_decree.h" #include "dap_chain_datum_tx_items.h" #include "dap_chain_node_cli.h" #include "dap_chain_node_cli_cmd_tx.h" @@ -1307,4 +1309,479 @@ int com_token(int a_argc, char ** a_argv, char **a_str_reply) return -5; } +/* Decree section */ +/** + * @brief + * 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 + * @param l_datum_token - updated pointer for l_datum_token variable after realloc + * @param l_certs_count - count of certificate + * @param l_datum_data_offset - offset of datum + * @param l_sign_counter - counter of successful data signing operation + * @return dap_chain_datum_token_t* + */ +static dap_chain_datum_decree_t * s_sign_decree_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; + size_t l_total_signs_size = a_datum_decree->header.signs_size, l_total_sign_count = 0; + + for(size_t i = 0; i < a_certs_count; i++) + { + dap_sign_t * l_sign = dap_cert_sign(a_certs[i], a_datum_decree, + sizeof(dap_chain_datum_decree_t) + a_datum_decree->header.data_size, 0); + + if (l_sign) { + size_t l_sign_size = dap_sign_get_size(l_sign); + a_datum_decree = DAP_REALLOC(a_datum_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size); + memcpy((byte_t*)a_datum_decree->data_n_signs + l_cur_sign_offset, l_sign, l_sign_size); + l_total_signs_size += l_sign_size; + l_cur_sign_offset += l_sign_size; + a_datum_decree->header.signs_size = l_total_signs_size; + DAP_DELETE(l_sign); + log_it(L_DEBUG,"<-- Signed with '%s'", a_certs[i]->name); + l_total_sign_count++; + } + } + + *a_total_sign_count = l_total_sign_count; + return a_datum_decree; +} + +// Decree commands handlers +int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) +{ + enum { CMD_NONE=0, CMD_CREATE, CMD_SIGN, CMD_ANCHOR }; + enum { TYPE_NONE=0, TYPE_COMMON, TYPE_SERVICE}; + enum { SUBTYPE_NONE=0, SUBTYPE_FEE, SUBTYPE_OWNERS, SUBTYPE_MIN_OWNERS, SUBTYPE_TON_MIN_SIGNS}; + int arg_index = 1; + const char *l_net_str = NULL; + const char * l_chain_str = NULL; + const char * l_certs_str = NULL; + dap_cert_t ** l_certs = NULL; + size_t l_certs_count = 0; + dap_chain_net_t * l_net = NULL; + dap_chain_t * l_chain = NULL; + + const char * l_hash_out_type = NULL; + 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"; + if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>"); + return -1; + } + + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_str); + // Select chain network + if(!l_net_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "command requires parameter '-net'"); + return -2; + } else { + if((l_net = dap_chain_net_by_name(l_net_str)) == NULL) { // Can't find such network + dap_cli_server_cmd_set_reply_text(a_str_reply, + "command requires parameter '-net' to be valid chain network name"); + return -3; + } + } + + int l_cmd = CMD_NONE; + if (dap_cli_server_cmd_find_option_val(a_argv, 1, 2, "create", NULL)) + l_cmd = CMD_CREATE; + else if (dap_cli_server_cmd_find_option_val(a_argv, 1, 2, "sign", NULL)) + l_cmd = CMD_SIGN; + else if (dap_cli_server_cmd_find_option_val(a_argv, 1, 2, "anchor", NULL)) + l_cmd = CMD_ANCHOR; + + // Public certifiacte of condition owner + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-certs", &l_certs_str); + if (!l_certs_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "decree create requires parameter '-certs'"); + return -106; + } + dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_count); + + switch (l_cmd) + { + case CMD_CREATE:{ + if(!l_certs_count) { + dap_cli_server_cmd_set_reply_text(a_str_reply, + "decree create command requres at least one valid certificate to sign the decree"); + return -106; + } + int l_type = TYPE_NONE; + if (dap_cli_server_cmd_find_option_val(a_argv, 2, 3, "common", NULL)) + l_type = TYPE_COMMON; + else if (dap_cli_server_cmd_find_option_val(a_argv, 2, 3, "service", NULL)) + l_type = TYPE_SERVICE; + + dap_chain_datum_decree_t *l_datum_decree = NULL; + + if (l_type == TYPE_COMMON){ + // Common decree create + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_str); + + // Search chain + if(l_chain_str) { + l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_str); + if (l_chain == NULL) { + char l_str_to_reply_chain[500] = {0}; + char *l_str_to_reply = NULL; + dap_sprintf(l_str_to_reply_chain, "%s requires parameter '-chain' to be valid chain name in chain net %s. Current chain %s is not valid\n", + a_argv[0], l_net_str, l_chain_str); + l_str_to_reply = dap_strcat2(l_str_to_reply,l_str_to_reply_chain); + dap_chain_t * l_chain; + l_str_to_reply = dap_strcat2(l_str_to_reply,"\nAvailable chain with decree support:\n"); + l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_DECREE); + l_str_to_reply = dap_strcat2(l_str_to_reply,"\t"); + l_str_to_reply = dap_strcat2(l_str_to_reply,l_chain->name); + l_str_to_reply = dap_strcat2(l_str_to_reply,"\n"); + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_to_reply); + return -103; + } else if (l_chain != dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_DECREE)){ // check chain to support decree + dap_cli_server_cmd_set_reply_text(a_str_reply, "Chain %s don't support decree", l_chain->name); + return -104; + } + }else if((l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_DECREE)) == NULL) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find chain with decree support."); + return -105; + } + + dap_tsd_t *l_tsd = NULL; + dap_cert_t **l_new_certs = NULL; + size_t l_new_certs_count = 0, l_total_tsd_size = 0; + dap_list_t *l_tsd_list = NULL; + + int l_subtype = SUBTYPE_NONE; + const char *l_param_value_str = NULL; + if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &l_param_value_str)){ + l_subtype = SUBTYPE_FEE; + l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint256_t); + l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE; + l_tsd->size = sizeof(uint256_t); + *(uint256_t*)(l_tsd->data) = dap_cvt_str_to_uint256(l_param_value_str); + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + }else if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-new_certs", &l_param_value_str)){ + l_subtype = SUBTYPE_OWNERS; + dap_cert_parse_str_list(l_param_value_str, &l_new_certs, &l_new_certs_count); + + dap_chain_net_t *a_net = dap_chain_net_by_name(l_net_str); + uint256_t l_min_signs = a_net->pub.decree->min_num_of_owners; + uint256_t l_num_of_valid_signs256 = GET_256_FROM_64((uint64_t)l_new_certs_count); + if (compare256(l_num_of_valid_signs256, l_min_signs) < 0) + { + log_it(L_WARNING,"Number of new certificates is less than minimum owner number."); + return -106; + } + + size_t l_failed_certs = 0; + for (size_t i=0;i<l_new_certs_count;i++){ + dap_pkey_t *l_pkey = dap_cert_to_pkey(l_new_certs[i]); + if(!l_pkey) + { + log_it(L_WARNING,"New cert [%d] have no public key."); + l_failed_certs++; + continue; + } + l_tsd = dap_tsd_create(DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER, l_pkey, sizeof(dap_pkey_t) + (size_t)l_pkey->header.size); + DAP_DELETE(l_pkey); + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + l_total_tsd_size += sizeof(dap_tsd_t) + (size_t)l_tsd->size; + } + if(l_failed_certs) + { + dap_list_free_full(l_tsd_list, NULL); + return -108; + } + }else if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-signs_verify", &l_param_value_str)){ + l_subtype = SUBTYPE_MIN_OWNERS; + uint256_t l_new_num_of_owners = dap_cvt_str_to_uint256(l_param_value_str); + + dap_chain_net_t *a_net = dap_chain_net_by_name(l_net_str); + uint256_t l_owners = a_net->pub.decree->num_of_owners; + uint256_t l_num_of_valid_signs256 = GET_256_FROM_64((uint64_t)l_new_certs_count); + if (compare256(l_num_of_valid_signs256, l_owners) > 0) + { + log_it(L_WARNING,"The minimum number of owners is greater than the total number of owners."); + dap_list_free_full(l_tsd_list, NULL); + return -107; + } + l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint256_t); + l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER; + l_tsd->size = sizeof(uint256_t); + *(uint256_t*)(l_tsd->data) = l_new_num_of_owners; + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + }else if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-ton_signs_verify", &l_param_value_str)){ + l_subtype = SUBTYPE_TON_MIN_SIGNS; + uint256_t l_new_num_of_owners = dap_cvt_str_to_uint256(l_param_value_str); + l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint256_t); + l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_TON_SIGNERS_MIN; + l_tsd->size = sizeof(uint256_t); + *(uint256_t*)(l_tsd->data) = l_new_num_of_owners; + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + }else{ + dap_cli_server_cmd_set_reply_text(a_str_reply, "Decree subtype fail."); + return -107; + } + + l_datum_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); + l_datum_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION; + l_datum_decree->header.ts_created = dap_time_now(); + l_datum_decree->header.type = l_type; + l_datum_decree->header.common_decree_params.net_id = dap_chain_net_id_by_name(l_net_str); + l_datum_decree->header.common_decree_params.chain_id = l_chain->id; + l_datum_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(l_net); + l_datum_decree->header.sub_type = l_subtype; + l_datum_decree->header.data_size = l_total_tsd_size; + l_datum_decree->header.signs_size = 0; + + size_t l_data_tsd_offset = 0; + for ( dap_list_t* l_iter=dap_list_first(l_tsd_list); l_iter; l_iter=l_iter->next){ + dap_tsd_t * l_b_tsd = (dap_tsd_t *) l_iter->data; + size_t l_tsd_size = dap_tsd_size(l_b_tsd); + memcpy((byte_t*)l_datum_decree->data_n_signs + l_data_tsd_offset, l_b_tsd, l_tsd_size); + l_data_tsd_offset += l_tsd_size; + } + + dap_list_free_full(l_tsd_list, NULL); + + }else if (l_type == TYPE_SERVICE) { + + }else{ + dap_cli_server_cmd_set_reply_text(a_str_reply, "not found decree type (common or service)"); + return -107; + } + + // Sign decree + size_t l_total_signs_success = 0; + if (l_certs_count) + l_datum_decree = s_sign_decree_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, + "Decree creation failed. Successful count of certificate signing is 0"); + return -108; + } + + // Create datum + dap_chain_datum_t * l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_DECREE, + l_datum_decree, + sizeof(*l_datum_decree) + l_datum_decree->header.data_size + + l_datum_decree->header.signs_size); + DAP_DELETE(l_datum_decree); + size_t l_datum_size = dap_chain_datum_size(l_datum); + + // Calc datum's hash + dap_chain_hash_fast_t l_key_hash; + dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_key_hash); + char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash); + char * l_key_str_out = dap_strcmp(l_hash_out_type, "hex") ? + dap_enc_base58_encode_hash_to_str(&l_key_hash) : l_key_str; + + // Add datum to mempool with datum_token hash as a key + char * l_gdb_group_mempool; + if (l_chain) + l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_new(l_chain); + else + l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_by_chain_type(l_net, CHAIN_TYPE_DECREE); + if (!l_gdb_group_mempool) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "No suitable chain for placing decree datum found"); + DAP_DELETE(l_datum); + DAP_DELETE(l_key_str); + DAP_DELETE(l_key_str_out); + DAP_DELETE(l_datum); + return -10; + } + bool l_placed = dap_global_db_set_sync(l_gdb_group_mempool, l_key_str, l_datum, l_datum_size, true) == 0; + dap_cli_server_cmd_set_reply_text(a_str_reply, "Datum %s is%s placed in datum pool", + l_key_str_out, l_placed ? "" : " not"); + + //additional checking for incorrect key format + DAP_DELETE(l_key_str); + DAP_DELETE(l_datum); + + break; + } + case CMD_SIGN:{ + if(!l_certs_count) { + dap_cli_server_cmd_set_reply_text(a_str_reply, + "decree sign command requres at least one valid certificate to sign the basic transaction of emission"); + return -106; + } + + const char * l_datum_hash_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-datum", &l_datum_hash_str); + if(l_datum_hash_str) { + char * l_datum_hash_hex_str = NULL; + char * l_datum_hash_base58_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_str); + // Search chain + if(l_chain_str) { + l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_str); + if (l_chain == NULL) { + char l_str_to_reply_chain[500] = {0}; + char *l_str_to_reply = NULL; + dap_sprintf(l_str_to_reply_chain, "%s requires parameter '-chain' to be valid chain name in chain net %s. Current chain %s is not valid\n", + a_argv[0], l_net_str, l_chain_str); + l_str_to_reply = dap_strcat2(l_str_to_reply,l_str_to_reply_chain); + dap_chain_t * l_chain; + l_str_to_reply = dap_strcat2(l_str_to_reply,"\nAvailable chain with decree support:\n"); + l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_DECREE); + l_str_to_reply = dap_strcat2(l_str_to_reply,"\t"); + l_str_to_reply = dap_strcat2(l_str_to_reply,l_chain->name); + l_str_to_reply = dap_strcat2(l_str_to_reply,"\n"); + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_to_reply); + return -103; + } else if (l_chain != dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_DECREE)){ // check chain to support decree + dap_cli_server_cmd_set_reply_text(a_str_reply, "Chain %s don't support decree", l_chain->name); + return -104; + } + }else if((l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_DECREE)) == NULL) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find chain with decree support."); + return -105; + } + + // Certificates thats will be used to sign currend datum decree +// dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-certs", &l_certs_str); + + // Load certs lists +// if (l_certs_str) +// dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_count); + +// if(!l_certs_count) { +// dap_cli_server_cmd_set_reply_text(a_str_reply, +// "decree sign command requres at least one valid certificate"); +// return -7; +// } + + char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_new(l_chain); + if(!l_gdb_group_mempool) { + l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_by_chain_type(l_net, CHAIN_TYPE_DECREE); + } + // datum hash may be in hex or base58 format + if(!dap_strncmp(l_datum_hash_str, "0x", 2) || !dap_strncmp(l_datum_hash_str, "0X", 2)) { + l_datum_hash_hex_str = dap_strdup(l_datum_hash_str); + l_datum_hash_base58_str = dap_enc_base58_from_hex_str_to_str(l_datum_hash_str); + } else { + l_datum_hash_hex_str = dap_enc_base58_to_hex_str_from_str(l_datum_hash_str); + l_datum_hash_base58_str = dap_strdup(l_datum_hash_str); + } + + const char *l_datum_hash_out_str; + if(!dap_strcmp(l_hash_out_type,"hex")) + l_datum_hash_out_str = l_datum_hash_hex_str; + else + l_datum_hash_out_str = l_datum_hash_base58_str; + + log_it(L_DEBUG, "Requested to sign decree creation %s in gdb://%s with certs %s", + l_gdb_group_mempool, l_datum_hash_hex_str, l_certs_str); + + dap_chain_datum_t * l_datum = NULL; + size_t l_datum_size = 0; + if((l_datum = (dap_chain_datum_t*) dap_global_db_get_sync(l_gdb_group_mempool, + l_datum_hash_hex_str, &l_datum_size, NULL, NULL )) != NULL) { + // Check if its decree creation + if(l_datum->header.type_id == DAP_CHAIN_DATUM_DECREE) { + dap_chain_datum_decree_t *l_datum_decree = DAP_DUP_SIZE(l_datum->data, l_datum->header.data_size); // for realloc + DAP_DELETE(l_datum); + + // Sign decree + size_t l_total_signs_success = 0; + if (l_certs_count) + l_datum_decree = s_sign_decree_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, + "Decree creation failed. Successful count of certificate signing is 0"); + return -108; + } + size_t l_decree_size = sizeof(*l_datum_decree) + l_datum_decree->header.data_size + l_datum_decree->header.signs_size; + dap_chain_datum_t * l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_DECREE, + l_datum_decree, l_decree_size); + DAP_DELETE(l_datum_decree); + + // Calc datum's hash + l_datum_size = dap_chain_datum_size(l_datum); + dap_chain_hash_fast_t l_key_hash={}; + dap_hash_fast(l_datum->data, l_decree_size, &l_key_hash); + char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash); + char * l_key_str_base58 = dap_enc_base58_encode_hash_to_str(&l_key_hash); + const char * l_key_out_str; + if(!dap_strcmp(l_hash_out_type,"hex")) + l_key_out_str = l_key_str; + else + l_key_out_str = l_key_str_base58; + + // Add datum to mempool with datum_token hash as a key + if( dap_global_db_set_sync(l_gdb_group_mempool, l_key_str, l_datum, dap_chain_datum_size(l_datum), true) == 0) { + + char* l_hash_str = l_datum_hash_hex_str; + // Remove old datum from pool + if( dap_global_db_del_sync(l_gdb_group_mempool, l_hash_str ) == 0) { + dap_cli_server_cmd_set_reply_text(a_str_reply, + "datum %s is replacing the %s in datum pool", + l_key_out_str, l_datum_hash_out_str); + + DAP_DELETE(l_datum); + //DAP_DELETE(l_datum_token); + DAP_DELETE(l_gdb_group_mempool); + return 0; + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, + "Warning! Can't remove old datum %s ( new datum %s added normaly in datum pool)", + l_datum_hash_out_str, l_key_out_str); + DAP_DELETE(l_datum); + //DAP_DELETE(l_datum_token); + DAP_DELETE(l_gdb_group_mempool); + return 1; + } + DAP_DELETE(l_hash_str); + DAP_DELETE(l_key_str); + DAP_DELETE(l_key_str_base58); + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, + "Error! datum %s produced from %s can't be placed in mempool", + l_key_out_str, l_datum_hash_out_str); + DAP_DELETE(l_datum); + //DAP_DELETE(l_datum_token); + DAP_DELETE(l_gdb_group_mempool); + DAP_DELETE(l_key_str); + DAP_DELETE(l_key_str_base58); + return -2; + } + + }else{ + dap_cli_server_cmd_set_reply_text(a_str_reply, + "Error! Wrong datum type. decree sign only decree datum"); + return -61; + } + }else{ + dap_cli_server_cmd_set_reply_text(a_str_reply, + "decree sign can't find datum with %s hash in the mempool of %s:%s",l_datum_hash_out_str,l_net? l_net->pub.name: "<undefined>", + l_chain?l_chain->name:"<undefined>"); + return -5; + } + DAP_DELETE(l_datum_hash_hex_str); + DAP_DELETE(l_datum_hash_base58_str); + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "decree sign need -datum <datum hash> argument"); + return -2; + } + break; + } + case CMD_ANCHOR:{ + + break; + } + default: + dap_cli_server_cmd_set_reply_text(a_str_reply, "Not found decree action. Use create, sign or anchor parametr"); + return -1; + } + + return 0; +} diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 0387edc7d4..8be8496228 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -38,6 +38,7 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "dap_chain_node.h" #include "dap_chain.h" #include "dap_chain_ledger.h" +#include "dap_chain_net_decree.h" #include "dap_chain_datum_tx.h" #include "uthash.h" @@ -83,6 +84,7 @@ typedef struct dap_chain_net{ dap_chain_t * chains; // double-linked list of chains const char *native_ticker; dap_ledger_t *ledger; + dap_chain_net_decree_t *decree; } pub; uint8_t pvt[]; } dap_chain_net_t; @@ -196,3 +198,5 @@ void dap_chain_net_sync_gdb_broadcast(dap_global_db_context_t *a_context, dap_st dap_list_t *dap_chain_datum_list(dap_chain_net_t *a_net, dap_chain_t *a_chain, dap_chain_datum_filter_func_t *a_filter_func, void *a_filter_func_param); int dap_chain_datum_add(dap_chain_t * a_chain, dap_chain_datum_t *a_datum, size_t a_datum_size, dap_hash_fast_t *a_tx_hash); + +bool dap_chain_net_get_load_mode(dap_chain_net_t * a_net); diff --git a/modules/net/include/dap_chain_net_decree.h b/modules/net/include/dap_chain_net_decree.h new file mode 100644 index 0000000000..1b2837a1f6 --- /dev/null +++ b/modules/net/include/dap_chain_net_decree.h @@ -0,0 +1,40 @@ +/* + * Authors: + * Frolov Daniil <daniil.frolov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Copyright (c) 2020, All rights reserved. + + This file is part of CellFrame SDK the open source project + + CellFrame 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. + + CellFrame 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 CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once + +#include "dap_chain_datum_decree.h" +#include "dap_list.h" + +typedef struct decree_params { + dap_list_t *pkeys; + uint256_t num_of_owners; + uint256_t min_num_of_owners; +} dap_chain_net_decree_t; + +// Default values + + +int dap_chain_net_decree_init(dap_chain_net_t *a_net); +int dap_chain_net_decree_deinit(dap_chain_net_t *a_net); + +int dap_chain_net_decree_load(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain); +int dap_chain_net_decree_verify(dap_chain_datum_decree_t * a_decree, dap_chain_net_t *a_net, uint32_t *a_signs_count, uint32_t *a_signs_verify); diff --git a/modules/net/include/dap_chain_net_tx.h b/modules/net/include/dap_chain_net_tx.h index 2c59bf7165..9b7e6038a9 100644 --- a/modules/net/include/dap_chain_net_tx.h +++ b/modules/net/include/dap_chain_net_tx.h @@ -87,4 +87,6 @@ dap_chain_datum_tx_spends_items_t * dap_chain_net_get_tx_cond_all_with_spends_by void dap_chain_datum_tx_spends_item_free(dap_chain_datum_tx_spends_item_t * a_items); 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_get_fee(dap_chain_net_id_t a_net_id, dap_chain_t *a_chain, 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, dap_chain_t *a_chain, uint256_t *a_value, dap_chain_addr_t *a_addr); +bool dap_chain_net_tx_replace_fee(dap_chain_net_id_t a_net_id, dap_chain_t *a_chain, uint256_t *a_value, dap_chain_addr_t *a_addr); diff --git a/modules/net/include/dap_chain_node_cli_cmd_tx.h b/modules/net/include/dap_chain_node_cli_cmd_tx.h index b421eb9746..00023c9606 100644 --- a/modules/net/include/dap_chain_node_cli_cmd_tx.h +++ b/modules/net/include/dap_chain_node_cli_cmd_tx.h @@ -44,3 +44,8 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply); */ int com_token(int a_argc, char ** a_argv, char **a_str_reply); +/** + * decree command + * + */ +int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply); diff --git a/modules/service/stake_lock/dap_chain_net_srv_stake_lock.c b/modules/service/stake_lock/dap_chain_net_srv_stake_lock.c index 2bb5e6600d..f02801c0c1 100644 --- a/modules/service/stake_lock/dap_chain_net_srv_stake_lock.c +++ b/modules/service/stake_lock/dap_chain_net_srv_stake_lock.c @@ -564,7 +564,7 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da /*________________________________________________________________________________________________________________*/ - bool l_net_fee_used = dap_chain_net_tx_get_fee(l_chain->net_id, &l_net_fee, &l_addr_fee); + bool l_net_fee_used = dap_chain_net_tx_get_fee(l_chain->net_id, NULL, &l_net_fee, &l_addr_fee); if(l_net_fee_used) SUM_256_256(l_value_need,l_net_fee,&l_value_need); SUM_256_256(l_value_need,l_value_fee,&l_value_need); @@ -1276,7 +1276,7 @@ dap_chain_datum_t *dap_chain_net_srv_stake_lock_datum_create(dap_chain_net_t *a_ // where to take coins for service dap_chain_addr_t l_addr_from; dap_chain_addr_t l_net_fee_addr = {}; - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id,&l_net_fee,&l_net_fee_addr); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, NULL, &l_net_fee, &l_net_fee_addr); if(l_net_fee_used) SUM_256_256(l_value_need,l_net_fee,&l_value_need); @@ -1411,7 +1411,7 @@ dap_chain_datum_t *dap_chain_burning_tx_create(dap_chain_t *a_chain, dap_enc_key const char *l_native_ticker = dap_chain_net_by_id(a_chain->net_id)->pub.native_ticker; dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(a_chain->ledger, a_token_ticker, a_addr_from, a_value, &l_value_transfer); - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, &l_net_fee, &l_addr_fee); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, NULL, &l_net_fee, &l_addr_fee); if(l_net_fee_used) SUM_256_256(l_total_fee,l_net_fee,&l_total_fee); @@ -1520,9 +1520,10 @@ static char *dap_chain_mempool_base_tx_for_stake_lock_create(dap_chain_t *a_chai dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); const char *l_native_ticker = l_net->pub.native_ticker; - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, &l_net_fee, &l_net_fee_addr); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, NULL, &l_net_fee, &l_net_fee_addr); if(l_net_fee_used) SUM_256_256(l_value_need,l_net_fee,&l_value_need); + // create first transaction (with tx_token) 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); diff --git a/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c index 1c1624f1f7..d6d3315ea1 100644 --- a/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c +++ b/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c @@ -100,7 +100,7 @@ int dap_chain_net_srv_stake_pos_delegate_init() size_t l_auth_certs_count = 0; dap_cert_t **l_auth_certs = NULL; for (dap_chain_t *l_chain = l_net_list[i]->pub.chains; l_chain; l_chain = l_chain->next) { - l_auth_certs = dap_chain_cs_dag_poa_get_auth_certs(l_chain, &l_auth_certs_count); + l_auth_certs = NULL;//dap_chain_cs_dag_poa_get_auth_certs(l_chain, &l_auth_certs_count); if (l_auth_certs) break; l_auth_certs = dap_chain_cs_block_poa_get_auth_certs(l_chain, &l_auth_certs_count); @@ -232,7 +232,7 @@ static bool s_stake_conditions_calc(dap_chain_tx_out_cond_t *a_cond, dap_chain_d size_t l_auth_certs_count = 0; dap_cert_t **l_auth_certs = NULL; for (dap_chain_t *l_chain = l_net->pub.chains; l_chain; l_chain = l_chain->next) { - l_auth_certs = dap_chain_cs_dag_poa_get_auth_certs(l_chain, &l_auth_certs_count); + l_auth_certs = NULL;//dap_chain_cs_dag_poa_get_auth_certs(l_chain, &l_auth_certs_count); if (l_auth_certs) break; l_auth_certs = dap_chain_cs_block_poa_get_auth_certs(l_chain, &l_auth_certs_count); @@ -624,7 +624,7 @@ static bool s_stake_block_commit(dap_chain_net_t *a_net, dap_list_t *a_tx_hash_l size_t l_auth_certs_count = 0; dap_cert_t **l_auth_certs = NULL; for(dap_chain_t *l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next) { - l_auth_certs = dap_chain_cs_dag_poa_get_auth_certs(l_chain, &l_auth_certs_count); + l_auth_certs = NULL;//dap_chain_cs_dag_poa_get_auth_certs(l_chain, &l_auth_certs_count); if(l_auth_certs) break; l_auth_certs = dap_chain_cs_block_poa_get_auth_certs(l_chain, &l_auth_certs_count); diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index 4b4b714a68..f7ff0c0a13 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -257,48 +257,50 @@ static bool s_xchange_verificator_callback(dap_ledger_t * a_ledger,dap_hash_fast */ static void s_callback_decree (dap_chain_net_srv_t * a_srv, dap_chain_net_t *a_net, dap_chain_t * a_chain, dap_chain_datum_decree_t * a_decree, size_t a_decree_size) { + +// TODO: finish function pthread_rwlock_wrlock(&s_service_fees_rwlock); dap_chain_net_srv_fee_item_t *l_fee = NULL; - switch(a_decree->header.action){ - case DAP_CHAIN_DATUM_DECREE_ACTION_UPDATE:{ - HASH_FIND(hh,s_service_fees,&a_net->pub.id, sizeof(a_net->pub.id), l_fee); - if(l_fee == NULL){ - log_it(L_WARNING,"Decree update for net id 0x%016" DAP_UINT64_FORMAT_X" when such id can't find in hash table", a_net->pub.id.uint64); - pthread_rwlock_unlock(&s_service_fees_rwlock); - return; - } - }break; - case DAP_CHAIN_DATUM_DECREE_ACTION_CREATE:{ - HASH_FIND(hh,s_service_fees,&a_net->pub.id, sizeof(a_net->pub.id), l_fee); - if (l_fee) { - log_it(L_WARNING, "Decree create for net id 0x%016" DAP_UINT64_FORMAT_X" when such id already in hash table", a_net->pub.id.uint64); - pthread_rwlock_unlock(&s_service_fees_rwlock); - return; - } - l_fee = DAP_NEW_Z(dap_chain_net_srv_fee_item_t); - l_fee->net_id = a_net->pub.id; - HASH_ADD(hh, s_service_fees, net_id, sizeof(l_fee->net_id), l_fee); - } break; - } - size_t l_tsd_offset = 0; - - while(l_tsd_offset < (a_decree_size - sizeof(a_decree->header)) ){ - dap_tsd_t *l_tsd = (dap_tsd_t*) (a_decree->tsd_sections + l_tsd_offset); - switch((dap_chain_net_srv_fee_tsd_type_t)l_tsd->type) { - case TSD_FEE_TYPE: - l_fee->fee_type = dap_tsd_get_scalar(l_tsd, uint16_t); - break; - case TSD_FEE: - l_fee->fee = dap_tsd_get_scalar(l_tsd, uint256_t); - break; - case TSD_FEE_ADDR: - l_fee->fee_addr = dap_tsd_get_scalar(l_tsd, dap_chain_addr_t); - default: - break; - } - l_tsd_offset += dap_tsd_size(l_tsd); - } - pthread_rwlock_unlock(&s_service_fees_rwlock); +// switch(a_decree->header.action){ +// case DAP_CHAIN_DATUM_DECREE_ACTION_UPDATE:{ +// HASH_FIND(hh,s_service_fees,&a_net->pub.id, sizeof(a_net->pub.id), l_fee); +// if(l_fee == NULL){ +// log_it(L_WARNING,"Decree update for net id 0x%016" DAP_UINT64_FORMAT_X" when such id can't find in hash table", a_net->pub.id.uint64); +// pthread_rwlock_unlock(&s_service_fees_rwlock); +// return; +// } +// }break; +// case DAP_CHAIN_DATUM_DECREE_ACTION_CREATE:{ +// HASH_FIND(hh,s_service_fees,&a_net->pub.id, sizeof(a_net->pub.id), l_fee); +// if (l_fee) { +// log_it(L_WARNING, "Decree create for net id 0x%016" DAP_UINT64_FORMAT_X" when such id already in hash table", a_net->pub.id.uint64); +// pthread_rwlock_unlock(&s_service_fees_rwlock); +// return; +// } +// l_fee = DAP_NEW_Z(dap_chain_net_srv_fee_item_t); +// l_fee->net_id = a_net->pub.id; +// HASH_ADD(hh, s_service_fees, net_id, sizeof(l_fee->net_id), l_fee); +// } break; +// } +// size_t l_tsd_offset = 0; +// TODO: move to ACTION_CREATE +// while(l_tsd_offset < (a_decree_size - sizeof(a_decree->header)) ){ +// dap_tsd_t *l_tsd = (dap_tsd_t*) (a_decree->data_n_signs + l_tsd_offset); +// switch((dap_chain_net_srv_fee_tsd_type_t)l_tsd->type) { +// case TSD_FEE_TYPE: +// l_fee->fee_type = dap_tsd_get_scalar(l_tsd, uint16_t); +// break; +// case TSD_FEE: +// l_fee->fee = dap_tsd_get_scalar(l_tsd, uint256_t); +// break; +// case TSD_FEE_ADDR: +// l_fee->fee_addr = dap_tsd_get_scalar(l_tsd, dap_chain_addr_t); +// default: +// break; +// } +// l_tsd_offset += dap_tsd_size(l_tsd); +// } +// pthread_rwlock_unlock(&s_service_fees_rwlock); } static bool s_srv_xchange_get_fee(dap_chain_net_id_t a_net_id, uint256_t *a_fee, dap_chain_addr_t *a_addr, uint16_t *a_type) @@ -351,7 +353,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_request(dap_chain_net_srv_xchan l_fee_transfer; dap_chain_addr_t l_addr_net_fee; dap_list_t *l_list_fee_out = NULL; - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_price->net->pub.id, &l_net_fee, &l_addr_net_fee); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_price->net->pub.id, NULL, &l_net_fee, &l_addr_net_fee); if (l_net_fee_used) SUM_256_256(l_total_fee, l_net_fee, &l_total_fee); @@ -491,7 +493,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha l_fee_transfer; dap_chain_addr_t l_net_fee_addr, l_service_fee_addr; dap_list_t *l_list_fee_out = NULL; - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_price->net->pub.id, &l_net_fee, &l_net_fee_addr); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_price->net->pub.id, NULL, &l_net_fee, &l_net_fee_addr); if (l_net_fee_used) SUM_256_256(l_net_fee, a_price->fee, &l_total_fee); uint16_t l_service_fee_type; @@ -792,7 +794,7 @@ static bool s_xchange_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price, } uint256_t l_net_fee = {}, l_transfer_fee; dap_chain_addr_t l_addr_fee = {}; - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_price->net->pub.id, &l_net_fee, &l_addr_fee); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_price->net->pub.id, NULL, &l_net_fee, &l_addr_fee); 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 -- GitLab