diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c index 1b4fece324c93e852660800218680b6047b06993..7403c053105e49b06793626f7cec67344ffa2f88 100644 --- a/modules/common/dap_chain_datum.c +++ b/modules/common/dap_chain_datum.c @@ -746,6 +746,18 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_TON_SIGNERS_MIN: l_subtype_str = "DECREE_COMMON_SUBTYPE_TON_SIGNERS_MIN"; break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE: + l_subtype_str = "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE"; + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE: + l_subtype_str = "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE"; + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE: + l_subtype_str = "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE"; + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT: + l_subtype_str = "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT"; + break; default: l_subtype_str = "DECREE_TYPE_UNKNOWN"; } @@ -760,13 +772,17 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c dap_string_append_printf(a_str_out,"=== Datum anchor ===\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_anchor_size); - char l_decree_hash_str[40] = ""; + char *l_decree_hash_str = NULL; dap_hash_fast_t l_decree_hash ={0}; dap_chain_datum_anchor_get_hash_from_data(l_anchor, &l_decree_hash); - dap_chain_hash_fast_to_str(&l_decree_hash, l_decree_hash_str, 40); + //dap_chain_hash_fast_to_str(&l_decree_hash, l_decree_hash_str, 40); + + l_decree_hash_str = dap_chain_hash_fast_to_str_new(&l_decree_hash); dap_string_append_printf(a_str_out, "decree hash: %s\n", l_decree_hash_str); + DAP_DELETE(l_decree_hash_str); + dap_chain_datum_anchor_certs_dump(a_str_out, l_anchor->data_n_sign + l_anchor->header.data_size, l_anchor->header.signs_size, a_hash_out_type); } break; } diff --git a/modules/net/dap_chain_net_anchor.c b/modules/net/dap_chain_net_anchor.c index 09d922f792eb285b2e2d585aa2bbbe5ff71cf775..b6743269d74562429b9856aab8ace8b41477fcba 100644 --- a/modules/net/dap_chain_net_anchor.c +++ b/modules/net/dap_chain_net_anchor.c @@ -83,8 +83,8 @@ int dap_chain_net_anchor_verify(dap_chain_datum_anchor_t * a_anchor, dap_chain_n return -106; } - - l_decree = dap_chain_net_decree_get_by_hash(l_decree_hash); + bool l_is_applied = false; + l_decree = dap_chain_net_decree_get_by_hash(l_decree_hash, &l_is_applied); if (!l_decree) { DAP_DELETE(l_signs_arr); @@ -93,6 +93,14 @@ int dap_chain_net_anchor_verify(dap_chain_datum_anchor_t * a_anchor, dap_chain_n return -107; } + if (l_is_applied) + { + DAP_DELETE(l_signs_arr); + DAP_DELETE(l_unique_signs); + log_it(L_WARNING,"The decree referred to by the anchor has already been applied"); + return -109; + } + size_t l_decree_signs_size = l_decree->header.signs_size; //multiple signs reading from datum dap_sign_t *l_decree_signs_block = (dap_sign_t *)((byte_t*)l_decree->data_n_signs + l_decree->header.data_size); @@ -178,14 +186,21 @@ int dap_chain_net_anchor_load(dap_chain_datum_anchor_t * a_anchor, dap_chain_t * return -109; } - - l_decree = dap_chain_net_decree_get_by_hash(l_hash); + bool l_is_applied = false; + l_decree = dap_chain_net_decree_get_by_hash(l_hash, &l_is_applied); if (!l_decree) { log_it(L_WARNING,"Decree is not found."); return -110; } + if (l_is_applied) + { + log_it(L_WARNING,"Decree already applyed."); + return -111; + } + + if((ret_val = dap_chain_net_decree_apply(l_decree, a_chain))!=0) { log_it(L_WARNING,"Decree applying failed"); diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c index 5bf23d465ce1437c227d84482da50757fb51a884..f357b28ee72b658b71d7ee771d8ba4a4e63df4d2 100644 --- a/modules/net/dap_chain_net_decree.c +++ b/modules/net/dap_chain_net_decree.c @@ -39,14 +39,20 @@ #define LOG_TAG "chain_net_decree" // private types definition +static struct decree_hh { + dap_hash_fast_t key; + bool is_applied; + dap_chain_datum_decree_t *decree; + UT_hash_handle hh; +} *s_decree_hh = NULL; // 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); +static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_net_t *a_net, dap_chain_t *a_chain, bool a_apply); +static int s_service_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain, bool a_apply); // Public functions @@ -104,6 +110,33 @@ int dap_chain_net_decree_deinit(dap_chain_net_t *a_net) return 0; } +int s_decree_verify_tsd(dap_chain_datum_decree_t * a_decree, dap_chain_net_t *a_net) +{ + int ret_val = 0; + dap_chain_net_t *l_net = NULL; + + if (!a_decree) + { + log_it(L_ERROR,"Invalid arguments."); + return -107; + } + + // Process decree + switch(a_decree->header.type){ + case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON:{ + ret_val = s_common_decree_handler(a_decree, a_net, NULL, false); + break; + } + case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:{ + ret_val = s_service_decree_handler(a_decree, NULL, false); + } + default: + log_it(L_WARNING,"Decree type is undefined!"); + ret_val = -100; + } + return ret_val; +} + 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; @@ -213,20 +246,28 @@ int dap_chain_net_decree_verify(dap_chain_datum_decree_t * a_decree, dap_chain_n return -106; } + // check tsd-section + if (s_decree_verify_tsd(a_decree, a_net)) + { + log_it(L_WARNING,"TSD checking error. Decree verification failed"); + return -106; + } + return 0; } int dap_chain_net_decree_apply(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain) { int ret_val = 0; + dap_chain_net_t *l_net = NULL; if (!a_decree || !a_chain) { - log_it(L_WARNING,"Invalid arguments. a_decree and a_chain must be not NULL"); + log_it(L_ERROR,"Invalid arguments."); return -107; } - dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); + l_net = dap_chain_net_by_id(a_chain->net_id); if (!l_net->pub.decree) { @@ -237,35 +278,45 @@ int dap_chain_net_decree_apply(dap_chain_datum_decree_t * a_decree, dap_chain_t if ((ret_val = dap_chain_net_decree_verify(a_decree, l_net, NULL, NULL)) != 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); + ret_val = s_common_decree_handler(a_decree, l_net, a_chain, true); break; } case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:{ - return s_service_decree_handler(a_decree, a_chain); + ret_val = s_service_decree_handler(a_decree, a_chain, true); } - default:; + default: + log_it(L_WARNING,"Decree type is undefined!"); + ret_val = -100; } - return -100; -} + if (!ret_val) + { + dap_hash_fast_t l_hash = {0}; + size_t l_data_size = sizeof(dap_chain_datum_decree_t) + a_decree->header.data_size + a_decree->header.signs_size; + dap_hash_fast(a_decree, l_data_size, &l_hash); + struct decree_hh *l_decree_hh = NULL; + + HASH_FIND(hh, s_decree_hh, &l_hash, sizeof(dap_hash_fast_t), l_decree_hh); + if (l_decree_hh) + l_decree_hh->is_applied = true; + } -static struct decree_data { - dap_hash_fast_t key; - dap_chain_datum_decree_t *decree; // Network fee value - UT_hash_handle hh; -} *s_decree_data = NULL; // Governance statements for networks + return ret_val; +} int dap_chain_net_decree_load(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain) { dap_hash_fast_t l_hash = {0}; - struct decree_data *l_decree_data = NULL; + struct decree_hh *l_decree_hh = NULL; int ret_val = 0; if (!a_chain || !a_chain) { - log_it(L_WARNING, "Bad arguments"); + log_it(L_ERROR, "Bad arguments"); return -100; } @@ -277,8 +328,10 @@ int dap_chain_net_decree_load(dap_chain_datum_decree_t * a_decree, dap_chain_t * return -108; } - if ((ret_val = dap_chain_net_decree_verify(a_decree, l_net, NULL, NULL)) != 0) + if ((ret_val = dap_chain_net_decree_verify(a_decree, l_net, NULL, NULL)) != 0){ + log_it(L_ERROR,"Decree verification failed!"); return ret_val; + } dap_chain_datum_decree_t * l_decree = NULL; size_t l_data_size = sizeof(dap_chain_datum_decree_t) + a_decree->header.data_size + a_decree->header.signs_size; @@ -286,25 +339,42 @@ int dap_chain_net_decree_load(dap_chain_datum_decree_t * a_decree, dap_chain_t * memcpy(l_decree, a_decree, l_data_size); dap_hash_fast(l_decree, l_data_size, &l_hash); - l_decree_data = DAP_NEW_Z_SIZE(struct decree_data, sizeof(struct decree_data) + l_decree->header.data_size + l_decree->header.signs_size); - l_decree_data->decree = l_decree; - l_decree_data->key = l_hash; + l_decree_hh = DAP_NEW_Z_SIZE(struct decree_hh, sizeof(struct decree_hh) + l_decree->header.data_size + l_decree->header.signs_size); + l_decree_hh->decree = l_decree; + l_decree_hh->key = l_hash; + l_decree_hh->is_applied = false; - HASH_ADD(hh, s_decree_data, key, sizeof(dap_hash_fast_t), l_decree_data); + if (a_decree->header.common_decree_params.chain_id.uint64 == a_chain->id.uint64) + { + ret_val = dap_chain_net_decree_apply(a_decree, a_chain); + if (ret_val){ + log_it(L_ERROR,"Decree applying failed!"); - return 0; + } else + { + l_decree_hh->is_applied = true; + } + + } + + HASH_ADD(hh, s_decree_hh, key, sizeof(dap_hash_fast_t), l_decree_hh); + + return ret_val; } -dap_chain_datum_decree_t * dap_chain_net_decree_get_by_hash(dap_hash_fast_t a_hash) +dap_chain_datum_decree_t * dap_chain_net_decree_get_by_hash(dap_hash_fast_t a_hash, bool *is_applied) { dap_hash_fast_t l_hash = a_hash; - struct decree_data* l_decree_data = NULL; + struct decree_hh* l_decree_hh = NULL; - HASH_FIND(hh, s_decree_data, &l_hash, sizeof(dap_hash_fast_t), l_decree_data); - if (!l_decree_data) + HASH_FIND(hh, s_decree_hh, &l_hash, sizeof(dap_hash_fast_t), l_decree_hh); + if (!l_decree_hh) return NULL; - return l_decree_data->decree; + if (is_applied) + *is_applied = l_decree_hh->is_applied; + + return l_decree_hh->decree; } // Private functions @@ -326,17 +396,20 @@ static bool s_verify_pkey (dap_sign_t *a_sign, dap_chain_net_t *a_net) return ret_val; } -static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain) +static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_net_t *a_net, dap_chain_t *a_chain, bool a_apply) { 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_chain_net_t *l_net = a_net; dap_list_t *l_owners_list = NULL; - l_net = dap_chain_net_by_id(a_chain->net_id); + if (a_apply && !a_chain){ + log_it(L_WARNING, "a_chain must not be NULL"); + return -112; + } switch (a_decree->header.sub_type) { @@ -357,6 +430,9 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai } if (!dap_chain_datum_decree_get_fee(a_decree, &l_uint256_buffer)){ + if (!a_apply) + break; + if (!dap_chain_net_tx_add_fee(a_chain->net_id, l_uint256_buffer, l_addr)) { log_it(L_WARNING,"Can't add/replace fee value."); return -102; @@ -373,6 +449,9 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai return -104; } + if (!a_apply) + break; + l_net->pub.decree->num_of_owners = l_uint256_buffer; dap_list_free_full(l_net->pub.decree->pkeys, NULL); @@ -383,10 +462,13 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai log_it(L_WARNING,"Can't get min number of ownners from decree."); return -105; } + if (!a_apply) + break; l_net->pub.decree->min_num_of_owners = l_uint256_buffer; break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_TON_SIGNERS_MIN: - + if (!a_apply) + break; break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE: if (dap_chain_datum_decree_get_stake_tx_hash(a_decree, &l_hash)){ @@ -405,6 +487,8 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai log_it(L_WARNING,"Can't get signer node address from decree."); return -105; } + if (!a_apply) + break; 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: @@ -412,6 +496,8 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai log_it(L_WARNING,"Can't get signing address from decree."); return -105; } + if (!a_apply) + break; dap_chain_net_srv_stake_key_invalidate(&l_addr); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE: @@ -419,6 +505,8 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai log_it(L_WARNING,"Can't get min stake value from decree."); return -105; } + if (!a_apply) + break; dap_chain_net_srv_stake_set_allowed_min_value(l_uint256_buffer); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT: @@ -426,6 +514,8 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai log_it(L_WARNING,"Can't get min stake value from decree."); return -105; } + if (!a_apply) + break; a_chain->callback_set_min_validators_count(a_chain, (uint16_t)dap_chain_uint256_to(l_uint256_buffer)); break; default: return -1; @@ -434,7 +524,7 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai return 0; } -static int s_service_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, bool a_apply) { // size_t l_datum_data_size = ; // dap_chain_net_srv_t * l_srv = dap_chain_net_srv_get(l_decree->header.srv_id); diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 2b455b996337a5d2afae0b48a122a354a913348c..b8e3c60d0b32c90bded8b2353b124cb07704c376 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -318,13 +318,13 @@ int dap_chain_node_cli_init(dap_config_t * g_config) // 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 create common -net <net_name> [-chain <chain_name>] [-decree_chain <chain_name>] -certs <certs list> -<Subtype param name> <Subtype param Value>\n" + "decree create service -net <net_name> [-chain <chain_name>] [-decree_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> -chain <chain_name> -datum <datum_hash>\n" "==Subtype Params==\n" "\t -fee <value>: sets fee for tx in net\n" - "\t -to_addr <wallet_addr>: sets wallet addr for network fee" + "\t -to_addr <wallet_addr>: sets wallet addr for network fee\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"); diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 02989e73f3fcf820e05920bfb29fe99e2e535cfc..441f45a176543465dbf79fcec658de885a24f79b 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -1397,11 +1397,13 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) int arg_index = 1; const char *l_net_str = NULL; const char * l_chain_str = NULL; + const char * l_decree_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; + dap_chain_t * l_decree_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); @@ -1487,6 +1489,33 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) return -105; } + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-decree_chain", &l_decree_chain_str); + + // Search chain + if(l_decree_chain_str) { + l_decree_chain = dap_chain_net_get_chain_by_name(l_net, l_decree_chain_str); + if (l_decree_chain == NULL) { + char l_str_to_reply_chain[500] = {0}; + char *l_str_to_reply = NULL; + sprintf(l_str_to_reply_chain, "%s requires parameter '-decree_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; + dap_chain_net_t * l_chain_net = l_net; + l_str_to_reply = dap_strcat2(l_str_to_reply,"\nAvailable chains:\n"); + DL_FOREACH(l_chain_net->pub.chains, l_chain) { + 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 { + l_decree_chain = l_chain; + } + + 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; @@ -1590,7 +1619,7 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) 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.chain_id = l_decree_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; @@ -1874,6 +1903,8 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) l_datum_anchor->header.ts_created = dap_time_now(); memcpy(l_datum_anchor->data_n_sign, l_tsd, dap_tsd_size(l_tsd)); + DAP_DEL_Z(l_tsd); + // Sign anchor size_t l_total_signs_success = 0; if (l_certs_count) diff --git a/modules/net/include/dap_chain_net_decree.h b/modules/net/include/dap_chain_net_decree.h index ae3c2c2642d91ef25e77998a44a6a01834ea9f68..0533d796b328073c63fa67638202015a94bc2dd9 100644 --- a/modules/net/include/dap_chain_net_decree.h +++ b/modules/net/include/dap_chain_net_decree.h @@ -42,4 +42,4 @@ int dap_chain_net_decree_apply(dap_chain_datum_decree_t * a_decree, dap_chain_t 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); int dap_chain_net_decree_load(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain); -dap_chain_datum_decree_t *dap_chain_net_decree_get_by_hash(dap_hash_fast_t a_hash); +dap_chain_datum_decree_t *dap_chain_net_decree_get_by_hash(dap_hash_fast_t a_hash, bool *is_applied);