From cb0bd67040b77553c5f587922eb93639229aa668 Mon Sep 17 00:00:00 2001
From: "roman.khlopkov" <roman.khlopkov@demlabs.net>
Date: Mon, 15 Jan 2024 18:18:24 +0300
Subject: [PATCH] [*] Master fixes port

---
 dap-sdk                                       |   2 +-
 modules/common/dap_chain_datum_tx_items.c     |   2 +-
 .../common/include/dap_chain_datum_tx_items.h |   2 +
 modules/net/srv/dap_chain_net_srv_order.c     |   4 +-
 .../dap_chain_net_srv_stake_pos_delegate.c    | 167 +++++++++++-------
 5 files changed, 108 insertions(+), 69 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index dc523abecb..23e30e2c0e 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit dc523abecb6bff079a72e71748cb295b4f40d11c
+Subproject commit 23e30e2c0e4d9ceac710c883cf4c25812fd20326
diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c
index 1082074df0..2a0611b9c4 100644
--- a/modules/common/dap_chain_datum_tx_items.c
+++ b/modules/common/dap_chain_datum_tx_items.c
@@ -438,7 +438,7 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_c
     if (IS_ZERO_256(a_value))
         return NULL;
     size_t l_tsd_total_size = a_sovereign_addr && !dap_chain_addr_is_blank(a_sovereign_addr) ?
-                sizeof(dap_tsd_t) * 2 + sizeof(*a_sovereign_addr) + sizeof(a_sovereign_tax) : 0;
+                                dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size() : 0;
     dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + l_tsd_total_size);
     if (!l_item) {
         return NULL;
diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h
index c646a3b499..7ab06e5c3b 100644
--- a/modules/common/include/dap_chain_datum_tx_items.h
+++ b/modules/common/include/dap_chain_datum_tx_items.h
@@ -183,6 +183,8 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap
 
 json_object* dap_chain_datum_tx_item_out_cond_srv_xchange_to_json(dap_chain_tx_out_cond_t* a_srv_xchange);
 
+DAP_STATIC_INLINE uint32_t dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size() { return sizeof(dap_chain_addr_t) + sizeof(uint256_t) + 2 * sizeof(dap_tsd_t); }
+
 /**
  * Create item dap_chain_tx_out_cond_t for stake service
  *
diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c
index aeae110585..a3af1a285d 100644
--- a/modules/net/srv/dap_chain_net_srv_order.c
+++ b/modules/net/srv/dap_chain_net_srv_order.c
@@ -564,9 +564,10 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d
         dap_string_append_printf(a_str_out, "  price:            %s (%s)\n", l_balance_coins, l_balance);
         DAP_DELETE(l_balance_coins);
         DAP_DELETE(l_balance);
+        dap_string_append_printf(a_str_out, "  price_token:      %s\n",  (*a_order->price_ticker) ? a_order->price_ticker: a_native_ticker);
+        dap_string_append_printf(a_str_out, "  units:            %zu\n", a_order->units);
         if( a_order->price_unit.uint32 )
             dap_string_append_printf(a_str_out, "  price_unit:       %s\n", dap_chain_net_srv_price_unit_uid_to_str(a_order->price_unit) );
-        dap_string_append_printf(a_str_out, "  price_token:      %s\n",  (*a_order->price_ticker) ? a_order->price_ticker: a_native_ticker);
         if ( a_order->node_addr.uint64)
             dap_string_append_printf(a_str_out, "  node_addr:        "NODE_ADDR_FP_STR"\n", NODE_ADDR_FP_ARGS_S(a_order->node_addr) );
 
@@ -595,7 +596,6 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d
         dap_sign_get_pkey_hash(l_sign, &l_sign_pkey);
         char *l_sign_pkey_hash_str = dap_hash_fast_to_str_new(&l_sign_pkey);
         dap_string_append_printf(a_str_out, "  pkey:             %s\n", l_sign_pkey_hash_str);
-        dap_string_append_printf(a_str_out, "  units:            %zu\n", a_order->units);
         DAP_DELETE(l_sign_pkey_hash_str);
         DAP_DELETE(l_hash_str);
         DAP_DELETE(l_ext_out);
diff --git a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
index b2eecedb98..77a9ae99fe 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
@@ -65,14 +65,14 @@ int dap_chain_net_srv_stake_pos_delegate_init()
 {
     dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, s_stake_verificator_callback, s_stake_updater_callback);
     dap_cli_server_cmd_add("srv_stake", s_cli_srv_stake, "Delegated stake service commands",
-    "\t\t=== Commands for work with orders ===\n"
+            "\t\t=== Commands for work with orders ===\n"
     "srv_stake order create [fee] -net <net_name> -value <value> -cert <priv_cert_name> [-H {hex(default) | base58}]\n"
         "\tCreates an order declaring the minimum fee that the validator agrees to for process a transaction.\n"
     "srv_stake order create validator -net <net_name> -value_min <minimum_stake_value> -value_max <maximum_stake_value>"
-                        " -tax <percent> -cert <priv_cert_name> [-H {hex(default) | base58}]\n"
+                        " -tax <percent> -cert <priv_cert_name> [-node_addr <for_validator_node>] [-H {hex(default) | base58}]\n"
         "\tCreates an order declaring wanted tax and minimum/maximum stake value that the validator agrees to work.\n"
     "srv_stake order create staker -net <net_name> -w <wallet_with_m_tokens> -value <stake_value> -fee <value> -tax <percent>"
-                        " [-addr <for_tax_collecting>]  [-cert <priv_cert_name>] [-H {hex(default) | base58}]\n"
+                        " [-addr <for_tax_collecting>]  [-cert <for_order_signing>] [-H {hex(default) | base58}]\n"
         "\tCreates an order allowing the validator to delegate it's key with specified params\n"
     "srv_stake order update -net <net_name> -order <order_hash> [-params]\n"
          "\tUpdates an order with specified hash\n"
@@ -80,20 +80,22 @@ int dap_chain_net_srv_stake_pos_delegate_init()
          "\tGet orders list of specified type within specified net name\n"
     "srv_stake order remove -net <net_name> -order <order_hash>\n"
          "\tRemove order with specified hash\n"
-     "\t\t === Commands for work with stake delegate ===\n"
-    "srv_stake delegate {-cert <pub_cert_name> [-node_addr <node_addr>] | -order <order_hash> [-tax_addr <wallet_addr_for_tax_collecting>]}"
-                        " -net <net_name> -w <wallet_name> -value <datoshi> -fee <value> \n"
+            "\t\t === Commands for work with stake delegate ===\n"
+            "srv_stake delegate {-cert <pub_cert_name> -value <datoshi> | "
+                                        "-order <order_hash> {[-tax_addr <wallet_addr_for_tax_collecting>] | "
+                                                "-cert <priv_cert_name> [-node_addr <for_validator_node>]}}"
+                                " -net <net_name> -w <wallet_name> -fee <value>\n"
          "\tDelegate public key in specified certificate or order with specified net name. Pay with specified value of m-tokens of native net token.\n"
+    "srv_stake invalidate -net <net_name> {-tx <transaction_hash> | -cert <delegated_cert> | -cert_pkey_hash <pkey_hash>}"
+                            " {-w <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 approve -net <net_name> -tx <transaction_hash> -poa_cert <priv_cert_name>\n"
          "\tApprove stake transaction by root node certificate within specified net name\n"
     "srv_stake list keys -net <net_name> [-cert <delegated_cert> | -pkey <pkey_hash_str>]\n"
          "\tShow the list of active stake keys (optional delegated with specified cert).\n"
     "srv_stake list tx -net <net_name> \n"
          "\tShow the list of key delegation transactions.\n"
-    "srv_stake invalidate -net <net_name> {-tx <transaction_hash> | -cert <delegated_cert> | -cert_pkey_hash <pkey_hash>}"
-                            " {-w <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\n"
     "srv_stake check -net <net_name> -tx <tx_hash>"
@@ -266,7 +268,7 @@ void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr
         dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, a_stake_tx_hash);
         if (l_tx) {
             dap_chain_tx_out_cond_t *l_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, NULL);
-            if (l_cond && l_cond->tsd_size == sizeof(dap_chain_addr_t) + sizeof(uint256_t) + sizeof(dap_tsd_t) * 2) {
+            if (l_cond && l_cond->tsd_size == dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size()) {
                 dap_tsd_t *l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_ADDR);
                 l_stake->sovereign_addr = dap_tsd_get_scalar(l_tsd, dap_chain_addr_t);
                 l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_VALUE);
@@ -561,15 +563,15 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_enc_
     uint256_t l_fee_back = {};
     // fee coin back
     SUBTRACT_256_256(l_fee_transfer, l_fee_total, &l_fee_back);
-    if(!IS_ZERO_256(l_fee_back)) {
-        if(dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_fee_back, l_native_ticker) != 1) {
+    if (!IS_ZERO_256(l_fee_back)) {
+        if (dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_fee_back, l_native_ticker) != 1) {
             log_it(L_ERROR, "Cant add fee back output");
             goto tx_fail;
         }
     }
 
     // add 'sign' item
-    if(dap_chain_datum_tx_add_sign_item(&l_tx, a_key) != 1) {
+    if (dap_chain_datum_tx_add_sign_item(&l_tx, a_key) != 1) {
         log_it(L_ERROR, "Can't add sign output");
         goto tx_fail;
     }
@@ -1262,7 +1264,16 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
         }
         dap_chain_addr_t l_signing_addr;
         dap_chain_addr_fill_from_key(&l_signing_addr, l_cert->enc_key, l_net->pub.id);
-        int l_result = dap_chain_net_srv_stake_verify_key_and_node(&l_signing_addr, &g_node_addr);
+        dap_chain_node_addr_t l_node_addr = g_node_addr;
+        const char *l_node_addr_str = NULL;
+        dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-node_addr", &l_node_addr_str);
+        if (l_node_addr_str) {
+            if (dap_chain_node_addr_from_str(&l_node_addr, l_node_addr_str)) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized node addr %s", l_node_addr_str);
+                return -14;
+            }
+        }
+        int l_result = dap_chain_net_srv_stake_verify_key_and_node(&l_signing_addr, &l_node_addr);
         if (l_result) {
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Key and node verification error");
             return l_result;
@@ -1286,7 +1297,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
                    *l_fee_str = NULL;
         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, "Validator order creation requires parameter -value");
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Staker order creation requires parameter -value");
             return -5;
         }
         uint256_t l_value = dap_chain_balance_scan(l_value_str);
@@ -1296,7 +1307,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
         }
         dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_fee_str);
         if (!l_fee_str) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Validator order creation requires parameter -fee");
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Staker order creation requires parameter -fee");
             return -7;
         }
         uint256_t l_fee = dap_chain_balance_scan(l_fee_str);
@@ -1306,7 +1317,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
         }
         dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-tax", &l_tax_str);
         if (!l_tax_str) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Validator order creation requires parameter -tax");
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Staker order creation requires parameter -tax");
             return -9;
         }
         uint256_t l_tax = dap_chain_coins_to_balance(l_tax_str);
@@ -1317,7 +1328,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
         }
         dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str);
         if (!l_wallet_str) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Validator order creation requires parameter -w");
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Staker order creation requires parameter -w");
             return -17;
         }
         dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config));
@@ -1327,21 +1338,22 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
         }
         // Create conditional transaction for order
         const char *l_sign_str = dap_chain_wallet_check_sign(l_wallet);
+        dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0);
+        dap_chain_wallet_close(l_wallet);
         dap_chain_addr_t l_addr = {};
         dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-addr", &l_addr_str);
         if (l_addr_str) {
             dap_chain_addr_t *l_spec_addr = dap_chain_addr_from_str(l_addr_str);
             if (!l_spec_addr) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified address is ivalid");
-                dap_chain_wallet_close(l_wallet);
+                DAP_DELETE(l_enc_key);
                 return -24;
             }
             l_addr = *l_spec_addr;
             DAP_DELETE(l_spec_addr);
-        }
-        dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0);
+        } else
+            dap_chain_addr_fill_from_key(&l_addr, l_enc_key, l_net->pub.id);
         dap_chain_datum_tx_t *l_tx = s_order_tx_create(l_net, l_enc_key, l_value, l_fee, l_tax, &l_addr);
-        dap_chain_wallet_close(l_wallet);
         DAP_DEL_Z(l_enc_key);
         char *l_tx_hash_str = NULL;
         if (!l_tx || !(l_tx_hash_str = s_stake_tx_put(l_tx, l_net, a_hash_out_type))) {
@@ -1380,20 +1392,25 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
     case CMD_UPDATE: {
         const char *l_order_hash_str = NULL;
         dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
-
+        if (!l_order_hash_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'srv_stake order %s' requires prameter -order\n",
+                                                l_cmd_num  == CMD_REMOVE ? "remove" : "update");
+            return -4;
+        }
         char *l_order_hash_hex_str;
         // datum hash may be in hex or base58 format
         if(!dap_strncmp(l_order_hash_str, "0x", 2) || !dap_strncmp(l_order_hash_str, "0X", 2))
             l_order_hash_hex_str = dap_strdup(l_order_hash_str);
         else
             l_order_hash_hex_str = dap_enc_base58_to_hex_str_from_str(l_order_hash_str);
-        dap_chain_net_srv_order_t *l_order =  dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_hex_str);
+        dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_hex_str);
         if (!l_order) {
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find order %s\n", l_order_hash_str);
             DAP_DELETE(l_order_hash_hex_str);
             return -5;
         }
-        if (l_order->srv_uid.uint64 != DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID) {
+        if (l_order->srv_uid.uint64 != DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID &&
+                l_order->srv_uid.uint64 != DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ORDERS) {
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Order %s is not a delegated stake order\n", l_order_hash_str);
             DAP_DELETE(l_order_hash_hex_str);
             return -6;
@@ -1463,27 +1480,54 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
                         l_order->srv_uid.uint64 != DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ORDERS)
                     continue;
                 // TODO add filters to list (token, address, etc.)
-                char *l_price_coins = dap_chain_balance_to_coins(l_order->price);
-                char *l_price_datoshi = dap_chain_balance_print(l_order->price);
-                char *l_node_addr = dap_strdup_printf(NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(l_order->node_addr));
-                char l_created[80] = {'\0'};
-                dap_time_t l_ts_created = l_order->ts_created;
-                dap_ctime_r(&l_ts_created, l_created);
-                dap_string_append_printf(l_reply_str, "Order: %s\n"
-                                                      "\tCreated: %s"
-                                                      "\tPrice: %s (%s) %s\n"
-                                                      "\tNode addr: %s\n",
-                                                      l_orders[i].key, l_created, l_price_coins, l_price_datoshi, l_order->price_ticker, l_node_addr);
-                DAP_DELETE(l_price_coins);
-                DAP_DELETE(l_price_datoshi);
-                DAP_DELETE(l_node_addr);
+                dap_string_append(l_reply_str, "\n");
+                dap_chain_net_srv_order_dump_to_string(l_order, l_reply_str, a_hash_out_type, l_net->pub.native_ticker);
+                if (l_order->srv_uid.uint64 == DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ORDERS) {
+                    if (l_order->direction == SERV_DIR_SELL) {
+                        dap_string_append(l_reply_str, "Value in this order type means minimum value of m-tokens for validator acceptable for key delegation with supplied tax\n"
+                                                       "Order external params:\n");
+                        struct validator_odrer_ext *l_ext = (struct validator_odrer_ext *)l_order->ext_n_sign;
+                        char *l_tax_str = dap_chain_balance_to_coins(l_ext->tax);
+                        dap_string_append_printf(l_reply_str, "  tax:              %s%%\n", l_tax_str);
+                        DAP_DEL_Z(l_tax_str);
+                        char *l_max_str = dap_chain_balance_to_coins(l_ext->value_max);
+                        dap_string_append_printf(l_reply_str, "  maximum_value:    %s\n", l_max_str);
+                        DAP_DEL_Z(l_max_str);
+                    } else { // l_order->direction = SERV_DIR_BUY
+                        dap_string_append(l_reply_str, "Value in this order type means value of m-tokens locked in conditional transaction attached to the order\n"
+                                                       "Order conditional tx params:\n");
+                        bool l_error = true;
+                        dap_chain_addr_t l_addr = {};
+                        uint256_t l_tax = uint256_0;
+                        dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order->tx_cond_hash);
+                        if (l_tx) {
+                            dap_chain_tx_out_cond_t *l_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, NULL);
+                            if (l_cond && l_cond->tsd_size == dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size()) {
+                                dap_tsd_t *l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_ADDR);
+                                l_addr = dap_tsd_get_scalar(l_tsd, dap_chain_addr_t);
+                                l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_VALUE);
+                                l_tax = dap_tsd_get_scalar(l_tsd, uint256_t);
+                                l_error = false;
+                            }
+                        }
+                        if (!l_error) {
+                            char *l_tax_str = dap_chain_balance_to_coins(l_tax);
+                            dap_string_append_printf(l_reply_str, "  sovereign_tax:    %s%%\n", l_tax_str);
+                            DAP_DEL_Z(l_tax_str);
+                            char *l_addr_str = dap_chain_addr_to_str(&l_addr);
+                            dap_string_append_printf(l_reply_str, "  sovereign_addr:   %s\n", l_addr_str);
+                            DAP_DEL_Z(l_addr_str);
+                        } else
+                            dap_string_append(l_reply_str, "  Conditional tx not found or illegal\n");
+                    }
+                } else
+                    dap_string_append(l_reply_str, "Value in this order type means minimum fee for validator acceptable for process transactions\n");
             }
             dap_global_db_objs_delete(l_orders, l_orders_count);
-            DAP_DELETE( l_gdb_group_str);
+            DAP_DELETE(l_gdb_group_str);
         }
-        if (!l_reply_str->len) {
+        if (!l_reply_str->len)
             dap_string_append(l_reply_str, "No orders found");
-        }
         *a_str_reply = dap_string_free(l_reply_str, false);
     } break;
 
@@ -1536,7 +1580,6 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
         dap_enc_key_delete(l_enc_key);
         return -13;
     }
-    dap_chain_node_addr_t l_node_addr = { .uint64 = 0 };
     uint256_t l_value = uint256_0;
     dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-value", &l_value_str);
     if (!l_value_str) {
@@ -1567,14 +1610,14 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
             return -20;
         }
         dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-node_addr", &l_node_addr_str);
-        if (l_node_addr_str) {
-            if (dap_chain_node_addr_from_str(&l_node_addr, l_node_addr_str)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized node addr %s", l_node_addr_str);
-                dap_enc_key_delete(l_enc_key);
-                return -14;
-            }
-        } else
-            l_node_addr.uint64 = dap_chain_net_get_cur_addr_int(l_net);
+    }
+    dap_chain_node_addr_t l_node_addr = g_node_addr;
+    if (l_node_addr_str) {
+        if (dap_chain_node_addr_from_str(&l_node_addr, l_node_addr_str)) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized node addr %s", l_node_addr_str);
+            dap_enc_key_delete(l_enc_key);
+            return -14;
+        }
     }
     if (l_order_hash_str) {
         dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_str);
@@ -1623,7 +1666,7 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
                 log_it(L_WARNING, "Requested conditional transaction have another ticker (not %s)", l_delegated_ticker);
                 return -38;
             }
-            if (l_cond->tsd_size != sizeof(dap_chain_addr_t) + sizeof(uint256_t) + sizeof(dap_tsd_t) * 2) {
+            if (l_cond->tsd_size != dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size()) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "The order's conditional transaction has invalid format");
                 dap_enc_key_delete(l_enc_key);
                 DAP_DELETE(l_order);
@@ -1723,12 +1766,13 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
         }
         DIV_256(l_sovereign_tax, GET_256_FROM_64(100), &l_sovereign_tax);
     }
-    if (dap_chain_net_srv_stake_key_delegated(&l_signing_addr)) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is already delegated");
-        dap_enc_key_delete(l_enc_key);
-        return -21;
-    }
 
+    int l_check_result = dap_chain_net_srv_stake_verify_key_and_node(&l_signing_addr, &l_node_addr);
+    if (l_check_result) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Key and node verification error");
+        dap_chain_wallet_close(l_wallet);
+        return l_check_result;
+    }
     if (compare256(l_value, s_srv_stake->delegate_allowed_min) == -1) {
         char *l_coin_str = dap_chain_balance_to_coins(l_value);
         char *l_value_min_str = dap_chain_balance_print(s_srv_stake->delegate_allowed_min);
@@ -1741,7 +1785,6 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
         dap_enc_key_delete(l_enc_key);
         return -11;
     }
-
     dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-fee", &l_fee_str);
     if (!l_fee_str) {
         dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'delegate' requires parameter -fee");
@@ -1754,12 +1797,6 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
         dap_enc_key_delete(l_enc_key);
         return -16;
     }
-    int ret_val = 0;
-    if((ret_val = dap_chain_net_srv_stake_verify_key_and_node(&l_signing_addr, &l_node_addr)) != 0){
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Key and node verification error");
-        dap_enc_key_delete(l_enc_key);
-        return ret_val;
-    }
 
     // Create conditional transaction
     dap_chain_datum_tx_t *l_tx = s_stake_tx_create(l_net, l_enc_key, l_value, l_fee, &l_signing_addr, &l_node_addr,
-- 
GitLab