From aafedc382ad97804724f9d7f751eac5aaeabae39 Mon Sep 17 00:00:00 2001
From: Roman Khlopkov <roman.khlopkov@demlabs.net>
Date: Mon, 25 May 2020 17:29:47 +0300
Subject: [PATCH] [*] Mempool auto processing debugged

---
 modules/chain/dap_chain.c                     | 54 ++++++++++++++++---
 modules/chain/include/dap_chain.h             |  7 +--
 modules/net/dap_chain_node.c                  | 12 +++--
 modules/net/include/dap_chain_node.h          |  2 +-
 .../xchange/dap_chain_net_srv_xchange.c       | 17 +++---
 5 files changed, 65 insertions(+), 27 deletions(-)

diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c
index 2b241c147f..bf81b508e0 100644
--- a/modules/chain/dap_chain.c
+++ b/modules/chain/dap_chain.c
@@ -159,7 +159,9 @@ void dap_chain_delete(dap_chain_t * a_chain)
        log_it(L_WARNING,"Trying to remove non-existent 0x%16llX:0x%16llX chain",a_chain->id.uint64,
               a_chain->net_id.uint64);
     a_chain->datum_types_count = 0;
-    DAP_DELETE (a_chain->datum_types);
+    DAP_DELETE(a_chain->datum_types);
+    a_chain->autoproc_datum_types_count = 0;
+    DAP_DELETE(a_chain->autoproc_datum_types);
     pthread_rwlock_unlock(&s_chain_items_rwlock);
 }
 
@@ -187,7 +189,7 @@ dap_chain_t * dap_chain_find_by_id(dap_chain_net_id_t a_chain_net_id,dap_chain_i
         return NULL;
 }
 
-dap_chain_type_t dap_chain_type_from_str(const char *a_type_str)
+static dap_chain_type_t s_chain_type_from_str(const char *a_type_str)
 {
     if(!dap_strcmp(a_type_str, "token")) {
         return CHAIN_TYPE_TOKEN;
@@ -198,7 +200,35 @@ dap_chain_type_t dap_chain_type_from_str(const char *a_type_str)
     if(!dap_strcmp(a_type_str, "transaction")) {
         return CHAIN_TYPE_TX;
     }
-    return CHAIN_TYPE_UNKNOWN;
+    return CHAIN_TYPE_LAST;
+}
+
+static uint16_t s_datum_type_from_str(const char *a_type_str)
+{
+    if(!dap_strcmp(a_type_str, "token")) {
+        return DAP_CHAIN_DATUM_TOKEN_DECL;
+    }
+    if(!dap_strcmp(a_type_str, "emission")) {
+        return DAP_CHAIN_DATUM_TOKEN_EMISSION;
+    }
+    if(!dap_strcmp(a_type_str, "transaction")) {
+        return DAP_CHAIN_DATUM_TX;
+    }
+    return DAP_CHAIN_DATUM_CUSTOM;
+}
+
+static uint16_t s_chain_type_convert(dap_chain_type_t a_type)
+{
+    switch (a_type) {
+    case CHAIN_TYPE_TOKEN:
+        return DAP_CHAIN_DATUM_TOKEN_DECL;
+    case CHAIN_TYPE_EMISSION:
+        return DAP_CHAIN_DATUM_TOKEN_EMISSION;
+    case CHAIN_TYPE_TX:
+        return DAP_CHAIN_DATUM_TX;
+    default:
+        return DAP_CHAIN_DATUM_CUSTOM;
+    }
 }
 
 /**
@@ -289,8 +319,8 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha
                 l_chain->datum_types = DAP_NEW_SIZE(dap_chain_type_t, l_datum_types_count * sizeof(dap_chain_type_t));
                 uint16_t l_count_recognized = 0;
                 for(uint16_t i = 0; i < l_datum_types_count; i++) {
-                    dap_chain_type_t l_chain_type = dap_chain_type_from_str(l_datum_types[i]);
-                    if (l_chain_type != CHAIN_TYPE_UNKNOWN) {
+                    dap_chain_type_t l_chain_type = s_chain_type_from_str(l_datum_types[i]);
+                    if (l_chain_type != CHAIN_TYPE_LAST) {
                         l_chain->datum_types[l_count_recognized] = l_chain_type;
                         l_count_recognized++;
                     }
@@ -302,11 +332,19 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha
             }
             // add datum types
             if(l_chain && l_datum_types_count) {
-                l_chain->datum_types = DAP_NEW_SIZE(dap_chain_type_t, l_datum_types_count * sizeof(dap_chain_type_t));
+                l_chain->autoproc_datum_types = DAP_NEW_SIZE(uint16_t, l_datum_types_count * sizeof(uint16_t));
                 uint16_t l_count_recognized = 0;
                 for(uint16_t i = 0; i < l_datum_types_count; i++) {
-                    dap_chain_type_t l_chain_type = dap_chain_type_from_str(l_datum_types[i]);
-                    if (l_chain_type != CHAIN_TYPE_UNKNOWN) {
+                    if (!strcmp(l_datum_types[i], "all")) {
+                        l_chain->autoproc_datum_types = DAP_REALLOC(l_chain->autoproc_datum_types, l_chain->datum_types_count * sizeof(uint16_t));
+                        for (int j = 0; j < l_chain->datum_types_count; j++) {
+                            l_chain->autoproc_datum_types[j] = s_chain_type_convert(l_chain->datum_types[j]);
+                        }
+                        l_count_recognized = l_chain->datum_types_count;
+                        break;
+                    }
+                    uint16_t l_chain_type = s_datum_type_from_str(l_datum_types[i]);
+                    if (l_chain_type != DAP_CHAIN_DATUM_CUSTOM) {
                         l_chain->autoproc_datum_types[l_count_recognized] = l_chain_type;
                         l_count_recognized++;
                     }
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index 5ddc85510c..9669445834 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -84,8 +84,7 @@ typedef  enum dap_chain_type
     CHAIN_TYPE_TOKEN,
     CHAIN_TYPE_EMISSION,
     CHAIN_TYPE_TX,
-    CHAIN_TYPE_LAST,
-    CHAIN_TYPE_UNKNOWN
+    CHAIN_TYPE_LAST
 } dap_chain_type_t;
 
 typedef struct dap_chain{
@@ -102,7 +101,7 @@ typedef struct dap_chain{
     uint16_t datum_types_count;
     dap_chain_type_t *datum_types;
     uint16_t autoproc_datum_types_count;
-    dap_chain_type_t *autoproc_datum_types;
+    uint16_t *autoproc_datum_types;
 
     // To hold it in double-linked lists
     struct dap_chain * next;
@@ -166,5 +165,3 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger,const char * a_chai
 
 void dap_chain_delete(dap_chain_t * a_chain);
 void dap_chain_add_callback_notify(dap_chain_t * a_chain, dap_chain_callback_notify_t a_callback, void * a_arg);
-
-dap_chain_type_t dap_chain_type_from_str(const char *a_type_str);
diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c
index 789afeeca7..983c394edf 100644
--- a/modules/net/dap_chain_node.c
+++ b/modules/net/dap_chain_node.c
@@ -239,7 +239,7 @@ dap_chain_node_info_t* dap_chain_node_info_read( dap_chain_net_t * a_net,dap_cha
     return node_info;
 }*/
 
-int dap_chain_node_mempool_process(dap_chain_t *a_chain)
+int dap_chain_node_mempool_process(dap_chain_t *a_chain, dap_chain_node_role_t a_role)
 {
     char *l_gdb_group_mempool = NULL;
     if (!a_chain) {
@@ -251,14 +251,14 @@ int dap_chain_node_mempool_process(dap_chain_t *a_chain)
     if (l_objs_size) {
         for (size_t i = 0; i < l_objs_size; i++) {
             dap_chain_datum_t *l_datum = (dap_chain_datum_t *)l_objs[i].value;
-            bool b_need_process = false;
+            bool l_need_process = false;
             for (uint16_t j = 0; j < a_chain->autoproc_datum_types_count; j++) {
                 if (l_datum->header.type_id == a_chain->autoproc_datum_types[j]) {
-                    b_need_process = true;
+                    l_need_process = true;
                     break;
                 }
             }
-            if (!b_need_process)
+            if (!l_need_process)
                 continue;
             if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX) {
                 dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data;
@@ -270,6 +270,8 @@ int dap_chain_node_mempool_process(dap_chain_t *a_chain)
                                                                             &l_tx_token->header.token_emission_hash)) {
                         continue;
                     }
+                } else if (a_role.enums == NODE_ROLE_ROOT) {
+                        continue;
                 }
             }
             if (a_chain->callback_datums_pool_proc(a_chain, &l_datum, 1) != 1) {
@@ -308,7 +310,7 @@ void dap_chain_node_mempool_periodic(void *a_param)
         if (l_mempool_auto) {
             dap_chain_t *l_chain;
             DL_FOREACH(l_net_list[i]->pub.chains, l_chain) {
-                dap_chain_node_mempool_process(l_chain);
+                dap_chain_node_mempool_process(l_chain, l_role);
             }
         }
     }
diff --git a/modules/net/include/dap_chain_node.h b/modules/net/include/dap_chain_node.h
index 1e5f0b6d7f..78931e2864 100644
--- a/modules/net/include/dap_chain_node.h
+++ b/modules/net/include/dap_chain_node.h
@@ -141,6 +141,6 @@ inline static char* dap_chain_node_addr_to_hash_str(dap_chain_node_addr_t *addre
     return a_key;
 }
 
-int dap_chain_node_mempool_process(dap_chain_t *a_chain);
+int dap_chain_node_mempool_process(dap_chain_t *a_chain, dap_chain_node_role_t a_role);
 int dap_chain_node_mempool_init();
 void dap_chain_node_mempool_deinit();
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 8618ed4b34..32485b1c29 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -136,7 +136,7 @@ static dap_chain_datum_tx_receipt_t *s_xchage_receipt_create(dap_chain_net_srv_x
 
 static dap_chain_datum_tx_t *s_xchange_tx_create_request(dap_chain_net_srv_xchange_price_t *a_price, dap_chain_wallet_t *a_wallet)
 {
-    if (!a_price || !a_price->net_sell || !a_price->net_buy || !*a_price->token_sell || !*a_price->token_buy || a_wallet) {
+    if (!a_price || !a_price->net_sell || !a_price->net_buy || !*a_price->token_sell || !*a_price->token_buy || !a_wallet) {
         return NULL;
     }
 
@@ -357,10 +357,11 @@ static bool s_xchage_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price, d
     dap_chain_datum_tx_add_in_cond_item(&l_tx, &a_price->tx_hash, l_prev_cond_idx, 0);
 
     // add 'out' item
-#ifndef NDEBUG
     const dap_chain_addr_t *l_buyer_addr = (dap_chain_addr_t *)l_tx_out_cond->params;
-    assert(l_buyer_addr == l_seller_addr);
-#endif
+    if (memcmp(l_seller_addr->data.hash, l_buyer_addr->data.hash, sizeof(dap_chain_hash_fast_t))) {
+        log_it(L_WARNING, "Only owner can invalidate exchange transaction");
+        return false;
+    }
     if (dap_chain_datum_tx_add_out_item(&l_tx, l_seller_addr, l_tx_out_cond->header.value)) {
         dap_chain_datum_tx_delete(l_tx);
         DAP_DELETE(l_seller_addr);
@@ -742,7 +743,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void *a_arg_func, char *
                 dap_chain_net_srv_xchange_price_t *l_price = DAP_NEW(dap_chain_net_srv_xchange_price_t);
                 l_price->net_sell = l_net;
                 strcpy(l_price->token_sell, l_order->price_ticker);
-                l_price->datoshi_buy = l_order->price;
+                l_price->datoshi_sell = l_order->price;
                 dap_srv_xchange_order_ext_t *l_ext = (dap_srv_xchange_order_ext_t *)l_order->ext;
                 dap_chain_net_id_t l_net_buy_id = { .uint64 = dap_lendian_get64((uint8_t *)&l_ext->net_sell_id) };
                 l_price->net_buy = dap_chain_net_by_id(l_net_buy_id);
@@ -750,11 +751,11 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void *a_arg_func, char *
                 strcpy(l_price->token_buy, l_ext->token_sell);
                 // Create conditional transaction
                 dap_chain_datum_tx_t *l_tx = s_xchange_tx_create_exchange(l_price, &l_order->tx_cond_hash, l_wallet);
-                if (l_tx) {
-                    s_xchange_tx_put(l_tx, l_net);
+                if (l_tx && s_xchange_tx_put(l_tx, l_net)) {
+                    // TODO send request to seller to delete order & price
+                    dap_chain_net_srv_order_delete_by_hash_str(l_price->net_buy, l_order_hash_str);
                 }
                 DAP_DELETE(l_price);
-                 dap_chain_net_srv_order_delete_by_hash_str(l_price->net_buy, l_order_hash_str);
                 DAP_DELETE(l_order);
                 dap_chain_node_cli_set_reply_text(a_str_reply, l_tx ? "Exchange transaction has done" :
                                                                       "Exchange transaction error");
-- 
GitLab