From ca92d888fd8b783d10f655c8b852cfb2c02e2c16 Mon Sep 17 00:00:00 2001
From: "roman.khlopkov" <roman.khlopkov@demlabs.net>
Date: Fri, 22 Dec 2023 11:10:43 +0300
Subject: [PATCH] [*] Base TX creation way returned for python plugins

---
 modules/mempool/dap_chain_mempool.c           | 34 ++++++++++++-------
 modules/mempool/include/dap_chain_mempool.h   |  2 +-
 modules/net/dap_chain_node_cli_cmd.c          |  1 +
 .../stake/dap_chain_net_srv_stake_lock.c      | 28 ++++++++++++---
 modules/type/blocks/dap_chain_cs_blocks.c     |  2 +-
 5 files changed, 48 insertions(+), 19 deletions(-)

diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index c0a021aa0d..13478d400a 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -1014,7 +1014,8 @@ char *dap_chain_mempool_tx_create_cond(dap_chain_net_t *a_net,
 }
 
 char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_emission_hash,
-                                       dap_chain_id_t a_emission_chain_id, dap_enc_key_t *a_private_key,
+                                       dap_chain_id_t a_emission_chain_id, uint256_t a_emission_value, const char *a_ticker,
+                                       dap_chain_addr_t *a_addr_to, dap_enc_key_t *a_private_key,
                                        const char *a_hash_out_type, uint256_t a_value_fee)
 {
     dap_return_val_if_fail(a_chain && a_emission_hash && a_private_key, NULL);
@@ -1024,15 +1025,25 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast
     dap_chain_addr_t l_addr_to_fee = {};
     dap_chain_addr_t l_addr_from_fee = {};
 
-    dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id);
-    dap_chain_datum_token_emission_t *l_emission = dap_ledger_token_emission_find(l_net->pub.ledger, a_emission_hash);
-    if (!l_emission) {
-        log_it(L_WARNING, "Specified emission not found");
-        return NULL;
+    dap_chain_addr_t *l_addr_to = a_addr_to;
+    uint256_t l_emission_value = a_emission_value;
+    const char *l_emission_ticker = a_ticker;
+
+    if (!a_addr_to) {
+        dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id);
+        dap_chain_datum_token_emission_t *l_emission = dap_ledger_token_emission_find(l_net->pub.ledger, a_emission_hash);
+        if (!l_emission) {
+            log_it(L_WARNING, "Specified emission not found");
+            return NULL;
+        }
+        // TODO add check for used emission
+        l_emission_ticker = l_emission->hdr.ticker;
+        l_emission_value = l_emission->hdr.value;
+        l_addr_to = &l_emission->hdr.address;
     }
-    uint256_t l_emission_value = l_emission->hdr.value;
+
     const char *l_native_ticker = dap_chain_net_by_id(a_chain->net_id)->pub.native_ticker;
-    bool not_native = dap_strcmp(l_emission->hdr.ticker, l_native_ticker);
+    bool not_native = dap_strcmp(l_emission_ticker, l_native_ticker);
     bool l_net_fee_used = IS_ZERO_256(a_value_fee) ? false :
                                                      dap_chain_net_tx_get_fee(a_chain->net_id, &l_net_fee, &l_addr_to_fee);
     if (l_net_fee_used)
@@ -1041,7 +1052,7 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast
     dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t));
     l_tx->header.ts_created = time(NULL);
     //in_ems
-    dap_chain_tx_in_ems_t *l_in_ems = dap_chain_datum_tx_item_in_ems_create(a_emission_chain_id, a_emission_hash, l_emission->hdr.ticker);
+    dap_chain_tx_in_ems_t *l_in_ems = dap_chain_datum_tx_item_in_ems_create(a_emission_chain_id, a_emission_hash, l_emission_ticker);
     if (l_in_ems) {
         dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*)l_in_ems);
         DAP_DELETE(l_in_ems);
@@ -1093,8 +1104,7 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast
             dap_chain_datum_tx_delete(l_tx);
             return NULL;
         }
-        if (!dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_emission->hdr.address,
-                                                 l_emission_value, l_emission->hdr.ticker)) {
+        if (!dap_chain_datum_tx_add_out_ext_item(&l_tx, l_addr_to, l_emission_value, l_emission_ticker)) {
             dap_chain_datum_tx_delete(l_tx);
             return NULL;
         }
@@ -1113,7 +1123,7 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast
                 return NULL;
             }
         }
-        if (!dap_chain_datum_tx_add_out_item(&l_tx, &l_emission->hdr.address, l_emission_value)) {
+        if (!dap_chain_datum_tx_add_out_item(&l_tx, l_addr_to, l_emission_value)) {
             dap_chain_datum_tx_delete(l_tx);
             return NULL;
         }        
diff --git a/modules/mempool/include/dap_chain_mempool.h b/modules/mempool/include/dap_chain_mempool.h
index 6ac84d3277..d18df1e803 100644
--- a/modules/mempool/include/dap_chain_mempool.h
+++ b/modules/mempool/include/dap_chain_mempool.h
@@ -98,7 +98,7 @@ int dap_chain_mempool_tx_create_massive(dap_chain_t * a_chain, dap_enc_key_t *a_
  * @return
  */
 char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_emission_hash,
-                                       dap_chain_id_t a_emission_chain_id, dap_enc_key_t *a_private_key,
+                                       dap_chain_id_t a_emission_chain_id, uint256_t a_emission_value, const char *a_ticker, dap_chain_addr_t *a_addr_to, dap_enc_key_t *a_private_key,
                                        const char *a_hash_out_type, uint256_t a_value_fee);
 
 dap_chain_datum_token_emission_t *dap_chain_mempool_emission_get(dap_chain_t *a_chain, const char *a_emission_hash_str);
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 6367e274c6..482c5f7aff 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -5635,6 +5635,7 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply)
             l_ret = -10;
         }
         l_tx_hash_str = dap_chain_mempool_base_tx_create(l_chain, &l_emission_hash, l_emission_chain->id,
+                                                         uint256_0, NULL, NULL, // Get this params from emission itself
                                                          l_priv_key, l_hash_out_type, l_value_fee);
         if (l_tx_hash_str) {
             dap_string_append_printf(l_string_ret, "\nDatum %s with 256bit TX is placed in datum pool\n", l_tx_hash_str);
diff --git a/modules/service/stake/dap_chain_net_srv_stake_lock.c b/modules/service/stake/dap_chain_net_srv_stake_lock.c
index cfeb70da97..819cd746bc 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_lock.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c
@@ -1189,13 +1189,31 @@ dap_chain_datum_t *s_stake_unlock_datum_create(dap_chain_net_t *a_net, dap_enc_k
     dap_list_t *l_list_fee_out = NULL, *l_list_used_out = NULL;
     bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_addr_fee);
     SUM_256_256(l_net_fee, a_value_fee, &l_total_fee);
-
     if (!IS_ZERO_256(l_total_fee)) {
-        l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker,
+        if (!l_main_native) {
+            l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker,
                                                                     &l_addr, l_total_fee, &l_fee_transfer);
-        if (!l_list_fee_out) {
-            log_it(L_WARNING, "Not enough funds to pay fee");
-            return NULL;
+            if (!l_list_fee_out) {
+                log_it(L_WARNING, "Not enough funds to pay fee");
+                return NULL;
+        } else if (compare256(a_value, l_total_fee) == -1) {
+            SUBTRACT_256_256(l_total_fee, a_value, &l_fee_part);
+            l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker,
+                                                                    &l_addr, l_fee_part, &l_fee_transfer);
+            char *l_total = dap_chain_balance_to_coins(!IS_ZERO_256(l_total_fee) ? l_total_fee : uint256_0);
+            char *l_value = dap_chain_balance_to_coins(a_value);
+            char *l_sub = dap_chain_balance_to_coins(l_fee_part);
+            char *l_transf = dap_chain_balance_to_coins(l_fee_part);
+            log_it(L_WARNING, "Total fee more than stake, total - (%s), stake - (%s), sub - (%s), transf - (%s) ",
+                                                            l_total, l_value, l_sub, l_transf);
+            DAP_DELETE(l_total);
+            DAP_DELETE(l_value);
+            DAP_DELETE(l_sub);
+            DAP_DELETE(l_transf);
+            if (!l_list_fee_out) {
+                log_it(L_WARNING, "Not enough funds to pay fee");
+                return NULL;
+            }
         }
     }
     if (!IS_ZERO_256(a_delegated_value)) {
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index a67f16afe9..b715b7a3cb 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -811,7 +811,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to date", l_to_date_str);
                     return -21;
                 }
-                struct tm *l_localtime = localtime(&l_to_time);
+                struct tm *l_localtime = localtime((time_t *)&l_to_time);
                 l_localtime->tm_mday += 1;  // + 1 day to end date, got it inclusive
                 l_to_time = mktime(l_localtime);
             }
-- 
GitLab