From aa78144ee96348c2c5a683a7077665214ac5cccc Mon Sep 17 00:00:00 2001 From: "alexey.stratulat" <alexey.stratulat@demlabs.net> Date: Mon, 5 Jun 2023 08:58:30 +0000 Subject: [PATCH] Support 8236 --- dap-sdk | 2 +- modules/chain/dap_chain_ledger.c | 308 ++++++++++++++---- modules/chain/include/dap_chain_ledger.h | 2 +- modules/common/dap_chain_datum.c | 32 +- .../common/include/dap_chain_datum_token.h | 4 +- modules/net/dap_chain_node_cli.c | 6 + modules/net/dap_chain_node_cli_cmd.c | 50 ++- modules/net/include/dap_chain_node_cli_cmd.h | 5 + 8 files changed, 327 insertions(+), 82 deletions(-) diff --git a/dap-sdk b/dap-sdk index 52084ccdc2..e96283ddc2 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 52084ccdc2e6d219625937edc77ee56ff1c58f86 +Subproject commit e96283ddc24d41a307badd6365d82cf524685f79 diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index a7e66e3450..911f7d94e0 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -114,8 +114,8 @@ typedef struct dap_chain_ledger_token_item { time_t last_update_token_time; // for auth operations - dap_sign_t ** auth_signs; - dap_chain_hash_fast_t * auth_signs_pkey_hash; + dap_pkey_t ** auth_pkeys; + dap_chain_hash_fast_t *auth_pkeys_hash; size_t auth_signs_total; size_t auth_signs_valid; uint16_t flags; @@ -269,6 +269,7 @@ static void s_threshold_txs_proc( dap_ledger_t * a_ledger); static void s_threshold_txs_free(dap_ledger_t *a_ledger); static void s_threshold_emission_free(dap_ledger_t *a_ledger); static int 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 int s_tsd_sign_apply(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 int s_ledger_permissions_check(dap_chain_ledger_token_item_t * a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size ); static bool s_ledger_tps_callback(void *a_arg); static int s_sort_ledger_tx_item(dap_chain_ledger_tx_item_t* a, dap_chain_ledger_tx_item_t* b); @@ -437,8 +438,7 @@ static bool s_ledger_token_update_check(dap_chain_ledger_token_item_t *a_cur_tok l_signs_upd_token = dap_chain_datum_token_signs_parse(a_token_update, a_token_update_size, &auth_signs_total, &auth_signs_valid); - if (a_cur_token_item->auth_signs_total != auth_signs_total - || a_cur_token_item->auth_signs_valid != auth_signs_valid) { + if (a_cur_token_item->auth_signs_valid > auth_signs_total) { DAP_DEL_Z(l_signs_upd_token); if(s_debug_more) log_it(L_WARNING,"Can't update token with ticker '%s' because: " @@ -450,13 +450,24 @@ static bool s_ledger_token_update_check(dap_chain_ledger_token_item_t *a_cur_tok return false; } if(auth_signs_total) { + size_t l_valid_pkeys = 0; for(uint16_t i = 0; i < auth_signs_total; i++){ - if (!dap_sign_match_pkey_signs(a_cur_token_item->auth_signs[i], l_signs_upd_token[i])) { - DAP_DEL_Z(l_signs_upd_token); - if(s_debug_more) - log_it(L_WARNING, "Can't update token with ticker '%s' because: Signs not compare", a_token_update->ticker); - return false; + dap_pkey_t *l_pkey_upd_token = dap_pkey_get_from_sign_deserialization(l_signs_upd_token[i]); + for (size_t j = 0; j < a_cur_token_item->auth_signs_total; j++) { + if (dap_pkey_match(a_cur_token_item->auth_pkeys[j], l_pkey_upd_token)) { + l_valid_pkeys++; + break; + } } + DAP_DELETE(l_pkey_upd_token); + } + if (a_cur_token_item->auth_signs_valid > l_valid_pkeys) { + DAP_DEL_Z(l_signs_upd_token); + if (s_debug_more) + log_it(L_WARNING, "Can't update token with ticker '%s' because: Insufficient number of valid signatures " + "for an token update. Verified %zu needs %zu.", a_token_update->ticker, l_valid_pkeys, + a_cur_token_item->auth_signs_valid); + return false; } } DAP_DEL_Z(l_signs_upd_token); @@ -467,7 +478,149 @@ static bool s_ledger_token_update_check(dap_chain_ledger_token_item_t *a_cur_tok return false; } } - return true; + // Check edit auth signs + size_t l_tsd_total_size = 0; + if (a_token_update->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE) + l_tsd_total_size = a_token_update->header_native_update.tsd_total_size; + else if (a_token_update->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE) + l_tsd_total_size = a_token_update->header_native_update.tsd_total_size; + // Checking that the TSD section with the threshold change is the only one. + //And getting lists of TSD sections with the removal and addition of certificates. + int l_quantity_tsd_section_edit_signs_emission = 0; + dap_tsd_t *l_tsd_signs_valid = NULL; + dap_list_t *l_tsd_list_remote_pkeys = NULL; + int l_quantity_tsd_remote_pkeys = 0; + dap_list_t *l_tsd_list_added_pkeys = NULL; + int l_quantity_tsd_add_pkeys = 0; + for (size_t l_tsd_offset = 0; l_tsd_offset < l_tsd_total_size; ) { + dap_tsd_t *l_tsd = (dap_tsd_t*)((byte_t*)a_token_update->data_n_tsd + l_tsd_offset); + size_t l_tsd_size = dap_tsd_size(l_tsd); + if (l_tsd_size == 0) { + if (s_debug_more) + log_it(L_ERROR, "Token refresh datum %s contains a non-valid TSD section. Size TSD section is 0.", a_token_update->ticker); + return false; + } else if (l_tsd_size + l_tsd_offset > l_tsd_total_size) { + if (s_debug_more) + log_it(L_ERROR, "Token refresh datum %s contains a non-valid TSD section. " + "The size of the TSD section and the offset exceed the set size of the TSD sections.", a_token_update->ticker); + return false; + } + switch (l_tsd->type) { + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: + l_quantity_tsd_section_edit_signs_emission++; + l_tsd_signs_valid = l_tsd; + break; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: + l_quantity_tsd_remote_pkeys++; + l_tsd_list_remote_pkeys = dap_list_append(l_tsd_list_remote_pkeys, l_tsd); + break; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: + l_quantity_tsd_add_pkeys++; + l_tsd_list_added_pkeys = dap_list_append(l_tsd_list_added_pkeys, l_tsd); + break; + } + l_tsd_offset += l_tsd_size; + } + if (l_quantity_tsd_section_edit_signs_emission > 1) { + if (s_debug_more) { + log_it(L_ERROR, "Datum contains %ud TSD sections of type DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID which is not true. " + "There can be at most one such TSD section.", l_quantity_tsd_section_edit_signs_emission); + } + dap_list_free1(l_tsd_list_added_pkeys); + dap_list_free1(l_tsd_list_remote_pkeys); + return false; + } + //Check new count signs + size_t l_new_signs_total = auth_signs_total + l_quantity_tsd_add_pkeys - l_quantity_tsd_remote_pkeys; + if (l_tsd_signs_valid) { + size_t l_signs_valid_from_tsd = (size_t)(dap_tsd_get_scalar(l_tsd_signs_valid,uint16_t)); + if (l_new_signs_total < l_signs_valid_from_tsd || l_signs_valid_from_tsd < 1) { + dap_list_free1(l_tsd_list_added_pkeys); + dap_list_free1(l_tsd_list_remote_pkeys); + return false; + } + } else { + if (l_new_signs_total < auth_signs_valid){ + dap_list_free1(l_tsd_list_added_pkeys); + dap_list_free1(l_tsd_list_remote_pkeys); + return false; + } + } + //Check valid remove_signs + bool isAccepted = false; + if (!l_tsd_list_remote_pkeys) + isAccepted = true; + else { + for (dap_list_t *l_ptr = l_tsd_list_remote_pkeys; l_ptr; l_ptr = dap_list_next(l_ptr)) { + dap_tsd_t *l_tsd = (dap_tsd_t *) l_ptr->data; + dap_hash_fast_t l_hash = dap_tsd_get_scalar(l_tsd, dap_hash_fast_t); + bool accepted = false; + for (size_t i = 0; i < auth_signs_total; i++) { + if (dap_hash_fast_compare(&a_cur_token_item->auth_pkeys_hash[i], &l_hash)) { + accepted = true; + break; + } + } + if (!accepted) { + if (s_debug_more) { + char *l_hash_str = dap_hash_fast_to_str_new(&l_hash); + log_it(L_ERROR, + "It is expected that the TSD parameter DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE will contain only " + "the hashes of the public keys of the signatures with which the given token was previously signed. But not %s", + l_hash_str); + DAP_DELETE(l_hash_str); + } + } + isAccepted = accepted; + } + } + if (!isAccepted) { + dap_list_free1(l_tsd_list_added_pkeys); + dap_list_free1(l_tsd_list_remote_pkeys); + return false; + } + //Check added signs + dap_chain_datum_token_t *l_token_tmp = DAP_DUP_SIZE(a_token_update, a_token_update_size); + l_token_tmp->header_native_update.tsd_total_size = 0; + isAccepted = true; + for (dap_list_t *l_ptr = l_tsd_list_added_pkeys; l_ptr; l_ptr = dap_list_next(l_ptr)) { + dap_tsd_t *l_tsd = (dap_tsd_t*)l_ptr->data; + if (l_tsd->size >= sizeof(dap_pkey_t)) { + dap_pkey_t *l_pkey = (dap_pkey_t *) l_tsd->data; + dap_hash_fast_t l_hf_pkey = {0}; + if (!dap_pkey_get_hash(l_pkey, &l_hf_pkey)) { + if (s_debug_more) + log_it(L_ERROR, "Failed to calculate the hash for the public key located in the " + "DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD section of the TSD"); + isAccepted = false; + break; + } + for (size_t i = 0; i < a_cur_token_item->auth_signs_total; i++) { + if (dap_hash_fast_compare(&l_hf_pkey, &a_cur_token_item->auth_pkeys_hash[i])) { + if (s_debug_more) { + char *l_hf_str = dap_hash_fast_to_str_new(&l_hf_pkey); + log_it(L_ERROR, "The public key with hash %s from the TSD section of the type " + "DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD cannot be added, because such " + "a key already exists in the ledger.", l_hf_str); + DAP_DELETE(l_hf_str); + } + isAccepted = false; + break; + } + } + } else { + if (s_debug_more) + log_it(L_ERROR, "It is expected that the size %zu of information from the TSD section of type " + "DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD will be greater than or equal to %zu.", + dap_tsd_size(l_tsd), sizeof(dap_pkey_t)); + isAccepted = false; + break; + } + } + dap_list_free1(l_tsd_list_added_pkeys); + dap_list_free1(l_tsd_list_remote_pkeys); + DAP_DELETE(l_token_tmp); + return isAccepted; } @@ -907,14 +1060,15 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * l_token_item->current_supply = l_token_item->total_supply; l_token_item->auth_signs_total = l_token->signs_total; l_token_item->auth_signs_valid = l_token->signs_valid; - l_token_item->auth_signs = dap_chain_datum_token_signs_parse(a_token, a_token_size, + dap_sign_t **l_signs = dap_chain_datum_token_signs_parse(a_token, a_token_size, &l_token_item->auth_signs_total, &l_token_item->auth_signs_valid); if (l_token_item->auth_signs_total) { - l_token_item->auth_signs_pkey_hash = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t, sizeof(dap_chain_hash_fast_t) * - l_token_item->auth_signs_total); + l_token_item->auth_pkeys = DAP_NEW_Z_SIZE(dap_pkey_t*, sizeof(dap_pkey_t*) * l_token_item->auth_signs_total); + l_token_item->auth_pkeys_hash = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t, sizeof(dap_chain_hash_fast_t) * l_token_item->auth_signs_total);; for (uint16_t k = 0; k < l_token_item->auth_signs_total; k++) { - dap_sign_get_pkey_hash(l_token_item->auth_signs[k], &l_token_item->auth_signs_pkey_hash[k]); + l_token_item->auth_pkeys[k] = dap_pkey_get_from_sign_deserialization(l_signs[k]); + dap_pkey_get_hash(l_token_item->auth_pkeys[k], &l_token_item->auth_pkeys_hash[k]); } } } @@ -994,6 +1148,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * DAP_DEL_Z(l_balance); } l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); + s_tsd_sign_apply(a_ledger, l_token_item, a_token, a_token_size); } break; case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: { @@ -1006,6 +1161,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * DAP_DEL_Z(l_balance); } l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); + s_tsd_sign_apply(a_ledger, l_token_item, a_token, a_token_size); } break; } @@ -1084,48 +1240,6 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite a_token_item->auth_signs_valid = dap_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_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--; - if(a_token_item->auth_signs_total){ - // Type sizeof's misunderstanding in realloc? - 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*) ); - }else{ - DAP_DEL_Z(a_token_item->auth_signs); - DAP_DEL_Z(a_token_item->auth_signs_pkey_hash); - } - - 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++; - // Type sizeof's misunderstanding in realloc? - 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{ - if(s_debug_more) - 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; - //Allowed tx receiver addres list add, remove or clear case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD:{ if( l_tsd->size == sizeof (dap_chain_addr_t) ){ @@ -1488,6 +1602,78 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite return 0; } +static int s_tsd_sign_apply(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_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->header_native_decl.tsd_total_size; + dap_tsd_t *l_new_signs_valid = NULL; + dap_list_t *l_remove_pkeys = NULL; + dap_list_t *l_added_pkeys = NULL; + + 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 ){ + if(s_debug_more) + log_it(L_ERROR,"Wrong zero TSD size, exiting TSD parse"); + break; + }else if (l_tsd_size + l_offset > l_tsd_total_size ){ + if(s_debug_more) + log_it(L_ERROR,"Wrong %zd TSD size, exiting TSD parse", l_tsd_size); + break; + } + switch (l_tsd->type) { + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: + l_new_signs_valid = l_tsd; + break; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: + l_added_pkeys = dap_list_append(l_added_pkeys, l_tsd->data); + break; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: + l_remove_pkeys = dap_list_append(l_remove_pkeys, l_tsd); + break; + } + } + for (dap_list_t *l_ptr = l_remove_pkeys; l_ptr; l_ptr = dap_list_next(l_ptr)) { + dap_tsd_t *l_tsd = l_ptr->data; + dap_hash_fast_t l_hash = dap_tsd_get_scalar(l_tsd, dap_chain_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_pkeys_hash[i] )){ + if (i+1 != a_token_item->auth_signs_total){ + memmove(a_token_item->auth_pkeys+i,a_token_item->auth_pkeys+i+1, + (a_token_item->auth_signs_total-i-1)*sizeof (void*)); + memmove(a_token_item->auth_pkeys_hash+i,a_token_item->auth_pkeys_hash+i+1, + (a_token_item->auth_signs_total-i-1)*sizeof(dap_chain_hash_fast_t)); + } + a_token_item->auth_signs_total--; + if(a_token_item->auth_signs_total) { + // Type sizeof's misunderstanding in realloc? + a_token_item->auth_pkeys = DAP_REALLOC(a_token_item->auth_pkeys,a_token_item->auth_signs_total*sizeof (dap_pkey_t*) ); + a_token_item->auth_pkeys_hash = DAP_REALLOC(a_token_item->auth_pkeys_hash,a_token_item->auth_signs_total*sizeof(dap_chain_hash_fast_t)); + } else { + DAP_DEL_Z(a_token_item->auth_pkeys); + DAP_DEL_Z(a_token_item->auth_pkeys_hash); + } + break; + } + } + } + for (dap_list_t *l_ptr = l_added_pkeys; l_ptr; l_ptr = dap_list_next(l_ptr)) { + dap_pkey_t *l_pkey = (dap_pkey_t*)l_ptr->data; + a_token_item->auth_signs_total++; + // Type sizeof's misunderstanding in realloc? + a_token_item->auth_pkeys = DAP_REALLOC(a_token_item->auth_pkeys,a_token_item->auth_signs_total*sizeof (dap_pkey_t*) ); + a_token_item->auth_pkeys_hash = DAP_REALLOC(a_token_item->auth_pkeys_hash,a_token_item->auth_signs_total*sizeof (dap_chain_hash_fast_t)); + a_token_item->auth_pkeys[a_token_item->auth_signs_total-1] = DAP_NEW_SIZE(dap_pkey_t, sizeof(dap_pkey_t)+l_pkey->header.size); + memcpy(a_token_item->auth_pkeys[a_token_item->auth_signs_total-1], l_pkey, sizeof(dap_pkey_t)+l_pkey->header.size); + dap_pkey_get_hash(l_pkey, &a_token_item->auth_pkeys_hash[a_token_item->auth_signs_total-1]); + } + if (l_new_signs_valid) { + a_token_item->auth_signs_valid = dap_tsd_get_scalar(l_new_signs_valid,uint16_t); + } + return 0; +} + 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)->load_mode) { @@ -1664,7 +1850,7 @@ size_t dap_chain_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const cha * @param a_token_ticker * @return */ -dap_list_t * dap_chain_ledger_token_auth_signs_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker) +dap_list_t * dap_chain_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker) { dap_list_t * l_ret = NULL; dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item; @@ -1673,7 +1859,7 @@ dap_list_t * dap_chain_ledger_token_auth_signs_hashes(dap_ledger_t *a_ledger, co if (!dap_strcmp(l_token_item->ticker, a_token_ticker)) { debug_if(s_debug_more, L_INFO, " ! Token %s : total %lu auth signs", a_token_ticker, l_token_item->auth_signs_total); for (size_t i = 0; i < l_token_item->auth_signs_total; i++) { - l_ret = dap_list_append(l_ret, (dap_chain_hash_fast_t*)(&l_token_item->auth_signs_pkey_hash[i])); + l_ret = dap_list_append(l_ret, (dap_chain_hash_fast_t*)(&l_token_item->auth_pkeys_hash[i])); } break; } @@ -2300,7 +2486,7 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ dap_sign_get_pkey_hash(l_sign, &l_sign_pkey_hash); // Find pkey in auth hashes for (uint16_t k=0; k< l_token_item->auth_signs_total; k++) { - if (dap_hash_fast_compare(&l_sign_pkey_hash, &l_token_item->auth_signs_pkey_hash[k])) { + if (dap_hash_fast_compare(&l_sign_pkey_hash, &l_token_item->auth_pkeys_hash[k])) { // Verify if its token emission header signed if (dap_sign_verify(l_sign, l_emi_ptr_check_size, l_sign_data_check_size) == 1) { l_aproves++; @@ -4397,8 +4583,8 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) } pthread_rwlock_unlock(&l_token_current->token_emissions_rwlock); DAP_DELETE(l_token_current->datum_token); - DAP_DELETE(l_token_current->auth_signs); - DAP_DELETE(l_token_current->auth_signs_pkey_hash); + DAP_DELETE(l_token_current->auth_pkeys); + DAP_DELETE(l_token_current->auth_pkeys_hash); DAP_DEL_Z(l_token_current->tx_recv_allow); DAP_DEL_Z(l_token_current->tx_recv_block); DAP_DEL_Z(l_token_current->tx_send_allow); diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h index 2fdd38b722..daf04624b0 100644 --- a/modules/chain/include/dap_chain_ledger.h +++ b/modules/chain/include/dap_chain_ledger.h @@ -154,7 +154,7 @@ dap_string_t *dap_chain_ledger_balance_info(dap_ledger_t *a_ledger); size_t dap_chain_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker); size_t dap_chain_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker); -dap_list_t * dap_chain_ledger_token_auth_signs_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker); +dap_list_t * dap_chain_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker); /** * Add token emission datum diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c index 85c1d4ca1c..da193b7272 100644 --- a/modules/common/dap_chain_datum.c +++ b/modules/common/dap_chain_datum.c @@ -115,25 +115,33 @@ 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,"total_signs_valid: %u\n", dap_tsd_get_scalar(l_tsd, uint16_t) ); break; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_ADD : - 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")) - ? dap_chain_hash_fast_to_str_new((dap_chain_hash_fast_t*) l_tsd->data) - : dap_enc_base58_encode_hash_to_str((dap_chain_hash_fast_t*) l_tsd->data); - dap_string_append_printf(a_str_out,"total_signs_add: %s\n", l_hash_str); - DAP_DELETE( l_hash_str ); - }else - dap_string_append_printf(a_str_out,"total_signs_add: <WRONG SIZE %u>\n", l_tsd->size); + 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)) { + dap_string_append_printf(a_str_out,"total_pkeys_add: <WRONG CALCULATION FINGERPRINT>\n"); + } else { + if (!dap_strcmp(a_hash_out_type, "hex") || !dap_strcmp(a_hash_out_type, "content_hash")) + l_hash_str = dap_chain_hash_fast_to_str_new(&l_hf); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(&l_hf); + dap_string_append_printf(a_str_out, "total_pkeys_add: %s\n", l_hash_str); + DAP_DELETE(l_hash_str); + } + } else + dap_string_append_printf(a_str_out,"total_pkeys_add: <WRONG SIZE %u>\n", l_tsd->size); break; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_REMOVE : + 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")) ? dap_chain_hash_fast_to_str_new((dap_chain_hash_fast_t*) l_tsd->data) : dap_enc_base58_encode_hash_to_str((dap_chain_hash_fast_t*) l_tsd->data); - dap_string_append_printf(a_str_out,"total_signs_remove: %s\n", l_hash_str ); + dap_string_append_printf(a_str_out,"total_pkeys_remove: %s\n", l_hash_str); DAP_DELETE( l_hash_str ); }else - dap_string_append_printf(a_str_out,"total_signs_add: <WRONG SIZE %u>\n", l_tsd->size); + dap_string_append_printf(a_str_out,"total_pkeys_remove: <WRONG SIZE %u>\n", l_tsd->size); break; case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK: { char *balance = NULL; diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index 0ae88809c7..37210a4d2a 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -258,10 +258,10 @@ extern const char *c_dap_chain_datum_token_flag_str[]; #define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID 0x0004 // Remove owner signature by pkey fingerprint -#define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_REMOVE 0x0005 +#define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE 0x0005 // Add owner signature's pkey fingerprint -#define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_ADD 0x0006 +#define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD 0x0006 // Emission for delegated token #define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK 0x0027 diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 8c3355f0ae..95917a8314 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -225,6 +225,12 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "\n" ); + dap_cli_server_cmd_add("token_update_sign", com_token_decl_sign, "Token update add sign and new sign", + "token_update_sign -net <net_name> -chain <chain_name> -datum <datum_hash> -certs <certs list> -new_certs <certs list>\n" + "\t Sign existent <datum hash> in mempool with <certs list>\n" + ); + // Token commands + dap_cli_server_cmd_add ("token_decl_sign", com_token_decl_sign, "Token declaration add sign", "token_decl_sign -net <net_name> -chain <chain_name> -datum <datum_hash> -certs <certs list>\n" "\t Sign existent <datum hash> in mempool with <certs list>\n" diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index ef2ba6ef5e..86bb99d626 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -2256,7 +2256,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(dap_chain_datum_token_t) + (*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); @@ -2352,7 +2352,8 @@ int com_token_decl_sign(int a_argc, char **a_argv, char ** a_str_reply) l_datum_hash_hex_str, &l_datum_size, NULL, NULL )) != NULL) { // Check if its token declaration - if(l_datum->header.type_id == DAP_CHAIN_DATUM_TOKEN_DECL) { + if(l_datum->header.type_id == DAP_CHAIN_DATUM_TOKEN_DECL || + l_datum->header.type_id == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) { dap_chain_datum_token_t *l_datum_token = DAP_DUP_SIZE(l_datum->data, l_datum->header.data_size); // for realloc DAP_DELETE(l_datum); if ((l_datum_token->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE) @@ -3363,9 +3364,48 @@ static int s_parse_additional_token_decl_arg(int a_argc, char ** a_argv, char ** if (a_params->ext.tx_sender_blocked) l_tsd_list = s_parse_wallet_addresses(a_params->ext.tx_sender_blocked, l_tsd_list, &l_tsd_total_size, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD); - if (!l_tsd_total_size) - return 0; - + const char* l_new_certs_str = NULL; + const char* l_remove_signs = NULL; + dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-new_certs", &l_new_certs_str); + dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-remove_certs", &l_remove_signs); + + //Added remove signs + if (l_remove_signs) { + size_t l_added_tsd_size = 0; + char *l_remove_signs_ptrs = NULL; + char *l_remove_signs_dup = strdup(l_remove_signs); + char *l_remove_signs_str = strtok_r(l_remove_signs_dup, ",", &l_remove_signs_ptrs); + for (; l_remove_signs_str; l_remove_signs_str = strtok_r(NULL, ",", &l_remove_signs_ptrs)) { + dap_hash_fast_t *l_hf = DAP_NEW(dap_hash_fast_t); + char *l_tmp = strdup(l_remove_signs_str); + if (dap_chain_hash_fast_from_str(l_tmp, l_hf) == 0) { + dap_tsd_t *l_hf_tsd = dap_tsd_create(DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE, l_hf, sizeof(dap_hash_fast_t)); + size_t l_hf_tsd_size = dap_tsd_size(l_hf_tsd); + l_tsd_list = dap_list_append(l_tsd_list, l_hf_tsd); + l_added_tsd_size += l_hf_tsd_size; + } + DAP_DELETE(l_hf); + DAP_DELETE(l_tmp); + } + DAP_DELETE(l_remove_signs_dup); + DAP_DELETE(l_remove_signs_str); + l_tsd_total_size += l_added_tsd_size; + } + //Added new certs + dap_cert_t **l_new_certs = NULL; + size_t l_new_certs_count = 0; + 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]); + 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); 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) { diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h index d42ec09455..48eb99f2d0 100644 --- a/modules/net/include/dap_chain_node_cli_cmd.h +++ b/modules/net/include/dap_chain_node_cli_cmd.h @@ -91,6 +91,11 @@ int com_token_update(int a_argc, char **a_argv, char ** a_str_reply); */ int com_token_decl_sign ( int a_argc, char **a_argv, char ** str_reply); +/* + * Token update sign + */ +int com_token_update_sign(int argc, char ** argv, char ** a_str_reply); + /** * Token emission */ -- GitLab