diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index c00e357d64a2e785f8bbacac4681c1f32816eb95..5bd9b5980d12f9888f4ac7cd69ba1be06a6e34fc 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -96,6 +96,8 @@ 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 void (*dap_chain_callback_set_min_esbocs_validators_count)(dap_chain_t *a_chain, uint16_t a_new_value); + typedef enum dap_chain_type { @@ -173,6 +175,7 @@ typedef struct dap_chain { dap_chain_callback_get_list callback_get_atoms; dap_chain_callback_get_poa_certs callback_get_poa_certs; + dap_chain_callback_set_min_esbocs_validators_count callback_set_min_esbocs_validators_count; dap_list_t * atom_notifiers; // dap_chain_callback_notify_t callback_notify; diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c index ad99cba74df7ba671c456855504f04f87de890a9..1b9a98312faea4390063d86d194b7ceb7593f6e3 100644 --- a/modules/common/dap_chain_datum_decree.c +++ b/modules/common/dap_chain_datum_decree.c @@ -173,6 +173,180 @@ int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, ui return 1; } +int dap_chain_datum_decree_get_stake_tx_hash(dap_chain_datum_decree_t *a_decree, dap_hash_fast_t *a_tx_hash) +{ + if(!a_decree || !a_tx_hash){ + log_it(L_WARNING,"Wrong arguments"); + return -1; + } + + size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; + + 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_STAKE_TX_HASH){ + if(l_tsd->size > sizeof(dap_hash_fast_t)){ + log_it(L_WARNING,"Wrong fee tsd data size."); + return -1; + } + *a_tx_hash = dap_tsd_get_scalar(l_tsd, dap_hash_fast_t); + return 0; + } + l_tsd_offset += l_tsd_size; + } + return 1; +} + +int dap_chain_datum_decree_get_stake_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_stake_value) +{ + if(!a_decree || !a_stake_value){ + log_it(L_WARNING,"Wrong arguments"); + return -1; + } + + size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; + + 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_STAKE_VALUE){ + if(l_tsd->size > sizeof(uint256_t)){ + log_it(L_WARNING,"Wrong fee tsd data size."); + return -1; + } + *a_stake_value = dap_tsd_get_scalar(l_tsd, uint256_t); + return 0; + } + l_tsd_offset += l_tsd_size; + } + return 1; +} + +int dap_chain_datum_decree_get_stake_signing_addr(dap_chain_datum_decree_t *a_decree, dap_chain_addr_t *a_signing_addr) +{ + if(!a_decree || !a_signing_addr){ + log_it(L_WARNING,"Wrong arguments"); + return -1; + } + + size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; + + 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_STAKE_SIGNING_ADDR){ + if(l_tsd->size > sizeof(dap_chain_addr_t)){ + log_it(L_WARNING,"Wrong fee tsd data size."); + return -1; + } + *a_signing_addr = dap_tsd_get_scalar(l_tsd, dap_chain_addr_t); + return 0; + } + l_tsd_offset += l_tsd_size; + } + return 1; +} + +int dap_chain_datum_decree_get_stake_signer_node_addr(dap_chain_datum_decree_t *a_decree, dap_chain_node_addr_t *a_node_addr) +{ + if(!a_decree || !a_node_addr){ + log_it(L_WARNING,"Wrong arguments"); + return -1; + } + + size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; + + 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_STAKE_SIGNER_NODE_ADDR){ + if(l_tsd->size > sizeof(dap_chain_node_addr_t)){ + log_it(L_WARNING,"Wrong fee tsd data size."); + return -1; + } + *a_node_addr = dap_tsd_get_scalar(l_tsd, dap_chain_node_addr_t); + return 0; + } + l_tsd_offset += l_tsd_size; + } + return 1; +} + +int dap_chain_datum_decree_get_stake_min_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_value) +{ + if(!a_decree || !a_min_value){ + log_it(L_WARNING,"Wrong arguments"); + return -1; + } + + size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; + + 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_STAKE_MIN_VALUE){ + if(l_tsd->size > sizeof(uint256_t)){ + log_it(L_WARNING,"Wrong fee tsd data size."); + return -1; + } + *a_min_value = dap_tsd_get_scalar(l_tsd, uint256_t); + return 0; + } + l_tsd_offset += l_tsd_size; + } + return 1; +} + +int dap_chain_datum_decree_get_stake_min_signers_count(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_signers_count) +{ + if(!a_decree || !a_min_signers_count){ + log_it(L_WARNING,"Wrong arguments"); + return -1; + } + + size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; + + 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_STAKE_MIN_SIGNERS_COUNT){ + if(l_tsd->size > sizeof(uint256_t)){ + log_it(L_WARNING,"Wrong fee tsd data size."); + return -1; + } + *a_min_signers_count = 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: "); diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h index 01baccd4bc7559a0aeacdd2fcddd2d64f7a31f78..1b7a6f492b2b475171a2dd30ce0ef6f2594fd44e 100644 --- a/modules/common/include/dap_chain_datum_decree.h +++ b/modules/common/include/dap_chain_datum_decree.h @@ -62,10 +62,14 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_ #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 +#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 +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE 0x0005 +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE 0x0006 +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE 0x0007 +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT 0x0008 // DECREE TSD types #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN 0x0001 @@ -74,6 +78,13 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_ #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER 0x0004 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_TON_SIGNERS_MIN 0x0005 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET 0x0006 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH 0x0007 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE 0x0008 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR 0x0009 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR 0x0010 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE 0x0011 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT 0x0012 + /** * @brief dap_chain_datum_decree_get_signs * @param decree pointer to decree @@ -115,6 +126,54 @@ dap_list_t *dap_chain_datum_decree_get_owners(dap_chain_datum_decree_t *a_decree */ int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_owners_num); +/** + * @brief dap_chain_datum_decree_get_tx_hash get stake tx hash + * @param a_decree pointer to decree + * @param a_tx_hash pointer to tx hash buffer + * @return result code. 0 - success + */ +int dap_chain_datum_decree_get_stake_tx_hash(dap_chain_datum_decree_t *a_decree, dap_hash_fast_t *a_tx_hash); + +/** + * @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_stake_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_stake_value); + +/** + * @brief dap_chain_datum_decree_get_stake_signing_addr get signing address + * @param a_decree pointer to decree + * @param a_signing_addr pointer to signing address buffer + * @return result code. 0 - success + */ +int dap_chain_datum_decree_get_stake_signing_addr(dap_chain_datum_decree_t *a_decree, dap_chain_addr_t *a_signing_addr); + +/** + * @brief dap_chain_datum_decree_get_stake_signer_node_addr get signer node address + * @param a_decree pointer to decree + * @param a_node_addr pointer to signer node address buffer + * @return result code. 0 - success + */ +int dap_chain_datum_decree_get_stake_signer_node_addr(dap_chain_datum_decree_t *a_decree, dap_chain_node_addr_t *a_node_addr); + +/** + * @brief dap_chain_datum_decree_get_stake_min_value get minimum stake value + * @param a_decree pointer to decree + * @param a_min_value pointer to min stake value buffer + * @return result code. 0 - success + */ +int dap_chain_datum_decree_get_stake_min_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_value); + +/** + * @brief dap_chain_datum_decree_get_stake_min_signers_count get minimum signers count + * @param a_decree pointer to decree + * @param a_min_signers_count pointer to min signer count buffer + * @return result code. 0 - success + */ +int dap_chain_datum_decree_get_stake_min_signers_count(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_signers_count); + /** * @brief dap_chain_datum_decree_certs_dump compose decree signatures output string * @param a_str_out pointer to output text buffer diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index f9eb785590c72121e2ea36071a78b5574a5f031a..023eddb34563f73e664ff72bcf0aed56860c6b48 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -4,6 +4,7 @@ #include "rand/dap_rand.h" #include "dap_chain_net.h" #include "dap_chain_common.h" +#include "dap_chain_mempool.h" #include "dap_chain_cell.h" #include "dap_chain_cs.h" #include "dap_chain_cs_blocks.h" @@ -11,6 +12,8 @@ #include "dap_stream_ch_chain_voting.h" #include "dap_chain_net_srv_stake_pos_delegate.h" #include "dap_chain_ledger.h" +#include "dap_chain_node_cli.h" +#include "dap_chain_node_cli_cmd.h" #define LOG_TAG "dap_chain_cs_esbocs" @@ -48,7 +51,8 @@ static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks); static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cfg); static size_t s_callback_block_sign(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t **a_block_ptr, size_t a_block_size); static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t *a_block, size_t a_block_size); - +void dap_chain_esbocs_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value); +static int s_cli_esbocs(int argc, char ** argv, char **str_reply); DAP_STATIC_INLINE const char *s_voting_msg_type_to_str(uint8_t a_type) { switch (a_type) { @@ -90,6 +94,9 @@ int dap_chain_cs_esbocs_init() { dap_stream_ch_chain_voting_init(); dap_chain_cs_add("esbocs", s_callback_new); + dap_cli_server_cmd_add ("esbocs", s_cli_esbocs, "ESBOCS commands", + "esbocs min_validators_count -net <net_name> -chain <chain_name> -cert <poa_cert_name> -val_count <value>" + "\tSets minimum validators count for ESBOCS consensus\n\n"); return 0; } @@ -111,6 +118,8 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) l_session->chain = a_chain; l_session->esbocs = l_esbocs; + l_esbocs->chain->callback_set_min_esbocs_validators_count = dap_chain_esbocs_set_min_validators_count; + l_esbocs->session = l_session; l_blocks->_inheritor = l_esbocs; @@ -298,10 +307,9 @@ static void *s_callback_list_form(const void *a_srv_validator, UNUSED_ARG void * return l_validator; } -void dap_chain_esbocs_set_min_validators_count(dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, uint16_t a_new_value) +void dap_chain_esbocs_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value) { - dap_chain_t *l_chain = dap_chain_net_get_chain_by_id(dap_chain_net_by_id(a_net_id), a_chain_id); - dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain); + dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks); dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); l_esbocs_pvt->min_validators_count = a_new_value; @@ -1506,3 +1514,139 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl } return 0; } + +static char *s_esbocs_decree_put(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net) +{ + // Put the transaction to mempool or directly to chains + size_t l_decree_size = dap_chain_datum_decree_get_size(a_decree); + dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_DECREE, a_decree, l_decree_size); + dap_chain_t *l_chain = dap_chain_net_get_chain_by_chain_type(a_net, CHAIN_TYPE_DECREE); + if (!l_chain) { + return NULL; + } + // Processing will be made according to autoprocess policy + char *l_ret = dap_chain_mempool_datum_add(l_datum, l_chain, "hex"); + DAP_DELETE(l_datum); + return l_ret; +} + +static dap_chain_datum_decree_t *s_esbocs_decree_set_min_validators_count(dap_chain_net_t *a_net, uint256_t a_value, dap_cert_t *a_cert) +{ + size_t l_total_tsd_size = 0; + dap_chain_datum_decree_t *l_decree = NULL; + dap_list_t *l_tsd_list = NULL; + dap_tsd_t *l_tsd = NULL; + + 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_STAKE_MIN_SIGNERS_COUNT; + l_tsd->size = sizeof(uint256_t); + *(uint256_t*)(l_tsd->data) = a_value; + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + + l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); + 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; + dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_DECREE); + if(!l_chain){ + log_it(L_ERROR, "Can't find chain with decree support."); + DAP_DELETE(l_decree); + return NULL; + } + l_decree->header.common_decree_params.chain_id = l_chain->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_STAKE_MIN_VALIDATORS_COUNT; + l_decree->header.data_size = l_total_tsd_size; + l_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_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); + + size_t l_cur_sign_offset = l_decree->header.data_size + l_decree->header.signs_size; + size_t l_total_signs_size = l_decree->header.signs_size; + + dap_sign_t * l_sign = dap_cert_sign(a_cert, l_decree, + sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size, 0); + + if (l_sign) { + size_t l_sign_size = dap_sign_get_size(l_sign); + l_decree = DAP_REALLOC(l_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size); + memcpy((byte_t*)l_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; + l_decree->header.signs_size = l_total_signs_size; + DAP_DELETE(l_sign); + log_it(L_DEBUG,"<-- Signed with '%s'", a_cert->name); + }else{ + log_it(L_ERROR, "Decree signing failed"); + DAP_DELETE(l_decree); + return NULL; + } + + return l_decree; +} + +/** + * @brief + * parse and execute cellframe-node-cli esbocs commands + * @param argc arguments count + * @param argv array with arguments + * @param arg_func + * @param str_reply + * @return + */ +static int s_cli_esbocs(int a_argc, char ** a_argv, char **a_str_reply) +{ + int ret = -666; + int l_arg_index = 1; + dap_chain_net_t * l_chain_net = NULL; + dap_chain_t * l_chain = NULL; + const char *l_cert_str = NULL, + *l_value_str = NULL; + + if (dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index,a_argc,a_argv,a_str_reply,&l_chain,&l_chain_net)) { + return -3; + } + + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); + if (!l_cert_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_validators_count' required parameter -cert"); + return -3; + } + dap_cert_t *l_poa_cert = dap_cert_find_by_name(l_cert_str); + if (!l_poa_cert) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); + return -25; + } + + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-val_count", &l_value_str); + if (!l_value_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_validators_count' required parameter -val_count"); + return -9; + } + uint256_t l_value = dap_chain_balance_scan(l_value_str); + if (IS_ZERO_256(l_value)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-val_count' param"); + return -10; + } + + dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_min_validators_count(l_chain_net, l_value, l_poa_cert); + if (l_decree && s_esbocs_decree_put(l_decree, l_chain_net)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count is setted"); + DAP_DELETE(l_decree); + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count setting failed"); + DAP_DELETE(l_decree); + return -21; + } + + return ret; +} diff --git a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h index 77778ec4b61f72f3edce906ae33ff9229a7373f5..0aaee8578e296a9718e1651fcdc3a980127caf93 100644 --- a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h +++ b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h @@ -135,3 +135,4 @@ typedef struct dap_chain_esbocs_session { #define DAP_CHAIN_ESBOCS(a) ((dap_chain_esbocs_t *)(a)->_inheritor) int dap_chain_cs_esbocs_init(); void dap_chain_cs_esbocs_deinit(void); + diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c index dfcf3abdafceeaaf453884aad5b52d85658a4d63..c2ef071b6104ec151dd6ac227108fa484bac87ea 100644 --- a/modules/net/dap_chain_net_decree.c +++ b/modules/net/dap_chain_net_decree.c @@ -32,6 +32,8 @@ #include "dap_chain_net_decree.h" #include "dap_chain_net_srv.h" #include "dap_chain_net_tx.h" +#include "dap_chain_net_srv_stake_pos_delegate.h" + #define LOG_TAG "chain_net_decree" @@ -326,8 +328,11 @@ 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) { - uint256_t l_fee, l_min_owners, l_num_of_owners; + uint256_t l_uint256_buffer; + dap_chain_addr_t l_addr = {}; //???????? + dap_hash_fast_t l_hash = {}; + dap_chain_node_addr_t l_node_addr = {}; dap_chain_net_t *l_net = NULL; dap_list_t *l_owners_list = NULL; @@ -351,14 +356,14 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai l_net->pub.decree->fee_addr = l_decree_addr; } - if (!dap_chain_datum_decree_get_fee(a_decree, &l_fee)){ + if (!dap_chain_datum_decree_get_fee(a_decree, &l_uint256_buffer)){ 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)){ + if(!dap_chain_net_tx_add_fee(a_chain->net_id, a_chain, &l_uint256_buffer, 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)){ + if(!dap_chain_net_tx_replace_fee(a_chain->net_id, a_chain, &l_uint256_buffer, l_addr)){ log_it(L_WARNING,"Can't replace fee value."); return -103; } @@ -369,26 +374,66 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai } break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS: - l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_num_of_owners); + l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_uint256_buffer); 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; + l_net->pub.decree->num_of_owners = l_uint256_buffer; 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: - if (dap_chain_datum_decree_get_min_owners(a_decree, &l_min_owners)){ + if (dap_chain_datum_decree_get_min_owners(a_decree, &l_uint256_buffer)){ 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; + l_net->pub.decree->min_num_of_owners = l_uint256_buffer; break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_TON_SIGNERS_MIN: + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE: + if (dap_chain_datum_decree_get_stake_tx_hash(a_decree, &l_hash)){ + log_it(L_WARNING,"Can't get tx hash from decree."); + return -105; + } + if (dap_chain_datum_decree_get_stake_value(a_decree, &l_uint256_buffer)){ + log_it(L_WARNING,"Can't get stake value from decree."); + return -105; + } + if (dap_chain_datum_decree_get_stake_signing_addr(a_decree, &l_addr)){ + log_it(L_WARNING,"Can't get signing address from decree."); + return -105; + } + if (dap_chain_datum_decree_get_stake_signer_node_addr(a_decree, &l_node_addr)){ + log_it(L_WARNING,"Can't get signer node address from decree."); + return -105; + } + dap_chain_net_srv_stake_key_delegate(l_net, &l_addr, &l_hash, l_uint256_buffer, &l_node_addr); + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE: + if (dap_chain_datum_decree_get_stake_signing_addr(a_decree, &l_addr)){ + log_it(L_WARNING,"Can't get signing address from decree."); + return -105; + } + dap_chain_net_srv_stake_key_invalidate(&l_addr); + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE: + if (dap_chain_datum_decree_get_stake_min_value(a_decree, &l_uint256_buffer)){ + log_it(L_WARNING,"Can't get min stake value from decree."); + return -105; + } + dap_chain_net_srv_stake_set_allowed_min_value(l_uint256_buffer); + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT: + if (dap_chain_datum_decree_get_stake_min_value(a_decree, &l_uint256_buffer)){ + log_it(L_WARNING,"Can't get min stake value from decree."); + return -105; + } + a_chain->callback_set_min_esbocs_validators_count(a_chain, (uint16_t)dap_chain_uint256_to(l_uint256_buffer)); break; default: return -1; } 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 ca0a8eb1e8bba2ed73714c37646d9423e0939cf8..976aa67b86d27fbf9101cc99faf0f3c40ad14b5e 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 @@ -44,6 +44,13 @@ static bool s_stake_verificator_callback(dap_ledger_t * a_ledger,dap_hash_fast_t static void s_stake_updater_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_cond); static dap_chain_net_srv_stake_t *s_srv_stake = NULL; +typedef struct dap_chain_net_srv_stake_cache_data +{ + uint256_t value; + dap_chain_addr_t signing_addr; + dap_chain_hash_fast_t tx_hash; + dap_chain_node_addr_t node_addr; +} DAP_ALIGN_PACKED dap_chain_net_srv_stake_cache_data_t; /** * @brief dap_stream_ch_vpn_init Init actions for VPN stream channel @@ -76,6 +83,8 @@ int dap_chain_net_srv_stake_pos_delegate_init() " {-wallet <wallet_name> -fee <value> | -poa_cert <cert_name>}\n" "\tInvalidate requested delegated stake transaction by hash or cert name or cert pkey hash within net name and" " return m-tokens to specified wallet (if any)\n" + "srv_stake min_value -net <net_name> -cert <cert_name> -value <value>" + "\tSets the minimum stake value" ); s_srv_stake = DAP_NEW_Z(dap_chain_net_srv_stake_t); @@ -124,11 +133,11 @@ static void s_stake_updater_callback(dap_ledger_t UNUSED_ARG *a_ledger, dap_chai dap_chain_net_srv_stake_key_invalidate(&a_cond->subtype.srv_stake_pos_delegate.signing_addr); } -static bool s_srv_stake_is_poa_cert(dap_enc_key_t *a_key) +static bool s_srv_stake_is_poa_cert(dap_chain_net_t *a_net, dap_enc_key_t *a_key) { bool l_is_poa_cert = false; dap_pkey_t *l_pkey = dap_pkey_from_enc_key(a_key); - for (dap_list_t *it = s_srv_stake->auth_cert_pkeys; it; it = it->next) + for (dap_list_t *it = a_net->pub.decree->pkeys; it; it = it->next) if (dap_pkey_compare(l_pkey, (dap_pkey_t *)it->data)) { l_is_poa_cert = true; break; @@ -150,6 +159,7 @@ void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr l_stake->value = a_value; l_stake->tx_hash = *a_stake_tx_hash; HASH_ADD(hh, s_srv_stake->itemlist, signing_addr, sizeof(dap_chain_addr_t), l_stake); + } void dap_chain_net_srv_stake_key_invalidate(dap_chain_addr_t *a_signing_addr) @@ -355,11 +365,82 @@ static dap_chain_datum_decree_t *s_stake_decree_approve(dap_chain_net_t *a_net, } // create approve decree + size_t l_total_tsd_size = 0; dap_chain_datum_decree_t *l_decree = NULL; - //TODO: form decree for key delegating + dap_list_t *l_tsd_list = NULL; + dap_tsd_t *l_tsd = NULL; + + l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(dap_hash_fast_t); + l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH; + l_tsd->size = sizeof(dap_hash_fast_t); + *(dap_hash_fast_t*)(l_tsd->data) = *a_stake_tx_hash; + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + + 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_STAKE_VALUE; + l_tsd->size = sizeof(uint256_t); + *(uint256_t*)(l_tsd->data) = l_tx_out_cond->header.value; + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + + l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(dap_chain_addr_t); + l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR; + l_tsd->size = sizeof(dap_chain_addr_t); + *(dap_chain_addr_t*)(l_tsd->data) = l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr; + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + + l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(dap_chain_node_addr_t); + l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR; + l_tsd->size = sizeof(dap_chain_node_addr_t); + *(dap_chain_node_addr_t*)(l_tsd->data) = l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr; + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + + l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); + 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 = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_DECREE)->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_STAKE_APPROVE; + l_decree->header.data_size = l_total_tsd_size; + l_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_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); + + size_t l_cur_sign_offset = l_decree->header.data_size + l_decree->header.signs_size; + size_t l_total_signs_size = l_decree->header.signs_size; + + dap_sign_t * l_sign = dap_cert_sign(a_cert, l_decree, + sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size, 0); + + if (l_sign) { + size_t l_sign_size = dap_sign_get_size(l_sign); + l_decree = DAP_REALLOC(l_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size); + memcpy((byte_t*)l_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; + l_decree->header.signs_size = l_total_signs_size; + DAP_DELETE(l_sign); + log_it(L_DEBUG,"<-- Signed with '%s'", a_cert->name); + }else{ + log_it(L_ERROR, "Decree signing failed"); + DAP_DELETE(l_decree); + return NULL; + } + //TODO: form decree for key delegating /* Used sections - a_stake_tx_hash l_tx_out_cond->header.value, l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr, @@ -371,6 +452,7 @@ static dap_chain_datum_decree_t *s_stake_decree_approve(dap_chain_net_t *a_net, log_it( L_ERROR, "Can't add sign output"); return NULL; } */ + return l_decree; } @@ -482,7 +564,7 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h return l_tx; } -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_enc_key_t *a_key) +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); @@ -501,8 +583,58 @@ static dap_chain_datum_decree_t *s_stake_decree_invalidate(dap_chain_net_t *a_ne } // create invalidate decree + size_t l_total_tsd_size = 0; dap_chain_datum_decree_t *l_decree = NULL; - //TODO: form decree for key delegating + dap_list_t *l_tsd_list = NULL; + dap_tsd_t *l_tsd = NULL; + + l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(dap_chain_addr_t); + l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR; + l_tsd->size = sizeof(dap_chain_addr_t); + *(dap_chain_addr_t*)(l_tsd->data) = l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr; + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + + l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); + 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 = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_DECREE)->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_STAKE_INVALIDATE; + l_decree->header.data_size = l_total_tsd_size; + l_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_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); + + size_t l_cur_sign_offset = l_decree->header.data_size + l_decree->header.signs_size; + size_t l_total_signs_size = l_decree->header.signs_size; + + dap_sign_t * l_sign = dap_cert_sign(a_cert, l_decree, + sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size, 0); + + if (l_sign) { + size_t l_sign_size = dap_sign_get_size(l_sign); + l_decree = DAP_REALLOC(l_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size); + memcpy((byte_t*)l_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; + l_decree->header.signs_size = l_total_signs_size; + DAP_DELETE(l_sign); + log_it(L_DEBUG,"<-- Signed with '%s'", a_cert->name); + }else{ + log_it(L_ERROR, "Decree signing failed"); + DAP_DELETE(l_decree); + return NULL; + } /* Used sections @@ -517,6 +649,64 @@ static dap_chain_datum_decree_t *s_stake_decree_invalidate(dap_chain_net_t *a_ne return l_decree; } +static dap_chain_datum_decree_t *s_stake_decree_set_min_stake(dap_chain_net_t *a_net, uint256_t a_value, dap_cert_t *a_cert) +{ + size_t l_total_tsd_size = 0; + dap_chain_datum_decree_t *l_decree = NULL; + dap_list_t *l_tsd_list = NULL; + dap_tsd_t *l_tsd = NULL; + + 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_STAKE_MIN_VALUE; + l_tsd->size = sizeof(uint256_t); + *(uint256_t*)(l_tsd->data) = a_value; + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + + l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); + 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 = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_DECREE)->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_STAKE_MIN_VALUE; + l_decree->header.data_size = l_total_tsd_size; + l_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_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); + + size_t l_cur_sign_offset = l_decree->header.data_size + l_decree->header.signs_size; + size_t l_total_signs_size = l_decree->header.signs_size; + + dap_sign_t * l_sign = dap_cert_sign(a_cert, l_decree, + sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size, 0); + + if (l_sign) { + size_t l_sign_size = dap_sign_get_size(l_sign); + l_decree = DAP_REALLOC(l_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size); + memcpy((byte_t*)l_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; + l_decree->header.signs_size = l_total_signs_size; + DAP_DELETE(l_sign); + log_it(L_DEBUG,"<-- Signed with '%s'", a_cert->name); + }else{ + log_it(L_ERROR, "Decree signing failed"); + DAP_DELETE(l_decree); + return NULL; + } + + return l_decree; +} + char *s_stake_order_create(dap_chain_net_t *a_net, uint256_t *a_fee, dap_enc_key_t *a_key) { dap_chain_hash_fast_t l_tx_hash = {}; @@ -797,7 +987,7 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, dap_strin static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) { enum { - CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_APPROVE, CMD_TX_LIST, CMD_INVALIDATE + CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_APPROVE, CMD_TX_LIST, CMD_INVALIDATE, CMD_MIN_VALUE }; int l_arg_index = 1; @@ -829,6 +1019,11 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "invalidate", NULL)) { l_cmd_num = CMD_INVALIDATE; } + // RSetss stake minimum value + else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "min_value", NULL)) { + l_cmd_num = CMD_MIN_VALUE; + } + switch (l_cmd_num) { case CMD_ORDER: return s_cli_srv_stake_order(a_argc, a_argv, l_arg_index + 1, a_str_reply, l_hash_out_type); @@ -957,7 +1152,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); return -18; } - if (!s_srv_stake_is_poa_cert(l_cert->enc_key)) { + if (!s_srv_stake_is_poa_cert(l_net, l_cert->enc_key)) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is not PoA root one"); return -21; } @@ -1150,11 +1345,11 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); return -25; } - if (!s_srv_stake_is_poa_cert(l_poa_cert->enc_key)) { + if (!s_srv_stake_is_poa_cert(l_net, l_poa_cert->enc_key)) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is not PoA root one"); return -26; } - dap_chain_datum_decree_t *l_decree = s_stake_decree_invalidate(l_net, l_final_tx_hash, l_poa_cert->enc_key); + dap_chain_datum_decree_t *l_decree = s_stake_decree_invalidate(l_net, l_final_tx_hash, l_poa_cert); if (l_decree && s_stake_decree_put(l_decree, l_net)) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified delageted key invalidated. " "Try to execute this command with -wallet to return m-tokens to owner"); @@ -1168,7 +1363,58 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) } } } break; + case CMD_MIN_VALUE: { + const char *l_net_str = NULL, + *l_cert_str = NULL, + *l_value_str = NULL; + l_arg_index++; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str); + if (!l_net_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' required parameter -net"); + return -3; + } + dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); + if (!l_net) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str); + return -4; + } + + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); + if (!l_cert_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' required parameter -cert"); + return -3; + } + dap_cert_t *l_poa_cert = dap_cert_find_by_name(l_cert_str); + if (!l_poa_cert) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); + return -25; + } + if (!s_srv_stake_is_poa_cert(l_net, l_poa_cert->enc_key)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is not PoA root one"); + return -26; + } + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_value_str); + if (!l_value_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' required parameter -value"); + return -9; + } + uint256_t l_value = dap_chain_balance_scan(l_value_str); + if (IS_ZERO_256(l_value)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-value' param"); + return -10; + } + + dap_chain_datum_decree_t *l_decree = s_stake_decree_set_min_stake(l_net, l_value, l_poa_cert); + if (l_decree && s_stake_decree_put(l_decree, l_net)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum stake value is setted"); + DAP_DELETE(l_decree); + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum stake value setting failed"); + DAP_DELETE(l_decree); + return -21; + } + } break; default: { dap_cli_server_cmd_set_reply_text(a_str_reply, "Command %s not recognized", a_argv[l_arg_index]); return -1; @@ -1233,3 +1479,4 @@ void dap_chain_net_srv_stake_get_fee_validators(dap_chain_net_t *a_net, dap_stri DAP_DELETE(l_average_balance); DAP_DELETE(l_average_coins); } +