diff --git a/dap-sdk b/dap-sdk index 3fe415cde8bfcf24a6d4f6a5ad14eca23ac0d356..9898f5774dea5c5dfaffce489e79611465efb302 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 3fe415cde8bfcf24a6d4f6a5ad14eca23ac0d356 +Subproject commit 9898f5774dea5c5dfaffce489e79611465efb302 diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 68391bb0f3da610c60eba83fc4d4999e2e33700f..717a46b29760392f885cb9db7817223b67f31baa 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -342,6 +342,9 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "decree info -net <net_name>\n" "Displays information about the parameters of the decrees in the network.\n"); + dap_cli_server_cmd_add ("exec_cmd", com_exec_cmd, "Execute command on remote node", + "exec_cmd -net <net_name> -addr <node_addr> -cmd <command,and,all,args,separated,by,commas>\n" ); + //Find command dap_cli_server_cmd_add("find", cmd_find, "The command searches for the specified elements by the specified attributes", "find datum -net <net_name> [-chain <chain_name>] -hash <datum_hash>\n" diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 644a40e19fc7cd937f1269010b179eb61a837275..d57ed48c6cbd80d7aab32506691e99608dcc02f7 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -103,6 +103,10 @@ #include "dap_json_rpc_errors.h" #include "dap_http_ban_list_client.h" #include "dap_chain_datum_tx_voting.h" +#include "dap_json_rpc.h" +#include "dap_json_rpc_request.h" +#include "dap_client_pvt.h" +#include "dap_enc.h" #define LOG_TAG "chain_node_cli_cmd" @@ -8752,3 +8756,101 @@ void dap_notify_new_client_send_info(dap_events_socket_t *a_es, UNUSED_ARG void } json_object_put(l_json_wallets); } + +static void s_stage_connected_callback(dap_client_t* a_client, void * a_arg) { + dap_chain_node_client_t *l_node_client = DAP_CHAIN_NODE_CLIENT(a_client); + UNUSED(a_arg); + if(l_node_client) { + pthread_mutex_lock(&l_node_client->wait_mutex); + l_node_client->state = NODE_CLIENT_STATE_ESTABLISHED; + pthread_cond_signal(&l_node_client->wait_cond); + pthread_mutex_unlock(&l_node_client->wait_mutex); + } +} + +static void s_stage_connected_error_callback(dap_client_t* a_client, void * a_arg) { + dap_chain_node_client_t *l_node_client = DAP_CHAIN_NODE_CLIENT(a_client); + UNUSED(a_arg); + if(l_node_client) { + pthread_mutex_lock(&l_node_client->wait_mutex); + l_node_client->state = NODE_CLIENT_STATE_ERROR; + pthread_cond_signal(&l_node_client->wait_cond); + pthread_mutex_unlock(&l_node_client->wait_mutex); + } +} + +int com_exec_cmd(int argc, char **argv, void **reply) { + json_object ** a_json_arr_reply = (json_object **) reply; + if (!dap_json_rpc_exec_cmd_inited()) { + dap_json_rpc_error_add(*a_json_arr_reply, -1, "Json-rpc module doesn't inited, check confings"); + return -1; + } + + const char * l_cmd_arg_str = NULL, * l_addr_str = NULL, * l_net_str = NULL; + int arg_index = 1; + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-cmd", &l_cmd_arg_str); + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-addr", &l_addr_str); + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-net", &l_net_str); + if (!l_cmd_arg_str || ! l_addr_str || !l_net_str) { + dap_json_rpc_error_add(*a_json_arr_reply, -2, "Command exec_cmd require args -cmd, -addr, -net"); + return -2; + } + dap_chain_net_t* l_net = NULL; + l_net = dap_chain_net_by_name(l_net_str); + if (!l_net){ + dap_json_rpc_error_add(*a_json_arr_reply, -3, "Can't find net %s", l_net_str); + return -3; + } + + dap_json_rpc_params_t * params = dap_json_rpc_params_create(); + char *l_cmd_str = dap_strdup(l_cmd_arg_str); + for(int i = 0; l_cmd_str[i] != '\0'; i++) { + if (l_cmd_str[i] == ',') + l_cmd_str[i] = ';'; + } + dap_json_rpc_params_add_data(params, l_cmd_str, TYPE_PARAM_STRING); + uint64_t l_id_response = dap_json_rpc_response_get_new_id(); + char ** l_cmd_arr_str = dap_strsplit(l_cmd_str, ";", -1); + dap_json_rpc_request_t *l_request = dap_json_rpc_request_creation(l_cmd_arr_str[0], params, l_id_response); + dap_strfreev(l_cmd_arr_str); + dap_chain_node_addr_t l_node_addr; + dap_chain_node_addr_from_str(&l_node_addr, l_addr_str); + + dap_chain_node_info_t *node_info = node_info_read_and_reply(l_net, &l_node_addr, NULL); + if(!node_info) { + log_it(L_DEBUG, "Can't find node with addr: %s", l_addr_str); + dap_json_rpc_error_add(*a_json_arr_reply, -6, "Can't find node with addr: %s", l_addr_str); + return -6; + } + int timeout_ms = 5000; //5 sec = 5000 ms + dap_chain_node_client_t * l_node_client = dap_chain_node_client_create(l_net, node_info, NULL, NULL); + + //handshake + l_node_client->client = dap_client_new(s_stage_connected_error_callback, l_node_client); + l_node_client->client->_inheritor = l_node_client; + dap_client_set_uplink_unsafe(l_node_client->client, &l_node_client->info->address, node_info->ext_host, node_info->ext_port); + dap_client_pvt_t * l_client_internal = DAP_CLIENT_PVT(l_node_client->client); + dap_client_go_stage(l_node_client->client, STAGE_ENC_INIT, s_stage_connected_callback); + //wait handshake + int res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_ESTABLISHED, timeout_ms); + if (res) { + log_it(L_ERROR, "No response from node"); + dap_json_rpc_error_add(*a_json_arr_reply, -8, "No reponse from node"); + dap_chain_node_client_close_unsafe(l_node_client); + DAP_DEL_Z(node_info); + return -8; + } + + //send request + json_object * l_response = NULL; + dap_json_rpc_request_send(l_client_internal, l_request, &l_response); + + if (l_response) { + json_object_array_add(*a_json_arr_reply, l_response); + } else { + json_object_array_add(*a_json_arr_reply, json_object_new_string("Empty reply")); + } + DAP_DEL_Z(node_info); + dap_json_rpc_request_free(l_request); + return 0; +} diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h index a76937af3b861d0ee346f0e740bbb77a72d1f892..1e68819778acbd329bbaf6450b2475f1edc55cec 100644 --- a/modules/net/include/dap_chain_node_cli_cmd.h +++ b/modules/net/include/dap_chain_node_cli_cmd.h @@ -382,3 +382,5 @@ typedef enum cmd_find_list_err { int cmd_find(int a_argc, char **a_argv, void **a_str_reply); void dap_notify_new_client_send_info(dap_events_socket_t *a_es, void *a_arg); + +int com_exec_cmd(int argc, char **argv, void **reply);