From 5e06a54a26ca78e9ad72e7d7299da5041874f8f2 Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Wed, 5 Apr 2023 08:59:19 +0000
Subject: [PATCH] features-8422

---
 modules/net/dap_chain_net_decree.c            |  4 ++
 .../dap_chain_net_srv_stake_pos_delegate.c    | 48 +++++++++++++++++++
 .../dap_chain_net_srv_stake_pos_delegate.h    |  1 +
 3 files changed, 53 insertions(+)

diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c
index 8a3713f803..3de84a47fb 100644
--- a/modules/net/dap_chain_net_decree.c
+++ b/modules/net/dap_chain_net_decree.c
@@ -469,6 +469,10 @@ 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(dap_chain_net_srv_stake_verify_key_and_node(&l_addr, &l_node_addr)){
+                log_it(L_WARNING, "Key and node verification error");
+                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);
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 e4fc001289..3a0189889b 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
@@ -219,6 +219,32 @@ dap_list_t *dap_chain_net_srv_stake_get_validators()
     return l_ret;
 }
 
+int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_node_addr)
+{
+    assert(s_srv_stake);
+    if (!a_signing_addr || !a_node_addr){
+        log_it(L_WARNING, "Bad arguments.");
+        return -100;
+    }
+
+    dap_chain_net_srv_stake_item_t *l_stake = NULL, *l_tmp = NULL;
+    HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp){
+        //check key not activated for other node
+        if(dap_chain_addr_compare(a_signing_addr, &l_stake->signing_addr)){
+                log_it(L_WARNING, "Key %s already active for node %s", dap_chain_addr_to_str(a_signing_addr), dap_chain_node_addr_to_hash_str(a_node_addr));
+                return -101;
+        }
+
+        //chek node have not other delegated key
+        if(a_node_addr->uint64 == l_stake->node_addr.uint64){
+            log_it(L_WARNING, "Node %s already have active key.", dap_chain_node_addr_to_hash_str(a_node_addr));
+            return -102;
+        }
+    }
+
+    return 0;
+}
+
 static bool s_stake_cache_check_tx(dap_hash_fast_t *a_tx_hash)
 {
     dap_chain_net_srv_stake_cache_item_t *l_stake;
@@ -278,6 +304,8 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_chai
     if (!a_net || !a_wallet || IS_ZERO_256(a_value) || !a_signing_addr || !a_node_addr)
         return NULL;
 
+
+
     const char *l_native_ticker = a_net->pub.native_ticker;
     char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
     dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, l_native_ticker);
@@ -428,6 +456,11 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t
         return NULL;
     }
 
+    if(dap_chain_net_srv_stake_verify_key_and_node(&l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr, &l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr)){
+        log_it(L_WARNING, "Key and node verification error");
+        return NULL;
+    }
+
     // create approve decree
     size_t l_total_tsd_size = 0;
     dap_chain_datum_decree_t *l_decree = NULL;
@@ -1246,6 +1279,21 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply)
             }
 
             // Create conditional transaction
+            int ret_val = 0;
+            if((ret_val = dap_chain_net_srv_stake_verify_key_and_node(&l_signing_addr, &l_node_addr)) != 0){
+                if (ret_val == -101){
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Key %s already active for node %s", dap_chain_addr_to_str(&l_signing_addr), dap_chain_node_addr_to_hash_str(&l_node_addr));
+                    return ret_val;
+                } else if (ret_val == -102){
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Node %s already have active key.", dap_chain_node_addr_to_hash_str(&l_node_addr));
+                    return ret_val;
+                }else{
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Key and node verification error");
+                    return ret_val;
+                }
+
+            }
+
             dap_chain_datum_tx_t *l_tx = s_stake_tx_create(l_net, l_wallet, l_value, l_fee, &l_signing_addr, &l_node_addr);
             dap_chain_wallet_close(l_wallet);
             if (!l_tx || !s_stake_tx_put(l_tx, l_net)) {
diff --git a/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h b/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h
index 30a3db4d65..913d91fe7f 100644
--- a/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h
+++ b/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h
@@ -69,6 +69,7 @@ void dap_chain_net_srv_stake_set_allowed_min_value(uint256_t a_value);
 uint256_t dap_chain_net_srv_stake_get_allowed_min_value();
 
 bool dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr);
+int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t* a_signing_addr, dap_chain_node_addr_t* a_node_addr);
 dap_list_t *dap_chain_net_srv_stake_get_validators();
 
 void dap_chain_net_srv_stake_get_fee_validators(dap_chain_net_t *a_net, dap_string_t *a_string);
-- 
GitLab