From 22dff263af6e351f95d1f8959ab53fcc1a2b2961 Mon Sep 17 00:00:00 2001
From: "Dmitriy A. Gerasimov" <dmitriy.gerasimov@demlabs.net>
Date: Thu, 26 Nov 2020 15:13:47 +0700
Subject: [PATCH] [*] Proc callbacks fixes

---
 CMakeLists.txt                            |   2 +-
 dap-sdk/net/core/dap_proc_queue.c         |  14 +-
 dap-sdk/net/core/dap_proc_thread.c        |  25 +++-
 dap-sdk/net/core/include/dap_proc_queue.h |   4 +-
 modules/chain/dap_chain_ledger.c          | 152 +++++++++++++++++++++-
 modules/net/dap_chain_net.c               |  43 +++---
 6 files changed, 203 insertions(+), 37 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6674d2d72a..fb253140c3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ project(cellframe-sdk C)
 cmake_minimum_required(VERSION 2.8)
 
 set(CMAKE_C_STANDARD 11)
-set(CELLFRAME_SDK_NATIVE_VERSION "2.6-55")
+set(CELLFRAME_SDK_NATIVE_VERSION "2.6-56")
 add_definitions ("-DCELLFRAME_SDK_VERSION=\"${CELLFRAME_SDK_NATIVE_VERSION}\"")
 
 set(DAPSDK_MODULES "")
diff --git a/dap-sdk/net/core/dap_proc_queue.c b/dap-sdk/net/core/dap_proc_queue.c
index 91502bfc25..ec98b6881c 100644
--- a/dap-sdk/net/core/dap_proc_queue.c
+++ b/dap-sdk/net/core/dap_proc_queue.c
@@ -75,14 +75,16 @@ static void s_queue_esocket_callback( dap_events_socket_t * a_es, void * a_msg)
         dap_proc_queue_item_t * l_item = DAP_NEW_Z(dap_proc_queue_item_t);
         l_item->callback = l_msg->callback;
         l_item->callback_arg = l_msg->callback_arg;
-        l_item->next=l_queue->items_last ;
-        if ( l_queue->items_last)
-            l_queue->items_last->prev = l_item;
 
-        l_queue->items_last = l_item->next;
+        if ( l_queue->item_last)
+            l_queue->item_last->prev = l_item;
 
-        if( !l_queue->items_fisrt)
-            l_queue->items_fisrt = l_item;
+        l_item->next=l_queue->item_last ;
+
+        l_queue->item_last = l_item;
+
+        if( !l_queue->item_first)
+            l_queue->item_first = l_item;
 
 
         // Add on top so after call this callback will be executed first
diff --git a/dap-sdk/net/core/dap_proc_thread.c b/dap-sdk/net/core/dap_proc_thread.c
index 4015d0f0d1..84a3818f8a 100644
--- a/dap-sdk/net/core/dap_proc_thread.c
+++ b/dap-sdk/net/core/dap_proc_thread.c
@@ -124,26 +124,37 @@ static void s_proc_event_callback(dap_events_socket_t * a_esocket, uint64_t a_va
     (void) a_value;
     //log_it(L_DEBUG, "Proc event callback");
     dap_proc_thread_t * l_thread = (dap_proc_thread_t *) a_esocket->_inheritor;
-    dap_proc_queue_item_t * l_item = l_thread->proc_queue->items_fisrt;
+    dap_proc_queue_item_t * l_item = l_thread->proc_queue->item_first;
     dap_proc_queue_item_t * l_item_old = NULL;
     bool l_is_anybody_for_repeat=false;
     while(l_item){
         bool l_is_finished = l_item->callback(l_thread, l_item->callback_arg);
         if (l_is_finished){
             if(l_item_old){
-                if ( ! l_item->prev )
-                    l_thread->proc_queue->items_last = l_item_old;
-                if ( ! l_item->next )
-                    l_thread->proc_queue->items_fisrt = l_item->prev;
+                if ( ! l_item->prev ){
+                    l_thread->proc_queue->item_last = l_item_old;
+                    if (l_thread->proc_queue->item_last)
+                        l_thread->proc_queue->item_last->next = NULL; // Next if it was - now its NULL
+                }
+                if ( ! l_item->next ){
+                    l_thread->proc_queue->item_first = l_item->prev;
+                    if (l_thread->proc_queue->item_first)
+                        l_thread->proc_queue->item_first->prev = NULL; // Prev if it was - now its NULL
+                }
 
                 l_item_old->prev = l_item->prev;
 
                 DAP_DELETE(l_item);
                 l_item = l_item_old->prev;
             }else{
-                l_thread->proc_queue->items_fisrt = l_item->prev;
+                l_thread->proc_queue->item_first = l_item->prev;
+                if (l_thread->proc_queue->item_first)
+                    l_thread->proc_queue->item_first->prev = NULL; // Prev if it was - now its NULL
+                else
+                    l_thread->proc_queue->item_last = NULL; // NULL last item
+
                 DAP_DELETE(l_item);
-                l_item = l_thread->proc_queue->items_fisrt;
+                l_item = l_thread->proc_queue->item_first;
             }
 
         }else{
diff --git a/dap-sdk/net/core/include/dap_proc_queue.h b/dap-sdk/net/core/include/dap_proc_queue.h
index b204d3692d..278a0685e1 100644
--- a/dap-sdk/net/core/include/dap_proc_queue.h
+++ b/dap-sdk/net/core/include/dap_proc_queue.h
@@ -37,8 +37,8 @@ typedef struct dap_proc_queue_item{
 typedef struct dap_proc_queue{
     dap_proc_thread_t * proc_thread;
     dap_events_socket_t *esocket;
-    dap_proc_queue_item_t * items_last;
-    dap_proc_queue_item_t * items_fisrt;
+    dap_proc_queue_item_t * item_last;
+    dap_proc_queue_item_t * item_first;
 } dap_proc_queue_t;
 
 dap_proc_queue_t * dap_proc_queue_create(dap_proc_thread_t * a_thread);
diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index 5bce29e7f1..598a4995ad 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -192,6 +192,7 @@ static  dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
 
 static void s_treshold_emissions_proc( dap_ledger_t * a_ledger);
 static void s_treshold_txs_proc( dap_ledger_t * a_ledger);
+static void s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size);
 
 static size_t s_treshold_emissions_max = 1000;
 static size_t s_treshold_txs_max = 10000;
@@ -332,10 +333,7 @@ int dap_chain_ledger_token_add(dap_ledger_t * a_ledger,  dap_chain_datum_token_t
             break;
             case DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_DECL:
                 log_it( L_NOTICE, "Private token %s type=DAP_CHAIN_DATUM_TOKEN_PRIVATE_DECL )", a_token->ticker);
-                l_token_item->total_supply = a_token->header_private.total_supply;
-                l_token_item->auth_signs= dap_chain_datum_token_signs_parse(a_token,a_token_size,
-                                                                                   &l_token_item->auth_signs_total,
-                                                                                    &l_token_item->auth_signs_valid );
+                s_token_tsd_parse(a_ledger,l_token_item, a_token, a_token_size);
             break;
             default:
                 log_it(L_WARNING,"Unknown token declaration type 0x%04X", a_token->type );
@@ -349,6 +347,152 @@ int dap_chain_ledger_token_add(dap_ledger_t * a_ledger,  dap_chain_datum_token_t
     return  0;
 }
 
+/**
+ * @brief s_token_tsd_parse
+ * @param a_ledger
+ * @param a_token
+ * @param a_token_size
+ */
+static void s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size)
+{
+    dap_chain_datum_token_tsd_t * l_tsd= dap_chain_datum_token_tsd_get(a_token,a_token_size);
+    size_t l_tsd_size=0;
+    size_t l_tsd_total_size =a_token_size-  (((byte_t*)l_tsd)- (byte_t*) a_token );
+
+    for( size_t l_offset=0; l_tsd && l_offset < l_tsd_total_size;  l_offset += l_tsd_size ){
+        l_tsd = (dap_chain_datum_token_tsd_t *) (((byte_t*)l_tsd ) +l_offset);
+        l_tsd_size =  l_tsd? dap_chain_datum_token_tsd_size(l_tsd): 0;
+        if( l_tsd_size==0 ){
+            log_it(L_ERROR,"Wrong zero TSD size, exiting TSD parse");
+            break;
+        }else if (l_tsd_size + l_offset > l_tsd_total_size ){
+            log_it(L_ERROR,"Wrong %zd TSD size, exiting TSD parse", l_tsd_size);
+            break;
+        }
+        switch (l_tsd->type) {
+           // set flags
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS:{
+                a_token_item->flags |= dap_chain_datum_token_tsd_get_scalar(l_tsd,uint16_t);
+            }break;
+
+           // unset flags
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS:{
+                a_token_item->flags ^= dap_chain_datum_token_tsd_get_scalar(l_tsd,uint16_t);
+            }break;
+
+            // set total supply
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY:{
+                a_token_item->total_supply = dap_chain_datum_token_tsd_get_scalar(l_tsd,uint64_t);
+            }break;
+
+            // Set total signs count value to set to be valid
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID:{
+                a_token_item->auth_signs_valid = dap_chain_datum_token_tsd_get_scalar(l_tsd,uint16_t);
+            }break;
+
+            // Remove owner signature by pkey fingerprint
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_REMOVE:{
+                dap_hash_fast_t l_hash = dap_chain_datum_token_tsd_get_scalar(l_tsd,dap_hash_fast_t);
+                for( size_t i=0; i<a_token_item->auth_signs_total; i++){
+                    if (dap_hash_fast_compare(&l_hash, &a_token_item->auth_signs_pkey_hash[i] )){
+                        if (i+1 != a_token_item->auth_signs_total){
+                            memmove(a_token_item->auth_signs+i,a_token_item->auth_signs+i+1,
+                                   (a_token_item->auth_signs_total-i-1)*sizeof (void*));
+                            memmove(a_token_item->auth_signs_pkey_hash+i,a_token_item->auth_signs_pkey_hash+i+1,
+                                   (a_token_item->auth_signs_total-i-1)*sizeof (void*));
+                        }
+                        a_token_item->auth_signs_total--;
+                        a_token_item->auth_signs = DAP_REALLOC(a_token_item->auth_signs,a_token_item->auth_signs_total*sizeof (void*) );
+                        a_token_item->auth_signs_pkey_hash = DAP_REALLOC(a_token_item->auth_signs_pkey_hash,a_token_item->auth_signs_total*sizeof (void*) );
+                        break;
+                    }
+                }
+            }break;
+
+            // Add owner signature's pkey fingerprint
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_ADD:{
+                if(l_tsd->size == sizeof (dap_hash_fast_t) ){
+                    a_token_item->auth_signs_total++;
+                    a_token_item->auth_signs = DAP_REALLOC(a_token_item->auth_signs,a_token_item->auth_signs_total*sizeof (void*) );
+                    a_token_item->auth_signs_pkey_hash = DAP_REALLOC(a_token_item->auth_signs_pkey_hash,a_token_item->auth_signs_total*sizeof (void*) );
+                    a_token_item->auth_signs[a_token_item->auth_signs_total-1] = NULL;
+                    memcpy( &a_token_item->auth_signs_pkey_hash[a_token_item->auth_signs_total-1], l_tsd->data, l_tsd->size ) ;
+                }else{
+                    log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_ADD expected to have %zd bytes data length, not %zd",
+                           sizeof (dap_hash_fast_t), l_tsd_size );
+                }
+            }break;
+
+            /// ------- Permissions list flags, grouped by update-remove-clear operations --------
+            // Blocked datum types list add, remove or clear
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_ADD:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_REMOVE:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_CLEAR:{
+            }break;
+
+
+
+            // Allowed datum types list add, remove or clear
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_ADD:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_REMOVE:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_CLEAR:{
+            }break;
+
+            //Allowed tx receiver addres list add, remove or clear
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_CLEAR:{
+            }break;
+
+
+            //Blocked tx receiver addres list add, remove or clear
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_CLEAR:{
+            }break;
+
+            //Allowed tx sender addres list add, remove or clear
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_CLEAR:{
+            }break;
+
+
+            //Blocked tx sender addres list add, remove or clear
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE:{
+            }break;
+
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_CLEAR:{
+            }break;
+            default:{}
+        }
+    }
+
+}
+
 int dap_chain_ledger_token_load(dap_ledger_t *a_ledger,  dap_chain_datum_token_t *a_token, size_t a_token_size)
 {
     if (PVT(a_ledger)->last_ticker.found) {
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 940b411ceb..96c92cc0cb 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -526,10 +526,11 @@ static int s_net_states_proc(dap_chain_net_t *a_net)
                 }
                 dap_stream_worker_t *l_worker = dap_client_get_stream_worker(l_node_client->client);
                 dap_stream_ch_chain_sync_request_t l_sync_gdb = {};
-                // Get last timestamp in log
-                l_sync_gdb.id_start = (uint64_t) dap_db_get_last_id_remote(l_node_client->remote_node_addr.uint64);
+                // Get last timestamp in log if wasn't SYNC_FROM_ZERO flag
+                if (! (l_pvt_net->flags & F_DAP_CHAIN_NET_SYNC_FROM_ZERO) )
+                    l_sync_gdb.id_start = (uint64_t) dap_db_get_last_id_remote(l_node_client->remote_node_addr.uint64);
                 l_sync_gdb.node_addr.uint64 = dap_chain_net_get_cur_addr_int(a_net);
-                log_it(L_DEBUG, "Prepared request to gdb sync from %llu to %llu", l_sync_gdb.id_start, l_sync_gdb.id_end);
+                log_it(L_DEBUG, "Prepared request to gdb sync from %llu to %llu", l_sync_gdb.id_start, l_sync_gdb.id_end?l_sync_gdb.id_end:-1 );
                 // find dap_chain_id_t
                 dap_chain_t *l_chain = dap_chain_net_get_chain_by_name(a_net, "gdb");
                 dap_chain_id_t l_chain_id = l_chain ? l_chain->id : (dap_chain_id_t ) {};
@@ -555,7 +556,7 @@ static int s_net_states_proc(dap_chain_net_t *a_net)
                 default:
                     log_it(L_INFO, "Node sync error %d",l_res);
                 }
-                /*
+
                 dap_chain_node_client_reset(l_node_client);
                 l_res = dap_stream_ch_chain_pkt_write_mt(l_worker, l_ch_chain, DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNC_GLOBAL_DB_RVRS, a_net->pub.id,
                                                          l_chain_id, a_net->pub.cell_id, &l_sync_gdb, sizeof(l_sync_gdb));
@@ -570,7 +571,7 @@ static int s_net_states_proc(dap_chain_net_t *a_net)
                 default:
                     log_it(L_INFO, "Node reverse sync error %d",l_res);
                 }
-                */
+
                 l_tmp = dap_list_next(l_tmp);
             }
             if (!l_pvt_net->links) {
@@ -578,7 +579,9 @@ static int s_net_states_proc(dap_chain_net_t *a_net)
             } else if (l_pvt_net->state_target >= NET_STATE_SYNC_CHAINS) {
                 l_pvt_net->state = NET_STATE_SYNC_CHAINS;
             } else {    // Synchronization done, go offline
-                log_it(L_INFO, "Synchronization done");
+                log_it(L_INFO, "Synchronization done, go offline");
+                l_pvt_net->flags ^= F_DAP_CHAIN_NET_GO_SYNC;
+                l_pvt_net->flags ^= F_DAP_CHAIN_NET_SYNC_FROM_ZERO;
                 l_pvt_net->state = l_pvt_net->state_target = NET_STATE_OFFLINE;
             }
         }
@@ -601,7 +604,9 @@ static int s_net_states_proc(dap_chain_net_t *a_net)
                 DL_FOREACH (a_net->pub.chains, l_chain) {
                     dap_chain_node_client_reset(l_node_client);
                     dap_stream_ch_chain_sync_request_t l_request = {0};
-                    dap_chain_get_atom_last_hash(l_chain,&l_request.hash_from);
+                    if (! (l_pvt_net->flags & F_DAP_CHAIN_NET_SYNC_FROM_ZERO) )
+                        dap_chain_get_atom_last_hash(l_chain,&l_request.hash_from);
+
                     if ( !dap_hash_fast_is_blank(&l_request.hash_from) ){
                         if(dap_log_level_get() <= L_DEBUG){
                             char l_hash_str[128]={[0]='\0'};
@@ -666,12 +671,14 @@ static int s_net_states_proc(dap_chain_net_t *a_net)
                 log_it( L_INFO,"Return back to state LINKS_PREPARE ");
                 l_pvt_net->state = NET_STATE_LINKS_PREPARE;
             } else {
-                log_it(L_INFO, "Synchronization done");
                 if (l_pvt_net->state_target == NET_STATE_ONLINE) {
-                    l_pvt_net->flags &= ~F_DAP_CHAIN_NET_GO_SYNC;
+                    l_pvt_net->flags ^= F_DAP_CHAIN_NET_GO_SYNC;
+                    l_pvt_net->flags ^= F_DAP_CHAIN_NET_SYNC_FROM_ZERO;
                     l_pvt_net->state = NET_STATE_ONLINE;
+                    log_it(L_INFO, "Synchronization done, status online");
                 } else {    // Synchronization done, go offline
                     l_pvt_net->state = l_pvt_net->state_target = NET_STATE_OFFLINE;
+                    log_it(L_INFO, "Synchronization done, go offline");
                 }
             }
         }
@@ -849,14 +856,16 @@ void dap_chain_net_delete( dap_chain_net_t * a_net )
 int dap_chain_net_init()
 {
     dap_chain_node_cli_cmd_item_create ("net", s_cli_net, NULL, "Network commands",
-        "net -net <chain net name> go < online | offline >\n"
-            "\tFind and establish links and stay online\n"
+        "net -net <chain net name> [-mode update|all] go < online | offline >\n"
+            "\tFind and establish links and stay online. \n"
+            "\tMode \"update\" is by default when only new chains and gdb are updated. Mode \"all\" updates everything from zero\n"
         "net -net <chain net name> get status\n"
             "\tLook at current status\n"
         "net -net <chain net name> stats tx [-from <From time>] [-to <To time>] [-prev_sec <Seconds>] \n"
             "\tTransactions statistics. Time format is <Year>-<Month>-<Day>_<Hours>:<Minutes>:<Seconds> or just <Seconds> \n"
-        "net -net <chain net name> sync < all | gdb | chains >\n"
+        "net -net <chain net name> [-mode update|all] sync < all | gdb | chains >\n"
             "\tSyncronyze gdb, chains or everything\n"
+            "\tMode \"update\" is by default when only new chains and gdb are updated. Mode \"all\" updates everything from zero\n"
         "net -net <chain net name> link < list | add | del | info | establish >\n"
             "\tList, add, del, dump or establish links\n"
         "net -net <chain net name> ca add {-cert <cert name> | -hash <cert hash>}\n"
@@ -1016,6 +1025,11 @@ static int s_cli_net( int argc, char **argv, void *arg_func, char **a_str_reply)
         dap_chain_node_cli_find_option_val(argv, arg_index, argc, "ca", &l_ca_str);
         dap_chain_node_cli_find_option_val(argv, arg_index, argc, "ledger", &l_ledger_str);
 
+        const char * l_sync_mode_str = "updates";
+        dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-mode", &l_sync_mode_str);
+        if ( !dap_strcmp(l_sync_mode_str,"all") )
+            dap_chain_net_get_flag_sync_from_zero(l_net);
+
         if ( l_stats_str ){
             if ( strcmp(l_stats_str,"tx") == 0 ) {
                 const char *l_to_str = NULL;
@@ -1126,11 +1140,6 @@ static int s_cli_net( int argc, char **argv, void *arg_func, char **a_str_reply)
 
         } else if( l_sync_str) {
 
-            const char * l_sync_mode_str = "updates";
-            dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-mode", &l_sync_mode_str);
-            if ( !dap_strcmp(l_sync_mode_str,"all") )
-                dap_chain_net_get_flag_sync_from_zero(l_net);
-
             if ( strcmp(l_sync_str,"all") == 0 ) {
                 dap_chain_node_cli_set_reply_text(a_str_reply,
                                                   "SYNC_ALL state requested to state machine. Current state: %s\n",
-- 
GitLab