From e0ac3c6f93280e7df9977aa1d7ec2609bb8756f7 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Fri, 26 Jul 2024 11:15:35 +0000
Subject: [PATCH] Feature 12448

---
 .../consensus/esbocs/dap_chain_cs_esbocs.c    | 116 ++++++++++--------
 .../esbocs/include/dap_chain_cs_esbocs.h      |  19 +++
 modules/net/dap_chain_ledger.c                |   1 -
 project.yaml                                  |   1 -
 4 files changed, 86 insertions(+), 51 deletions(-)

diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 4867bb7d90..6e3fd2fb1d 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -2939,15 +2939,18 @@ static dap_chain_datum_decree_t *s_esbocs_decree_set_emergency_validator(dap_cha
     return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL);
 }
 
-static void s_print_emergency_validators(char **a_str_reply, dap_list_t *a_validator_addrs)
+static void s_print_emergency_validators(json_object *json_obj_out, dap_list_t *a_validator_addrs)
 {
-    dap_string_t *l_str_out = dap_string_new("Current emergency validators list:\n");
-    for (dap_list_t *it = a_validator_addrs; it; it = it->next) {
+    json_object *json_arr_validators = json_object_new_array();
+    size_t i=1;
+    for (dap_list_t *it = a_validator_addrs; it; it = it->next, i++) {
+        json_object *json_obj_validator = json_object_new_object();
         dap_chain_addr_t *l_addr = it->data;
-        dap_string_append_printf(l_str_out, "%s\n", dap_chain_hash_fast_to_str_static(&l_addr->data.hash_fast));
+        json_object_object_add(json_obj_validator,"#", json_object_new_uint64(i));
+        json_object_object_add(json_obj_validator,"addr hash", json_object_new_string(dap_chain_hash_fast_to_str_static(&l_addr->data.hash_fast)));
+        json_object_array_add(json_arr_validators, json_obj_validator);
     }
-    *a_str_reply = l_str_out->str;
-    dap_string_free(l_str_out, false);
+    json_object_object_add(json_obj_out,"Current emergency validators list", json_arr_validators);
 }
 
 /**
@@ -2964,16 +2967,16 @@ static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply)
     int l_arg_index = 1;
     dap_chain_net_t *l_chain_net = NULL;
     dap_chain_t *l_chain = 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,
-                                                      CHAIN_TYPE_ANCHOR))
+    json_object **json_arr_reply = (json_object **)a_str_reply;
+        
+    if (dap_chain_node_cli_cmd_values_parse_net_chain_for_json(&l_arg_index, a_argc, a_argv, &l_chain, &l_chain_net,
+                                                                CHAIN_TYPE_ANCHOR))
         return -3;
     const char *l_chain_type = dap_chain_get_cs_type(l_chain);
     if (strcmp(l_chain_type, "esbocs")) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply,
-                        "Type of chain \"%s\" is not block. Chain with current consensus \"%s\" is not supported by this command",
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_CHAIN_TYPE_ERR,"Type of chain \"%s\" is not block. Chain with current consensus \"%s\" is not supported by this command",
                         l_chain->name, l_chain_type);
-            return -2;
+            return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_CHAIN_TYPE_ERR;
     }
     dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain);
     dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks);
@@ -3017,73 +3020,82 @@ static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply)
             const char *l_cert_str = NULL;
             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' requires parameter -cert");
-                return -3;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_PARAM_ERR,"Command 'min_validators_count' requires parameter -cert");
+                return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_PARAM_ERR;
             }
             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_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_CERT_ERR,"Specified certificate not found");
+                return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_CERT_ERR;
             }
             if (!l_poa_cert->enc_key || !l_poa_cert->enc_key->priv_key_data) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate doesn't contain a private key");
-                return -26;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_PVT_KEY_ERR,"Specified certificate doesn't contain a private key");
+                return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_PVT_KEY_ERR;
             }
         } else if (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "show") > 0)
             l_subcommand_show = true;
         else
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized subcommand '%s'", a_argv[l_arg_index]);
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_UNKNOWN,"Unrecognized subcommand '%s'", a_argv[l_arg_index]);
     }
 
     int ret = 0;
     // Do subcommand action
     switch (l_subcmd) {
 
-    case SUBCMD_MIN_VALIDATORS_COUNT: {
+    case SUBCMD_MIN_VALIDATORS_COUNT: {        
         if (!l_subcommand_show) {
             const char *l_value_str = NULL;
             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 '%s' requires parameter -val_count", l_subcmd_strs[l_subcmd]);
-                return -9;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_PARAM_ERR,"Command '%s' requires parameter -val_count", l_subcmd_strs[l_subcmd]);
+                return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_PARAM_ERR;
             }
             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_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_UNREC_COM_ERR,"Unrecognized number in '-val_count' param");
+                return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_UNREC_COM_ERR;
             }
             dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_min_validators_count(
                                                     l_chain_net, l_chain, l_value, l_poa_cert);
             char *l_decree_hash_str = NULL;
             if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count has been set."
-                                                               " Decree hash %s", l_decree_hash_str);
+                json_object * json_obj_out = json_object_new_object();
+                json_object_object_add(json_obj_out,"status", json_object_new_string("Minimum validators count has been set"));
+                json_object_object_add(json_obj_out,"decree hash", json_object_new_string(l_decree_hash_str));
+                json_object_array_add(*json_arr_reply, json_obj_out);
                 DAP_DEL_MULTY(l_decree, l_decree_hash_str);
             } else {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count setting failed");
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_MINVALSET_ERR,"Minimum validators count setting failed");
                 DAP_DEL_Z(l_decree);
-                return -21;
+                return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_MINVALSET_ERR;
             }
-        } else
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count is %d", l_esbocs_pvt->min_validators_count);
+        } else{
+            json_object * json_obj_out = json_object_new_object();
+            json_object_object_add(json_obj_out,"Minimum validators count", json_object_new_uint64(l_esbocs_pvt->min_validators_count));
+            json_object_array_add(*json_arr_reply, json_obj_out);
+        }            
     } break;
 
     case SUBCMD_CHECK_SIGNS_STRUCTURE: {
+        json_object * json_obj_out = json_object_new_object();
         if (!l_subcommand_show) {
             dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_signs_check(l_chain_net, l_chain, l_subcommand_add, l_poa_cert);
             char *l_decree_hash_str = NULL;
             if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Checking signs structure has been %s. Decree hash %s",
-                                                                l_subcommand_add ? "enabled" : "disabled", l_decree_hash_str);
+                json_object_object_add(json_obj_out,"Checking signs structure has been", l_subcommand_add ? json_object_new_string("enabled") : json_object_new_string("disabled"));
+                json_object_object_add(json_obj_out,"Decree hash", json_object_new_string(l_decree_hash_str));
+                json_object_array_add(*json_arr_reply, json_obj_out);
                 DAP_DEL_MULTY(l_decree, l_decree_hash_str);
             } else {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Checking signs structure setting failed");
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_CHECKING_ERR,"Checking signs structure setting failed");
                 DAP_DEL_Z(l_decree);
-                return -21;
+                json_object_put(json_obj_out);
+                return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_CHECKING_ERR;
             }
-        } else
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Checking signs structure is %s", l_esbocs_pvt->check_signs_structure ?
-                                                                                "enabled" : "disabled");
+        } else{
+            json_object_object_add(json_obj_out,"Checking signs structure is", l_esbocs_pvt->check_signs_structure ? json_object_new_string("enabled") : json_object_new_string("disabled"));
+            json_object_array_add(*json_arr_reply, json_obj_out);
+        }            
     } break;
 
     case SUBCMD_EMERGENCY_VALIDATOR: {
@@ -3091,13 +3103,13 @@ static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply)
             const char *l_hash_str = NULL, *l_type_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-pkey_hash", &l_hash_str);
             if (!l_hash_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command '%s' requires parameter -pkey_hash", l_subcmd_strs[l_subcmd]);
-                return -9;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_HASH_ERR,"Command '%s' requires parameter -pkey_hash", l_subcmd_strs[l_subcmd]);
+                return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_HASH_ERR;
             }
             dap_hash_fast_t l_pkey_hash;
             if (dap_chain_hash_fast_from_str(l_hash_str, &l_pkey_hash)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid hash format in 'pkey_hash' param");
-                return -10;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_HASH_FORMAT_ERR,"Invalid hash format in 'pkey_hash' param");
+                return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_HASH_FORMAT_ERR;
             }
             dap_sign_type_t l_sig_type = { .type = SIG_TYPE_DILITHIUM };
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-sig_type", &l_type_str);
@@ -3106,21 +3118,27 @@ static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply)
             dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_emergency_validator(l_chain_net, l_chain, &l_pkey_hash, l_sig_type, l_subcommand_add, l_poa_cert);
             char *l_decree_hash_str = NULL;
             if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Emergency validator %s has been %s. Decree hash %s",
-                                                        dap_chain_hash_fast_to_str_static(&l_pkey_hash),
-                                                        l_subcommand_add ? "added" : "deleted", l_decree_hash_str);
+                json_object * json_obj_out = json_object_new_object();
+                json_object_object_add(json_obj_out,"Emergency validator", json_object_new_string(dap_chain_hash_fast_to_str_static(&l_pkey_hash)));
+                json_object_object_add(json_obj_out,"status", l_subcommand_add ? json_object_new_string("added") : json_object_new_string("deleted"));
+                json_object_object_add(json_obj_out,"Decree hash", json_object_new_string(l_decree_hash_str));
+                json_object_array_add(*json_arr_reply, json_obj_out);
                 DAP_DEL_MULTY(l_decree, l_decree_hash_str);
             } else {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Emergency validator %s failed", l_subcommand_add ? "adding" : "deleting");
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_ADD_DEL_ERR,
+                                        "Emergency validator %s failed", l_subcommand_add ? "adding" : "deleting");
                 DAP_DEL_Z(l_decree);
-                return -21;
+                return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_ADD_DEL_ERR;
             }
-        } else
-            s_print_emergency_validators((char **)a_str_reply, l_esbocs_pvt->emergency_validator_addrs);
+        } else{
+            json_object * json_obj_out = json_object_new_object();
+            s_print_emergency_validators(json_obj_out, l_esbocs_pvt->emergency_validator_addrs);
+            json_object_array_add(*json_arr_reply, json_obj_out);
+        }            
     } break;
 
     default:
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized subcommand '%s'", a_argv[l_arg_index - 1]);
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_SUB_ERR,"Unrecognized subcommand '%s'", a_argv[l_arg_index - 1]);
     }
     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 594c9d9e7e..a715325895 100644
--- a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
+++ b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
@@ -219,6 +219,25 @@ typedef struct dap_chain_esbocs_block_collect{
     dap_chain_cell_id_t cell_id;
 }dap_chain_esbocs_block_collect_t;
 
+typedef enum s_com_esbocs_err{
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_OK = 0,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_PARAM_ERR,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_CHAIN_TYPE_ERR,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_CERT_ERR,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_PVT_KEY_ERR,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_UNREC_COM_ERR,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_MINVALSET_ERR,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_CHECKING_ERR,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_HASH_ERR,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_HASH_FORMAT_ERR,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_ADD_DEL_ERR,
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_SUB_ERR,
+
+    /* add custom codes here */
+
+    DAP_CHAIN_NODE_CLI_COM_ESBOCS_UNKNOWN /* MAX */
+} s_com_esbocs_err_t;
+
 #define DAP_CHAIN_ESBOCS(a) ((dap_chain_esbocs_t *)(a)->_inheritor)
 
 typedef enum dap_chain_block_autocollect_type {
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index 8f01ec2503..1aa8a000bb 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -501,7 +501,6 @@ static dap_ledger_t *dap_ledger_handle_new(void)
     pthread_rwlock_init(&l_ledger_pvt->balance_accounts_rwlock , NULL);
     pthread_rwlock_init(&l_ledger_pvt->stake_lock_rwlock, NULL);
     pthread_rwlock_init(&l_ledger_pvt->rewards_rwlock, NULL);
-
     return l_ledger;
 }
 
diff --git a/project.yaml b/project.yaml
index b6755cc483..b902b81e04 100644
--- a/project.yaml
+++ b/project.yaml
@@ -12,7 +12,6 @@ build_dependencies:
     - 'curl'
     - 'jq'
     - 'xsltproc'
-    
 
 deploy_dependencies:
   deb:
-- 
GitLab