From bd65f7c5dc1d0df97099e4c4fa603c947fe967c9 Mon Sep 17 00:00:00 2001
From: "alexey.stratulat" <alexey.stratulat@demlabs.net>
Date: Tue, 6 Jun 2023 18:42:27 +0000
Subject: [PATCH] Support 8236

---
 modules/common/dap_chain_datum.c     | 64 +++++++++++++++-------------
 modules/net/dap_chain_node_cli_cmd.c | 32 ++++++++++++--
 2 files changed, 62 insertions(+), 34 deletions(-)

diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c
index da193b7272..dd477b9db5 100644
--- a/modules/common/dap_chain_datum.c
+++ b/modules/common/dap_chain_datum.c
@@ -61,31 +61,36 @@ void s_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_token_t *a_
         dap_string_append_printf(a_str_out,"<CORRUPTED TSD SECTION>\n");
         return;
     }
-    size_t l_offset = 0;
-    size_t l_offset_max = 0;
+    size_t l_tsd_total_size = 0;
     switch (a_token->type) {
         case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL:
             switch (a_token->subtype) {
                 case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE:
-                    l_offset_max = a_token->header_private_decl.tsd_total_size; break;
+                    l_tsd_total_size = a_token->header_private_decl.tsd_total_size; break;
                 case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE:
-                    l_offset_max = a_token->header_native_decl.tsd_total_size; break;
+                    l_tsd_total_size = a_token->header_native_decl.tsd_total_size; break;
                 default: break;
             } break;
         case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE:
             switch (a_token->subtype) {
                 case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE:
-                    l_offset_max = a_token->header_private_update.tsd_total_size; break;
+                    l_tsd_total_size = a_token->header_private_update.tsd_total_size; break;
                 case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE:
-                    l_offset_max = a_token->header_native_update.tsd_total_size; break;
+                    l_tsd_total_size = a_token->header_native_update.tsd_total_size; break;
                 default: break;
             } break;
         default: break;
     }
-    while (l_offset < l_offset_max) {
-        if ((l_tsd->size+l_offset) > l_offset_max) {
+    size_t l_tsd_size = 0;
+    for (size_t l_offset = 0; l_offset < l_tsd_total_size; l_offset += l_tsd_size) {
+        l_tsd = (dap_tsd_t *) (((byte_t*)l_tsd) + l_tsd_size);
+        l_tsd_size = l_tsd ? dap_tsd_size(l_tsd) : 0;
+        if (l_tsd_size == 0) {
+            log_it(L_ERROR,"Wrong zero TSD size, exiting s_datum_token_dump_tsd()");
+            return;
+        } else if (l_tsd_size+l_offset > l_tsd_total_size) {
             log_it(L_WARNING, "<CORRUPTED TSD> too big size %u when left maximum %zu",
-                   l_tsd->size, l_offset_max - l_offset);
+                   l_tsd->size, l_tsd_total_size - l_offset);
             return;
         }
         switch( l_tsd->type){
@@ -93,28 +98,28 @@ void s_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_token_t *a_
                 dap_string_append_printf(a_str_out,"flags_set: ");
                 dap_chain_datum_token_flags_dump(a_str_out,
                                                  dap_tsd_get_scalar(l_tsd, uint16_t));
-            break;
+                continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS:
                 dap_string_append_printf(a_str_out,"flags_unset: ");
                 dap_chain_datum_token_flags_dump(a_str_out,
                                                  dap_tsd_get_scalar(l_tsd, uint16_t));
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY: { // 256
                 char *l_balance = dap_chain_balance_print(dap_tsd_get_scalar(l_tsd, uint256_t));
                 dap_string_append_printf(a_str_out, "total_supply: %s\n", l_balance);
                 DAP_DELETE(l_balance);
             }
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_OLD: {// 128
                 char *l_balance = dap_chain_balance_print(GET_256_FROM_128(dap_tsd_get_scalar(l_tsd, uint128_t)));
                 dap_string_append_printf(a_str_out, "total_supply: %s\n", l_balance);
                 DAP_DELETE(l_balance);
             }
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID :
                 dap_string_append_printf(a_str_out,"total_signs_valid: %u\n",
                                          dap_tsd_get_scalar(l_tsd, uint16_t) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD:
                 if(l_tsd->size >= sizeof(dap_pkey_t)){
                     char *l_hash_str;
@@ -132,7 +137,7 @@ void s_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_token_t *a_
                     }
                 } else
                     dap_string_append_printf(a_str_out,"total_pkeys_add: <WRONG SIZE %u>\n", l_tsd->size);
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE:
                 if(l_tsd->size == sizeof(dap_chain_hash_fast_t) ){
                     char *l_hash_str = (!dap_strcmp(a_hash_out_type,"hex")|| !dap_strcmp(a_hash_out_type, "content_hash"))
@@ -142,65 +147,64 @@ void s_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_token_t *a_
                     DAP_DELETE( l_hash_str );
                 }else
                     dap_string_append_printf(a_str_out,"total_pkeys_remove: <WRONG SIZE %u>\n", l_tsd->size);
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK: {
                 char *balance = NULL;
                 dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section = dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t);
                 dap_string_append_printf(a_str_out, "ticker_token_from: %s\nemission_rate: %s\n",
                                          l_tsd_section->ticker_token_from, (balance = dap_chain_balance_to_coins(l_tsd_section->emission_rate)));
                 DAP_DEL_Z(balance);
-            }break;
+            }continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_ADD  :
                 dap_string_append_printf(a_str_out,"datum_type_allowed_add: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_REMOVE  :
                 dap_string_append_printf(a_str_out,"datum_type_allowed_remove: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_ADD  :
                 dap_string_append_printf(a_str_out,"datum_type_blocked_add: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_REMOVE:
                 dap_string_append_printf(a_str_out,"datum_type_blocked_remove: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD:
                 dap_string_append_printf(a_str_out,"tx_sender_allowed_add: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE:
                 dap_string_append_printf(a_str_out,"tx_sender_allowed_remove: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD:
                 dap_string_append_printf(a_str_out,"tx_sender_blocked_add: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE:
                 dap_string_append_printf(a_str_out,"tx_sender_blocked_remove: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD:
                 dap_string_append_printf(a_str_out,"tx_receiver_allowed_add: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE:
                 dap_string_append_printf(a_str_out,"tx_receiver_allowed: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD:
                 dap_string_append_printf(a_str_out, "tx_receiver_blocked_add: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE:
                 dap_string_append_printf(a_str_out, "tx_receiver_blocked_remove: %s\n",
                                          dap_tsd_get_string_const(l_tsd) );
-            break;
+            continue;
             default: dap_string_append_printf(a_str_out, "<0x%04hX>: <size %u>\n", l_tsd->type, l_tsd->size);
         }
-        l_offset += dap_tsd_size(l_tsd);
     }
 }
 
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 8c266c652e..940a7b0f2b 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -2248,6 +2248,10 @@ static dap_chain_datum_token_t * s_sign_cert_in_cycle(dap_cert_t ** l_certs, dap
             ((l_datum_token->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE)
             ||(l_datum_token->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE)))
         l_tsd_size = l_datum_token->header_native_decl.tsd_total_size;
+    if ((l_datum_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) &&
+            ((l_datum_token->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE)
+             ||(l_datum_token->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE)))
+        l_tsd_size = l_datum_token->header_native_update.tsd_total_size;
     uint16_t l_tmp_cert_sign_count = l_datum_token->signs_total;
     l_datum_token->signs_total = 0;
 
@@ -2258,7 +2262,7 @@ static dap_chain_datum_token_t * s_sign_cert_in_cycle(dap_cert_t ** l_certs, dap
 
         if (l_sign) {
             size_t l_sign_size = dap_sign_get_size(l_sign);
-            l_datum_token = DAP_REALLOC(l_datum_token, sizeof(dap_chain_datum_token_t) + (*l_datum_signs_offset) + l_sign_size);
+            l_datum_token = DAP_REALLOC(l_datum_token, sizeof(*l_datum_token) + (*l_datum_signs_offset) + l_sign_size);
             memcpy(l_datum_token->data_n_tsd + *l_datum_signs_offset, l_sign, l_sign_size);
             *l_datum_signs_offset += l_sign_size;
             DAP_DELETE(l_sign);
@@ -3382,15 +3386,18 @@ static int s_parse_additional_token_decl_arg(int a_argc, char ** a_argv, char **
     dap_cert_parse_str_list(l_new_certs_str, &l_new_certs, &l_new_certs_count);
     for (size_t i=0; i < l_new_certs_count; i++){
         dap_pkey_t *l_pkey = dap_cert_to_pkey(l_new_certs[i]);
+        if (!l_pkey) {
+            log_it(L_ERROR, "Can't get pkey for cert: %s", l_new_certs[i]->name);
+            continue;
+        }
         size_t l_pkey_size = sizeof(dap_pkey_t) + l_pkey->header.size;
         dap_tsd_t *l_pkey_tsd = dap_tsd_create(DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD, l_pkey, l_pkey_size);
         size_t l_pkey_tsd_size = dap_tsd_size(l_pkey_tsd);
         l_tsd_list = dap_list_append(l_tsd_list, l_pkey_tsd);
         l_tsd_total_size += l_pkey_tsd_size;
         DAP_DELETE(l_pkey);
-        DAP_DELETE(l_new_certs[i]);
     }
-    DAP_DELETE(l_new_certs);
+    DAP_DEL_Z(l_new_certs);
     size_t l_tsd_offset = 0;
     a_params->ext.parsed_tsd = DAP_NEW_SIZE(byte_t, l_tsd_total_size);
     for (dap_list_t *l_iter = dap_list_first(l_tsd_list); l_iter; l_iter = l_iter->next) {
@@ -3420,6 +3427,21 @@ static int s_parse_additional_token_decl_arg(int a_argc, char ** a_argv, char **
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD:
                 log_it(L_DEBUG,"== TX_RECEIVER_BLOCKED_ADD: binary data");
             break;
+            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD:
+                if(l_tsd->size >= sizeof(dap_pkey_t)){
+                    char *l_hash_str;
+                    dap_pkey_t *l_pkey = (dap_pkey_t*)l_tsd->data;
+                    dap_hash_fast_t l_hf = {0};
+                    if (!dap_pkey_get_hash(l_pkey, &l_hf)) {
+                        log_it(L_DEBUG, "== total_pkeys_add: <WRONG CALCULATION FINGERPRINT>");
+                    } else {
+                        l_hash_str = dap_chain_hash_fast_to_str_new(&l_hf);
+                        log_it(L_DEBUG, "== total_pkeys_add: %s", l_hash_str);
+                        DAP_DELETE(l_hash_str);
+                    }
+                } else
+                    log_it(L_DEBUG,"== total_pkeys_add: <WRONG SIZE %u>", l_tsd->size);
+            break;
             default: log_it(L_DEBUG, "== 0x%04X: binary data %u size ",l_tsd->type, l_tsd->size );
         }
         size_t l_tsd_size = dap_tsd_size(l_tsd);
@@ -3880,6 +3902,7 @@ int com_token_update(int a_argc, char ** a_argv, char ** a_str_reply)
                 l_datum_token->signs_valid = l_signs_emission;
                 l_datum_token->header_native_update.tsd_total_size = l_params->ext.tsd_total_size;
                 l_datum_token->header_native_update.decimals = atoi(l_params->decimals_str);
+                l_datum_data_offset = l_params->ext.tsd_total_size;
             } else { // if (l_params->type == DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_UPDATE) {
                 log_it(L_DEBUG,"Prepared TSD sections for private token on %zd total size", l_params->ext.tsd_total_size);
                 snprintf(l_datum_token->ticker, sizeof(l_datum_token->ticker), "%s", l_ticker);
@@ -3888,6 +3911,7 @@ int com_token_update(int a_argc, char ** a_argv, char ** a_str_reply)
                 l_datum_token->signs_valid = l_signs_emission;
                 l_datum_token->header_private_update.tsd_total_size = l_params->ext.tsd_total_size;
                 l_datum_token->header_private_update.decimals = atoi(l_params->decimals_str);
+                l_datum_data_offset = l_params->ext.tsd_total_size;
             }
             // Add TSD sections in the end
             // Add TSD sections in the end
@@ -3941,7 +3965,7 @@ int com_token_update(int a_argc, char ** a_argv, char ** a_str_reply)
     dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_key_hash);
     char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash);
     char * l_key_str_out = dap_strcmp(l_hash_out_type, "hex") ?
-                           dap_enc_base58_encode_hash_to_str(&l_key_hash) : l_key_str;
+                           dap_enc_base58_encode_hash_to_str(&l_key_hash) : dap_strdup(l_key_str);
 
     // Add datum to mempool with datum_token hash as a key
     char *l_gdb_group_mempool = l_chain
-- 
GitLab