diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 9539f01355c0e8479eb6d810b4f520789856f472..f09423b565013cb36178ef99a8b1f36dcebcb802 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -70,7 +70,10 @@ static pthread_rwlock_t s_verificators_rwlock; #define MAX_OUT_ITEMS 10 typedef struct dap_chain_ledger_token_emission_item { dap_chain_hash_fast_t datum_token_emission_hash; - dap_chain_datum_token_emission_t *datum_token_emission; + union { + dap_chain_datum_token_emission_t *datum_token_emission; + dap_chain_datum_256_token_emission_t *datum_256_token_emission; // 256 + }; size_t datum_token_emission_size; UT_hash_handle hh; } dap_chain_ledger_token_emission_item_t; @@ -123,6 +126,12 @@ typedef struct dap_chain_ledger_tokenizer { UT_hash_handle hh; } dap_chain_ledger_tokenizer_t; +typedef struct dap_chain_ledger_tokenizer_256 { + char token_ticker[10]; + uint256_t sum; + UT_hash_handle hh; +} dap_chain_ledger_tokenizer_256_t; + typedef struct dap_chain_ledger_tx_bound { dap_chain_hash_fast_t tx_prev_hash_fast; dap_chain_datum_tx_t *tx_prev; @@ -1319,6 +1328,7 @@ int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, const dap_chain dap_chain_datum_token_emission_t * dap_chain_ledger_token_emission_find(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash) { + dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); dap_chain_datum_token_emission_t * l_token_emission = NULL; dap_chain_ledger_token_item_t * l_token_item = NULL; @@ -1338,6 +1348,31 @@ dap_chain_datum_token_emission_t * dap_chain_ledger_token_emission_find(dap_ledg return l_token_emission; } +// 256 +dap_chain_datum_256_token_emission_t * dap_chain_ledger_token_emission_256_find(dap_ledger_t *a_ledger, + const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash) +{ + dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); + dap_chain_datum_256_token_emission_t * l_token_emission = NULL; + dap_chain_ledger_token_item_t * l_token_item = NULL; + pthread_rwlock_rdlock(&l_ledger_priv->tokens_rwlock); + HASH_FIND_STR(l_ledger_priv->tokens, a_token_ticker, l_token_item); + pthread_rwlock_unlock(&l_ledger_priv->tokens_rwlock); + + if(l_token_item) { + dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL; + pthread_rwlock_rdlock(&l_token_item->token_emissions_rwlock); + HASH_FIND(hh, l_token_item->token_emissions, a_token_emission_hash, sizeof(*a_token_emission_hash), + l_token_emission_item); + pthread_rwlock_unlock(&l_token_item->token_emissions_rwlock); + if( l_token_emission_item) { + l_token_emission = l_token_emission_item->datum_256_token_emission; + } + } + return l_token_emission; +} + + /** * @brief dap_chain_ledger_set_local_cell_id * @param a_local_cell_id @@ -1584,6 +1619,10 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // sum of values in 'out' items from the previous transactions dap_chain_ledger_tokenizer_t *l_values_from_prev_tx = NULL, *l_values_from_cur_tx = NULL, *l_value_cur = NULL, *l_tmp = NULL, *l_res = NULL; + + dap_chain_ledger_tokenizer_256_t *l_values_from_prev_tx_256 = NULL, *l_values_from_cur_tx_256 = NULL, + *l_value_cur_256 = NULL, *l_tmp_256 = NULL, *l_res_256 = NULL; + char *l_token = NULL; dap_chain_ledger_token_item_t * l_token_item = NULL; dap_chain_hash_fast_t *l_emission_hash; @@ -1622,6 +1661,9 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_chain_tx_in_cond_t *l_tx_in_cond; dap_chain_hash_fast_t l_tx_prev_hash={0}; uint8_t l_cond_type = *(uint8_t *)l_list_tmp->data; + + bool l_is_type_256 = false; + // one of the previous transaction if (l_cond_type == TX_ITEM_TYPE_IN) { l_tx_in = (dap_chain_tx_in_t *)l_list_tmp->data; @@ -1655,12 +1697,20 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_is_first_transaction = true; if (!l_token) { dap_chain_tx_token_t *l_tx_token = (dap_chain_tx_token_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_TOKEN, NULL); - if (!l_tx_token) { + dap_chain_tx_token_t *l_tx_token_256 = (dap_chain_tx_token_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_256_TOKEN, NULL); + if (l_tx_token) { // TX_ITEM_TYPE_TOKEN + l_token = l_tx_token->header.ticker; + l_emission_hash = &l_tx_token->header.token_emission_hash; + + } else if (l_tx_token_256) { // TX_ITEM_TYPE_256_TOKEN + l_token = l_tx_token_256->header.ticker; + l_emission_hash = &l_tx_token_256->header.token_emission_hash; + + } else { l_err_num = -4; break; } - l_token = l_tx_token->header.ticker; - l_emission_hash = &l_tx_token->header.token_emission_hash; + } DAP_DELETE(bound_item); continue; @@ -1702,6 +1752,8 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } uint64_t l_value; + uint256_t l_value_256 = uint256_0; + // Get list of all 'out' items from previous transaction dap_list_t *l_list_prev_out = dap_chain_datum_tx_items_get(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, NULL); // Get one 'out' item in previous transaction bound with current 'in' item @@ -1713,12 +1765,20 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } if (l_cond_type == TX_ITEM_TYPE_IN) { dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_prev_out; - if (l_type == TX_ITEM_TYPE_OUT) { + if ( l_type == TX_ITEM_TYPE_OUT ) { bound_item->out.tx_prev_out = l_tx_prev_out; memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out->addr,sizeof (bound_item->out.tx_prev_out->addr)); - } else if (l_type == TX_ITEM_TYPE_OUT_EXT) { + } else if ( l_type == TX_ITEM_TYPE_256_OUT ) { // 256 + l_is_type_256 = true; + bound_item->out.tx_prev_out_256 = l_tx_prev_out; + memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out_256->addr,sizeof (bound_item->out.tx_prev_out_256->addr)); + } else if (l_type == TX_ITEM_TYPE_OUT_EXT ) { bound_item->out.tx_prev_out_ext = l_tx_prev_out; memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out_ext->addr,sizeof (bound_item->out.tx_prev_out_ext->addr)); + } else if ( l_type == TX_ITEM_TYPE_256_OUT_EXT ) { // 256 + l_is_type_256 = true; + bound_item->out.tx_prev_out_ext_256 = l_tx_prev_out; + memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out_ext_256->addr,sizeof (bound_item->out.tx_prev_out_ext_256->addr)); } else { l_err_num = -8; break; @@ -1737,27 +1797,57 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // calculate hash from public key dap_hash_fast(l_pkey_ser, l_pkey_ser_size, &l_hash_pkey); // hash of public key in 'out' item of previous transaction - uint8_t *l_prev_out_addr_key = (l_type == TX_ITEM_TYPE_OUT) ? - bound_item->out.tx_prev_out->addr.data.key : - bound_item->out.tx_prev_out_ext->addr.data.key; + + uint8_t *l_prev_out_addr_key = NULL; + if ( l_type == TX_ITEM_TYPE_256_OUT ) // 256 + l_prev_out_addr_key = bound_item->out.tx_prev_out_256->addr.data.key; + + else if ( l_type == TX_ITEM_TYPE_OUT ) + l_prev_out_addr_key = bound_item->out.tx_prev_out->addr.data.key; + + else if ( l_type == TX_ITEM_TYPE_256_OUT_EXT ) // 256 + l_prev_out_addr_key = bound_item->out.tx_prev_out_ext_256->addr.data.key; + + else + l_prev_out_addr_key = bound_item->out.tx_prev_out_ext->addr.data.key; + + // uint8_t *l_prev_out_addr_key = (l_type == TX_ITEM_TYPE_OUT || l_type == TX_ITEM_TYPE_256_OUT) ? + // bound_item->out.tx_prev_out->addr.data.key : + // bound_item->out.tx_prev_out_ext->addr.data.key; // 4. compare public key hashes in the signature of the current transaction and in the 'out' item of the previous transaction if(memcmp(&l_hash_pkey, l_prev_out_addr_key, sizeof(dap_chain_hash_fast_t))) { l_err_num = -9; break; } } - if (l_type == TX_ITEM_TYPE_OUT) { + + if ( l_type == TX_ITEM_TYPE_256_OUT ) // 256 + l_value_256 = bound_item->out.tx_prev_out_256->header.value; + + else if ( l_type == TX_ITEM_TYPE_OUT ) l_value = bound_item->out.tx_prev_out->header.value; + + else if ( l_type == TX_ITEM_TYPE_256_OUT_EXT ) { // 256 + l_value_256 = bound_item->out.tx_prev_out_ext_256->header.value; + l_token = bound_item->out.tx_prev_out_ext_256->token; } else { l_value = bound_item->out.tx_prev_out_ext->header.value; l_token = bound_item->out.tx_prev_out_ext->token; } + // if (l_type == TX_ITEM_TYPE_OUT || l_type == TX_ITEM_TYPE_256_OUT) { + // l_value = bound_item->out.tx_prev_out->header.value; + // } else { + // l_value = bound_item->out.tx_prev_out_ext->header.value; + // l_token = bound_item->out.tx_prev_out_ext->token; + // } + } else { // TX_ITEM_TYPE_IN_COND - if(*(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT_COND) { + dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_prev_out; + if( l_type != TX_ITEM_TYPE_OUT_COND && l_type != TX_ITEM_TYPE_256_OUT_COND) { l_err_num = -8; break; } - if (! l_token_item){ + if (!l_token_item){ l_err_num = -16; log_it(L_ERROR,"Can't find token item for conditioned tx out"); break; @@ -1771,12 +1861,27 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); size_t l_pkey_ser_size = 0; const uint8_t *l_pkey_ser = dap_sign_get_pkey(l_sign, &l_pkey_ser_size); - dap_chain_tx_out_cond_t *l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out; + + dap_chain_tx_out_cond_t *l_tx_prev_out_cond = NULL; + dap_chain_256_tx_out_cond_t *l_tx_prev_out_cond_256 = NULL; // 256 + + if ( l_type == TX_ITEM_TYPE_256_OUT_COND ) { // 256 + l_is_type_256 = true; + l_tx_prev_out_cond_256 = (dap_chain_256_tx_out_cond_t *)l_tx_prev_out; + } else { + l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out; + } + if (l_pkey_ser_size != l_prev_pkey_ser_size || memcmp(l_prev_pkey_ser, l_pkey_ser, l_prev_pkey_ser_size)) { // 5b. Call verificator for conditional output dap_chain_ledger_verificator_t *l_verificator; - int l_tmp = (int)l_tx_prev_out_cond->header.subtype; + int l_tmp; + if ( l_type == TX_ITEM_TYPE_256_OUT_COND ) { // 256 + l_tmp = (int)l_tx_prev_out_cond_256->header.subtype; + } else { + l_tmp = (int)l_tx_prev_out_cond->header.subtype; + } pthread_rwlock_rdlock(&s_verificators_rwlock); HASH_FIND_INT(s_verificators, &l_tmp, l_verificator); pthread_rwlock_unlock(&s_verificators_rwlock); @@ -1786,14 +1891,21 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_err_num = -13; break; } - if (l_verificator->callback(l_tx_prev_out_cond, a_tx) == false) { + if (l_verificator->callback(l_tx_prev_out_cond, a_tx) == false && + l_verificator->callback(l_tx_prev_out_cond_256, a_tx) == false ) { l_err_num = -14; break; } } - bound_item->out.tx_prev_out_cond = l_tx_prev_out_cond; - // calculate sum of values from previous transactions - l_value = l_tx_prev_out_cond->header.value; + + if ( l_type == TX_ITEM_TYPE_256_OUT_COND ) { // 256 + bound_item->out.tx_prev_out_cond_256 = l_tx_prev_out_cond_256; + // calculate sum of values from previous transactions + l_value_256 = l_tx_prev_out_cond_256->header.value; + } else { + bound_item->out.tx_prev_out_cond = l_tx_prev_out_cond; + l_value = l_tx_prev_out_cond->header.value; + } l_token = NULL; } if (!l_token || !*l_token) { @@ -1815,6 +1927,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_err_num = -15; break; } + // Check permissions if ( (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED ) || // If all is blocked - check if we're (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN) ){ // in white list @@ -1842,14 +1955,25 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } } - HASH_FIND_STR(l_values_from_prev_tx, l_token, l_value_cur); - if (!l_value_cur) { - l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); - strcpy(l_value_cur->token_ticker, l_token); - HASH_ADD_STR(l_values_from_prev_tx, token_ticker, l_value_cur); + if ( l_is_type_256 ) { // 256 + HASH_FIND_STR(l_values_from_prev_tx_256, l_token, l_value_cur_256); + if (!l_value_cur_256) { + l_value_cur_256 = DAP_NEW_Z(dap_chain_ledger_tokenizer_256_t); + strcpy(l_value_cur_256->token_ticker, l_token); + HASH_ADD_STR(l_values_from_prev_tx_256, token_ticker, l_value_cur_256); + } + SUM_256_256(l_value_cur_256->sum, l_value_256, &l_value_cur_256->sum); + + } else { + HASH_FIND_STR(l_values_from_prev_tx, l_token, l_value_cur); + if (!l_value_cur) { + l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); + strcpy(l_value_cur->token_ticker, l_token); + HASH_ADD_STR(l_values_from_prev_tx, token_ticker, l_value_cur); + } + // calculate sum of values from previous transactions per each token + l_value_cur->sum += l_value; } - // calculate sum of values from previous transactions per each token - l_value_cur->sum += l_value; l_list_bound_items = dap_list_append(l_list_bound_items, bound_item); } if (l_list_in) @@ -1862,30 +1986,43 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { DAP_DELETE(l_value_cur); } + HASH_ITER(hh, l_values_from_prev_tx_256, l_value_cur_256, l_tmp_256) { + DAP_DELETE(l_value_cur_256); + } return l_err_num; } // 6. Compare sum of values in 'out' items in the current transaction and in the previous transactions // Calculate the sum of values in 'out' items from the current transaction bool l_multichannel = false; - if (HASH_COUNT(l_values_from_prev_tx) > 1) { + if (HASH_COUNT(l_values_from_prev_tx) > 1 || HASH_COUNT(l_values_from_prev_tx_256) > 1) { l_multichannel = true; } else { l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); if(l_token) strcpy(l_value_cur->token_ticker, l_token); HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); + + // 256 + l_value_cur_256 = DAP_NEW_Z(dap_chain_ledger_tokenizer_256_t); + if(l_token) + strcpy(l_value_cur_256->token_ticker, l_token); + HASH_ADD_STR(l_values_from_cur_tx_256, token_ticker, l_value_cur_256); + } + dap_list_t *l_list_tx_out = NULL; bool emission_flag = !l_is_first_transaction || (l_is_first_transaction && l_ledger_priv->check_token_emission); // find 'out' items dap_list_t *l_list_out = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx, TX_ITEM_TYPE_OUT_ALL, NULL); uint64_t l_value=0; + uint256_t l_value_256=uint256_0; for (l_list_tmp = l_list_out; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp)) { dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data; dap_chain_addr_t l_tx_out_to={0}; - if (l_type == TX_ITEM_TYPE_OUT) - { + bool l_is_type_256 = false; + + if (l_type == TX_ITEM_TYPE_OUT) { dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)l_list_tmp->data; if (l_multichannel) { // token ticker is mandatory for multichannel transactions l_err_num = -16; @@ -1896,6 +2033,20 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } memcpy(&l_tx_out_to , &l_tx_out->addr, sizeof (l_tx_out_to)); l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); + + } else if (l_type == TX_ITEM_TYPE_256_OUT) { // 256 + l_is_type_256 = true; + dap_chain_256_tx_out_t *l_tx_out = (dap_chain_256_tx_out_t *)l_list_tmp->data; + if (l_multichannel) { // token ticker is mandatory for multichannel transactions + l_err_num = -16; + break; + } + if (emission_flag) { + l_value_256 = l_tx_out->header.value; + } + memcpy(&l_tx_out_to , &l_tx_out->addr, sizeof (l_tx_out_to)); + l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); + } else if (l_type == TX_ITEM_TYPE_OUT_EXT) { dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)l_list_tmp->data; if (!l_multichannel) { // token ticker is depricated for single-channel transactions @@ -1908,6 +2059,21 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } memcpy(&l_tx_out_to , &l_tx_out->addr, sizeof (l_tx_out_to)); l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); + + } else if (l_type == TX_ITEM_TYPE_256_OUT_EXT) { // 256 + l_is_type_256 = true; + dap_chain_256_tx_out_ext_t *l_tx_out = (dap_chain_256_tx_out_ext_t *)l_list_tmp->data; + if (!l_multichannel) { // token ticker is depricated for single-channel transactions + l_err_num = -16; + break; + } + if (emission_flag) { + l_value_256 = l_tx_out->header.value; + l_token = l_tx_out->token; + } + memcpy(&l_tx_out_to , &l_tx_out->addr, sizeof (l_tx_out_to)); + l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); + } else if (l_type == TX_ITEM_TYPE_OUT_COND) { dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)l_list_tmp->data; if (emission_flag) { @@ -1919,16 +2085,42 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t break; } l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); + + } else if (l_type == TX_ITEM_TYPE_256_OUT_COND) { // 256 + l_is_type_256 = true; + dap_chain_256_tx_out_cond_t *l_tx_out = (dap_chain_256_tx_out_cond_t *)l_list_tmp->data; + if (emission_flag) { + l_value_256 = l_tx_out->header.value; + } + if (l_multichannel) { // out_cond have no field .token + log_it(L_WARNING, "No conditional output support for multichannel transaction"); + l_err_num = -18; + break; + } + l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); } - if (l_multichannel) { - HASH_FIND_STR(l_values_from_cur_tx, l_token, l_value_cur); - if (!l_value_cur) { - l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); - strcpy(l_value_cur->token_ticker, l_token); - HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); + + if (l_is_type_256) { // 256 + if (l_multichannel) { + HASH_FIND_STR(l_values_from_cur_tx_256, l_token, l_value_cur_256); + if (!l_value_cur) { + l_value_cur_256 = DAP_NEW_Z(dap_chain_ledger_tokenizer_256_t); + strcpy(l_value_cur_256->token_ticker, l_token); + HASH_ADD_STR(l_values_from_cur_tx_256, token_ticker, l_value_cur_256); + } + } + SUM_256_256(l_value_cur_256->sum, l_value_256, &l_value_cur_256->sum); + } else { + if (l_multichannel) { + HASH_FIND_STR(l_values_from_cur_tx, l_token, l_value_cur); + if (!l_value_cur) { + l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); + strcpy(l_value_cur->token_ticker, l_token); + HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); + } } + l_value_cur->sum += l_value; } - l_value_cur->sum += l_value; // Get permissions for token l_token_item = NULL; @@ -1971,7 +2163,6 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } } - if ( l_list_out ) dap_list_free(l_list_out); @@ -1979,11 +2170,14 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t while (l_is_first_transaction && !l_err_num) { if (l_ledger_priv->check_token_emission) { // Check the token emission dap_chain_datum_token_emission_t * l_token_emission = dap_chain_ledger_token_emission_find(a_ledger, l_token, l_emission_hash); - if (l_token_emission) { - if (l_token_emission->hdr.value != l_value_cur->sum) { + dap_chain_datum_256_token_emission_t * l_token_emission_256 = dap_chain_ledger_token_emission_256_find(a_ledger, l_token, l_emission_hash); + if (l_token_emission || l_token_emission_256) { + if (l_token_emission->hdr.value != l_value_cur->sum && + !EQUAL_256(l_token_emission_256->hdr.value, l_value_cur_256->sum) ) { l_err_num = -10; } l_value_cur = NULL; + l_value_cur_256 = NULL; } else { log_it(L_WARNING, "Emission for tx_token wasn't found"); l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION; @@ -1992,17 +2186,33 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } break; } + while (!l_is_first_transaction && !l_err_num) { + bool l_err_flag = false; + bool l_err_flag_256 = false; HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { HASH_FIND_STR(l_values_from_cur_tx, l_value_cur->token_ticker, l_res); if (!l_res || l_res->sum != l_value_cur->sum) { if(s_debug_more) log_it(L_ERROR, "Sum of values in out items of current tx (%"DAP_UINT64_FORMAT_U") is not equal outs from previous tx (%"DAP_UINT64_FORMAT_U") for token %s", l_res ? l_res->sum : 0, l_value_cur->sum, l_value_cur->token_ticker); - l_err_num = -12; + l_err_flag = true; + break; + } + } + HASH_ITER(hh, l_values_from_prev_tx_256, l_value_cur_256, l_tmp_256) { + HASH_FIND_STR(l_values_from_cur_tx_256, l_value_cur_256->token_ticker, l_res_256); + if (!l_res_256 || !EQUAL_256(l_res_256->sum,l_value_cur_256->sum) ) { + if(s_debug_more) + log_it(L_ERROR, "Sum of values in out items of current tx 256 (%"DAP_UINT64_FORMAT_U") is not equal outs from previous tx (%"DAP_UINT64_FORMAT_U") for token %s", + dap_chain_uint256_to( ( l_res_256 ? l_res_256->sum : uint256_0) ), dap_chain_uint256_to(l_value_cur_256->sum), l_value_cur_256->token_ticker); + l_err_flag_256 = true; break; } } + if ( l_err_flag && l_err_flag_256 ) + l_err_num = -12; + break; } @@ -2012,6 +2222,15 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t HASH_ITER(hh, l_values_from_cur_tx, l_value_cur, l_tmp) { DAP_DELETE(l_value_cur); } + + // 256 + HASH_ITER(hh, l_values_from_prev_tx_256, l_value_cur_256, l_tmp_256) { + DAP_DELETE(l_value_cur_256); + } + HASH_ITER(hh, l_values_from_cur_tx_256, l_value_cur_256, l_tmp_256) { + DAP_DELETE(l_value_cur_256); + } + if (!a_list_bound_items || l_err_num) { dap_list_free_full(l_list_bound_items, free); } else { diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h index 31baa98f0f70fb9ccf3f3a8a963fb197c7e18c50..05c3fb91769681808d6ac440364037c4769d79cc 100644 --- a/modules/chain/include/dap_chain_ledger.h +++ b/modules/chain/include/dap_chain_ledger.h @@ -139,6 +139,10 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_emission_t * dap_chain_ledger_token_emission_find(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash); +// 256 +dap_chain_datum_256_token_emission_t * dap_chain_ledger_token_emission_256_find(dap_ledger_t *a_ledger, + const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash); + const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_chain_hash_fast_t *a_tx_hash); void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index 1e90a809804126eb0746806a418b6e3f4ad8ec3a..c5699fa79730cfe5f495b44b033134d7583dd605 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -172,6 +172,9 @@ size_t dap_chain_datum_item_tx_get_size(const uint8_t *a_item) case TX_ITEM_TYPE_TOKEN: // token item size = dap_chain_tx_token_get_size((const dap_chain_tx_token_t*) a_item); break; + case TX_ITEM_TYPE_256_TOKEN: // token item + size = dap_chain_tx_token_get_size((const dap_chain_tx_token_t*) a_item); + break; default: return 0; } @@ -193,6 +196,17 @@ dap_chain_tx_token_t* dap_chain_datum_tx_item_token_create(dap_chain_hash_fast_t strncpy(l_item->header.ticker, a_ticker, sizeof(l_item->header.ticker) - 1); return l_item; } +// 256 +dap_chain_tx_token_t* dap_chain_datum_tx_item_256_token_create(dap_chain_hash_fast_t * a_datum_token_hash,const char * a_ticker) +{ + if(!a_ticker) + return NULL; + dap_chain_tx_token_t *l_item = DAP_NEW_Z(dap_chain_tx_token_t); + l_item->header.type = TX_ITEM_TYPE_256_TOKEN; + memcpy (& l_item->header.token_emission_hash, a_datum_token_hash, sizeof ( *a_datum_token_hash ) ); + strncpy(l_item->header.ticker, a_ticker, sizeof(l_item->header.ticker) - 1); + return l_item; +} /** * Create item dap_chain_tx_out_t diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h index 68e85ce5a2641eb38255e5b396981561fe78abc7..a181bf6254df223d911932a525f6b6ac60dc8ead 100644 --- a/modules/common/include/dap_chain_common.h +++ b/modules/common/include/dap_chain_common.h @@ -201,6 +201,10 @@ typedef enum dap_chain_tx_item_type { TX_ITEM_TYPE_SIG = 0x30, TX_ITEM_TYPE_TOKEN = 0x40, TX_ITEM_TYPE_TOKEN_EXT = 0x41, + + TX_ITEM_TYPE_256_TOKEN = 0x42, + TX_ITEM_TYPE_256_TOKEN_EXT = 0x43, + TX_ITEM_TYPE_IN_COND = 0x50, /// @brief Transaction: conditon inputs TX_ITEM_TYPE_OUT_COND = 0x60, /// @brief Transaction: conditon outputs diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h index c68c373fdb2b7a03106a7dcfe87ae589f1df4417..512c21c482a30a804d2573e59a88ffae27afff62 100644 --- a/modules/common/include/dap_chain_datum_tx_items.h +++ b/modules/common/include/dap_chain_datum_tx_items.h @@ -86,6 +86,9 @@ size_t dap_chain_datum_item_tx_get_size(const uint8_t *a_item); */ dap_chain_tx_token_t* dap_chain_datum_tx_item_token_create(dap_chain_hash_fast_t * a_datum_token_hash,const char * a_ticker); +//256 +dap_chain_tx_token_t* dap_chain_datum_tx_item_256_token_create(dap_chain_hash_fast_t * a_datum_token_hash,const char * a_ticker); + /** * Create item dap_chain_tx_out_t * diff --git a/modules/consensus/none/dap_chain_cs_none.c b/modules/consensus/none/dap_chain_cs_none.c index 9f8939c1f376ac065946c590953f317445232fc9..eee00fb90a968f9189e633c2dd99868c08912995 100644 --- a/modules/consensus/none/dap_chain_cs_none.c +++ b/modules/consensus/none/dap_chain_cs_none.c @@ -321,11 +321,13 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha if (dap_chain_ledger_token_load(a_chain->ledger,l_token, l_datum->header.data_size)) return ATOM_REJECT; }break; + case DAP_CHAIN_DATUM_256_TOKEN_EMISSION: // 256 case DAP_CHAIN_DATUM_TOKEN_EMISSION: { dap_chain_datum_token_emission_t *l_token_emission = (dap_chain_datum_token_emission_t*) l_datum->data; if (dap_chain_ledger_token_emission_load(a_chain->ledger, l_token_emission, l_datum->header.data_size)) return ATOM_REJECT; }break; + case DAP_CHAIN_DATUM_256_TX: // 256 case DAP_CHAIN_DATUM_TX:{ dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; // No trashhold herr, don't save bad transactions to base diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 45190dce94cabdfc7f2a67201b464f2fa8f3f9bc..dc27fd869b16608b44da8f9f228337b3e1445c97 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -1135,7 +1135,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config) if ( l_listen_unix_socket_path && l_listen_unix_socket_permissions ) { if ( l_listen_unix_socket_permissions_str ) { uint16_t l_perms; - dap_sscanf(l_listen_unix_socket_permissions_str,"%hu", &l_perms); + dap_sscanf(l_listen_unix_socket_permissions_str,"%ho", &l_perms); l_listen_unix_socket_permissions = l_perms; } log_it( L_INFO, "Console interace on path %s (%04o) ", l_listen_unix_socket_path, l_listen_unix_socket_permissions ); diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 815826f3db26d45c22afb67b0c43a36ae22cb6e4..d70c37a1108e3734bdfe0c4863919bedde5316f7 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -3143,9 +3143,14 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) const char * l_addr_str = NULL; const char * l_emission_hash_str = NULL; + const char * l_type_256 = NULL; + char * l_emission_hash_str_new = NULL; dap_chain_hash_fast_t l_emission_hash={0}; + dap_chain_datum_token_emission_t * l_emission = NULL; + dap_chain_datum_256_token_emission_t * l_emission_256 = NULL; // 256 + char * l_emission_hash_str_base58 = NULL; const char * l_certs_str = NULL; @@ -3180,6 +3185,9 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) // Wallet address that recieves the emission dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-emission", &l_emission_hash_str); + // 256 + dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-256", &l_type_256); + // Wallet address that recieves the emission dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-certs", &l_certs_str); @@ -3214,7 +3222,6 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) return -4; } - if (l_emission_hash_str){// Load emission l_emission_hash_str_base58 = dap_enc_base58_encode_hash_to_str(&l_emission_hash); if (dap_chain_hash_fast_from_str( l_emission_hash_str,&l_emission_hash) == 0 ){ @@ -3247,8 +3254,6 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) } } - - dap_chain_addr_t * l_addr = dap_chain_addr_from_str(l_addr_str); if(!l_addr) { @@ -3292,38 +3297,77 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) size_t l_emission_size = sizeof(l_emission->hdr) + sizeof(l_emission->data.type_auth.signs_count); - l_emission = DAP_NEW_Z_SIZE(dap_chain_datum_token_emission_t, l_emission_size); - strncpy(l_emission->hdr.ticker, l_ticker, sizeof(l_emission->hdr.ticker) - 1); - l_emission->hdr.value = l_emission_value; - l_emission->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH; - memcpy(&l_emission->hdr.address, l_addr, sizeof(l_emission->hdr.address)); - // Then add signs + size_t l_emission_256_size = sizeof(l_emission_256->hdr) + + sizeof(l_emission_256->data.type_auth.signs_count); + size_t l_offset = 0; - for(size_t i = 0; i < l_certs_size; i++) { - dap_sign_t * l_sign = dap_cert_sign(l_certs[i], &l_emission->hdr, - sizeof(l_emission->hdr), 0); - size_t l_sign_size = dap_sign_get_size(l_sign); - l_emission_size += l_sign_size; - l_emission = DAP_REALLOC(l_emission, l_emission_size); - memcpy(l_emission->data.type_auth.signs + l_offset, l_sign, l_sign_size); - l_offset += l_sign_size; - DAP_DELETE(l_sign); + if ( !l_type_256 ) { + l_emission = DAP_NEW_Z_SIZE(dap_chain_datum_token_emission_t, l_emission_size); + l_emission->hdr.value = l_emission_value; + + strncpy(l_emission->hdr.ticker, l_ticker, sizeof(l_emission->hdr.ticker) - 1); + l_emission->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH; + memcpy(&l_emission->hdr.address, l_addr, sizeof(l_emission->hdr.address)); + + for(size_t i = 0; i < l_certs_size; i++) { + dap_sign_t * l_sign = dap_cert_sign(l_certs[i], &l_emission->hdr, + sizeof(l_emission->hdr), 0); + size_t l_sign_size = dap_sign_get_size(l_sign); + l_emission_size += l_sign_size; + l_emission = DAP_REALLOC(l_emission, l_emission_size); + memcpy(l_emission->data.type_auth.signs + l_offset, l_sign, l_sign_size); + l_offset += l_sign_size; + DAP_DELETE(l_sign); + } + } else { // 256 + l_emission_256 = DAP_NEW_Z_SIZE(dap_chain_datum_256_token_emission_t, l_emission_256_size); + l_emission_256->hdr.value = GET_256(l_emission_value); + + strncpy(l_emission_256->hdr.ticker, l_ticker, sizeof(l_emission_256->hdr.ticker) - 1); + l_emission_256->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH; + memcpy(&l_emission_256->hdr.address, l_addr, sizeof(l_emission_256->hdr.address)); + + for(size_t i = 0; i < l_certs_size; i++) { + dap_sign_t * l_sign = dap_cert_sign(l_certs[i], &l_emission_256->hdr, + sizeof(l_emission_256->hdr), 0); + size_t l_sign_size = dap_sign_get_size(l_sign); + l_emission_256_size += l_sign_size; + l_emission_256 = DAP_REALLOC(l_emission_256, l_emission_256_size); + memcpy(l_emission_256->data.type_auth.signs + l_offset, l_sign, l_sign_size); + l_offset += l_sign_size; + DAP_DELETE(l_sign); + } } + dap_chain_datum_t * l_datum_emission; + // Produce datum - dap_chain_datum_t * l_datum_emission = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN_EMISSION, - l_emission, - l_emission_size); + if ( !l_type_256 ) { + l_datum_emission = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN_EMISSION, + l_emission, + l_emission_size); + } else { // 256 + l_datum_emission = dap_chain_datum_create(DAP_CHAIN_DATUM_256_TOKEN_EMISSION, + l_emission_256, + l_emission_256_size); + } + size_t l_datum_emission_size = sizeof(l_datum_emission->header) + l_datum_emission->header.data_size; // Calc token's hash //dap_chain_hash_fast_t l_emission_hash; - dap_hash_fast(l_emission, l_emission_size, &l_emission_hash); + if ( !l_type_256 ) { + dap_hash_fast(l_emission, l_emission_size, &l_emission_hash); + } else { // 256 + dap_hash_fast(l_emission_256, l_emission_256_size, &l_emission_hash); + } l_emission_hash_str = l_emission_hash_str_new = dap_chain_hash_fast_to_str_new(&l_emission_hash); l_emission_hash_str_base58 = dap_enc_base58_encode_hash_to_str(&l_emission_hash); // Delete token emission DAP_DEL_Z(l_emission); + DAP_DEL_Z(l_emission_256); // 256 + // // Calc datum's hash // dap_chain_hash_fast_t l_datum_emission_hash; // dap_hash_fast(l_datum_emission, l_datum_emission_size, (uint8_t*) &l_datum_emission_hash); @@ -3355,15 +3399,29 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) // create first transaction (with tx_token) dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); dap_chain_hash_fast_t l_tx_prev_hash = { 0 }; + dap_chain_tx_token_t *l_tx_token; + dap_chain_tx_out_t *l_out; + dap_chain_256_tx_out_t *l_out_256; + // create items - dap_chain_tx_token_t *l_tx_token = dap_chain_datum_tx_item_token_create(&l_emission_hash, l_ticker); + if ( !l_type_256 ) { + l_tx_token = dap_chain_datum_tx_item_token_create(&l_emission_hash, l_ticker); + l_out = dap_chain_datum_tx_item_out_create(l_addr, l_emission_value); + } else { // 256 + l_tx_token = dap_chain_datum_tx_item_256_token_create(&l_emission_hash, l_ticker); + l_out_256 = dap_chain_datum_tx_item_256_out_create(l_addr, GET_256(l_emission_value) ); + } dap_chain_tx_in_t *l_in = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, 0); - dap_chain_tx_out_t *l_out = dap_chain_datum_tx_item_out_create(l_addr, l_emission_value); // pack items to transaction dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_tx_token); dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_in); - dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_out); + + if ( !l_type_256 ) { + dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_out); + } else { //256 + dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_out_256); + } // Base tx don't need signature items but let it be if (l_certs){ @@ -3383,16 +3441,22 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) DAP_DEL_Z(l_tx_token); DAP_DEL_Z(l_in); - DAP_DEL_Z(l_out); + // DAP_DEL_Z(l_out); + // DAP_DEL_Z(l_out_256); DAP_DEL_Z(l_emission_hash_str_new); l_emission_hash_str = NULL; DAP_DEL_Z(l_emission_hash_str_base58); size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); + dap_chain_datum_t * l_datum_tx; // Pack transaction into the datum - dap_chain_datum_t * l_datum_tx = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size); + if ( !l_type_256 ) { + l_datum_tx = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size); + } else { + l_datum_tx = dap_chain_datum_create(DAP_CHAIN_DATUM_256_TX, l_tx, l_tx_size); + } size_t l_datum_tx_size = dap_chain_datum_size(l_datum_tx); // use l_tx hash for compatible with utho hash diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 68f9099a5a3ec5db4c6a2fb212ebc4420ff1f7ab..a5a51032558aa303823eff019b298f6176cdf1a8 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -163,7 +163,7 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, dap_chain_balance_to_coins(dap_chain_uint128_from_uint256( ((dap_chain_256_tx_out_t*)item)->header.value) ), - ((dap_chain_256_tx_out_t*)item)->header.value, + dap_chain_uint256_to(((dap_chain_256_tx_out_t*)item)->header.value), dap_chain_addr_to_str(&((dap_chain_256_tx_out_t*)item)->addr)); break; case TX_ITEM_TYPE_TOKEN: @@ -261,7 +261,8 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, ((dap_chain_datum_256_tx_receipt_t*)item)->receipt_info.value_datoshi ) ), - ((dap_chain_datum_256_tx_receipt_t*)item)->receipt_info.value_datoshi); + dap_chain_uint256_to(((dap_chain_datum_256_tx_receipt_t*)item)->receipt_info.value_datoshi) + ); if (((dap_chain_datum_256_tx_receipt_t*)item)->exts_size == sizeof(dap_sign_t) + sizeof(dap_sign_t)){ dap_sign_t *l_provider = DAP_NEW_Z(dap_sign_t); memcpy(l_provider, ((dap_chain_datum_256_tx_receipt_t*)item)->exts_n_signs, sizeof(dap_sign_t)); @@ -379,8 +380,9 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, dap_chain_balance_to_coins( dap_chain_uint128_from_uint256(((dap_chain_256_tx_out_cond_t*)item)->header.value) ), - ((dap_chain_256_tx_out_cond_t*)item)->header.value, - dap_chain_tx_out_cond_subtype_to_str(((dap_chain_256_tx_out_cond_t*)item)->header.subtype)); + dap_chain_uint256_to(((dap_chain_256_tx_out_cond_t*)item)->header.value), + dap_chain_tx_out_cond_subtype_to_str(((dap_chain_256_tx_out_cond_t*)item)->header.subtype) + ); switch (((dap_chain_256_tx_out_cond_t*)item)->header.subtype) { case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash); @@ -394,18 +396,20 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, dap_chain_balance_to_coins(dap_chain_uint128_from_uint256( ((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi) ), - ((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi); + dap_chain_uint256_to(((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi) + ); DAP_FREE(l_hash_str_tmp); break; case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE: dap_string_append_printf(a_str_out, "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" "\t\t\t addr: %s\n" "\t\t\t value: %Lf", - ((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_stake.srv_uid.uint64, - dap_chain_addr_to_str( + ((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_stake.srv_uid.uint64, + dap_chain_addr_to_str( &((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_stake.fee_addr - ), - ((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_stake.fee_value); + ), + ((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_stake.fee_value + ); break; case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: dap_string_append_printf(a_str_out, "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" @@ -420,7 +424,8 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, ((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_xchange.value ) ), - ((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_xchange.value); + dap_chain_uint256_to(((dap_chain_256_tx_out_cond_t*)item)->subtype.srv_xchange.value) + ); break; } break; @@ -1212,7 +1217,6 @@ static char* dap_db_history_token_list(dap_chain_t * a_chain, const char *a_toke static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger, const char *a_filter_token_name, const char *a_filtr_addr_base58, const char *a_hash_out_type, long a_datum_start, long a_datum_end, long *a_total_datums, dap_chain_tx_hash_processed_ht_t *a_tx_hash_processed) { dap_string_t *l_str_out = dap_string_new(NULL); - bool l_tx_hash_found = false; // list all transactions dap_tx_data_t *l_tx_data_hash = NULL; @@ -1232,7 +1236,6 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger return NULL ; } for(size_t l_datum_n = 0; l_datum_n < l_datums_count; l_datum_n++) { - dap_chain_datum_t *l_datum = l_datums[l_datum_n]; if(!l_datum) { // || l_datum->header.type_id != DAP_CHAIN_DATUM_TX) { // go to next atom @@ -1378,6 +1381,7 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger // emission case DAP_CHAIN_DATUM_256_TOKEN_EMISSION: { + // datum out of page if(a_datum_start >= 0 && (l_datum_num+l_datum_num_global < (size_t)a_datum_start || l_datum_num+l_datum_num_global >= (size_t)a_datum_end)) { l_token_num++; @@ -1396,7 +1400,7 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger uint256_t emission_value = uint256_0; DIV_256(l_token_em->hdr.value, GET_256(DATOSHI_LD), &emission_value); - dap_string_append_printf(l_str_out, "emission: %.0Lf(%"DAP_UINT64_FORMAT_U") %s, type: %s, version: %d\n", + dap_string_append_printf(l_str_out, "emission 256: %.0Lf(%"DAP_UINT64_FORMAT_U") %s, type: %s, version: %d\n", dap_chain_uint128_from_uint256(emission_value), dap_chain_uint128_from_uint256(l_token_em->hdr.value), l_token_em->hdr.ticker, @@ -1694,6 +1698,20 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger l_tx_num++;*/ } break; + + // transaction + case DAP_CHAIN_DATUM_256_TX:{ + + // datum out of page + if(a_datum_start >= 0 && (l_datum_num+l_datum_num_global < (size_t)a_datum_start || l_datum_num+l_datum_num_global >= (size_t)a_datum_end)) { + l_tx_num++; + break; + } + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datum->data; + s_dap_chain_datum_tx_out_data(l_tx, a_ledger, l_str_out, a_hash_out_type, true, &a_tx_hash_processed, &l_tx_num); + } + break; + default: dap_string_append_printf(l_str_out, "unknown datum type=%d\n", l_datum->header.type_id); break; @@ -1763,7 +1781,6 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>"); return -1; } - int l_cmd = CMD_NONE; if (dap_chain_node_cli_find_option_val(a_argv, 1, 2, "list", NULL)){ l_cmd = CMD_LIST; @@ -1772,6 +1789,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) if (dap_chain_node_cli_find_option_val(a_argv, 2, 3, "info", NULL)) l_cmd = CMD_TX_INFO; } + // command tx_history if(l_cmd == CMD_TX_HISTORY) { bool l_is_all = dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-all", NULL); @@ -1798,6 +1816,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) return -3; } } + //Select chain emission if(!l_chain_str) { // chain may be null -> then all chain use //dap_chain_node_cli_set_reply_text(a_str_reply, "command requires parameter '-chain'"); @@ -1824,6 +1843,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) // dap_chain_hash_fast_to_str(&l_tx_hash, hash_str,99); // int gsdgsd=523; } + dap_chain_addr_t *l_addr = NULL; // if need addr if(l_wallet_name || l_addr_base58) { @@ -1857,7 +1877,9 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) // all chain else l_chain_cur = dap_chain_enum(&l_chain_tmp); + while(l_chain_cur) { + // only selected net if(l_net->pub.id.uint64 == l_chain_cur->net_id.uint64) { // separator between chains @@ -1867,12 +1889,14 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) char *l_str_out = NULL; dap_string_append_printf(l_str_ret, "chain: %s\n", l_chain_cur->name); dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str); + if(l_is_all) { // without filters l_str_out = dap_db_history_filter(l_chain_cur, l_ledger, NULL, NULL, l_hash_out_type, -1, 0, NULL, l_list_tx_hash_processd); dap_string_append_printf(l_str_ret, "all history:\n%s\n", l_str_out ? l_str_out : " empty"); } else { + l_str_out = l_tx_hash_str ? dap_db_history_tx(&l_tx_hash, l_chain_cur, l_hash_out_type) : dap_db_history_addr(l_addr, l_chain_cur, l_hash_out_type); @@ -1897,6 +1921,8 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_enum_unlock(); l_chain_cur = dap_chain_enum(&l_chain_tmp); } + + DAP_DELETE(l_addr); _dap_chain_tx_hash_processed_ht_free(l_list_tx_hash_processd); // all chain @@ -1907,6 +1933,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) return 0; } else if(l_cmd == CMD_LIST){ + enum {SUBCMD_NONE, SUBCMD_LIST_COIN}; int l_sub_cmd = SUBCMD_NONE; if (dap_chain_node_cli_find_option_val(a_argv, 2, 3, "coins", NULL )) @@ -1932,6 +1959,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_string_free(l_str_ret, true); return 0; } else if (l_cmd == CMD_TX_INFO){ + //GET hash dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_tx_hash_str); //get net diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 6357613e3b74fc029ddfa6c5ec064bd68f0fe1da..ebf2a5be23151d9a0e4c7380b67552621397aa37 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -303,16 +303,13 @@ static int s_dap_chain_add_atom_to_ledger(dap_chain_cs_dag_t * a_dag, dap_ledger return dap_chain_ledger_token_load(a_ledger, l_token, l_datum->header.data_size); } break; + case DAP_CHAIN_DATUM_256_TOKEN_EMISSION: // 256 case DAP_CHAIN_DATUM_TOKEN_EMISSION: { dap_chain_datum_token_emission_t *l_token_emission = (dap_chain_datum_token_emission_t*) l_datum->data; return dap_chain_ledger_token_emission_load(a_ledger, l_token_emission, l_datum->header.data_size); } break; - case DAP_CHAIN_DATUM_256_TOKEN_EMISSION: { // 256 - dap_chain_datum_256_token_emission_t *l_token_emission = (dap_chain_datum_256_token_emission_t*) l_datum->data; - return dap_chain_ledger_token_emission_load(a_ledger, l_token_emission, l_datum->header.data_size); - } - break; + case DAP_CHAIN_DATUM_256_TX: // 256 case DAP_CHAIN_DATUM_TX: { dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; // don't save bad transactions to base