diff --git a/CMakeLists.txt b/CMakeLists.txt index 1992d015edfde19a7c35e539ff46e389f60f56c4..f636bcbb1b833494a7a6f050b56fd67bd9a1c6ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,7 @@ endif() if(NOT DEFINED CELLFRAME_MODULES) include (dap-sdk/cmake/OS_Detection.cmake) - set(CELLFRAME_MODULES "core chains mining network srv cs-dag-poa cs-esbocs cs-none - srv-app srv-app-db srv-datum srv-stake srv-voting srv-bridge srv-xchange") + set(CELLFRAME_MODULES "core chains mining network cs-dag-poa cs-esbocs cs-none srv-stake srv-voting srv-bridge srv-xchange") if(LINUX OR DARWIN) set(CELLFRAME_MODULES "${CELLFRAME_MODULES} srv-vpn") diff --git a/dap-sdk b/dap-sdk index bb5982cd7e216b9ed7f55cb80d781ed259265903..f709ca0249c5c2118b0d01fdc6c68a369b0d9b49 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit bb5982cd7e216b9ed7f55cb80d781ed259265903 +Subproject commit f709ca0249c5c2118b0d01fdc6c68a369b0d9b49 diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index 5fc8fa11461308a07281a83cffc9b818571b5933..712acc0c474c38d273adf3ce05957e65f213083a 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -257,14 +257,14 @@ static dap_chain_type_t s_chain_type_from_str(const char *a_type_str) /** * @brief s_datum_type_from_str - * get datum type (DAP_CHAIN_DATUM_TOKEN_DECL, DAP_CHAIN_DATUM_TOKEN_EMISSION, DAP_CHAIN_DATUM_TX) by str value + * get datum type (DAP_CHAIN_DATUM_TOKEN, DAP_CHAIN_DATUM_TOKEN_EMISSION, DAP_CHAIN_DATUM_TX) by str value * @param a_type_str datum type in string value (token,emission,transaction) * @return uint16_t */ static uint16_t s_datum_type_from_str(const char *a_type_str) { if(!dap_strcmp(a_type_str, "token")) { - return DAP_CHAIN_DATUM_TOKEN_DECL; + return DAP_CHAIN_DATUM_TOKEN; } if(!dap_strcmp(a_type_str, "emission")) { return DAP_CHAIN_DATUM_TOKEN_EMISSION; @@ -295,7 +295,7 @@ static uint16_t s_chain_type_convert(dap_chain_type_t a_type) { switch (a_type) { case CHAIN_TYPE_TOKEN: - return DAP_CHAIN_DATUM_TOKEN_DECL; + return DAP_CHAIN_DATUM_TOKEN; case CHAIN_TYPE_EMISSION: return DAP_CHAIN_DATUM_TOKEN_EMISSION; case CHAIN_TYPE_TX: @@ -607,6 +607,7 @@ int dap_chain_load_all(dap_chain_t *a_chain) if (!a_chain) return -2; if (a_chain->callback_load_from_gdb) { + a_chain->is_mapped = false; a_chain->callback_load_from_gdb(a_chain); return 0; } diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c index 65ab04d6b278bcaf66ab412c0a8b7561297d46f0..9fcb14a39e937e10c9bf57963764bd6acc8c13c1 100644 --- a/modules/chain/tests/dap_chain_ledger_tests.c +++ b/modules/chain/tests/dap_chain_ledger_tests.c @@ -40,14 +40,14 @@ dap_chain_datum_token_t *dap_ledger_test_create_datum_decl(dap_cert_t *a_cert, if (a_tsd_section && a_size_tsd_section != 0) { l_token->header_native_decl.tsd_total_size = a_size_tsd_section; l_token = DAP_REALLOC(l_token, sizeof(dap_chain_datum_token_t) + a_size_tsd_section); - memcpy(l_token->data_n_tsd, a_tsd_section, a_size_tsd_section); + memcpy(l_token->tsd_n_signs, a_tsd_section, a_size_tsd_section); } dap_sign_t * l_sign = dap_cert_sign(a_cert,l_token, sizeof(*l_token) + a_size_tsd_section, 0); if (l_sign) { size_t l_sign_size = dap_sign_get_size(l_sign); l_token = DAP_REALLOC(l_token, sizeof(dap_chain_datum_token_t) + a_size_tsd_section + l_sign_size); - memcpy(l_token->data_n_tsd + a_size_tsd_section, l_sign, l_sign_size); + memcpy(l_token->tsd_n_signs + a_size_tsd_section, l_sign, l_sign_size); DAP_DELETE(l_sign); l_token->signs_total = 1; *a_token_size = sizeof(dap_chain_datum_token_t) + l_sign_size + a_size_tsd_section; @@ -598,7 +598,7 @@ void dap_ledger_test_datums_removing(dap_ledger_t *a_ledger, dap_hash_fast_t *a_ dap_chain_hash_fast_t l_cond_returning_tx_hash = {0}; dap_hash_fast(l_cond_returning_tx, dap_chain_datum_tx_get_size(l_cond_returning_tx), &l_cond_returning_tx_hash); int err_code = dap_ledger_tx_add(a_ledger, l_cond_returning_tx, &l_cond_returning_tx_hash, false); - printf("err_code = %s\n", dap_ledger_tx_check_err_str(err_code)); + printf("err_code = %s\n", dap_ledger_check_error_str(err_code)); dap_assert(!err_code, "Returning of funds from cond transaction is"); uint256_t l_cond_spending_balance_after = dap_ledger_test_print_balance(a_ledger, &l_cond_spending_addr); dap_assert(compare256(l_cond_spending_balance_after, dap_chain_uint256_from(2U)), "Returning of funds from conditional tx from ledger testing"); @@ -618,7 +618,7 @@ void dap_ledger_test_datums_removing(dap_ledger_t *a_ledger, dap_hash_fast_t *a_ dap_hash_fast_t l_cond_tx_hash = {}; dap_hash_fast(l_cond_tx, dap_chain_datum_tx_get_size(l_cond_tx), &l_cond_tx_hash); int err_code = dap_ledger_tx_add(a_ledger, l_cond_tx, &l_cond_tx_hash, false); - printf("err_code = %s\n", dap_ledger_tx_check_err_str(err_code)); + printf("err_code = %s\n", dap_ledger_check_error_str(err_code)); dap_assert(!err_code, "Adding of stake cond transaction to ledger is"); dap_assert(!dap_ledger_tx_remove(a_ledger, l_cond_tx, &l_cond_tx_hash), "Test of stake conditional transaction removing from ledger:"); @@ -633,7 +633,7 @@ void dap_ledger_test_datums_removing(dap_ledger_t *a_ledger, dap_hash_fast_t *a_ dap_hash_fast_t l_stake_cond_tx_hash = {}; dap_hash_fast(l_stake_cond_tx, dap_chain_datum_tx_get_size(l_stake_cond_tx), &l_stake_cond_tx_hash); int err_code = dap_ledger_tx_add(a_ledger, l_stake_cond_tx, &l_stake_cond_tx_hash, false); - printf("err_code = %s\n", dap_ledger_tx_check_err_str(err_code)); + printf("err_code = %s\n", dap_ledger_check_error_str(err_code)); dap_assert(!err_code, "Adding of stake cond transaction to ledger is"); sleep(3); // Create stake unlock tx @@ -643,15 +643,15 @@ void dap_ledger_test_datums_removing(dap_ledger_t *a_ledger, dap_hash_fast_t *a_ dap_chain_datum_tx_t *l_unstake_cond_tx = dap_ledger_test_create_unstake_tx_cond(a_from_key, &l_stake_cond_tx_hash, dap_chain_uint256_from(20U), a_ledger); dap_hash_fast_t l_unstake_cond_tx_hash = {}; - dap_hash_fast(l_unstake_cond_tx, dap_chain_datum_tx_get_size(l_stake_cond_tx), &l_unstake_cond_tx_hash); + dap_hash_fast(l_unstake_cond_tx, dap_chain_datum_tx_get_size(l_unstake_cond_tx), &l_unstake_cond_tx_hash); err_code = dap_ledger_tx_add(a_ledger, l_unstake_cond_tx, &l_unstake_cond_tx_hash, false); - printf("err_code = %s\n", dap_ledger_tx_check_err_str(err_code)); + printf("err_code = %s\n", dap_ledger_check_error_str(err_code)); dap_assert(!err_code, "Adding of unstake cond transaction to ledger is"); uint256_t l_balance_delegated_after_unstaking = dap_ledger_test_print_delegate_balance(a_ledger, &l_addr); dap_assert(!compare256(l_balance_delegated_after_unstaking, uint256_0), "Compare delegated token balance after creating unstake transactions:") err_code = dap_ledger_tx_remove(a_ledger, l_unstake_cond_tx, &l_unstake_cond_tx_hash); - printf("err_code = %s\n", dap_ledger_tx_check_err_str(err_code)); + printf("err_code = %s\n", dap_ledger_check_error_str(err_code)); dap_assert(!err_code, "Test of unstake conditional transaction removing from ledger:"); l_balance_after = dap_ledger_test_print_balance(a_ledger, &l_addr); dap_assert(!compare256(l_balance_delegated_after_unstaking, uint256_0), "Compare delegated token balance after removing unstake transaction:") @@ -714,7 +714,7 @@ void dap_ledger_test_excess_supply(dap_ledger_t *a_ledger, dap_cert_t *a_cert, d size_t l_decl_size = 0; dap_chain_datum_token_t *l_decl = dap_ledger_test_create_datum_decl(a_cert, &l_decl_size, l_token_ticker, dap_chain_uint256_from(s_total_supply), NULL, 0, DAP_CHAIN_DATUM_TOKEN_FLAG_NONE); - dap_assert_PIF(!dap_ledger_token_add(a_ledger, l_decl, l_decl_size), "Adding token declaration to ledger."); + dap_assert_PIF(!dap_ledger_token_add(a_ledger, (byte_t *)l_decl, l_decl_size), "Adding token declaration to ledger."); dap_chain_datum_token_emission_t *l_femi = dap_chain_datum_emission_create(l_value_first_emi, l_token_ticker, a_addr); l_femi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_femi); dap_chain_hash_fast_t l_femi_hash = {0}; @@ -751,7 +751,7 @@ addr_key_container_t *gen_addr(dap_chain_net_id_t a_iddn){ dap_chain_addr_fill_from_key(l_addr, l_new_key, a_iddn); l_container->enc_key = l_new_key; l_container->addr = l_addr; - l_container->str = dap_chain_addr_to_str(l_container->addr); + l_container->str = dap_strdup(dap_chain_addr_to_str(l_container->addr)); return l_container; } @@ -807,7 +807,7 @@ void dap_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a_cert, //DAP_CHAIN_DATUM_TOKEN_FLAG_NONE); l_flags_decl); - dap_assert_PIF(!dap_ledger_token_add(a_ledger, l_decl, l_decl_size), + dap_assert_PIF(!dap_ledger_token_add(a_ledger, (byte_t *)l_decl, l_decl_size), "Can't added datum in ledger"); //Check emission in not a white list dap_chain_datum_token_emission_t *l_emi = dap_chain_datum_emission_create( @@ -873,16 +873,16 @@ void dap_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a_cert, // l_datum_token_update->header_native_update.tsd_total_size = l_offset; // l_datum_token_update->signs_total = 1; // l_offset = 0; -// memcpy(l_datum_token_update->data_n_tsd, l_tsd_update_total_size, dap_tsd_size(l_tsd_update_total_size)); +// memcpy(l_datum_token_update->tsd_n_signs, l_tsd_update_total_size, dap_tsd_size(l_tsd_update_total_size)); // l_offset += dap_tsd_size(l_tsd_update_total_size); -// memcpy(l_datum_token_update->data_n_tsd + l_offset, l_tsd_dis_flags, dap_tsd_size(l_tsd_dis_flags)); +// memcpy(l_datum_token_update->tsd_n_signs + l_offset, l_tsd_dis_flags, dap_tsd_size(l_tsd_dis_flags)); // l_offset += dap_tsd_size(l_tsd_dis_flags); // dap_sign_t * l_sign = dap_cert_sign(a_cert, l_datum_token_update, // sizeof(*l_datum_token_update) - sizeof(uint16_t), 0); // if (l_sign) { // size_t l_sign_size = dap_sign_get_size(l_sign); // l_datum_token_update = DAP_REALLOC(l_datum_token_update, sizeof(dap_chain_datum_token_t) + l_offset + l_sign_size); -// memcpy(l_datum_token_update->data_n_tsd + l_offset, l_sign, l_sign_size); +// memcpy(l_datum_token_update->tsd_n_signs + l_offset, l_sign, l_sign_size); // DAP_DELETE(l_sign); // size_t l_token_update_size = sizeof(dap_chain_datum_token_t) + l_sign_size + l_offset; // dap_assert(!dap_ledger_token_add(a_ledger, l_datum_token_update, l_token_update_size), @@ -921,7 +921,7 @@ void dap_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a_cert, //DAP_CHAIN_DATUM_TOKEN_FLAG_NONE); l_flags_decl); - dap_assert_PIF(!dap_ledger_token_add(a_ledger, l_decl, l_decl_size), + dap_assert_PIF(!dap_ledger_token_add(a_ledger, (byte_t *)l_decl, l_decl_size), "Can't added datum in ledger"); //Check emission at addr in block list dap_chain_datum_token_emission_t *l_emi_block = dap_chain_datum_emission_create( @@ -1006,9 +1006,9 @@ void dap_ledger_test_run(void){ dap_chain_uint256_from(s_total_supply), NULL, 0, DAP_CHAIN_DATUM_TOKEN_FLAG_NONE); dap_assert_PIF(l_token_decl || l_token_decl_size == 0, "Generate token declaration."); int l_check_added_decl_token = 0; - l_check_added_decl_token = dap_ledger_token_decl_add_check(l_ledger, l_token_decl, l_token_decl_size); + l_check_added_decl_token = dap_ledger_token_add_check(l_ledger, (byte_t *)l_token_decl, l_token_decl_size); dap_assert_PIF(l_check_added_decl_token == 0, "Checking whether it is possible to add a token declaration to ledger."); - dap_assert_PIF(!dap_ledger_token_add(l_ledger, l_token_decl, l_token_decl_size), "Adding token declaration to ledger."); + dap_assert_PIF(!dap_ledger_token_add(l_ledger, (byte_t *)l_token_decl, l_token_decl_size), "Adding token declaration to ledger."); // Create emission dap_chain_addr_t l_addr = {0}; @@ -1031,9 +1031,9 @@ void dap_ledger_test_run(void){ uint256_0, (byte_t*)l_tsd, dap_tsd_size(l_tsd), DAP_CHAIN_DATUM_TOKEN_FLAG_NONE); dap_assert_PIF(l_token_decl || l_token_decl_size == 0, "Generate delegated token declaration."); l_check_added_decl_token = 0; - l_check_added_decl_token = dap_ledger_token_decl_add_check(l_ledger, l_token_decl, l_token_decl_size); + l_check_added_decl_token = dap_ledger_token_add_check(l_ledger, (byte_t *)l_token_decl, l_token_decl_size); dap_assert_PIF(l_check_added_decl_token == 0, "Checking whether it is possible to add a token declaration to ledger."); - dap_assert_PIF(!dap_ledger_token_add(l_ledger, l_token_decl, l_token_decl_size), "Adding token declaration to ledger."); + dap_assert_PIF(!dap_ledger_token_add(l_ledger, (byte_t *)l_token_decl, l_token_decl_size), "Adding token declaration to ledger."); //first base tx dap_chain_datum_tx_t *l_base_tx = dap_ledger_test_create_datum_base_tx(l_emi_sign, &l_emi_hash, l_addr, l_cert); diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c index f70b98db1c44f4d8e48f4e285803295974fdf862..81773569cb7b68d306c0dd4c2241c6b942a40893 100644 --- a/modules/common/dap_chain_datum.c +++ b/modules/common/dap_chain_datum.c @@ -60,165 +60,6 @@ dap_chain_datum_t *dap_chain_datum_create(uint16_t a_type_id, const void *a_data memcpy(l_datum->data, a_data, (uint32_t)a_data_size); return l_datum; } - -void dap_chain_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_token_t *a_token, size_t a_token_size, const char *a_hash_out_type) -{ - dap_tsd_t *l_tsd = dap_chain_datum_token_tsd_get(a_token, a_token_size); - if (l_tsd == NULL) { - dap_string_append_printf(a_str_out,"<CORRUPTED TSD SECTION>\n"); - return; - } - 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_tsd_total_size = a_token->header_private_decl.tsd_total_size; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - 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_tsd_total_size = a_token->header_private_update.tsd_total_size; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - l_tsd_total_size = a_token->header_native_update.tsd_total_size; break; - default: break; - } break; - default: break; - } - 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 dap_chain_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_tsd_total_size - l_offset); - return; - } - switch(l_tsd->type) { - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS: { - dap_string_append_printf(a_str_out,"flags_set: "); - uint16_t l_t = 0; - dap_chain_datum_token_flags_dump(a_str_out, _dap_tsd_get_scalar(l_tsd, &l_t)); - continue; - } - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS: { - dap_string_append_printf(a_str_out,"flags_unset: "); - uint16_t l_t = 0; - dap_chain_datum_token_flags_dump(a_str_out, _dap_tsd_get_scalar(l_tsd, &l_t)); - continue; - } - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY: { // 256 - uint256_t l_t = uint256_0; - dap_string_append_printf( a_str_out, "total_supply: %s\n", - dap_uint256_to_char(_dap_tsd_get_scalar(l_tsd, &l_t), NULL) ); - continue; - } - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_OLD: { // 128 - uint128_t l_t = uint128_0; - dap_string_append_printf( a_str_out, "total_supply: %s\n", - dap_uint256_to_char(GET_256_FROM_128(_dap_tsd_get_scalar(l_tsd, &l_t)), NULL) ); - continue; - } - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: { - uint16_t l_t = 0; - dap_string_append_printf(a_str_out,"total_signs_valid: %u\n", _dap_tsd_get_scalar(l_tsd, &l_t)); - continue; - } - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: - if(l_tsd->size >= sizeof(dap_pkey_t)) { - const char *l_hash_str; - dap_pkey_t *l_pkey = (dap_pkey_t*)l_tsd->data; - dap_hash_fast_t l_hf = { }; - 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_static(&l_hf); - else - l_hash_str = dap_enc_base58_encode_hash_to_str_static(&l_hf); - dap_string_append_printf(a_str_out, "total_pkeys_add: %s\n", l_hash_str); - } - } else - dap_string_append_printf(a_str_out,"total_pkeys_add: <WRONG SIZE %u>\n", l_tsd->size); - continue; - - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: - if(l_tsd->size == sizeof(dap_chain_hash_fast_t) ){ - const 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_static((dap_chain_hash_fast_t*) l_tsd->data) - : dap_enc_base58_encode_hash_to_str_static((dap_chain_hash_fast_t*) l_tsd->data); - dap_string_append_printf(a_str_out,"total_pkeys_remove: %s\n", l_hash_str); - } else - dap_string_append_printf(a_str_out,"total_pkeys_remove: <WRONG SIZE %u>\n", l_tsd->size); - continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK: { - 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); - const char *l_balance, *l_tmp = dap_uint256_to_char(l_tsd_section->emission_rate, &l_balance); - dap_string_append_printf(a_str_out, "ticker_token_from: %s\nemission_rate: %s\n", - l_tsd_section->ticker_token_from, l_balance); - }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) ); - 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) ); - 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) ); - 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) ); - 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) ); - 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) ); - 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) ); - 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) ); - 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) ); - 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) ); - 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) ); - 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) ); - continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION: - dap_string_append_printf(a_str_out, "description: '%s'\n", l_tsd->data); - continue; - default: dap_string_append_printf(a_str_out, "<0x%04hX>: <size %u>\n", l_tsd->type, l_tsd->size); - } - } -} - void dap_datum_token_dump_tsd_to_json(json_object * json_obj_out, dap_chain_datum_token_t *a_token, size_t a_token_size, const char *a_hash_out_type) { dap_tsd_t *l_tsd = dap_chain_datum_token_tsd_get(a_token, a_token_size); @@ -278,13 +119,6 @@ void dap_datum_token_dump_tsd_to_json(json_object * json_obj_out, dap_chain_datu DAP_DELETE(l_balance); continue; } - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_OLD: { // 128 - uint128_t l_t = uint128_0; - char *l_balance = dap_chain_balance_print(GET_256_FROM_128(_dap_tsd_get_scalar(l_tsd, &l_t))); - json_object_object_add(json_obj_out, "total_supply", json_object_new_string(l_balance)); - DAP_DELETE(l_balance); - continue; - } case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: { uint16_t l_t = 0; json_object_object_add(json_obj_out, "total_signs_valid", json_object_new_int(_dap_tsd_get_scalar(l_tsd, &l_t))); @@ -1009,201 +843,7 @@ bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum, * @brief dap_chain_net_dump_datum * process datum verification process. Can be: * if DAP_CHAIN_DATUM_TX, called dap_ledger_tx_add_check - * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_ledger_token_decl_add_check - * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_ledger_token_emission_add_check - * @param a_str_out - * @param a_datum - */ -void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type, dap_chain_net_id_t a_net_id) -{ - if( a_datum == NULL){ - dap_string_append_printf(a_str_out,"==Datum is NULL\n"); - return; - } - dap_hash_fast_t l_datum_hash; - dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_datum_hash); - const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") - ? dap_enc_base58_encode_hash_to_str_static(&l_datum_hash) - : dap_chain_hash_fast_to_str_static(&l_datum_hash); - switch (a_datum->header.type_id) { - case DAP_CHAIN_DATUM_TOKEN_DECL: { - size_t l_token_size = a_datum->header.data_size; - dap_chain_datum_token_t * l_token = dap_chain_datum_token_read(a_datum->data, &l_token_size); - if(l_token_size < sizeof(dap_chain_datum_token_t)){ - dap_string_append_printf(a_str_out,"==Datum has incorrect size. Only %zu, while at least %zu is expected\n", - l_token_size, sizeof(dap_chain_datum_token_t)); - DAP_DEL_Z(l_token); - return; - } - dap_string_append_printf(a_str_out,"=== Datum Token Declaration ===\n"); - dap_string_append_printf(a_str_out, "hash: %s\n", l_hash_str); - dap_string_append_printf(a_str_out, "ticker: %s\n", l_token->ticker); - dap_string_append_printf(a_str_out, "size: %zd\n", l_token_size); - dap_string_append_printf(a_str_out, "version: %d\n", l_token->version); - switch (l_token->type) { - case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: { - dap_string_append(a_str_out,"type: DECL\n"); - switch (l_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE:{ - dap_string_append(a_str_out,"subtype: PRIVATE\n"); - dap_string_append_printf(a_str_out, "decimals: %d\n", l_token->header_private_decl.decimals); - dap_string_append_printf(a_str_out, "auth signs (valid/total) %u/%u\n", l_token->signs_valid, l_token->signs_total); - dap_string_append_printf(a_str_out, "total_supply: %s\n", dap_uint256_to_char(l_token->total_supply, NULL)); - dap_string_append(a_str_out,"flags: "); - dap_chain_datum_token_flags_dump(a_str_out, l_token->header_private_update.flags); - dap_chain_datum_token_dump_tsd(a_str_out, l_token, l_token_size, a_hash_out_type); - size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_private_update.tsd_total_size; - dap_chain_datum_token_certs_dump(a_str_out, l_token->data_n_tsd + l_token->header_private_update.tsd_total_size, - l_certs_field_size, a_hash_out_type); - } break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: { - dap_string_append(a_str_out, "subtype: CF20\n"); - dap_string_append_printf(a_str_out, "decimals: %d\n", l_token->header_native_decl.decimals); - dap_string_append_printf(a_str_out, "auth signs (valid/total) %u/%u\n", l_token->signs_valid, l_token->signs_total); - dap_string_append_printf(a_str_out, "total_supply: %s\n", dap_uint256_to_char(l_token->total_supply, NULL)); - dap_string_append(a_str_out, "flags: "); - dap_chain_datum_token_flags_dump(a_str_out, l_token->header_native_decl.flags); - dap_chain_datum_token_dump_tsd(a_str_out, l_token, l_token_size, a_hash_out_type); - size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_native_decl.tsd_total_size; - dap_chain_datum_token_certs_dump(a_str_out, l_token->data_n_tsd + l_token->header_native_decl.tsd_total_size, - l_certs_field_size, a_hash_out_type); - } break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: { - dap_chain_addr_t l_premine_addr = l_token->header_public.premine_address; - dap_string_append(a_str_out, "subtype: PUBLIC\n"); - dap_string_append_printf(a_str_out, "premine_supply: %s", dap_uint256_to_char(l_token->header_public.premine_supply, NULL)); - dap_string_append_printf(a_str_out, "premine_address: %s", dap_chain_addr_to_str(&l_premine_addr)); - dap_string_append(a_str_out, "flags: "); - dap_chain_datum_token_flags_dump(a_str_out, l_token->header_public.flags); - } break; - } - } break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: { - dap_string_append(a_str_out,"type: UPDATE\n"); - switch (l_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: { - dap_string_append(a_str_out,"subtype: PRIVATE\n"); - dap_string_append_printf(a_str_out, "decimals: %d\n", l_token->header_private_decl.decimals); - dap_string_append_printf(a_str_out, "auth signs (valid/total) %u/%u\n", l_token->signs_valid, l_token->signs_total); - dap_string_append_printf(a_str_out, "total_supply: %s\n", dap_uint256_to_char(l_token->total_supply, NULL)); - dap_string_append(a_str_out,"flags: "); - dap_chain_datum_token_flags_dump(a_str_out, l_token->header_private_update.flags); - dap_chain_datum_token_dump_tsd(a_str_out, l_token, l_token_size, a_hash_out_type); - size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_private_update.tsd_total_size; - dap_chain_datum_token_certs_dump(a_str_out, l_token->data_n_tsd + l_token->header_private_update.tsd_total_size, - l_certs_field_size, a_hash_out_type); - } break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: { - dap_string_append_printf(a_str_out,"subtype: CF20\n"); - dap_string_append_printf(a_str_out, "decimals: %d\n", l_token->header_native_update.decimals); - dap_string_append_printf(a_str_out, "auth signs (valid/total) %u/%u\n", l_token->signs_valid, l_token->signs_total); - dap_string_append_printf(a_str_out, "total_supply: %s\n", dap_uint256_to_char(l_token->total_supply, NULL)); - dap_string_append(a_str_out, "flags: "); - dap_chain_datum_token_flags_dump(a_str_out, l_token->header_native_update.flags); - dap_chain_datum_token_dump_tsd(a_str_out, l_token, l_token_size, a_hash_out_type); - size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_native_update.tsd_total_size; - dap_chain_datum_token_certs_dump(a_str_out, l_token->data_n_tsd + l_token->header_native_update.tsd_total_size, - l_certs_field_size, a_hash_out_type); - } break; - } - } break; - default: - dap_string_append(a_str_out,"type: UNKNOWN\n"); - break; - } - if (l_token->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE ) { - dap_string_append(a_str_out, "subtype: SIMPLE\n"); - dap_string_append_printf(a_str_out, "decimals: %d\n", l_token->header_simple.decimals); - dap_string_append_printf(a_str_out, "sign_total: %hu\n", l_token->signs_total ); - dap_string_append_printf(a_str_out, "sign_valid: %hu\n", l_token->signs_valid ); - dap_string_append_printf(a_str_out, "total_supply: %s\n", dap_uint256_to_char(l_token->total_supply, NULL)); - size_t l_certs_field_size = l_token_size - sizeof(*l_token); - dap_chain_datum_token_certs_dump(a_str_out, l_token->data_n_tsd, - l_certs_field_size, a_hash_out_type); - } - DAP_DELETE(l_token); - } break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION: { - size_t l_emission_size = a_datum->header.data_size; - dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_datum->data, &l_emission_size); - const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_emission->hdr.value, &l_coins_str); - dap_string_append_printf(a_str_out, "emission: hash %s\n\t%s(%s) %s, type: %s, version: %d\n", - l_hash_str, - l_coins_str, - l_value_str, - l_emission->hdr.ticker, - c_dap_chain_datum_token_emission_type_str[l_emission->hdr.type], - l_emission->hdr.version); - dap_string_append_printf(a_str_out, " to addr: %s\n", dap_chain_addr_to_str(&(l_emission->hdr.address))); - switch (l_emission->hdr.type) { - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH: - dap_string_append_printf(a_str_out, " signs_count: %d\n", l_emission->data.type_auth.signs_count); - dap_string_append_printf(a_str_out, " tsd_total_size: %"DAP_UINT64_FORMAT_U"\n", - l_emission->data.type_auth.tsd_total_size); - - if ( ( (void *) l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size) > - ((void *) l_emission + l_emission_size) ) - { - log_it(L_ERROR, "Illformed DATUM type %d, TSD section is out-of-buffer (%" DAP_UINT64_FORMAT_U " vs %zu)", - l_emission->hdr.type, l_emission->data.type_auth.tsd_total_size, l_emission_size); - dap_string_append_printf(a_str_out, " Skip incorrect or illformed DATUM"); - break; - } - dap_chain_datum_token_certs_dump(a_str_out, l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size, - l_emission->data.type_auth.size - l_emission->data.type_auth.tsd_total_size, a_hash_out_type); - break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO: - dap_string_append_printf(a_str_out, " codename: %s\n", l_emission->data.type_algo.codename); - break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT: { - char l_time_str[32]; - // get time of create datum - if(dap_time_to_str_rfc822(l_time_str, sizeof(l_time_str), l_emission->data.type_presale.lock_time) < 1) - l_time_str[0] = '\0'; - dap_string_append_printf(a_str_out, " flags: 0x%x, lock_time: %s\n", l_emission->data.type_presale.flags, l_time_str); - dap_string_append_printf(a_str_out, " addr: %s\n", dap_chain_addr_to_str(&l_emission->data.type_presale.addr)); - } - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER: - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED: - default: - break; - } - DAP_DELETE(l_emission); - } break; - case DAP_CHAIN_DATUM_TX: { - dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)a_datum->data; - dap_chain_datum_dump_tx(l_tx, NULL, a_str_out, a_hash_out_type, &l_datum_hash, a_net_id); - } break; - case DAP_CHAIN_DATUM_DECREE:{ - dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *)a_datum->data; - size_t l_decree_size = dap_chain_datum_decree_get_size(l_decree); - dap_string_append_printf(a_str_out,"=== Datum decree ===\n"); - dap_string_append_printf(a_str_out, "hash: %s\n", l_hash_str); - dap_string_append_printf(a_str_out, "size: %zd\n", l_decree_size); - dap_chain_datum_decree_dump(a_str_out, l_decree, l_decree_size, a_hash_out_type); - } break; - case DAP_CHAIN_DATUM_ANCHOR:{ - dap_chain_datum_anchor_t *l_anchor = (dap_chain_datum_anchor_t *)a_datum->data; - size_t l_anchor_size = sizeof(dap_chain_datum_anchor_t) + l_anchor->header.data_size + l_anchor->header.signs_size; - dap_string_append_printf(a_str_out,"=== Datum anchor ===\n"); - dap_string_append_printf(a_str_out, "hash: %s\n", l_hash_str); - dap_string_append_printf(a_str_out, "size: %zd\n", l_anchor_size); - dap_hash_fast_t l_decree_hash = { }; - dap_chain_datum_anchor_get_hash_from_data(l_anchor, &l_decree_hash); - l_hash_str = dap_chain_hash_fast_to_str_static(&l_decree_hash); - dap_string_append_printf(a_str_out, "decree hash: %s\n", l_hash_str); - dap_chain_datum_anchor_certs_dump(a_str_out, l_anchor->data_n_sign + l_anchor->header.data_size, l_anchor->header.signs_size, a_hash_out_type); - } break; - } -} - - - -/** - * @brief dap_chain_net_dump_datum - * process datum verification process. Can be: - * if DAP_CHAIN_DATUM_TX, called dap_ledger_tx_add_check - * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_ledger_token_decl_add_check + * if DAP_CHAIN_DATUM_TOKEN, called dap_ledger_token_add_check * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_ledger_token_emission_add_check * @param a_obj_out * @param a_datum @@ -1216,12 +856,12 @@ void dap_chain_datum_dump_json(json_object *a_obj_out, dap_chain_datum_t *a_dat } json_object * json_obj_datum = json_object_new_object(); dap_hash_fast_t l_datum_hash; - dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_datum_hash); + dap_chain_datum_calc_hash(a_datum, &l_datum_hash); const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_datum_hash) : dap_chain_hash_fast_to_str_static(&l_datum_hash); switch (a_datum->header.type_id) { - case DAP_CHAIN_DATUM_TOKEN_DECL: { + case DAP_CHAIN_DATUM_TOKEN: { size_t l_token_size = a_datum->header.data_size; dap_chain_datum_token_t * l_token = dap_chain_datum_token_read(a_datum->data, &l_token_size); if(l_token_size < sizeof(dap_chain_datum_token_t)){ @@ -1251,7 +891,7 @@ void dap_chain_datum_dump_json(json_object *a_obj_out, dap_chain_datum_t *a_dat dap_chain_datum_token_flags_dump_to_json(json_obj_datum,l_token->header_private_update.flags); dap_datum_token_dump_tsd_to_json(json_obj_datum,l_token, l_token_size, a_hash_out_type); size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_private_update.tsd_total_size; - dap_chain_datum_token_certs_dump_to_json(json_obj_datum,l_token->data_n_tsd + l_token->header_private_update.tsd_total_size, + dap_chain_datum_token_certs_dump_to_json(json_obj_datum,l_token->tsd_n_signs + l_token->header_private_update.tsd_total_size, l_certs_field_size, a_hash_out_type); } break; case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: { @@ -1265,7 +905,7 @@ void dap_chain_datum_dump_json(json_object *a_obj_out, dap_chain_datum_t *a_dat dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_native_decl.flags); dap_datum_token_dump_tsd_to_json(json_obj_datum, l_token, l_token_size, a_hash_out_type); size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_native_decl.tsd_total_size; - dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd + l_token->header_native_decl.tsd_total_size, + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->tsd_n_signs + l_token->header_native_decl.tsd_total_size, l_certs_field_size, a_hash_out_type); } break; case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: { @@ -1293,7 +933,7 @@ void dap_chain_datum_dump_json(json_object *a_obj_out, dap_chain_datum_t *a_dat dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_private_update.flags); dap_datum_token_dump_tsd_to_json(json_obj_datum, l_token, l_token_size, a_hash_out_type); size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_private_update.tsd_total_size; - dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd + l_token->header_private_update.tsd_total_size, + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->tsd_n_signs + l_token->header_private_update.tsd_total_size, l_certs_field_size, a_hash_out_type); } break; case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: { @@ -1307,7 +947,7 @@ void dap_chain_datum_dump_json(json_object *a_obj_out, dap_chain_datum_t *a_dat dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_native_update.flags); dap_datum_token_dump_tsd_to_json(json_obj_datum, l_token, l_token_size, a_hash_out_type); size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_native_update.tsd_total_size; - dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd + l_token->header_native_update.tsd_total_size, + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->tsd_n_signs + l_token->header_native_update.tsd_total_size, l_certs_field_size, a_hash_out_type); } break; } @@ -1324,7 +964,7 @@ void dap_chain_datum_dump_json(json_object *a_obj_out, dap_chain_datum_t *a_dat json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL))); size_t l_certs_field_size = l_token_size - sizeof(*l_token); - dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd, + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->tsd_n_signs, l_certs_field_size, a_hash_out_type); } DAP_DELETE(l_token); diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index 33e053fda53f3fa834be3a22dfd88296f704ffdd..6d7b79800318759dff58658571c16dada8d70173 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -70,152 +70,109 @@ dap_tsd_t* dap_chain_datum_token_tsd_get(dap_chain_datum_token_t *a_token, size_ log_it(L_WARNING, "Token size %lu < %lu header size, corrupted token datum", a_token_size, sizeof(dap_chain_datum_token_t)); return NULL; } - return (dap_tsd_t*)a_token->data_n_tsd; + return (dap_tsd_t*)a_token->tsd_n_signs; } dap_chain_datum_token_t *dap_chain_datum_token_read(const byte_t *a_token_serial, size_t *a_token_size) { - dap_chain_datum_token_old_t *l_token_old = (dap_chain_datum_token_old_t*)a_token_serial; - size_t l_token_data_n_tsd_size = *a_token_size - sizeof(dap_chain_datum_token_old_t); - size_t l_token_size = l_token_data_n_tsd_size + sizeof(dap_chain_datum_token_t); - switch (((dap_chain_datum_token_t*)a_token_serial)->type) { + dap_return_val_if_fail(a_token_serial && a_token_size, NULL); + if (*a_token_size < sizeof(dap_chain_datum_token_old_t)) { + log_it(L_WARNING, "Too small token size %zu", *a_token_size); + return NULL; + } + dap_chain_datum_token_old_t *l_token_old = (dap_chain_datum_token_old_t *)a_token_serial; + size_t l_token_tsd_n_signs_size = *a_token_size - sizeof(dap_chain_datum_token_old_t); + size_t l_token_size = dap_chain_datum_token_is_old(l_token_old->type) ? l_token_tsd_n_signs_size + sizeof(dap_chain_datum_token_t) + : *a_token_size; + dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); + if (!l_token) { + log_it(L_CRITICAL, c_error_memory_alloc); + return NULL; + } + switch (l_token_old->type) { + case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE: { - dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); - if (!l_token) { - log_it(L_CRITICAL, c_error_memory_alloc); - return NULL; - } *l_token = (dap_chain_datum_token_t) { .type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL, - .version = 1, .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE, - .signs_valid = l_token_old->signs_valid, - .signs_total = l_token_old->signs_total, - .total_supply = l_token_old->total_supply, .header_simple.decimals = l_token_old->header_simple.decimals, - }; - dap_stpcpy(l_token->ticker, l_token_old->ticker); - memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); - *a_token_size = l_token_size; - return l_token; - } + }; + } break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL: { - dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); - if (!l_token) { - log_it(L_CRITICAL, c_error_memory_alloc); - return NULL; - } *l_token = (dap_chain_datum_token_t) { .type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL, - .version = 1, .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE, - .signs_valid = l_token_old->signs_valid, - .signs_total = l_token_old->signs_total, - .total_supply = l_token_old->total_supply, .header_private_decl.flags = l_token_old->header_private_decl.flags, .header_private_decl.tsd_total_size = l_token_old->header_private_decl.tsd_total_size, .header_private_decl.decimals = l_token_old->header_private_decl.decimals }; - dap_stpcpy(l_token->ticker, l_token_old->ticker); - memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); - *a_token_size = l_token_size; - return l_token; - } + } break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE: { - dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); - if (!l_token) { - log_it(L_CRITICAL, c_error_memory_alloc); - return NULL; - } *l_token = (dap_chain_datum_token_t) { .type = DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE, - .version = 1, .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE, - .signs_valid = l_token_old->signs_valid, - .signs_total = l_token_old->signs_total, - .total_supply = l_token_old->total_supply, .header_private_update.flags = l_token_old->header_private_update.flags, .header_private_update.tsd_total_size = l_token_old->header_private_update.tsd_total_size, .header_private_update.decimals = l_token_old->header_private_update.decimals }; - dap_stpcpy(l_token->ticker, l_token_old->ticker); - memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); - *a_token_size = l_token_size; - return l_token; - } + } break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_DECL: { - dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); - if (!l_token) { - log_it(L_CRITICAL, c_error_memory_alloc); - return NULL; - } *l_token = (dap_chain_datum_token_t) { .type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL, - .version = 1, .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE, - .signs_valid = l_token_old->signs_valid, - .signs_total = l_token_old->signs_total, - .total_supply = l_token_old->total_supply, .header_native_decl.flags = l_token_old->header_native_decl.flags, .header_native_decl.tsd_total_size = l_token_old->header_native_decl.tsd_total_size, .header_native_decl.decimals = l_token_old->header_native_decl.decimals }; - dap_stpcpy(l_token->ticker, l_token_old->ticker); - memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); - *a_token_size = l_token_size; - return l_token; - } + } break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE: { - dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); - if (!l_token) { - log_it(L_CRITICAL, c_error_memory_alloc); - return NULL; - } *l_token = (dap_chain_datum_token_t) { .type = DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE, - .version = 1, .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE, - .signs_valid = l_token_old->signs_valid, - .signs_total = l_token_old->signs_total, - .total_supply = l_token_old->total_supply, .header_native_update.flags = l_token_old->header_native_update.flags, .header_native_update.tsd_total_size = l_token_old->header_native_update.tsd_total_size, .header_native_update.decimals = l_token_old->header_native_update.decimals }; - dap_stpcpy(l_token->ticker, l_token_old->ticker); - memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); - *a_token_size = l_token_size; - return l_token; - } + } break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PUBLIC: { - dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); - if (!l_token) { - log_it(L_CRITICAL, c_error_memory_alloc); - return NULL; - } *l_token = (dap_chain_datum_token_t) { .type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL, - .version = 1, .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC, - .signs_valid = l_token_old->signs_valid, - .signs_total = l_token_old->signs_total, - .total_supply = l_token_old->total_supply, .header_public.flags = l_token_old->header_public.flags, .header_public.premine_supply = l_token_old->header_public.premine_supply, .header_public.premine_address = l_token_old->header_public.premine_address }; - dap_stpcpy(l_token->ticker, l_token_old->ticker); - memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); - *a_token_size = l_token_size; - return l_token; - } + } break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: - return DAP_DUP_SIZE(a_token_serial, *a_token_size); + if (*a_token_size < sizeof(dap_chain_datum_token_t)) { + log_it(L_WARNING, "Too small token size %zu", *a_token_size); + DAP_DELETE(l_token); + return NULL; + } + return memcpy(l_token, a_token_serial, l_token_size); + default: log_it(L_NOTICE, "Unknown token type '%d' read", ((dap_chain_datum_token_t*)a_token_serial)->type); + DAP_DELETE(l_token); return NULL; } + + l_token->version = 2; + l_token->signs_valid = l_token_old->signs_valid; + l_token->signs_total = l_token_old->signs_total; + l_token->total_supply = l_token_old->total_supply; + dap_strncpy(l_token->ticker, l_token_old->ticker, DAP_CHAIN_TICKER_SIZE_MAX); + if (l_token_tsd_n_signs_size) + memcpy(l_token->tsd_n_signs, l_token_old->tsd_n_signs, l_token_tsd_n_signs_size); + *a_token_size = l_token_size; + return l_token; } /** @@ -273,10 +230,10 @@ void dap_chain_datum_token_flags_dump_to_json(json_object * json_obj_out, uint16 /** * @brief dap_chain_datum_token_certs_dump * @param a_str_out - * @param a_data_n_tsd + * @param a_tsd_n_signs * @param a_certs_size */ -void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_data_n_tsd, size_t a_certs_size, const char *a_hash_out_type) +void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_tsd_n_signs, size_t a_certs_size, const char *a_hash_out_type) { dap_string_append_printf(a_str_out, "signatures: "); if (!a_certs_size) { @@ -288,7 +245,7 @@ void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_data_ size_t l_offset = 0; for (int i = 1; l_offset < (a_certs_size); i++) { - dap_sign_t *l_sign = (dap_sign_t *) (a_data_n_tsd + l_offset); + dap_sign_t *l_sign = (dap_sign_t *) (a_tsd_n_signs + l_offset); l_offset += dap_sign_get_size(l_sign); if (l_sign->header.sign_size == 0) { dap_string_append_printf(a_str_out, "<CORRUPTED - 0 size signature>\n"); @@ -319,10 +276,10 @@ void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_data_ /** * @brief dap_chain_datum_token_certs_dump_to_json * @param a_json_obj_out - * @param a_data_n_tsd + * @param a_tsd_n_signs * @param a_certs_size */ -void dap_chain_datum_token_certs_dump_to_json(json_object *a_json_obj_out, byte_t * a_data_n_tsd, size_t a_certs_size, const char *a_hash_out_type) +void dap_chain_datum_token_certs_dump_to_json(json_object *a_json_obj_out, byte_t * a_tsd_n_signs, size_t a_certs_size, const char *a_hash_out_type) { json_object_object_add(a_json_obj_out, "Signatures", json_object_new_string("")); if (!a_certs_size) { @@ -334,7 +291,7 @@ void dap_chain_datum_token_certs_dump_to_json(json_object *a_json_obj_out, byte_ json_object * json_arr_seg = json_object_new_array(); for (int i = 1; l_offset < (a_certs_size); i++) { json_object * l_json_obj_out = json_object_new_object(); - dap_sign_t *l_sign = (dap_sign_t *) (a_data_n_tsd + l_offset); + dap_sign_t *l_sign = (dap_sign_t *) (a_tsd_n_signs + l_offset); l_offset += dap_sign_get_size(l_sign); if (l_sign->header.sign_size == 0) { json_object_object_add(l_json_obj_out, "status", json_object_new_string("<CORRUPTED - 0 size signature>")); @@ -367,88 +324,6 @@ void dap_chain_datum_token_certs_dump_to_json(json_object *a_json_obj_out, byte_ json_object_object_add(a_json_obj_out, "status", json_arr_seg); } - -dap_sign_t ** dap_chain_datum_token_signs_parse(dap_chain_datum_token_t * a_datum_token, size_t a_datum_token_size, size_t *a_signs_total, size_t * a_signs_valid) -{ - assert(a_datum_token_size); - assert(a_datum_token); - assert(a_signs_total); - assert(a_signs_valid); - assert(a_datum_token_size >= sizeof(dap_chain_datum_token_old_t)); - if (!a_datum_token->signs_total) { - log_it(L_ERROR, "No signs in datum token with ticker '%s', type %d", a_datum_token->ticker, a_datum_token->type); - return NULL; - } - *a_signs_total = 0; - *a_signs_valid = a_datum_token->signs_valid; - size_t l_offset = 0; - size_t l_signs_offset = 0; - switch (a_datum_token->type) { - case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: - switch (a_datum_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: - l_signs_offset = sizeof(dap_chain_datum_token_t); - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: - l_signs_offset = sizeof(dap_chain_datum_token_t) + a_datum_token->header_private_decl.tsd_total_size; - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - l_signs_offset = sizeof(dap_chain_datum_token_t) + a_datum_token->header_native_decl.tsd_total_size; - break; - } - break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: - switch (a_datum_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: - l_signs_offset = sizeof(dap_chain_datum_token_t); - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: - l_signs_offset = sizeof(dap_chain_datum_token_t) + a_datum_token->header_private_update.tsd_total_size; - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - l_signs_offset = sizeof(dap_chain_datum_token_t) + a_datum_token->header_native_update.tsd_total_size; - break; - } - break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE: - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PUBLIC: - l_signs_offset = sizeof(dap_chain_datum_token_old_t); - break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL: - l_signs_offset = sizeof(dap_chain_datum_token_old_t) + a_datum_token->header_private_decl.tsd_total_size; - break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE: - l_signs_offset = sizeof(dap_chain_datum_token_old_t) + a_datum_token->header_private_update.tsd_total_size; - break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_DECL: - l_signs_offset = sizeof(dap_chain_datum_token_old_t) + a_datum_token->header_native_decl.tsd_total_size; - break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE: - l_signs_offset = sizeof(dap_chain_datum_token_old_t) + a_datum_token->header_native_update.tsd_total_size; - break; - default: - l_signs_offset = sizeof(dap_chain_datum_token_t); - break; - } - dap_sign_t **l_ret = DAP_NEW_Z_SIZE(dap_sign_t*, sizeof(dap_sign_t*) * a_datum_token->signs_total); - if (!l_ret) { - log_it(L_CRITICAL, "Out of memory!"); - return NULL; - } - for (uint16_t i = 0; i < a_datum_token->signs_total && l_offset <= a_datum_token_size - l_signs_offset; ++i) { - l_ret[i] = (dap_sign_t*)((byte_t*)a_datum_token + l_signs_offset + l_offset); - size_t l_sign_size = dap_sign_get_size(l_ret[i]); - if (l_sign_size == 0 || l_sign_size > a_datum_token_size - l_offset) { - *a_signs_total = 0; - DAP_DELETE(l_ret); - return NULL; - } - (*a_signs_total)++; - l_offset += l_sign_size; - } - return l_ret; -} - /* Token emission section */ dap_chain_datum_token_emission_t *dap_chain_datum_emission_create(uint256_t a_value, const char *a_ticker, dap_chain_addr_t *a_addr) diff --git a/modules/common/include/dap_chain_datum.h b/modules/common/include/dap_chain_datum.h index cf461b6e3ada48df17313c01128347cacd56ad76..74f39e9ca3bff1a76be6016a9e46479d56f4e246 100644 --- a/modules/common/include/dap_chain_datum.h +++ b/modules/common/include/dap_chain_datum.h @@ -46,9 +46,9 @@ #define DAP_CHAIN_DATUM_TX_REQUEST 0x0300 /// Smart contract: DVM code section -#define DAP_CHAIN_DATUM_WASM_CODE 0x0900 +#define DAP_CHAIN_DATUM_WASM_CODE 0x0900 /// Smart contract: DVM code section -#define DAP_CHAIN_DATUM_WASM_DATA 0x0901 +#define DAP_CHAIN_DATUM_WASM_DATA 0x0901 /// Smart contract: EVM code section #define DAP_CHAIN_DATUM_EVM_CODE 0x0910 @@ -62,13 +62,13 @@ /// Token /// Simple token decl -#define DAP_CHAIN_DATUM_TOKEN_DECL 0xf000 -#define DAP_CHAIN_DATUM_TOKEN_EMISSION 0xf100 -#define DAP_CHAIN_DATUM_TOKEN_DISMISSAL 0xf200 +#define DAP_CHAIN_DATUM_TOKEN 0xf000 +#define DAP_CHAIN_DATUM_TOKEN_EMISSION 0xf100 +#define DAP_CHAIN_DATUM_TOKEN_DISMISSAL 0xf200 -#define DAP_CHAIN_DATUM_ANCHOR 0x0a00 +#define DAP_CHAIN_DATUM_ANCHOR 0x0a00 -#define DAP_CHAIN_DATUM_CUSTOM 0xffff +#define DAP_CHAIN_DATUM_CUSTOM 0xffff #define DAP_DATUM_TYPE_STR(t, s) \ switch (t) { \ @@ -90,8 +90,8 @@ s = "DATUM_SIGNER"; break; \ case DAP_CHAIN_DATUM_CUSTOM: \ s = "DATUM_CUSTOM"; break; \ - case DAP_CHAIN_DATUM_TOKEN_DECL: \ - s = "DATUM_TOKEN_DECL"; break; \ + case DAP_CHAIN_DATUM_TOKEN: \ + s = "DATUM_TOKEN"; break; \ case DAP_CHAIN_DATUM_TOKEN_EMISSION:\ s = "DATUM_TOKEN_EMISSION"; break;\ case DAP_CHAIN_DATUM_DECREE: \ @@ -138,7 +138,14 @@ DAP_STATIC_INLINE size_t dap_chain_datum_size(const dap_chain_datum_t *a_datum) { if (!a_datum) return 0; - return sizeof(a_datum->header) + a_datum->header.data_size; + return sizeof(a_datum->header) + a_datum->header.data_size; +} + +DAP_STATIC_INLINE void dap_chain_datum_calc_hash(const dap_chain_datum_t *a_datum, dap_hash_fast_t *a_out_hash) +{ + if (!a_datum || !a_out_hash) + return; + dap_hash_fast(a_datum->data, a_datum->header.data_size, a_out_hash); } dap_chain_datum_t * dap_chain_datum_create(uint16_t a_type_id, const void * a_data, size_t a_data_size); @@ -151,7 +158,6 @@ DAP_STATIC_INLINE const char *dap_chain_datum_type_id_to_str(uint16_t a_type_id) return l_ret; } -void dap_chain_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_token_t *a_token, size_t a_token_size, const char *a_hash_out_type); void dap_datum_token_dump_tsd_to_json(json_object * json_obj_out, dap_chain_datum_token_t *a_token, size_t a_token_size, const char *a_hash_out_type); void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type, dap_chain_net_id_t a_net_id); bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h index f8f40ea74fbd7f417d455d0f3b3f7729d280890a..1d6722f12c9e351a1f1f06788ae4d0dd81959c4a 100644 --- a/modules/common/include/dap_chain_datum_decree.h +++ b/modules/common/include/dap_chain_datum_decree.h @@ -291,7 +291,7 @@ void dap_chain_datum_decree_dump_json(json_object *a_obj_out, dap_chain_datum_d /** * @brief dap_chain_datum_decree_certs_dump compose decree signatures output string * @param a_str_out pointer to output text buffer - * @param a_data_n_tsd pointer to signs decree section + * @param a_tsd_n_signs pointer to signs decree section * @param a_certs_size size of decree signatures */ void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type); diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index e993e219a04ba91d4d17bc605cb60def9943938c..0ca591b61e41fca0575a5ce2451d86c6ae9fa7da 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -34,7 +34,7 @@ // Token declaration -typedef struct dap_chain_datum_token_old{ +typedef struct dap_chain_datum_token_old { uint16_t type; char ticker[DAP_CHAIN_TICKER_SIZE_MAX]; uint16_t signs_valid; // Emission auth signs @@ -77,11 +77,11 @@ typedef struct dap_chain_datum_token_old{ byte_t header[256]; // For future changes }; uint16_t signs_total; // Emission auth signs - byte_t data_n_tsd[]; // Signs and/or types-size-data sections + byte_t tsd_n_signs[]; // Signs and/or types-size-data sections } DAP_ALIGN_PACKED dap_chain_datum_token_old_t; // Token declaration -typedef struct dap_chain_datum_token{ +typedef struct dap_chain_datum_token { uint16_t type; uint16_t version; uint16_t subtype; @@ -126,56 +126,44 @@ typedef struct dap_chain_datum_token{ } DAP_ALIGN_PACKED header_public; byte_t header[256]; // For future changes }; - byte_t data_n_tsd[]; // Signs and/or types-size-data sections + byte_t tsd_n_signs[]; // Signs and/or types-size-data sections } DAP_ALIGN_PACKED dap_chain_datum_token_t; typedef struct dap_chain_datum_token_tsd_delegate_from_stake_lock { - byte_t ticker_token_from[DAP_CHAIN_TICKER_SIZE_MAX]; - // dap_hash_fast_t hash_token_from;//TODO: ??? - uint256_t emission_rate; // In "coins", 1^18 == 1.0 - uint32_t flags; // Some emission flags for future - byte_t padding[256]; // Some free space for future + byte_t ticker_token_from[DAP_CHAIN_TICKER_SIZE_MAX]; + uint256_t emission_rate; // In "coins", 1^18 == 1.0 + byte_t padding[4]; // Some free space for future } DAP_ALIGN_PACKED dap_chain_datum_token_tsd_delegate_from_stake_lock_t; -// Token declaration type -// Simple private token decl -//#define DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE 0x0001 -// Extended declaration of privatetoken with in-time control -//#define DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL 0x0002 -// Token update -//#define DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE 0x0003 -// Open token with now ownership -//#define DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PUBLIC 0x0004 - -// 256 +// Old token declaration & update types // Simple private token decl #define DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE 0x0005 // Extended declaration of privatetoken with in-time control #define DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL 0x0006 // Token update #define DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE 0x0007 -// Open token with now ownership +// Open token with no ownership #define DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PUBLIC 0x0008 // Native token type #define DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_DECL 0x0009 // Token update #define DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE 0x000A -// Open token with now ownership + // New datum types with versioning and subtypes. // Declaration token -#define DAP_CHAIN_DATUM_TOKEN_TYPE_DECL 0x0010 +#define DAP_CHAIN_DATUM_TOKEN_TYPE_DECL 0x0010 // Updated token -#define DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE 0x0011 +#define DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE 0x0011 // Subtypes // Simple private token decl -#define DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE 0x0001 +#define DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE 0x0001 // Extended declaration of privatetoken with in-time control -#define DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE 0x0002 +#define DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE 0x0002 // Native token -#define DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE 0x0003 -// Open token with now ownership -#define DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC 0x0004 +#define DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE 0x0003 +// Open token with no ownership +#define DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC 0x0004 // Macros for token flags @@ -251,9 +239,8 @@ extern const char *c_dap_chain_datum_token_flag_str[]; #define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS 0x0001 #define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS 0x0002 -// Total supply limits -#define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_OLD 0x0003 // 128 -#define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY 0x0026 // 256 +// Total supply limit +#define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY 0x0026 // Set total signs count value to set to be valid #define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID 0x0004 @@ -413,8 +400,7 @@ DAP_STATIC_INLINE int dap_chain_datum_token_get_delegated_ticker(char *a_buf, co if (!a_buf || !a_ticker) return -1; *a_buf = 'm'; - strncpy(a_buf + 1, a_ticker, DAP_CHAIN_TICKER_SIZE_MAX - 2); - a_buf[DAP_CHAIN_TICKER_SIZE_MAX - 1] = '\0'; + dap_strncpy(a_buf + 1, a_ticker, DAP_CHAIN_TICKER_SIZE_MAX - 1); return 0; } @@ -522,9 +508,8 @@ extern const char *c_dap_chain_datum_token_emission_type_str[]; dap_tsd_t* dap_chain_datum_token_tsd_get(dap_chain_datum_token_t * a_token, size_t a_token_size); void dap_chain_datum_token_flags_dump(dap_string_t * a_str_out, uint16_t a_flags); void dap_chain_datum_token_flags_dump_to_json(json_object * json_obj_out, uint16_t a_flags); -void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_data_n_tsd, size_t a_certs_size, const char *a_hash_out_type); -void dap_chain_datum_token_certs_dump_to_json(json_object *a_json_obj_out, byte_t * a_data_n_tsd, size_t a_certs_size, const char *a_hash_out_type); -dap_sign_t ** dap_chain_datum_token_signs_parse(dap_chain_datum_token_t * a_datum_token, size_t a_datum_token_size, size_t *a_signs_count, size_t * a_signs_valid); +void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_tsd_n_signs, size_t a_certs_size, const char *a_hash_out_type); +void dap_chain_datum_token_certs_dump_to_json(json_object *a_json_obj_out, byte_t * a_tsd_n_signs, size_t a_certs_size, const char *a_hash_out_type); dap_chain_datum_token_t *dap_chain_datum_token_read(const byte_t *a_token_serial, size_t *a_token_size); dap_chain_datum_token_emission_t *dap_chain_datum_emission_create(uint256_t a_value, const char *a_ticker, dap_chain_addr_t *a_addr); diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h index ae3eef5e42e62f99abf0f84015e6f2a46760d0de..e8a6ec192e5cdd3764526e9b2340aa223d5563d9 100644 --- a/modules/common/include/dap_chain_datum_tx.h +++ b/modules/common/include/dap_chain_datum_tx.h @@ -155,3 +155,18 @@ int dap_chain_datum_tx_verify_sign(dap_chain_datum_tx_t *a_tx); int dap_chain_datum_tx_get_fee_value (dap_chain_datum_tx_t *a_tx, uint256_t *a_value); + +/** + * @brief dap_chain_node_datum_tx_calc_hash + * @param a_tx + * @return + */ +DAP_STATIC_INLINE dap_chain_hash_fast_t* dap_chain_node_datum_tx_calc_hash(dap_chain_datum_tx_t *a_tx) +{ + dap_chain_hash_fast_t *tx_hash = DAP_NEW_Z(dap_chain_hash_fast_t); + if (!tx_hash) { + return NULL; + } + dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), tx_hash); + return tx_hash; +} diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index 037b369271ab6f7f7754c53d0f0ecc3aeee6bbfe..6f12359e7035d108ee94a4fae35dffb1c0b2e3e3 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -379,7 +379,7 @@ void dap_chain_esbocs_add_block_collect(dap_chain_block_cache_t *a_block_cache, dap_chain_t *l_chain = a_block_collect_params->chain; if (a_type == DAP_CHAIN_BLOCK_COLLECT_BOTH || a_type == DAP_CHAIN_BLOCK_COLLECT_FEES) { dap_sign_t *l_sign = dap_chain_block_sign_get(a_block_cache->block, a_block_cache->block_size, 0); - if (dap_pkey_match_sign(a_block_collect_params->block_sign_pkey, l_sign)) { + if (dap_pkey_compare_with_sign(a_block_collect_params->block_sign_pkey, l_sign)) { dap_chain_net_t *l_net = dap_chain_net_by_id(l_chain->net_id); assert(l_net); uint256_t l_value_fee = uint256_0; @@ -559,7 +559,7 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf if (l_order->srv_uid.uint64 != DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID) continue; dap_sign_t *l_order_sign = (dap_sign_t*)(l_order->ext_n_sign + l_order->ext_size); - if (!dap_pkey_match_sign(l_esbocs_pvt->block_sign_pkey, l_order_sign)) + if (!dap_pkey_compare_with_sign(l_esbocs_pvt->block_sign_pkey, l_order_sign)) continue; if (!l_order_service) l_order_service = l_order; @@ -2768,8 +2768,12 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl log_it(L_WARNING, "Incorrect header size with block %p on chain %s", a_block, a_blocks->chain->name); return -7; } - - if (a_block->hdr.meta_n_datum_n_signs_size && + size_t l_offset = dap_chain_block_get_sign_offset(a_block, a_block_size); + if (!l_offset) { + log_it(L_WARNING, "Block with size %zu parsing error", a_block_size); + return -5; + } + if ((a_block->hdr.meta_n_datum_n_signs_size > l_offset || a_block->hdr.version == 2) && a_block->hdr.meta_n_datum_n_signs_size != a_block_size - sizeof(a_block->hdr)) { log_it(L_WARNING, "Incorrect size with block %p on chain %s", a_block, a_blocks->chain->name); return -8; @@ -2779,11 +2783,7 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl // It's a block candidate, don't check signs return 0; - size_t l_offset = dap_chain_block_get_sign_offset(a_block, a_block_size); - if (!l_offset) { - log_it(L_WARNING, "Block with size %zu parsing error", a_block_size); - return -5; - } + size_t l_signs_count = 0; dap_sign_t **l_signs = dap_sign_get_unique_signs(a_block->meta_n_datum_n_sign+l_offset, a_block_size-sizeof(a_block->hdr)-l_offset, &l_signs_count); diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index d1d6aaa9fce6b698ab3f6964311f6f51632a4845..d559a8eceb40df4dd6dd41fec09c8d2e581b2192 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -91,7 +91,7 @@ char *dap_chain_mempool_datum_add(const dap_chain_datum_t *a_datum, dap_chain_t dap_return_val_if_pass(!a_datum, NULL); dap_chain_hash_fast_t l_key_hash; - dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_key_hash); + dap_chain_datum_calc_hash(a_datum, &l_key_hash); char *l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash); const char *l_key_str_out = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_key_hash) @@ -99,7 +99,7 @@ char *dap_chain_mempool_datum_add(const dap_chain_datum_t *a_datum, dap_chain_t const char *l_type_str; switch (a_datum->header.type_id) { - case DAP_CHAIN_DATUM_TOKEN_DECL: + case DAP_CHAIN_DATUM_TOKEN: l_type_str = "token"; break; case DAP_CHAIN_DATUM_TOKEN_EMISSION: { @@ -1205,13 +1205,13 @@ dap_chain_datum_token_emission_t *dap_chain_mempool_datum_emission_extract(dap_c dap_chain_datum_token_t *l_token = dap_ledger_token_ticker_check(l_net->pub.ledger, l_ticker); if (!l_token) return NULL; - if (l_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE && l_token->type == DAP_CHAIN_DATUM_TOKEN_DECL) + if (l_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE && l_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_DECL) return NULL; /*int l_signs_valid = 0; dap_sign_t *l_ems_sign = (dap_sign_t *)(l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size); for (int i = 0; i < l_emission->data.type_auth.signs_count; i++) { uint32_t l_ems_pkey_size = l_ems_sign->header.sign_pkey_size; - dap_sign_t *l_token_sign = (dap_sign_t *)(l_token->data_n_tsd + l_token->header_native_decl.tsd_total_size); + dap_sign_t *l_token_sign = (dap_sign_t *)(l_token->tsd_n_signs + l_token->header_native_decl.tsd_total_size); for (int j = 0; j < l_token->signs_total; j++) { if (l_ems_pkey_size == l_ems_sign->header.sign_pkey_size && !memcmp(l_token_sign->pkey_n_sign, l_ems_sign->pkey_n_sign, l_ems_pkey_size)) { diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index 4099260c113ba0d5e282eb8412f50a9dea5eeb08..79b536b49915023c07a3596d7087c3a561b284c2 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -68,10 +68,11 @@ typedef struct dap_ledger_verificator { UT_hash_handle hh; } dap_ledger_verificator_t; -typedef struct dap_chain_ledger_votings_callbacks{ +typedef struct dap_chain_ledger_votings_callbacks { dap_chain_ledger_voting_callback_t voting_callback; dap_chain_ledger_voting_delete_callback_t voting_delete_callback; } dap_chain_ledger_votings_callbacks_t; + typedef struct dap_ledger_service_info { dap_chain_net_srv_uid_t service_uid; // hash key char tag_str[32]; // tag string name @@ -89,69 +90,6 @@ static dap_chain_ledger_votings_callbacks_t s_voting_callbacks; #define MAX_OUT_ITEMS 10 -static const char * const s_ledger_tx_check_err_str[] = { - [DAP_LEDGER_TX_CHECK_OK] = "DAP_LEDGER_TX_CHECK_OK", - [DAP_LEDGER_TX_CHECK_NULL_TX] = "DAP_LEDGER_TX_CHECK_NULL_TX", - [DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE] = "DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE", - [DAP_LEDGER_TX_ALREADY_CACHED] = "DAP_LEDGER_TX_ALREADY_CACHED", - [DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN] = "DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN", - [DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED", - [DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED", - [DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND", - [DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS] = "DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS", - [DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND", - [DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN", - [DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS", - [DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE] = "DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE", - [DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS] = "DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS", - [DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX] = "DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX", - [DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY] = "DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY", - [DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE", - [DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND", - [DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED", - [DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED", - [DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND", - [DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND", - [DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH] = "DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH", - [DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX] = "DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX", - [DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET] = "DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET", - [DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE] = "DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE", - [DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND", - [DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND", - [DAP_LEDGER_PERMISSION_CHECK_FAILED] = "DAP_LEDGER_PERMISSION_CHECK_FAILED", - [DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS] = "DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS", - [DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED", - [DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL] = "DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL" -}; - -static const char * const s_ledger_emission_add_err_str[] = { - [DAP_LEDGER_EMISSION_ADD_OK] = "DAP_LEDGER_EMISSION_ADD_OK", - [DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL] = "DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL", - [DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED] = "DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED", - [DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW] = "DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW", - [DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY] = "DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY", - [DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS] = "DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS", - [DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN] = "DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN", - [DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE] = "DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE", - [DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED] = "DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED" -}; - -static const char * const s_ledger_token_decl_err_str[] = { - [DAP_LEDGER_TOKEN_DECL_ADD_OK] = "DAP_LEDGER_TOKEN_DECL_ADD_OK", - [DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL", - [DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE", - [DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK", - [DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN", - [DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN", - [DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS" -}; - -char *dap_ledger_tx_check_err_str(int a_code) { - return (a_code >= DAP_LEDGER_TX_CHECK_OK) && (a_code < DAP_LEDGER_TX_CHECK_UNKNOWN) - ? (char*)s_ledger_tx_check_err_str[(dap_ledger_tx_check_t)a_code] - : dap_itoa(a_code); -} - typedef struct dap_ledger_stake_lock_item { dap_chain_hash_fast_t tx_for_stake_lock_hash; dap_chain_hash_fast_t tx_used_out; @@ -176,11 +114,9 @@ typedef struct dap_ledger_token_update_item { } dap_ledger_token_update_item_t; typedef struct dap_ledger_token_item { - uint16_t version; char ticker[DAP_CHAIN_TICKER_SIZE_MAX]; - uint16_t type; uint16_t subtype; - dap_chain_datum_token_t * datum_token; + dap_chain_datum_token_t *datum_token; uint64_t datum_token_size; uint256_t total_supply; @@ -195,10 +131,10 @@ typedef struct dap_ledger_token_item { // for auth operations dap_pkey_t ** auth_pkeys; - dap_chain_hash_fast_t *auth_pkeys_hash; + dap_chain_hash_fast_t *auth_pkey_hashes; size_t auth_signs_total; size_t auth_signs_valid; - uint16_t flags; + uint32_t flags; dap_chain_addr_t * tx_recv_allow; size_t tx_recv_allow_size; dap_chain_addr_t * tx_recv_block; @@ -207,8 +143,12 @@ typedef struct dap_ledger_token_item { size_t tx_send_allow_size; dap_chain_addr_t * tx_send_block; size_t tx_send_block_size; - char *description_token; - size_t description_token_size; + char *description; + // For delegated tokens + bool is_delegated; + char delegated_from[DAP_CHAIN_TICKER_SIZE_MAX]; + uint256_t emission_rate; + UT_hash_handle hh; } dap_ledger_token_item_t; @@ -354,9 +294,6 @@ static void s_threshold_emissions_proc( dap_ledger_t * a_ledger); 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_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_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_ledger_token_item_t * a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size ); static int s_sort_ledger_tx_item(dap_ledger_tx_item_t* a, dap_ledger_tx_item_t* b); static size_t s_threshold_emissions_max = 1000; @@ -552,7 +489,7 @@ void dap_ledger_deinit() * Create empty dap_ledger_t structure * @return dap_ledger_t* */ -static dap_ledger_t * dap_ledger_handle_new(void) +static dap_ledger_t *dap_ledger_handle_new(void) { dap_ledger_t *l_ledger = DAP_NEW_Z(dap_ledger_t); if ( !l_ledger ) { @@ -578,7 +515,6 @@ static dap_ledger_t * dap_ledger_handle_new(void) (dap_timer_callback_t)s_threshold_txs_free, l_ledger); l_ledger_pvt->threshold_emissions_free_timer = dap_interval_timer_create(s_threshold_free_timer_tick, (dap_timer_callback_t) s_threshold_emission_free, l_ledger); - l_ledger_pvt->mapped = dap_config_get_item_bool_default(g_config, "ledger", "mapped", true); return l_ledger; } @@ -632,247 +568,781 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_ return l_json; } +inline static dap_ledger_token_item_t *s_ledger_find_token(dap_ledger_t *a_ledger, const char *a_token_ticker) +{ + dap_return_val_if_fail(a_ledger && a_token_ticker, NULL); + dap_ledger_token_item_t *l_token_item; + pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); + HASH_FIND_STR(PVT(a_ledger)->tokens, a_token_ticker, l_token_item); + pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + return l_token_item; +} + /** - * @brief s_ledger_token_update_check - * @param a_cur_token_item - * @param a_token_update - * @param a_token_update_size - * @return true or false + * @brief s_token_tsd_parse + * + * @param a_ledger + * @param a_item_apply_to + * @param a_token + * @param a_token_size + * @return int */ -static bool s_ledger_token_update_check(dap_ledger_token_item_t *a_cur_token_item, dap_chain_datum_token_t *a_token_update, size_t a_token_update_size) +static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain_datum_token_t *a_current_datum, + dap_ledger_t *a_ledger, byte_t *a_tsd, size_t a_tsd_total_size, bool a_apply) { - dap_sign_t **l_signs_upd_token; - size_t auth_signs_total = 0; - size_t auth_signs_valid = 0; - dap_ledger_token_update_item_t *l_token_update_item; - dap_hash_fast_t l_hash_token_update; - - dap_hash_fast(a_token_update, a_token_update_size, &l_hash_token_update); - pthread_rwlock_rdlock(&a_cur_token_item->token_ts_updated_rwlock); - HASH_FIND(hh, a_cur_token_item->token_ts_updated, &l_hash_token_update, sizeof(dap_hash_fast_t), - l_token_update_item); - pthread_rwlock_unlock(&a_cur_token_item->token_ts_updated_rwlock); - if (l_token_update_item - && a_cur_token_item->last_update_token_time == l_token_update_item->updated_time) { - if (s_debug_more) - log_it(L_WARNING,"This update for token '%s' was already applied", a_token_update->ticker); - return false; - } - - /*if (a_cur_token_item->auth_signs_total != a_token_update->signs_total - || a_cur_token_item->auth_signs_valid != a_token_update->signs_valid) { - if(s_debug_more) - log_it(L_WARNING,"Can't update token with ticker '%s' because: " - "l_token_item auth signs total/valid == %lu/%lu | " - "token_update auth signs total/valid == %hu/%hu", - a_token_update->ticker, - a_cur_token_item->auth_signs_total, a_cur_token_item->auth_signs_valid, - a_token_update->signs_total, a_token_update->signs_valid); - return false; - }*/ - - 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_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: " - "l_token_item auth signs total/valid == %lu/%lu | " - "token_update auth signs total/valid == %lu/%lu", - a_token_update->ticker, - a_cur_token_item->auth_signs_total, a_cur_token_item->auth_signs_valid, - auth_signs_total, auth_signs_valid); - return false; - } - if(auth_signs_total) { - size_t l_valid_pkeys = 0; - for(uint16_t i = 0; i < auth_signs_total; i++){ - dap_pkey_t *l_pkey_upd_token = dap_pkey_get_from_sign(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); - if (!IS_ZERO_256(a_token_update->total_supply)){ - if (compare256(a_token_update->total_supply, a_cur_token_item->total_supply) < 0) {//compare old 'total_supply' to updated - if(s_debug_more) - log_it(L_WARNING, "Can't update token with ticker '%s' because: the new 'total_supply' cannot be smaller than the old one", a_token_update->ticker); - return false; - } - } - // 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, *l_tsd_list_added_pkeys = NULL; - int l_quantity_tsd_remote_pkeys = 0, 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; + if (!a_tsd_total_size) { + debug_if(a_item_apply_to, L_NOTICE, "No TSD sections in datum token"); + return DAP_LEDGER_CHECK_OK; + } + dap_return_val_if_pass(a_apply && !a_item_apply_to, DAP_LEDGER_CHECK_INVALID_ARGS); + size_t l_new_signs_valid = a_item_apply_to ? a_item_apply_to->auth_signs_valid : 0; + size_t l_new_signs_total = a_item_apply_to ? a_item_apply_to->auth_signs_total : 0; + dap_pkey_t **l_new_pkeys = NULL; + dap_hash_fast_t *l_new_pkey_hashes = NULL; + bool l_was_pkeys_copied = false; + size_t l_new_tx_recv_allow_size = a_item_apply_to ? a_item_apply_to->tx_recv_allow_size : 0; + size_t l_new_tx_recv_block_size = a_item_apply_to ? a_item_apply_to->tx_recv_block_size : 0; + size_t l_new_tx_send_allow_size = a_item_apply_to ? a_item_apply_to->tx_send_allow_size : 0; + size_t l_new_tx_send_block_size = a_item_apply_to ? a_item_apply_to->tx_send_block_size : 0; + dap_chain_addr_t *l_new_tx_recv_allow = NULL, *l_new_tx_recv_block = NULL, + *l_new_tx_send_allow = NULL, *l_new_tx_send_block = NULL; + bool l_was_tx_recv_allow_copied = false, l_was_tx_recv_block_copied = false, + l_was_tx_send_allow_copied = false, l_was_tx_send_block_copied = false; + + int ret = DAP_LEDGER_CHECK_OK; + size_t l_tsd_size = 0; + dap_tsd_t *l_tsd = (dap_tsd_t *)a_tsd; + for (size_t l_offset = 0; l_offset < a_tsd_total_size; l_offset += l_tsd_size) { + if (l_offset + sizeof(dap_tsd_t) > a_tsd_total_size) { + log_it(L_WARNING, "Incorrect TSD section size, less than header"); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + l_tsd = (dap_tsd_t *)((byte_t *)l_tsd + l_tsd_size); + l_tsd_size = dap_tsd_size(l_tsd); + if (l_offset + l_tsd_size > a_tsd_total_size) { + log_it(L_WARNING, "Wrong TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; } 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; + // set flags + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS: { + if (l_tsd->size != sizeof(uint16_t)) { + log_it(L_WARNING, "Wrong SET_FLAGS TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + if (!a_apply) 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); + a_item_apply_to->flags |= dap_tsd_get_scalar(l_tsd, uint16_t); + } break; + + // unset flags + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS: { + if (l_tsd->size != sizeof(uint16_t)) { + log_it(L_WARNING, "Wrong UNSET_FLAGS TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + if (!a_apply) 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); + a_item_apply_to->flags &= ~dap_tsd_get_scalar(l_tsd, uint16_t); + } break; + + // set total supply + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY: { // 256 + if (l_tsd->size != sizeof(uint256_t)) { + log_it(L_WARNING, "Wrong TOTAL_SUPPLY TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + if (!a_item_apply_to) { + log_it(L_WARNING, "Unexpected TOTAL_SUUPLY TSD section in datum token declaration"); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN; + goto ret_n_clear; + } + uint256_t l_new_supply = dap_tsd_get_scalar(l_tsd, uint256_t); + if (!IS_ZERO_256(a_item_apply_to->total_supply) && !IS_ZERO_256(l_new_supply) && + compare256(a_item_apply_to->total_supply, l_new_supply) < 0) { //compare old 'total_supply' can be updated + log_it(L_WARNING, "Can't update token with ticker '%s' because the new 'total_supply' can't be smaller than the old one", a_item_apply_to->ticker); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_SUPPLY; + goto ret_n_clear; + } + if (!a_apply) 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_free(l_tsd_list_added_pkeys); - dap_list_free(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) { - uint16_t l_signs_valid_from_tsd = 0; - _dap_tsd_get_scalar(l_tsd_signs_valid, &l_signs_valid_from_tsd); - if (l_new_signs_total < (size_t)l_signs_valid_from_tsd || l_signs_valid_from_tsd < 1) { - dap_list_free(l_tsd_list_added_pkeys); - dap_list_free(l_tsd_list_remote_pkeys); - return false; - } - } else { - if (l_new_signs_total < auth_signs_valid){ - dap_list_free(l_tsd_list_added_pkeys); - dap_list_free(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, &l_hash); - 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; + a_item_apply_to->total_supply = l_new_supply; + } 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)) { + log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_ADD TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + // Check if its correct + dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t); + if (dap_chain_addr_check_sum(l_add_addr)) { + log_it(L_WARNING, "Wrong address checksum in TSD param TX_RECEIVER_ALLOWED_ADD"); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR; + goto ret_n_clear; + } + if (!l_new_tx_recv_allow && l_new_tx_recv_allow_size && !l_was_tx_recv_allow_copied) { + assert(a_item_apply_to->tx_recv_allow); + // Deep copy addrs to sandbox + l_new_tx_recv_allow = DAP_DUP_SIZE(a_item_apply_to->tx_recv_allow, l_new_tx_recv_allow_size * sizeof(dap_chain_addr_t)); + if (!l_new_tx_recv_allow) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + } + l_was_tx_recv_allow_copied = true; + // Check if its already present + for (size_t i = 0; i < l_new_tx_recv_allow_size; i++) { // Check for all the list + if (dap_chain_addr_compare(l_new_tx_recv_allow + i, l_add_addr)) { // Found + log_it(L_WARNING, "TSD param TX_RECEIVER_ALLOWED_ADD has address %s thats already present in list", + dap_chain_addr_to_str(l_add_addr)); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH; + goto ret_n_clear; + } + } + l_new_tx_recv_allow = l_new_tx_recv_allow + ? DAP_REALLOC(l_new_tx_recv_allow, (l_new_tx_recv_allow_size + 1) * sizeof(dap_chain_addr_t)) + : DAP_NEW_Z(dap_chain_addr_t); + if (!l_new_tx_recv_allow) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + l_new_tx_recv_allow[l_new_tx_recv_allow_size++] = *l_add_addr; + } break; + + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE: { + if (l_tsd->size != sizeof(dap_chain_addr_t)) { + log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + // Check if its correct + dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t); + if (dap_chain_addr_check_sum(l_add_addr)) { + log_it(L_WARNING, "Wrong address checksum in TSD param TX_RECEIVER_ALLOWED_REMOVE"); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR; + goto ret_n_clear; + } + if (!l_new_tx_recv_allow && l_new_tx_recv_allow_size && !l_was_tx_recv_allow_copied) { + assert(a_item_apply_to->tx_recv_allow); + // Deep copy addrs to sandbox + l_new_tx_recv_allow = DAP_DUP_SIZE(a_item_apply_to->tx_recv_allow, l_new_tx_recv_allow_size * sizeof(dap_chain_addr_t)); + if (!l_new_tx_recv_allow) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + } + l_was_tx_recv_allow_copied = true; + // Check if its already present + size_t i = 0; + for ( ; i < l_new_tx_recv_allow_size; i++) // Check for all the list + if (dap_chain_addr_compare(l_new_tx_recv_allow + i, l_add_addr)) break; + if (i == l_new_tx_recv_allow_size) { + log_it(L_WARNING, "TSD param TX_RECEIVER_ALLOWED_REMOVE has address %s thats not present in list", + dap_chain_addr_to_str(l_add_addr)); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH; + goto ret_n_clear; + } + // Addr removing + if (--l_new_tx_recv_allow_size > i) + memmove(l_new_tx_recv_allow + i, l_new_tx_recv_allow + i + 1, + (l_new_tx_recv_allow_size - i - 1) * sizeof(dap_chain_addr_t)); + // Memory clearing + if (l_new_tx_recv_allow_size) + l_new_tx_recv_allow = DAP_REALLOC(l_new_tx_recv_allow, + l_new_tx_recv_allow_size * sizeof(dap_chain_addr_t)); + else + DAP_DEL_Z(l_new_tx_recv_allow); + } break; + + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_CLEAR: { + if (l_tsd->size != 0) { + log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + DAP_DEL_Z(l_new_tx_recv_allow); + l_new_tx_recv_allow_size = 0; + l_was_tx_recv_block_copied = true; + } break; + + // Blocked tx receiver addres list add, remove or clear + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD: { + if (l_tsd->size != sizeof(dap_chain_addr_t)) { + log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_ADD TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + // Check if its correct + dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t); + if (dap_chain_addr_check_sum(l_add_addr)) { + log_it(L_WARNING, "Wrong address checksum in TSD param TX_RECEIVER_BLOCKED_ADD"); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR; + goto ret_n_clear; + } + if (!l_new_tx_recv_block && l_new_tx_recv_block_size && !l_was_tx_recv_block_copied) { + assert(a_item_apply_to->tx_recv_block); + // Deep copy addrs to sandbox + l_new_tx_recv_block = DAP_DUP_SIZE(a_item_apply_to->tx_recv_block, l_new_tx_recv_block_size * sizeof(dap_chain_addr_t)); + if (!l_new_tx_recv_block) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; } } - 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); + l_was_tx_recv_block_copied = true; + // Check if its already present + for (size_t i = 0; i < l_new_tx_recv_block_size; i++) { // Check for all the list + if (dap_chain_addr_compare(l_new_tx_recv_block + i, l_add_addr)) { // Found + log_it(L_WARNING, "TSD param TX_RECEIVER_BLOCKED_ADD has address %s thats already present in list", + dap_chain_addr_to_str(l_add_addr)); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH; + goto ret_n_clear; } } - isAccepted = accepted; - } - } - if (!isAccepted) { - dap_list_free(l_tsd_list_added_pkeys); - dap_list_free(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); - if (!l_token_tmp) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - dap_list_free(l_tsd_list_added_pkeys); - dap_list_free(l_tsd_list_remote_pkeys); - return false; - } + l_new_tx_recv_block = l_new_tx_recv_block + ? DAP_REALLOC(l_new_tx_recv_block, (l_new_tx_recv_block_size + 1) * sizeof(dap_chain_addr_t)) + : DAP_NEW_Z(dap_chain_addr_t); + if (!l_new_tx_recv_block) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + l_new_tx_recv_block[l_new_tx_recv_block_size++] = *l_add_addr; + } break; + + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE: { + if (l_tsd->size != sizeof(dap_chain_addr_t)) { + log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + // Check if its correct + dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t); + if (dap_chain_addr_check_sum(l_add_addr)) { + log_it(L_WARNING, "Wrong address checksum in TSD param TX_RECEIVER_BLOCKED_REMOVE"); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR; + goto ret_n_clear; + } + if (!l_new_tx_recv_block && l_new_tx_recv_block_size && !l_was_tx_recv_block_copied) { + assert(a_item_apply_to->tx_recv_block); + // Deep copy addrs to sandbox + l_new_tx_recv_block = DAP_DUP_SIZE(a_item_apply_to->tx_recv_block, l_new_tx_recv_block_size * sizeof(dap_chain_addr_t)); + if (!l_new_tx_recv_block) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + } + l_was_tx_recv_block_copied = true; + // Check if its already present + size_t i = 0; + for ( ; i < l_new_tx_recv_block_size; i++) // Check for all the list + if (dap_chain_addr_compare(l_new_tx_recv_block + i, l_add_addr)) + break; + if (i == l_new_tx_recv_block_size) { + log_it(L_WARNING, "TSD param TX_RECEIVER_BLOCKED_REMOVE has address %s thats not present in list", + dap_chain_addr_to_str(l_add_addr)); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH; + goto ret_n_clear; + } + // Addr removing + if (--l_new_tx_recv_block_size > i) + memmove(l_new_tx_recv_block + i, l_new_tx_recv_block + i + 1, + (l_new_tx_recv_block_size - i - 1) * sizeof(dap_chain_addr_t)); + // Memory clearing + if (l_new_tx_recv_block_size) + l_new_tx_recv_block = DAP_REALLOC(l_new_tx_recv_block, + l_new_tx_recv_block_size * sizeof(dap_chain_addr_t)); + else + DAP_DEL_Z(l_new_tx_recv_block); + } break; + + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_CLEAR: { + if (l_tsd->size != 0) { + log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + DAP_DEL_Z(l_new_tx_recv_block); + l_new_tx_recv_block_size = 0; + l_was_tx_recv_block_copied = true; + } break; + + // Blocked tx sender addres list add, remove or clear + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD: { + if (l_tsd->size != sizeof(dap_chain_addr_t)) { + log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_ADD TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + // Check if its correct + dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t); + if (dap_chain_addr_check_sum(l_add_addr)) { + log_it(L_WARNING, "Wrong address checksum in TSD param TX_SENDER_ALLOWED_ADD"); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR; + goto ret_n_clear; + } + if (!l_new_tx_send_allow && l_new_tx_send_allow_size && !l_was_tx_send_allow_copied) { + assert(a_item_apply_to->tx_send_allow); + // Deep copy addrs to sandbox + l_new_tx_send_allow = DAP_DUP_SIZE(a_item_apply_to->tx_send_allow, l_new_tx_send_allow_size * sizeof(dap_chain_addr_t)); + if (!l_new_tx_send_allow) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + } + l_was_tx_send_allow_copied = true; + // Check if its already present + for (size_t i = 0; i < l_new_tx_send_allow_size; i++) { // Check for all the list + if (dap_chain_addr_compare(l_new_tx_send_allow + i, l_add_addr)) { // Found + log_it(L_WARNING, "TSD param TX_SENDER_ALLOWED_ADD has address %s thats already present in list", + dap_chain_addr_to_str(l_add_addr)); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH; + goto ret_n_clear; + } + } + l_new_tx_send_allow = l_new_tx_send_allow + ? DAP_REALLOC(l_new_tx_send_allow, (l_new_tx_send_allow_size + 1) * sizeof(dap_chain_addr_t)) + : DAP_NEW_Z(dap_chain_addr_t); + if (!l_new_tx_send_allow) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + l_new_tx_send_allow[l_new_tx_send_allow_size++] = *l_add_addr; + } break; + + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE: { + if (l_tsd->size != sizeof(dap_chain_addr_t)) { + log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + // Check if its correct + dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t); + if (dap_chain_addr_check_sum(l_add_addr)) { + log_it(L_WARNING, "Wrong address checksum in TSD param TX_SENDER_ALLOWED_REMOVE"); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR; + goto ret_n_clear; + + } + if (!l_new_tx_send_allow && l_new_tx_send_allow_size && !l_was_tx_send_allow_copied) { + assert(a_item_apply_to->tx_send_allow); + // Deep copy addrs to sandbox + l_new_tx_send_allow = DAP_DUP_SIZE(a_item_apply_to->tx_send_allow, l_new_tx_send_allow_size * sizeof(dap_chain_addr_t)); + if (!l_new_tx_send_allow) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + } + l_was_tx_send_allow_copied = true; + // Check if its already present + size_t i = 0; + for ( ; i < l_new_tx_send_allow_size; i++) // Check for all the list + if (dap_chain_addr_compare(l_new_tx_send_allow + i, l_add_addr)) + break; + if (i == l_new_tx_send_allow_size) { + log_it(L_WARNING, "TSD param TX_SENDER_ALLOWED_REMOVE has address %s thats not present in list", + dap_chain_addr_to_str(l_add_addr)); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH; + goto ret_n_clear; + } + // Addr removing + if (--l_new_tx_send_allow_size > i) + memmove(l_new_tx_send_allow + i, l_new_tx_send_allow + i + 1, + (l_new_tx_send_allow_size - i - 1) * sizeof(dap_chain_addr_t)); + // Memory clearing + if (l_new_tx_send_allow_size) + l_new_tx_send_allow = DAP_REALLOC(l_new_tx_send_allow, + l_new_tx_send_allow_size * sizeof(dap_chain_addr_t)); + else + DAP_DEL_Z(l_new_tx_send_allow); + } break; + + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_CLEAR: { + if (l_tsd->size != 0) { + log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + DAP_DEL_Z(l_new_tx_send_allow); + l_new_tx_send_allow_size = 0; + l_was_tx_send_allow_copied = true; + } break; - 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; + // Blocked tx sender addres list add, remove or clear + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD: { + if (l_tsd->size != sizeof(dap_chain_addr_t)) { + log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_ADD TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + // Check if its correct + dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t); + if (dap_chain_addr_check_sum(l_add_addr)) { + log_it(L_WARNING, "Wrong address checksum in TSD param TX_SENDER_BLOCKED_ADD"); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR; + goto ret_n_clear; + } + if (!l_new_tx_send_block && l_new_tx_send_block_size && !l_was_tx_send_block_copied) { + assert(a_item_apply_to->tx_send_block); + // Deep copy addrs to sandbox + l_new_tx_send_block = DAP_DUP_SIZE(a_item_apply_to->tx_send_block, l_new_tx_send_block_size * sizeof(dap_chain_addr_t)); + if (!l_new_tx_send_block) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + } + l_was_tx_send_block_copied = true; + // Check if its already present + for (size_t i = 0; i < l_new_tx_send_block_size; i++) { // Check for all the list + if (dap_chain_addr_compare(l_new_tx_send_block + i, l_add_addr)) { // Found + log_it(L_WARNING, "TSD param TX_SENDER_BLOCKED_ADD has address %s thats already present in list", + dap_chain_addr_to_str(l_add_addr)); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH; + goto ret_n_clear; + } + } + if (!a_apply) break; + l_new_tx_send_block = l_new_tx_send_block + ? DAP_REALLOC(l_new_tx_send_block, (l_new_tx_send_block_size + 1) * sizeof(dap_chain_addr_t)) + : DAP_NEW_Z(dap_chain_addr_t); + if (!l_new_tx_send_block) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; } - 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; + l_new_tx_send_block[l_new_tx_send_block_size++] = *l_add_addr; + } break; + + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE: { + if (l_tsd->size != sizeof(dap_chain_addr_t)) { + log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + // Check if its correct + dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t); + if (dap_chain_addr_check_sum(l_add_addr)) { + log_it(L_WARNING, "Wrong address checksum in TSD param TX_SENDER_BLOCKED_REMOVE"); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR; + goto ret_n_clear; + } + if (!l_new_tx_send_block && l_new_tx_send_block_size && !l_was_tx_send_block_copied) { + assert(a_item_apply_to->tx_send_block); + // Deep copy addrs to sandbox + l_new_tx_send_block = DAP_DUP_SIZE(a_item_apply_to->tx_send_block, l_new_tx_send_block_size * sizeof(dap_chain_addr_t)); + if (!l_new_tx_send_block) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + } + l_was_tx_send_block_copied = true; + // Check if its already present + size_t i = 0; + for ( ; i < l_new_tx_send_block_size; i++) // Check for all the list + if (dap_chain_addr_compare(l_new_tx_send_block + i, l_add_addr)) break; + if (i == l_new_tx_send_block_size) { + log_it(L_WARNING, "TSD param TX_SENDER_BLOCKED_REMOVE has address %s thats not present in list", + dap_chain_addr_to_str(l_add_addr)); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH; + goto ret_n_clear; + } + // Addr removing + if (--l_new_tx_send_block_size > i) + memmove(l_new_tx_send_block + i, l_new_tx_send_block + i + 1, + (l_new_tx_send_block_size - i - 1) * sizeof(dap_chain_addr_t)); + // Memory clearing + if (l_new_tx_send_block_size) + l_new_tx_send_block = DAP_REALLOC(l_new_tx_send_block, + l_new_tx_send_block_size * sizeof(dap_chain_addr_t)); + else + DAP_DEL_Z(l_new_tx_send_block); + } break; + + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_CLEAR: { + if (l_tsd->size != 0) { + log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + DAP_DEL_Z(l_new_tx_send_block); + l_new_tx_send_block_size = 0; + l_was_tx_send_block_copied = true; + } break; + + case DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION: { + if (l_tsd->size == 0 || l_tsd->data[l_tsd->size - 1] != 0) { + log_it(L_ERROR, "Wrong TOKEN_DESCRIPTION TSD format or size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + if (!a_apply) + break; + DAP_DEL_Z(a_item_apply_to->description); + a_item_apply_to->description = strdup((char *)l_tsd->data); + } break; + + // Set signs count value need to emission be valid + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: { + if (l_tsd->size != sizeof(uint16_t)) { + log_it(L_WARNING, "Wrong SIGNS_VALID TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + l_new_signs_valid = dap_tsd_get_scalar(l_tsd, uint16_t); + } break; + + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: { + if (l_tsd->size < sizeof(dap_pkey_t) || l_tsd->size != dap_pkey_get_size((dap_pkey_t *)l_tsd->data)) { + log_it(L_WARNING, "Wrong TOTAL_PKEYS_ADD TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + if (!l_new_pkeys && l_new_signs_total && !l_was_pkeys_copied) { + assert(a_item_apply_to->auth_pkeys); + assert(a_item_apply_to->auth_pkey_hashes); + // Deep copy pkeys & its hashes to sandbox + l_new_pkeys = DAP_NEW_SIZE(dap_pkey_t *, l_new_signs_total * sizeof(dap_pkey_t *)); + if (!l_new_pkeys) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + for (size_t i = 0; i < l_new_signs_total; i++) { + l_new_pkeys[i] = DAP_DUP_SIZE(a_item_apply_to->auth_pkeys[i], dap_pkey_get_size(a_item_apply_to->auth_pkeys[i])); + if (!l_new_pkeys[i]) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + } + assert(!l_new_pkey_hashes); + l_new_pkey_hashes = DAP_DUP_SIZE(a_item_apply_to->auth_pkey_hashes, l_new_signs_total * sizeof(dap_hash_t)); + if (!l_new_pkey_hashes) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; } } - } 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_free(l_tsd_list_added_pkeys); - dap_list_free(l_tsd_list_remote_pkeys); - DAP_DELETE(l_token_tmp); - return isAccepted; -} + l_was_pkeys_copied = true; + dap_pkey_t *l_new_auth_pkey = dap_tsd_get_object(l_tsd, dap_pkey_t); + dap_pkey_type_t l_pkey_type_correction = { .type = DAP_PKEY_TYPE_NULL }; + if (dap_pkey_type_to_enc_key_type(l_new_auth_pkey->header.type) == DAP_ENC_KEY_TYPE_INVALID) { + dap_sign_type_t l_sign_type = { .type = l_new_auth_pkey->header.type.type }; // Legacy cratch + l_pkey_type_correction = dap_pkey_type_from_sign_type(l_sign_type); + if (l_pkey_type_correction.type == DAP_PKEY_TYPE_NULL) { + log_it(L_WARNING, "Unknonw public key type %hu", l_new_auth_pkey->header.type.type); + ret = DAP_LEDGER_CHECK_PARSE_ERROR; + goto ret_n_clear; + } + } + // Check if its already present + dap_hash_t l_new_auth_pkey_hash; + dap_pkey_get_hash(l_new_auth_pkey, &l_new_auth_pkey_hash); + for (size_t i = 0; i < l_new_signs_total; i++) { + if (dap_pkey_compare(l_new_auth_pkey, l_new_pkeys[i])) { + log_it(L_WARNING, "TSD param TOTAL_PKEYS_ADD has pkey %s thats already present in list", + dap_hash_fast_to_str_static(&l_new_auth_pkey_hash)); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH; + goto ret_n_clear; + } + } + l_new_pkeys = l_new_pkeys ? DAP_REALLOC(l_new_pkeys, (l_new_signs_total + 1) * sizeof(dap_pkey_t *)) + : DAP_NEW_Z(dap_pkey_t *); + if (!l_new_pkeys) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + // Pkey adding + l_new_pkeys[l_new_signs_total] = DAP_DUP_SIZE(l_new_auth_pkey, dap_pkey_get_size(l_new_auth_pkey)); + if (!l_new_pkeys[l_new_signs_total]) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + if (l_pkey_type_correction.type != DAP_PKEY_TYPE_NULL) + l_new_pkeys[l_new_signs_total]->header.type = l_pkey_type_correction; + + l_new_pkey_hashes = l_new_pkey_hashes ? DAP_REALLOC(l_new_pkey_hashes, (l_new_signs_total + 1) * sizeof(dap_hash_t)) + : DAP_NEW_Z(dap_hash_t); + if (!l_new_pkey_hashes) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + l_new_pkey_hashes[l_new_signs_total++] = l_new_auth_pkey_hash; + } break; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: { + if (l_tsd->size != sizeof(dap_hash_t)) { + log_it(L_WARNING, "Wrong TOTAL_PKEYS_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + if (!l_new_pkeys && l_new_signs_total && !l_was_pkeys_copied) { + assert(a_item_apply_to->auth_pkeys); + assert(a_item_apply_to->auth_pkey_hashes); + // Deep copy pkeys & its hashes to sandbox + l_new_pkeys = DAP_NEW_SIZE(dap_pkey_t *, l_new_signs_total * sizeof(dap_pkey_t *)); + if (!l_new_pkeys) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + for (size_t i = 0; i < l_new_signs_total; i++) { + l_new_pkeys[i] = DAP_DUP_SIZE(a_item_apply_to->auth_pkeys[i], dap_pkey_get_size(a_item_apply_to->auth_pkeys[i])); + if (!l_new_pkeys[i]) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + } + assert(!l_new_pkey_hashes); + l_new_pkey_hashes = DAP_DUP_SIZE(a_item_apply_to->auth_pkey_hashes, l_new_signs_total * sizeof(dap_hash_t)); + if (!l_new_pkey_hashes) { + log_it(L_CRITICAL, c_error_memory_alloc); + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + goto ret_n_clear; + } + } + l_was_pkeys_copied = true; + dap_hash_t l_new_auth_pkey_hash = dap_tsd_get_scalar(l_tsd, dap_hash_t); + // Check if its already present + size_t i = 0; + for ( ; i < l_new_signs_total; i++) // Check for all the list + if (dap_hash_fast_compare(l_new_pkey_hashes + i, &l_new_auth_pkey_hash)) + break; + if (i == l_new_signs_total) { + log_it(L_WARNING, "TSD param TOTAL_PKEYS_REMOVE has public key hash %s thats not present in list", + dap_hash_fast_to_str_static(&l_new_auth_pkey_hash)); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH; + goto ret_n_clear; + } + // Pkey removing + DAP_DELETE(l_new_pkeys[i]); + if (--l_new_signs_total > i) { + memmove(l_new_pkeys + i, l_new_pkeys + i + 1, (l_new_signs_total - i - 1) * sizeof(dap_pkey_t *)); + memmove(l_new_pkey_hashes + i, l_new_pkey_hashes + i + 1, (l_new_signs_total - i - 1) * sizeof(dap_hash_t)); + } + // Memory clearing + if (l_new_signs_total) { + l_new_pkeys = DAP_REALLOC(l_new_pkeys, l_new_signs_total * sizeof(dap_pkey_t *)); + l_new_pkey_hashes = DAP_REALLOC(l_new_pkey_hashes, l_new_signs_total * sizeof(dap_hash_t)); + } else + DAP_DEL_MULTY(l_new_pkeys, l_new_pkey_hashes); + } break; -inline static dap_ledger_token_item_t *s_ledger_find_token(dap_ledger_t *a_ledger, const char *a_token_ticker) -{ - dap_ledger_token_item_t *l_token_item; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_FIND_STR(PVT(a_ledger)->tokens, a_token_ticker, l_token_item); - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - return l_token_item; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK: { + if (a_current_datum->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE) { + log_it(L_WARNING, "TSD section DELEGATE_EMISSION_FROM_STAKE_LOCK allowed for NATIVE subtype only"); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN; + goto ret_n_clear; + } + if (l_tsd->size != sizeof(dap_chain_datum_token_tsd_delegate_from_stake_lock_t) && + l_tsd->size != sizeof(dap_chain_datum_token_tsd_delegate_from_stake_lock_t) + 256 /* Legacy size */) { + log_it(L_WARNING, "Wrong DELEGATE_EMISSION_FROM_STAKE_LOCK TSD size %zu, exiting TSD parse", l_tsd_size); + ret = DAP_LEDGER_CHECK_INVALID_SIZE; + goto ret_n_clear; + } + dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_delegate = dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t); + const char *l_basic_token_ticker = (const char *)l_delegate->ticker_token_from; + char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; + dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, l_basic_token_ticker); + if (dap_strcmp(l_delegated_ticker, a_current_datum->ticker)) { + log_it(L_WARNING, "Unexpected delegated token ticker %s (expected %s)", a_current_datum->ticker, l_delegated_ticker); + ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_OTHER_TICKER_EXPECTED; + goto ret_n_clear; + } + dap_ledger_token_item_t *l_basic_token = NULL; + HASH_FIND_STR(PVT(a_ledger)->tokens, l_basic_token_ticker, l_basic_token); + if (!l_basic_token) { + log_it(L_WARNING, "Basic token ticker %s for delegated token isn't found", l_basic_token_ticker); + ret = DAP_LEDGER_CHECK_TICKER_NOT_FOUND; + goto ret_n_clear; + } + if (IS_ZERO_256(l_delegate->emission_rate)) { + log_it(L_WARNING, "Emission rate for delegated toke should not be a zero"); + ret = DAP_LEDGER_CHECK_ZERO_VALUE; + goto ret_n_clear; + } + if (!a_apply) + break; + assert(a_item_apply_to); + a_item_apply_to->is_delegated = true; + strcpy(a_item_apply_to->delegated_from, l_basic_token->ticker); + a_item_apply_to->emission_rate = l_delegate->emission_rate; + } break; + + default: + log_it(L_ERROR, "Unexpected TSD type %hu", l_tsd->type); + ret = DAP_LEDGER_CHECK_PARSE_ERROR; + goto ret_n_clear; + } + } + if (l_new_signs_total < l_new_signs_valid) { + ret = DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS; + goto ret_n_clear; + } + if (a_apply) { + if (l_was_tx_recv_allow_copied) { + a_item_apply_to->tx_recv_allow_size = l_new_tx_recv_allow_size; + DAP_DEL_Z(a_item_apply_to->tx_recv_allow); + a_item_apply_to->tx_recv_allow = l_new_tx_recv_allow; + } + if (l_was_tx_recv_block_copied) { + a_item_apply_to->tx_recv_block_size = l_new_tx_recv_block_size; + DAP_DEL_Z(a_item_apply_to->tx_recv_block); + a_item_apply_to->tx_recv_block = l_new_tx_recv_block; + } + if (l_was_tx_send_allow_copied) { + a_item_apply_to->tx_send_allow_size = l_new_tx_send_allow_size; + DAP_DEL_Z(a_item_apply_to->tx_send_allow); + a_item_apply_to->tx_send_allow = l_new_tx_send_allow; + } + if (l_was_tx_send_block_copied) { + a_item_apply_to->tx_send_block_size = l_new_tx_send_block_size; + DAP_DEL_Z(a_item_apply_to->tx_send_block); + a_item_apply_to->tx_send_block = l_new_tx_send_block; + } + a_item_apply_to->auth_signs_valid = l_new_signs_valid; + if (l_was_pkeys_copied) { + for (size_t i = 0; i < a_item_apply_to->auth_signs_total; i++) + DAP_DELETE(a_item_apply_to->auth_pkeys[i]); + DAP_DEL_Z(a_item_apply_to->auth_pkeys); + DAP_DEL_Z(a_item_apply_to->auth_pkey_hashes); + a_item_apply_to->auth_signs_total = l_new_signs_total; + a_item_apply_to->auth_pkeys = l_new_pkeys; + a_item_apply_to->auth_pkey_hashes = l_new_pkey_hashes; + } + return DAP_LEDGER_CHECK_OK; + } + // Checks passed +ret_n_clear: + if (l_new_pkeys) + for (size_t i = 0; i < l_new_signs_total; i++) + DAP_DELETE(l_new_pkeys[i]); + DAP_DEL_MULTY(l_new_tx_recv_allow, l_new_tx_recv_block, l_new_tx_send_allow, l_new_tx_send_block, l_new_pkeys, l_new_pkey_hashes); + return ret; } /** @@ -882,76 +1352,221 @@ inline static dap_ledger_token_item_t *s_ledger_find_token(dap_ledger_t *a_ledge * @param a_token_size * @return */ -int dap_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size) +int s_token_add_check(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size, + dap_ledger_token_item_t **a_token_item, dap_chain_datum_token_t **a_token_out, + size_t *a_tsd_total_size, size_t *a_signs_size, + dap_hash_fast_t *a_token_update_hash) { - if ( !a_ledger){ - if(s_debug_more) - log_it(L_ERROR, "NULL ledger, can't add datum with token declaration!"); - return DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL; + size_t l_token_size = a_token_size; + dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(a_token, &l_token_size); + if (!l_token) + return DAP_LEDGER_CHECK_INVALID_SIZE; + if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_DECL) { + log_it(L_WARNING, "Unknown token type %hu", l_token->type); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_PARSE_ERROR; } - - bool l_update_token = a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE; - dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token->ticker); - if (l_token_item != NULL) { + if (!l_token->ticker[0] || l_token->ticker[DAP_CHAIN_TICKER_SIZE_MAX - 1]) { + log_it(L_WARNING, "Unreadable token ticker"); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_PARSE_ERROR; + } + char *ptr = l_token->ticker; + while (*ptr) { + if (!dap_ascii_isalnum(*ptr++)) { + log_it(L_WARNING, "Token ticker is not alpha-numeric"); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_PARSE_ERROR; + } + } + if (!l_token->signs_total) { + log_it(L_WARNING, "No auth signs in token '%s' datum!", l_token->ticker); + DAP_DELETE(l_token); + return DAP_LEDGER_TOKEN_ADD_CHECK_NOT_ENOUGH_UNIQUE_SIGNS; + } + bool l_update_token = l_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE; + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token->ticker); + dap_hash_fast_t l_token_update_hash = {}; + if (l_token_item) { if (!l_update_token) { - log_it(L_WARNING, "Duplicate token declaration for ticker '%s'", a_token->ticker); - return DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE; - } else if (!s_ledger_token_update_check(l_token_item, a_token, a_token_size)) - return DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK; - } else if (!l_token_item && l_update_token) { - log_it(L_WARNING, "Can't update token that doesn't exist for ticker '%s'", a_token->ticker); - return DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN; + log_it(L_WARNING, "Duplicate token declaration for ticker '%s'", l_token->ticker); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_ALREADY_CACHED; + } + if (l_token->signs_total < l_token_item->auth_signs_valid) { + log_it(L_WARNING, "Datum token for ticker '%s' has only %hu signatures out of %zu", + l_token->ticker, l_token->signs_total, l_token_item->auth_signs_valid); + DAP_DELETE(l_token); + return DAP_LEDGER_TOKEN_ADD_CHECK_NOT_ENOUGH_UNIQUE_SIGNS; + } + dap_hash_fast(l_token, l_token_size, &l_token_update_hash); + dap_ledger_token_update_item_t *l_token_update_item; + pthread_rwlock_rdlock(&l_token_item->token_ts_updated_rwlock); + HASH_FIND(hh, l_token_item->token_ts_updated, &l_token_update_hash, sizeof(dap_hash_fast_t), l_token_update_item); + pthread_rwlock_unlock(&l_token_item->token_ts_updated_rwlock); + if (l_token_update_item) { + log_it(L_WARNING, "This update for token '%s' was already applied", l_token->ticker); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_ALREADY_CACHED; + } + if (a_token_update_hash) + *a_token_update_hash = l_token_update_hash; + } else if (l_update_token) { + log_it(L_WARNING, "Can't update token that doesn't exist for ticker '%s'", l_token->ticker); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_TICKER_NOT_FOUND; + } else if (l_token->signs_total < l_token->signs_valid) { + log_it(L_WARNING, "Datum token for ticker '%s' has only %hu signatures out of %hu", + l_token->ticker, l_token->signs_total, l_token->signs_valid); + DAP_DELETE(l_token); + return DAP_LEDGER_TOKEN_ADD_CHECK_NOT_ENOUGH_UNIQUE_SIGNS; } - // Check signs - size_t l_signs_unique = 0; + // Check TSD size_t l_size_tsd_section = 0; - switch (a_token->type) { - case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: { - switch (a_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: - l_size_tsd_section = a_token->header_private_decl.tsd_total_size; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - l_size_tsd_section = a_token->header_native_decl.tsd_total_size; break; - } - }break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: { - switch (a_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: - l_size_tsd_section = a_token->header_private_update.tsd_total_size; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - l_size_tsd_section = a_token->header_native_update.tsd_total_size; break; - } - } break; - } - size_t l_signs_size = a_token_size - sizeof(dap_chain_datum_token_t) - l_size_tsd_section; - dap_sign_t **l_signs = dap_sign_get_unique_signs(a_token->data_n_tsd + l_size_tsd_section, l_signs_size, &l_signs_unique); - if (l_signs_unique == a_token->signs_total){ - size_t l_signs_approve = 0; - uint16_t l_tmp_auth_signs = a_token->signs_total; - if (a_token->version == 2) a_token->signs_total = 0; - for (size_t i=0; i < l_signs_unique; i++) - if (!dap_sign_verify_all(l_signs[i], l_signs_size, a_token, sizeof(dap_chain_datum_token_t)+l_size_tsd_section)) - l_signs_approve++; - a_token->signs_total = l_tmp_auth_signs; - if (l_signs_approve == a_token->signs_total){ - return DAP_LEDGER_TOKEN_DECL_ADD_OK; - } else { - log_it(L_WARNING, "The token declaration has %zu valid signatures out of %hu.", l_signs_approve, a_token->signs_total); - return DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN; + if (l_update_token) { + switch (l_token->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: + l_size_tsd_section = l_token->header_private_decl.tsd_total_size; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: + l_size_tsd_section = l_token->header_native_decl.tsd_total_size; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: + break; + default: + /* Bogdanoff, unknown token subtype update. What shall we TODO? */ + log_it(L_WARNING, "Unknown token subtype '0x%0hX' update! Ticker: %s, total_supply: %s, signs_valid: %hu, signs_total: %hu", + l_token->type, l_token->ticker, dap_uint256_to_char(l_token->total_supply, NULL), + l_token->signs_valid, l_token->signs_total); + /* Dump it right now */ + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_PARSE_ERROR; } } else { - log_it(L_WARNING, "The number of unique token signs %zu is less than total token signs set to %hu.", - l_signs_unique, a_token->signs_total); - return DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS; + switch (l_token->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: + l_size_tsd_section = l_token->header_private_update.tsd_total_size; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: + l_size_tsd_section = l_token->header_native_update.tsd_total_size; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: + break; + default: + /* Bogdanoff, unknown token subtype declaration. What shall we TODO? */ + log_it(L_WARNING, "Unknown token subtype '0x%0hX' declaration! Ticker: %s, total_supply: %s, signs_valid: %hu, signs_total: %hu", + l_token->type, l_token->ticker, dap_uint256_to_char(l_token->total_supply, NULL), + l_token->signs_valid, l_token->signs_total); + /* Dump it right now */ + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_PARSE_ERROR; + } } - // Checks passed - return DAP_LEDGER_TOKEN_DECL_ADD_OK; + if (l_token_size < sizeof(dap_chain_datum_token_t) + l_size_tsd_section) { + log_it(L_WARNING, "Incorrect size %zu of datum token, expected at least %zu", l_token_size, + sizeof(dap_chain_datum_token_t) + l_size_tsd_section); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_INVALID_SIZE; + } + // Check signs + byte_t *l_signs_ptr = l_token->tsd_n_signs + l_size_tsd_section; + size_t l_signs_size = 0, l_signs_offset = sizeof(dap_chain_datum_token_t) + l_size_tsd_section; + for (uint16_t l_signs_passed = 0; l_signs_passed < l_token->signs_total; l_signs_passed++) { + dap_sign_t *l_sign = (dap_sign_t *)(l_signs_ptr + l_signs_size); + if (l_token_size < l_signs_offset + l_signs_size + sizeof(dap_sign_t)) { + log_it(L_WARNING, "Incorrect size %zu of datum token, expected at least %zu", l_token_size, + l_signs_offset + l_signs_size + sizeof(dap_sign_t)); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_INVALID_SIZE; + } + l_signs_size += dap_sign_get_size(l_sign); + } + if (l_token_size != l_signs_offset + l_signs_size) { + log_it(L_WARNING, "Incorrect size %zu of datum token, expected %zu", l_token_size, l_signs_offset + l_signs_size); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_INVALID_SIZE; + } + size_t l_signs_unique = l_token->signs_total; + dap_sign_t **l_signs = dap_sign_get_unique_signs(l_signs_ptr, l_signs_size, &l_signs_unique); + if (l_signs_unique != l_token->signs_total) { + DAP_DEL_Z(l_signs); + log_it(L_WARNING, "The number of unique token signs %zu is less than total token signs set to %hu", + l_signs_unique, l_token->signs_total); + DAP_DELETE(l_token); + return DAP_LEDGER_TOKEN_ADD_CHECK_NOT_ENOUGH_UNIQUE_SIGNS; + } + bool l_legacy_type = a_token_size != l_token_size; + size_t l_signs_approve = 0; + size_t l_verify_size = 0; + uint16_t l_tmp_auth_signs = 0; + if (l_legacy_type) + l_verify_size = sizeof(dap_chain_datum_token_old_t) - sizeof(uint16_t); + else { + l_verify_size = l_signs_offset; + l_tmp_auth_signs = l_token->signs_total; + l_token->signs_total = 0; + } + for (size_t i = 0; i < l_signs_unique; i++) { + if (!dap_sign_verify(l_signs[i], l_legacy_type ? a_token : (void *)l_token, l_verify_size)) { + if (l_update_token) { + for (size_t j = 0; j < l_token_item->auth_signs_total; j++) { + if (dap_pkey_compare_with_sign(l_token_item->auth_pkeys[j], l_signs[i])) { + l_signs_approve++; + break; + } + } + } else + l_signs_approve++; + } + } + DAP_DELETE(l_signs); + if (!l_legacy_type) + l_token->signs_total = l_tmp_auth_signs; + size_t l_signs_need = l_update_token ? l_token_item->auth_signs_valid : l_token->signs_total; + if (l_signs_approve < l_signs_need) { + log_it(L_WARNING, "Datum token for ticker '%s' has only %zu valid signatures out of %zu", + l_token->ticker, l_signs_approve, l_signs_need); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS; + } + // Check content & size of enclosed TSD sections + pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); + int ret = s_token_tsd_parse(l_token_item, l_token, a_ledger, l_token->tsd_n_signs, l_size_tsd_section, false); + pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + dap_ledger_hal_item_t *l_hash_found = NULL; + if (ret != DAP_LEDGER_CHECK_OK) { + if (s_hal_items) { + dap_hash_fast_t l_token_hash; + if (!dap_hash_fast_is_blank(&l_token_update_hash)) + l_token_hash = l_token_update_hash; + else + dap_hash_fast(a_token, a_token_size, &l_token_hash); + HASH_FIND(hh, s_hal_items, &l_token_hash, sizeof(dap_hash_fast_t), l_hash_found); + debug_if(s_debug_more && l_hash_found, L_MSG, "Datum %s is whitelisted", dap_hash_fast_to_str_static(&l_token_hash)); + } + if (!l_hash_found) { + DAP_DELETE(l_token); + return ret; + } + } + if (a_token_item) + *a_token_item = l_token_item; + if (a_token_out) + *a_token_out = l_token; + else + DAP_DELETE(l_token); + if (a_tsd_total_size) + *a_tsd_total_size = l_size_tsd_section; + if (a_signs_size) + *a_signs_size = l_signs_size; + return l_hash_found ? DAP_LEDGER_CHECK_WHITELISTED : DAP_LEDGER_CHECK_OK; } -char *dap_ledger_token_decl_add_err_code_to_str(int a_code) { - return (a_code >= DAP_LEDGER_TOKEN_DECL_ADD_OK) && (a_code < DAP_LEDGER_TOKEN_DECL_ADD_UNKNOWN) - ? (char*)s_ledger_token_decl_err_str[(dap_ledger_token_decl_add_err_t)a_code] - : dap_itoa(a_code); +int dap_ledger_token_add_check(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size) +{ + dap_return_val_if_fail(a_ledger && a_token && a_token_size, DAP_LEDGER_CHECK_INVALID_ARGS); + int ret = s_token_add_check(a_ledger, a_token, a_token_size, NULL, NULL, NULL, NULL, NULL); + if (ret == DAP_LEDGER_CHECK_WHITELISTED) + ret = DAP_LEDGER_CHECK_OK; + return ret; } /** @@ -962,14 +1577,235 @@ char *dap_ledger_token_decl_add_err_code_to_str(int a_code) { */ dap_chain_datum_token_t *dap_ledger_token_ticker_check(dap_ledger_t *a_ledger, const char *a_token_ticker) { - if (!a_ledger) { - debug_if(s_debug_more, L_WARNING, "NULL ledger, can't find token ticker"); - return NULL; - } + dap_return_val_if_fail(a_ledger && a_token_ticker, NULL); dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token_ticker); return l_token_item ? l_token_item->datum_token : NULL; } +/** + * @brief update current_supply in token cache + * + * @param a_ledger ledger object + * @param l_token_item token item object + */ +void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_ledger_token_item_t *l_token_item) +{ + if (!PVT(a_ledger)->cached) + return; + char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TOKENS_STR); + size_t l_cache_size = l_token_item->datum_token_size + sizeof(uint256_t); + uint8_t *l_cache = DAP_NEW_STACK_SIZE(uint8_t, l_cache_size); + if ( !l_cache ) { + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + return; + } + memcpy(l_cache, &l_token_item->current_supply, sizeof(uint256_t)); + memcpy(l_cache + sizeof(uint256_t), l_token_item->datum_token, l_token_item->datum_token_size); + if (dap_global_db_set(l_gdb_group, l_token_item->ticker, l_cache, l_cache_size, false, NULL, NULL)) { + char *l_supply = dap_chain_balance_print(l_token_item->current_supply); + log_it(L_WARNING, "Ledger cache mismatch, can't add token [%s] with supply %s", l_token_item->ticker, l_supply); + DAP_DELETE(l_supply); + } + DAP_DELETE(l_gdb_group); +} + +static bool s_ledger_token_supply_check(dap_ledger_token_item_t *a_token_item, uint256_t a_value) +{ + if ((IS_ZERO_256(a_token_item->total_supply) || IS_ZERO_256(a_value))) + return true; + if (compare256(a_token_item->current_supply, a_value) >= 0) + return true; + char *l_supply_str = dap_chain_balance_print(a_token_item->current_supply); + char *l_value_str = dap_chain_balance_print(a_value); + log_it(L_WARNING, "Token current supply %s < emission value %s", l_supply_str, l_value_str); + DAP_DEL_MULTY(l_supply_str, l_value_str); + return false; +} + +static bool s_ledger_token_supply_check_update(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_token_item, uint256_t a_value, bool a_for_removing) +{ + assert(a_token_item); + if ((IS_ZERO_256(a_token_item->total_supply) || IS_ZERO_256(a_value))) + return true; + if (!s_ledger_token_supply_check(a_token_item, a_value) && !a_for_removing) + return false; + int l_overflow = false; + if(a_for_removing) + l_overflow = SUM_256_256(a_token_item->current_supply, a_value, &a_token_item->current_supply); + else + l_overflow = SUBTRACT_256_256(a_token_item->current_supply, a_value, &a_token_item->current_supply); + assert(!l_overflow); + const char *l_balance; dap_uint256_to_char(a_token_item->current_supply, &l_balance); + log_it(L_NOTICE, "New current supply %s for token %s", l_balance, a_token_item->ticker); + s_ledger_token_cache_update(a_ledger, a_token_item); + return true; +} + +/** + * @brief dap_ledger_token_add + * @param a_token + * @param a_token_size + * @return + */ +int dap_ledger_token_add(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size) +{ + dap_return_val_if_fail(a_ledger && a_token && a_token_size, DAP_LEDGER_CHECK_INVALID_ARGS); + dap_ledger_token_item_t *l_token_item = NULL; + dap_chain_datum_token_t *l_token = NULL; + size_t l_tsd_total_size = 0, l_signs_size = 0; + dap_hash_fast_t l_token_update_hash; + int ret = s_token_add_check(a_ledger, a_token, a_token_size, &l_token_item, &l_token, + &l_tsd_total_size, &l_signs_size, &l_token_update_hash); + if (ret != DAP_LEDGER_CHECK_OK && ret != DAP_LEDGER_CHECK_WHITELISTED) + return ret; + + if (!l_token_item) { + assert(l_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_DECL); + l_token_item = DAP_NEW_Z(dap_ledger_token_item_t); + if ( !l_token_item ) { + DAP_DELETE(l_token); + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + } + *l_token_item = (dap_ledger_token_item_t) { + .subtype = l_token->subtype, + .total_supply = l_token->total_supply, + .current_supply = l_token->total_supply, + .auth_signs_total = l_token->signs_total, + .auth_signs_valid = l_token->signs_valid, + .token_emissions_rwlock = PTHREAD_RWLOCK_INITIALIZER, + .token_ts_updated_rwlock = PTHREAD_RWLOCK_INITIALIZER, + .auth_pkeys = DAP_NEW_Z_SIZE(dap_pkey_t*, sizeof(dap_pkey_t*) * l_token->signs_total), + .auth_pkey_hashes = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t, sizeof(dap_chain_hash_fast_t) * l_token->signs_total) + }; + switch (l_token->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: + l_token_item->flags = l_token->header_private_decl.flags; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: + l_token_item->flags = l_token->header_native_decl.flags; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: + l_token_item->flags = l_token->header_public.flags; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: + default:; + } + if ( !l_token_item->auth_pkeys ) { + DAP_DEL_MULTY(l_token, l_token_item); + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + }; + if ( !l_token_item->auth_pkey_hashes ) { + DAP_DEL_MULTY(l_token, l_token_item->auth_pkeys, l_token_item); + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + } + size_t l_auth_signs_total = l_token->signs_total; + dap_sign_t **l_signs = dap_sign_get_unique_signs(l_token->tsd_n_signs + l_tsd_total_size, + l_signs_size, + &l_auth_signs_total); +#define CLEAN_UP DAP_DEL_MULTY(l_token, l_token_item->auth_pkeys, l_token_item->auth_pkey_hashes, l_token_item) + if (!l_signs) { + CLEAN_UP; + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + } + dap_stpcpy((char *)l_token_item->ticker, l_token->ticker); + for (uint16_t k = 0; k < l_token_item->auth_signs_total; k++) { + l_token_item->auth_pkeys[k] = dap_pkey_get_from_sign(l_signs[k]); + if (!l_token_item->auth_pkeys[k]) { + CLEAN_UP; + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + } + dap_pkey_get_hash(l_token_item->auth_pkeys[k], &l_token_item->auth_pkey_hashes[k]); + } +#undef CLEAN_UP + DAP_DELETE(l_signs); + l_token_item->datum_token_size = sizeof(dap_chain_datum_token_t) + l_tsd_total_size + l_signs_size; + l_token_item->datum_token = l_token; + pthread_rwlock_wrlock(&PVT(a_ledger)->tokens_rwlock); + HASH_ADD_STR(PVT(a_ledger)->tokens, ticker, l_token_item); + } else { + assert(l_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE); + pthread_rwlock_wrlock(&PVT(a_ledger)->tokens_rwlock); + dap_ledger_token_update_item_t *l_token_update_item; + pthread_rwlock_wrlock(&l_token_item->token_ts_updated_rwlock); + HASH_FIND(hh, l_token_item->token_ts_updated, &l_token_update_hash, sizeof(dap_hash_fast_t), l_token_update_item); + if (l_token_update_item) { + pthread_rwlock_unlock(&l_token_item->token_ts_updated_rwlock); + pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + log_it(L_ERROR, "Token update with hash %s already exist in token %s hash-table", + dap_hash_fast_to_str_static(&l_token_update_hash), l_token->ticker); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_APPLY_ERROR; + } + l_token_update_item = DAP_NEW(dap_ledger_token_update_item_t); + if (!l_token_update_item) { + pthread_rwlock_unlock(&l_token_item->token_ts_updated_rwlock); + pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + log_it(L_CRITICAL, c_error_memory_alloc); + DAP_DELETE(l_token); + return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + } + *l_token_update_item = (dap_ledger_token_update_item_t) { + .update_token_hash = l_token_update_hash, + .datum_token_update = l_token, + .datum_token_update_size = sizeof(dap_chain_datum_token_t) + l_tsd_total_size + l_signs_size, + .updated_time = dap_time_now() + }; + HASH_ADD(hh, l_token_item->token_ts_updated, update_token_hash, sizeof(dap_chain_hash_fast_t), l_token_update_item); + pthread_rwlock_unlock(&l_token_item->token_ts_updated_rwlock); + l_token_item->last_update_token_time = l_token_update_item->updated_time; + } + if (ret != DAP_LEDGER_CHECK_WHITELISTED) { + ret = s_token_tsd_parse(l_token_item, l_token, a_ledger, l_token->tsd_n_signs, l_tsd_total_size, true); + assert(ret == DAP_LEDGER_CHECK_OK); + } + pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + const char *l_balance_dbg = NULL, *l_declare_update_str = NULL, *l_type_str = NULL; + if (s_debug_more) + dap_uint256_to_char(l_token->total_supply, &l_balance_dbg); + switch (l_token->type) { + case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: l_declare_update_str = "declared"; break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: l_declare_update_str = "updated"; break; + default: assert(false); break; + } + switch (l_token->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: l_type_str = "Simple"; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: l_type_str = "Private"; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: l_type_str = "CF20"; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: l_type_str = "Public"; break; + default: assert(false); break; + } + debug_if(s_debug_more, L_INFO, "%s token %s has been %s, total_supply: %s, signs_valid: %zu, signs_total: %zu", + l_type_str, l_token_item->ticker, l_declare_update_str, + l_balance_dbg, l_token_item->auth_signs_valid, l_token_item->auth_signs_total); + + s_threshold_emissions_proc(a_ledger); /* TODO process thresholds only for no-consensus chains */ + s_ledger_token_cache_update(a_ledger, l_token_item); + return ret; +} + +int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size) +{ + if (dap_chain_net_get_load_mode(a_ledger->net)) { + const char *l_ticker = NULL; + switch (*(uint16_t *)a_token) { + case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: + l_ticker = ((dap_chain_datum_token_t *)a_token)->ticker; + break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE: + case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PUBLIC: + case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_DECL: + case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL: + l_ticker = ((dap_chain_datum_token_old_t *)a_token)->ticker; + break; + } + if (l_ticker && s_ledger_find_token(a_ledger, l_ticker)) + return DAP_LEDGER_CHECK_OK; + } + return dap_ledger_token_add(a_ledger, a_token, a_token_size); +} + /** * @brief s_tx_header_print * prepare data for print, add time @@ -1098,877 +1934,58 @@ static void s_dump_datum_tx_for_addr(dap_ledger_tx_item_t *a_item, bool a_unspen const char *l_dst_addr_str = l_dst_addr ? dap_chain_addr_to_str(l_dst_addr) : dap_chain_tx_out_cond_subtype_to_str( ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.subtype); - json_object_object_add(l_json_obj_datum, "send", json_object_new_string(dap_uint256_to_char(l_value, NULL))); - json_object_object_add(l_json_obj_datum, "to addr", json_object_new_string(l_dst_addr_str)); - json_object_object_add(l_json_obj_datum, "token", l_src_token ? json_object_new_string(l_src_token) : json_object_new_string("UNKNOWN")); - json_object_array_add(json_arr_out, l_json_obj_datum); - } - if (l_dst_addr && !memcmp(l_dst_addr, a_addr, sizeof(dap_chain_addr_t))) { - json_object * l_json_obj_datum = json_object_new_object(); - if (!l_header_printed) { - s_tx_header_print(l_json_obj_datum, l_tx, a_hash_out_type, l_tx_hash); - l_header_printed = true; - } - const char *l_dst_token = (l_type == TX_ITEM_TYPE_OUT_EXT) ? - (const char *)(((dap_chain_tx_out_ext_t *)l_list_out->data)->token) : NULL; - const char *l_src_addr_str = l_base_tx ? "emission" - : (l_src_addr ? dap_chain_addr_to_str(l_src_addr) - : dap_chain_tx_out_cond_subtype_to_str( - l_src_subtype)); - json_object_object_add(l_json_obj_datum, "recv ", json_object_new_string(dap_uint256_to_char(l_value, NULL))); - json_object_object_add(l_json_obj_datum, "token ", l_dst_token ? json_object_new_string(l_dst_token) : - (l_src_token ? json_object_new_string(l_src_token) : json_object_new_string("UNKNOWN"))); - json_object_object_add(l_json_obj_datum, "from ", json_object_new_string(l_src_addr_str)); - json_object_array_add(json_arr_out, l_json_obj_datum); - } - } - dap_list_free(l_list_out_items); -} - -json_object *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only) -{ - json_object * json_arr_out = json_object_new_array(); - if (!json_arr_out) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return NULL; - } - - //dap_chain_tx_hash_processed_ht_t *l_tx_data_ht = NULL; - dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp; - dap_ledger_private_t * l_ledger_pvt = PVT(a_ledger); - - pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); - //unsigned test = dap_ledger_count(a_ledger); - HASH_ITER(hh, l_ledger_pvt->ledger_items, l_tx_item, l_tx_tmp) { - s_dump_datum_tx_for_addr(l_tx_item, a_unspent_only, a_ledger, a_addr, a_hash_out_type, json_arr_out); - } - pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); - - // if no history - if(!json_arr_out) - { - json_object * json_obj_addr = json_object_new_object(); - json_object_object_add(json_obj_addr, "status:", json_object_new_string("empty")); - json_object_array_add(json_arr_out, json_obj_addr); - } - return json_arr_out; -} - -/** - * @brief update current_supply in token cache - * - * @param a_ledger ledger object - * @param l_token_item token item object - */ -void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_ledger_token_item_t *l_token_item) -{ - if (!PVT(a_ledger)->cached) - return; - char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TOKENS_STR); - size_t l_cache_size = l_token_item->datum_token_size + sizeof(uint256_t); - uint8_t *l_cache = DAP_NEW_STACK_SIZE(uint8_t, l_cache_size); - if ( !l_cache ) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return; - } - memcpy(l_cache, &l_token_item->current_supply, sizeof(uint256_t)); - memcpy(l_cache + sizeof(uint256_t), l_token_item->datum_token, l_token_item->datum_token_size); - if (dap_global_db_set(l_gdb_group, l_token_item->ticker, l_cache, l_cache_size, false, NULL, NULL)) { - char *l_supply = dap_chain_balance_print(l_token_item->current_supply); - log_it(L_WARNING, "Ledger cache mismatch, can't add token [%s] with supply %s", l_token_item->ticker, l_supply); - DAP_DELETE(l_supply); - } - DAP_DELETE(l_gdb_group); -} - -static bool s_ledger_token_supply_check_unsafe(dap_ledger_token_item_t *a_token_item, uint256_t a_value) -{ - if (compare256(a_token_item->current_supply, a_value) >= 0) - return true; - char *l_supply_str = dap_chain_balance_print(a_token_item->current_supply); - char *l_value_str = dap_chain_balance_print(a_value); - log_it(L_WARNING, "Token current supply %s < emission value %s", l_supply_str, l_value_str); - DAP_DEL_MULTY(l_supply_str, l_value_str); - return false; -} - -static bool s_ledger_token_supply_check(dap_ledger_token_item_t *a_token_item, uint256_t a_value) -{ - assert(a_token_item); - if (IS_ZERO_256(a_token_item->total_supply) || IS_ZERO_256(a_value)) - return true; - return s_ledger_token_supply_check_unsafe(a_token_item, a_value); -} - -static bool s_ledger_token_supply_check_update(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_token_item, uint256_t a_value, bool a_for_removing) -{ - assert(a_token_item); - if ((IS_ZERO_256(a_token_item->total_supply) || IS_ZERO_256(a_value))) - return true; - if (!s_ledger_token_supply_check_unsafe(a_token_item, a_value) && !a_for_removing) - return false; - int l_overflow = false; - if(a_for_removing) - l_overflow = SUM_256_256(a_token_item->current_supply, a_value, &a_token_item->current_supply); - else - l_overflow = SUBTRACT_256_256(a_token_item->current_supply, a_value, &a_token_item->current_supply); - assert(!l_overflow); - const char *l_balance; dap_uint256_to_char(a_token_item->current_supply, &l_balance); - log_it(L_NOTICE, "New current supply %s for token %s", l_balance, a_token_item->ticker); - s_ledger_token_cache_update(a_ledger, a_token_item); - return true; -} - - -/** - * @brief s_ledger_update_token_add_in_hash_table - * @param a_cur_token_item - * @param a_token_update - * @param a_token_update_size - * @return true or false - */ -static bool s_ledger_update_token_add_in_hash_table(dap_ledger_token_item_t *a_cur_token_item, dap_chain_datum_token_t *a_token_update, size_t a_token_update_size) -{ - dap_ledger_token_update_item_t *l_token_update_item; - dap_hash_fast_t l_hash_token_update; - bool new_item = false; - - dap_hash_fast(a_token_update, a_token_update_size, &l_hash_token_update); - pthread_rwlock_rdlock(&a_cur_token_item->token_ts_updated_rwlock); - HASH_FIND(hh, a_cur_token_item->token_ts_updated, &l_hash_token_update, sizeof(dap_hash_fast_t), - l_token_update_item); - pthread_rwlock_unlock(&a_cur_token_item->token_ts_updated_rwlock); - if (l_token_update_item - && a_cur_token_item->last_update_token_time == l_token_update_item->updated_time) { - if (s_debug_more) - log_it(L_WARNING, "Error: item 'dap_ledger_token_update_item_t' already exist in hash-table"); - return false; - } else if (!l_token_update_item){ - new_item = true; - l_token_update_item = DAP_NEW(dap_ledger_token_update_item_t); - if (!l_token_update_item) { - if (s_debug_more) - log_it(L_ERROR, "Error: memory allocation when try adding item 'dap_ledger_token_update_item_t' to hash-table"); - return false; - } - *l_token_update_item = (dap_ledger_token_update_item_t) { - .update_token_hash = l_hash_token_update, - .datum_token_update = a_token_update, - .datum_token_update_size = a_token_update_size - }; - } - - l_token_update_item->updated_time = dap_time_now(); - - if (new_item) { - pthread_rwlock_wrlock(&a_cur_token_item->token_ts_updated_rwlock); - HASH_ADD(hh, a_cur_token_item->token_ts_updated, update_token_hash, sizeof(dap_chain_hash_fast_t), l_token_update_item); - pthread_rwlock_unlock(&a_cur_token_item->token_ts_updated_rwlock); - } - - if (!l_token_update_item) { - if (s_debug_more) - log_it(L_ERROR, "Error: adding to hash-table. Be careful, there may be leaks"); - return false; - } - - a_cur_token_item->last_update_token_time = l_token_update_item->updated_time; - - return true; -} - -/** - * @brief dap_ledger_token_add - * @param a_token - * @param a_token_size - * @return - */ -int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size) -{ - if (!a_ledger || !a_token) { - debug_if(s_debug_more, L_ERROR, "NULL ledger, can't add datum with token declaration!"); - return -1; - } - - dap_chain_datum_token_t *l_token = a_token; - dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token->ticker); - if (l_token_item) { - if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE - && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE - && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE) { - log_it(L_ERROR, "Duplicate token declaration for ticker '%s'", l_token->ticker); - DAP_DELETE(l_token); - return -3; - } - if (s_ledger_token_update_check(l_token_item, l_token, a_token_size)) { - if (!s_ledger_update_token_add_in_hash_table(l_token_item, l_token, a_token_size)) { - log_it(L_ERROR, "Failed to update token with ticker '%s' in ledger", l_token->ticker); - DAP_DELETE(l_token); - return -5; - } - if (!IS_ZERO_256(l_token->total_supply)) { - SUBTRACT_256_256(l_token_item->total_supply, l_token_item->current_supply, &l_token_item->current_supply); - SUBTRACT_256_256(l_token->total_supply, l_token_item->current_supply, &l_token_item->current_supply); - } else { - l_token_item->current_supply = l_token->total_supply; - } - l_token_item->total_supply = l_token->total_supply; - DAP_DELETE(l_token_item->datum_token); - } else { - log_it(L_ERROR, "Token with ticker '%s' update check failed", l_token->ticker); - DAP_DELETE(l_token); - return -2; - } - } else if (l_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) { - log_it(L_WARNING, "Token with ticker '%s' does not yet exist, declare it first", l_token->ticker); - DAP_DELETE(l_token); - return -6; - } - - if (!l_token_item) { - size_t l_auth_signs_total, l_auth_signs_valid; - dap_sign_t **l_signs = dap_chain_datum_token_signs_parse(l_token, a_token_size, &l_auth_signs_total, &l_auth_signs_valid); - if (!l_signs || !l_auth_signs_total) { - log_it(L_ERROR, "No auth signs in token '%s' datum!", l_token->ticker); - DAP_DELETE(l_token); - return -7; - } - l_token_item = DAP_NEW_Z(dap_ledger_token_item_t); - if ( !l_token_item ) { - DAP_DELETE(l_token); - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return -8; - } - *l_token_item = (dap_ledger_token_item_t) { - .version = l_token->version, - .type = l_token->type, - .subtype = l_token->subtype, - .total_supply = l_token->total_supply, - .current_supply = l_token->total_supply, - .token_emissions_rwlock = PTHREAD_RWLOCK_INITIALIZER, - .token_ts_updated_rwlock = PTHREAD_RWLOCK_INITIALIZER, - .auth_pkeys = DAP_NEW_Z_SIZE(dap_pkey_t*, sizeof(dap_pkey_t*) * l_token->signs_total), - .auth_pkeys_hash = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t, sizeof(dap_chain_hash_fast_t) * l_token->signs_total), - .auth_signs_total = l_auth_signs_total, - .auth_signs_valid = l_auth_signs_valid, - .description_token_size = 0 - }; - if ( !l_token_item->auth_pkeys ) { - DAP_DELETE(l_token); - DAP_DELETE(l_token_item); - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return -6; - }; - if ( !l_token_item->auth_pkeys ) { - DAP_DELETE(l_token); - DAP_DEL_Z(l_token_item->auth_pkeys); - DAP_DELETE(l_token_item); - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return -6; - } - dap_stpcpy(l_token_item->ticker, l_token->ticker); - for (uint16_t k = 0; k < l_token_item->auth_signs_total; k++) { - l_token_item->auth_pkeys[k] = dap_pkey_get_from_sign(l_signs[k]); - dap_pkey_get_hash(l_token_item->auth_pkeys[k], &l_token_item->auth_pkeys_hash[k]); - } - DAP_DELETE(l_signs); - } - - - l_token_item->datum_token_size = a_token_size; - l_token_item->datum_token = l_token; - l_token_item->datum_token->type = l_token->type; - - if(l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE - && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE - && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE) { - pthread_rwlock_wrlock(&PVT(a_ledger)->tokens_rwlock); - HASH_ADD_STR(PVT(a_ledger)->tokens, ticker, l_token_item); - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - } - int l_res_token_tsd_parse = 0; - - const char *l_balance_dbg = NULL; - if (s_debug_more) - dap_uint256_to_char(l_token->total_supply, &l_balance_dbg); - -#define CLEAN_UP DAP_DEL_MULTY(l_token, l_token_item->auth_pkeys, l_token_item->auth_pkeys_hash, l_token_item) - - switch (l_token->type) { - case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: - switch (l_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: - debug_if(s_debug_more, L_INFO, "Simple token %s declared, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", - l_token->ticker, l_balance_dbg, - l_token->signs_valid, l_token->signs_total); - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: - debug_if(s_debug_more, L_INFO, "Private token %s declared, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", - l_token->ticker, l_balance_dbg, - l_token->signs_valid, l_token->signs_total); - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size); - s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size); - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - debug_if(s_debug_more, L_INFO, "CF20 token %s declared, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", - l_token->ticker, l_balance_dbg, - l_token->signs_valid, l_token->signs_total); - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size); - s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size); - break; - default: - /* Bogdanoff, unknown token subtype declaration. What shall we TODO? */ - debug_if(s_debug_more, L_ERROR, "Unknown token subtype '0x%04X' declaration! Ticker: %s, total_supply: %s, total_signs_valid: %hu, signs_total: %hu" - "Dump it!", - l_token->type, l_token->ticker, l_balance_dbg, - l_token->signs_valid, l_token->signs_total); - /* Dump it right now */ - CLEAN_UP; - return -8; - } break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: - switch (l_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: - debug_if(s_debug_more, L_INFO, "Simple token %s updated, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", - l_token->ticker, l_balance_dbg, - l_token->signs_valid, l_token->signs_total); - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: - debug_if(s_debug_more, L_INFO, "Private token %s updated, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", - l_token->ticker, l_balance_dbg, - l_token->signs_valid, l_token->signs_total); - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size); - s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size); - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - debug_if(s_debug_more, L_INFO, "CF20 token %s updated, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", - l_token->ticker, l_balance_dbg, - l_token->signs_valid, l_token->signs_total); - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size); - s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size); - break; - default: - /* Bogdanoff, unknown token type update. What shall we TODO? */ - debug_if(s_debug_more, L_ERROR, "Unknown token subtype '0x%04X' update! Ticker: %s, total_supply: %s, total_signs_valid: %hu, signs_total: %hu" - "Dump it!", - l_token->type, l_token->ticker, l_balance_dbg, - l_token->signs_valid, l_token->signs_total); - /* Dump it right now */ - CLEAN_UP; - return -8; - } break; - default: - debug_if(s_debug_more, L_ERROR, "Unknown token type 0x%04X, Dump it!", l_token->type); - CLEAN_UP; - return -8; - } - if (l_res_token_tsd_parse) { - debug_if(s_debug_more, L_ERROR, "Can't parse tsd section for %s token, code error: %i", l_token->ticker, l_res_token_tsd_parse); - CLEAN_UP; - return -1; - } -#undef CLEAN_UP - s_threshold_emissions_proc(a_ledger); /* TODO process thresholds only for no-consensus chains */ - s_ledger_token_cache_update(a_ledger, l_token_item); - return 0; -} - -/** - * @brief s_token_tsd_parse - * - * @param a_ledger - * @param a_token_item - * @param a_token - * @param a_token_size - * @return int - */ -static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size) -{ - UNUSED(a_ledger); - 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; - a_token_item->flags = a_token->header_native_decl.flags; - - 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) { - // set flags - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS:{ - uint16_t l_flags = 0; - a_token_item->flags |= _dap_tsd_get_scalar(l_tsd, &l_flags); - }break; - - // unset flags - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS:{ - uint16_t l_flags = 0; - a_token_item->flags &= ~_dap_tsd_get_scalar(l_tsd, &l_flags); - }break; - - // set total supply - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY:{ // 256 - a_token_item->total_supply = uint256_0; - _dap_tsd_get_scalar(l_tsd, &a_token_item->total_supply); - }break; - - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_OLD:{ // 128 - uint128_t l_total_supply128 = uint128_0; - a_token_item->total_supply = GET_256_FROM_128(_dap_tsd_get_scalar(l_tsd,&l_total_supply128)); - }break; - - // Set total signs count value to set to be valid - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID:{ - uint16_t l_signs_valid = 0; - a_token_item->auth_signs_valid = _dap_tsd_get_scalar(l_tsd, &l_signs_valid); - }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) ){ - a_token_item->tx_recv_allow = a_token_item->tx_recv_allow - ? DAP_REALLOC(a_token_item->tx_recv_allow, (a_token_item->tx_recv_allow_size + 1) * sizeof(*a_token_item->tx_recv_allow)) - : DAP_NEW_Z_SIZE(dap_chain_addr_t,sizeof(*a_token_item->tx_recv_allow)); - - // Check if its correct - dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - if (dap_chain_addr_check_sum(l_add_addr)) { - debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD"); - return -12; - } - // Check if its already present - if (a_token_item->tx_recv_allow) { - for( size_t i=0; i < a_token_item->tx_recv_allow_size; i++){ // Check for all the list - if ( memcmp(&a_token_item->tx_recv_allow[i], l_tsd->data, l_tsd->size) == 0 ){ // Found - debug_if(s_debug_more, L_ERROR, - "TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD has address %s thats already present in list", - dap_chain_addr_to_str((dap_chain_addr_t*) l_tsd->data )); - DAP_DEL_Z(a_token_item->tx_recv_allow); - return -11; - } - } - if(a_token_item->tx_recv_allow){ - a_token_item->tx_recv_allow[a_token_item->tx_recv_allow_size] = *(dap_chain_addr_t*)l_tsd->data; - a_token_item->tx_recv_allow_size++; - } - - }else{ - log_it(L_ERROR,"Out of memory! Can't extend TX_RECEIVER_ALLOWED array"); - return -20; - } - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD expected to have %zu bytes data length, not %u", - sizeof (dap_chain_addr_t), l_tsd->size ); - return -10; - } - }break; - - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE:{ - if( l_tsd->size == sizeof (dap_chain_addr_t) ){ - // Check if its correct - dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - if (dap_chain_addr_check_sum(l_add_addr)) { - debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE"); - return -12; - } - bool l_was_found=false; - for( size_t i=0; i < a_token_item->tx_recv_allow_size; i++){ // Check for all the list - if ( memcmp(&a_token_item->tx_recv_allow[i], l_tsd->data, l_tsd->size) == 0 ){ // Found - if( i +1 != a_token_item->tx_recv_allow_size ) - memmove(&a_token_item->tx_recv_allow[i],&a_token_item->tx_recv_allow[i+1], - sizeof(*a_token_item->tx_recv_allow)*(a_token_item->tx_recv_allow_size-i-1 ) ); - a_token_item->tx_recv_allow_size--; - l_was_found = true; - break; - } - } - // TODO - UNUSED(l_was_found); - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE expected to have %zu bytes data length, not %u", - sizeof (dap_chain_addr_t), l_tsd->size ); - return -10; - } - }break; - - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_CLEAR:{ - if( l_tsd->size == 0 ){ - if( a_token_item->tx_recv_allow ) - DAP_DEL_Z(a_token_item->tx_recv_allow); - a_token_item->tx_recv_allow_size = 0; - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_CLEAR expected to have 0 bytes data length, not %u", - l_tsd->size ); - return -10; - } - }break; - - - //Blocked tx receiver addres list add, remove or clear - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD:{ - if( l_tsd->size == sizeof (dap_chain_addr_t) ){ - dap_chain_addr_t * l_addrs = a_token_item->tx_recv_block - ? DAP_NEW_Z_SIZE(dap_chain_addr_t, sizeof(*a_token_item->tx_recv_block)) - : DAP_REALLOC(a_token_item->tx_recv_block, - (a_token_item->tx_recv_block_size + 1) * sizeof(*a_token_item->tx_recv_block)); - // Check if its correct - dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - if (dap_chain_addr_check_sum(l_add_addr)) { - DAP_DEL_Z(l_addrs); - debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD"); - return -12; - } - // Check if its already present - if(a_token_item->tx_recv_block) - for( size_t i=0; i < a_token_item->tx_recv_block_size; i++){ // Check for all the list - if ( memcmp(&a_token_item->tx_recv_block[i], l_tsd->data, l_tsd->size) == 0 ){ // Found - debug_if(s_debug_more, L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD has address %s thats already present in list", - dap_chain_addr_to_str((dap_chain_addr_t*) l_tsd->data )); - DAP_DELETE(l_addrs); - DAP_DEL_Z(a_token_item->tx_recv_allow); - return -11; - } - } - - if(l_addrs) { - l_addrs[a_token_item->tx_recv_block_size] = *(dap_chain_addr_t*)l_tsd->data; - a_token_item->tx_recv_block_size++; - a_token_item->tx_recv_block = l_addrs; - - } else { - log_it(L_ERROR,"Out of memory! Can't extend TX_RECEIVER_BLOCKED array"); - } - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD expected to have %zu bytes data length, not %u", - sizeof (dap_chain_addr_t), l_tsd->size ); - return -10; - } - }break; - - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE:{ - if( l_tsd->size == sizeof (dap_chain_addr_t) ){ - // Check if its correct - dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - if (dap_chain_addr_check_sum(l_add_addr)) { - debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE"); - return -12; - } - bool l_was_found=false; - for( size_t i=0; i < a_token_item->tx_recv_block_size; i++){ // Check for all the list - if ( memcmp(&a_token_item->tx_recv_block[i], l_tsd->data, l_tsd->size) == 0 ){ // Found - if( i +1 != a_token_item->tx_recv_block_size ) - memmove(&a_token_item->tx_recv_block[i],&a_token_item->tx_recv_block[i+1], - sizeof(*a_token_item->tx_recv_block)*(a_token_item->tx_recv_block_size-i-1 ) ); - a_token_item->tx_recv_block_size--; - l_was_found = true; - break; - } - } - // TODO - UNUSED(l_was_found); - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE expected to have %zu bytes data length, not %u", - sizeof (dap_chain_addr_t), l_tsd->size ); - return -10; - } - }break; - - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_CLEAR:{ - if( l_tsd->size == 0 ){ - if( a_token_item->tx_recv_block ) - DAP_DEL_Z(a_token_item->tx_recv_block); - a_token_item->tx_recv_block_size = 0; - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_CLEAR expected to have 0 bytes data length, not %u", - l_tsd->size ); - return -10; - } - }break; - - //Allowed tx sender addres list add, remove or clear - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD:{ - if( l_tsd->size == sizeof (dap_chain_addr_t) ){ - dap_chain_addr_t * l_addrs = a_token_item->tx_send_allow ? DAP_NEW_Z_SIZE( dap_chain_addr_t, - sizeof(*a_token_item->tx_send_allow) ) - : DAP_REALLOC(a_token_item->tx_send_allow,(a_token_item->tx_send_allow_size+1)*sizeof (*a_token_item->tx_send_allow) ); - // Check if its correct - dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - if (dap_chain_addr_check_sum(l_add_addr)) { - DAP_DEL_Z(l_addrs); - debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD"); - return -12; - } - // Check if its already present - for( size_t i=0; i < a_token_item->tx_send_allow_size; i++){ // Check for all the list - if ( memcmp(&a_token_item->tx_send_allow[i], l_tsd->data, l_tsd->size) == 0 ){ // Found - debug_if(s_debug_more, L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD has address %s thats already present in list", - dap_chain_addr_to_str((dap_chain_addr_t*) l_tsd->data )); - DAP_DELETE(l_addrs); - return -11; - } - } - if(l_addrs) { - l_addrs[a_token_item->tx_send_allow_size] = *(dap_chain_addr_t*)l_tsd->data; - a_token_item->tx_send_allow_size++; - a_token_item->tx_send_allow = l_addrs; - - } else { - log_it(L_ERROR,"Out of memory! Can't extend TX_SENDER_ALLOWED array"); - } - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD expected to have %zu bytes data length, not %u", - sizeof (dap_chain_addr_t), l_tsd->size ); - } - }break; - - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE:{ - if( l_tsd->size == sizeof (dap_chain_addr_t) ){ - // Check if its correct - dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - if (dap_chain_addr_check_sum(l_add_addr)) { - debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE"); - return -12; - } - bool l_was_found=false; - for( size_t i=0; i < a_token_item->tx_send_allow_size; i++){ // Check for all the list - if ( memcmp(&a_token_item->tx_send_allow[i], l_tsd->data, l_tsd->size) == 0 ){ // Found - if( i +1 != a_token_item->tx_send_allow_size ) - memmove(&a_token_item->tx_send_allow[i],&a_token_item->tx_send_allow[i+1], - sizeof(*a_token_item->tx_send_allow)*(a_token_item->tx_send_allow_size-i-1 ) ); - a_token_item->tx_send_allow_size--; - l_was_found = true; - break; - } - } - // TODO - UNUSED(l_was_found); - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE expected to have %zu bytes data length, not %u", - sizeof (dap_chain_addr_t), l_tsd->size ); - return -10; - } - }break; - - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_CLEAR:{ - if( l_tsd->size == 0 ){ - if( a_token_item->tx_send_allow ) - DAP_DEL_Z(a_token_item->tx_send_allow); - a_token_item->tx_send_allow_size = 0; - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_CLEAR expected to have 0 bytes data length, not %u", - l_tsd->size ); - return -10; - } - }break; - - - //Blocked tx sender addres list add, remove or clear - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD:{ - if( l_tsd->size == sizeof (dap_chain_addr_t) ){ - dap_chain_addr_t *l_addrs = a_token_item->tx_send_block - ? DAP_NEW_Z_SIZE(dap_chain_addr_t, sizeof(*a_token_item->tx_send_block)) - : DAP_REALLOC(a_token_item->tx_send_block, (a_token_item->tx_send_block_size + 1) * sizeof(*a_token_item->tx_send_block)); - // Check if its correct - dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - if (dap_chain_addr_check_sum(l_add_addr)) { - DAP_DEL_Z(l_addrs); - debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD"); - return -12; - } - // Check if its already present - for( size_t i=0; i < a_token_item->tx_send_block_size; i++){ // Check for all the list - if ( memcmp(&a_token_item->tx_send_block[i], l_tsd->data, l_tsd->size) == 0 ){ // Found - debug_if(s_debug_more, L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD has address %s thats already present in list", - dap_chain_addr_to_str((dap_chain_addr_t*) l_tsd->data )); - DAP_DELETE(l_addrs); - return -11; - } - } - if(l_addrs) { - l_addrs[a_token_item->tx_send_block_size] = *(dap_chain_addr_t*)l_tsd->data; - a_token_item->tx_send_block_size++; - a_token_item->tx_send_block = l_addrs; - - } else { - log_it(L_ERROR,"Out of memory! Can't extend TX_SENDER_BLOCKED array"); - } - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD expected to have %zu bytes data length, not %u", - sizeof (dap_chain_addr_t), l_tsd->size ); - } - }break; - - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE:{ - if( l_tsd->size == sizeof (dap_chain_addr_t) ){ - // Check if its correct - dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - if (dap_chain_addr_check_sum(l_add_addr)) { - debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE"); - return -12; - } - bool l_was_found=false; - for( size_t i=0; i < a_token_item->tx_send_block_size; i++){ // Check for all the list - if ( memcmp(&a_token_item->tx_send_block[i], l_tsd->data, l_tsd->size) == 0 ){ // Found - if( i +1 != a_token_item->tx_send_block_size ) - memmove(&a_token_item->tx_send_block[i],&a_token_item->tx_send_block[i+1], - sizeof(*a_token_item->tx_send_block)*(a_token_item->tx_send_block_size-i-1 ) ); - a_token_item->tx_send_block_size--; - l_was_found = true; - break; - } - } - // TODO - UNUSED(l_was_found); - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE expected to have %zu bytes data length, not %u", - sizeof (dap_chain_addr_t), l_tsd->size ); - return -10; - } - }break; - - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_CLEAR:{ - if( l_tsd->size == 0 ){ - if( a_token_item->tx_send_block ) - DAP_DEL_Z(a_token_item->tx_send_block); - a_token_item->tx_send_block_size = 0; - }else{ - if(s_debug_more) - log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_CLEAR expected to have 0 bytes data length, not %u", - l_tsd->size ); - return -10; - } - }break; - case DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION: { - if (l_tsd->size == 0){ - if (s_debug_more) - log_it(L_ERROR, "TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION expected to " - "have 0 bytes data length"); - return -10; - } - if (a_token_item->description_token_size != 0) - DAP_DELETE(a_token_item->description_token); - a_token_item->description_token_size = l_tsd->size; - a_token_item->description_token = DAP_NEW_Z_SIZE(char, l_tsd->size); - memcpy(a_token_item->description_token, l_tsd->data, l_tsd->size); - } break; - default:{} - } - } - return 0; -} - -static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_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; + json_object_object_add(l_json_obj_datum, "send", json_object_new_string(dap_uint256_to_char(l_value, NULL))); + json_object_object_add(l_json_obj_datum, "to addr", json_object_new_string(l_dst_addr_str)); + json_object_object_add(l_json_obj_datum, "token", l_src_token ? json_object_new_string(l_src_token) : json_object_new_string("UNKNOWN")); + json_object_array_add(json_arr_out, l_json_obj_datum); } - } - 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, &l_hash); - 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; + if (l_dst_addr && !memcmp(l_dst_addr, a_addr, sizeof(dap_chain_addr_t))) { + json_object * l_json_obj_datum = json_object_new_object(); + if (!l_header_printed) { + s_tx_header_print(l_json_obj_datum, l_tx, a_hash_out_type, l_tx_hash); + l_header_printed = true; } + const char *l_dst_token = (l_type == TX_ITEM_TYPE_OUT_EXT) ? + (const char *)(((dap_chain_tx_out_ext_t *)l_list_out->data)->token) : NULL; + const char *l_src_addr_str = l_base_tx ? "emission" + : (l_src_addr ? dap_chain_addr_to_str(l_src_addr) + : dap_chain_tx_out_cond_subtype_to_str( + l_src_subtype)); + json_object_object_add(l_json_obj_datum, "recv ", json_object_new_string(dap_uint256_to_char(l_value, NULL))); + json_object_object_add(l_json_obj_datum, "token ", l_dst_token ? json_object_new_string(l_dst_token) : + (l_src_token ? json_object_new_string(l_src_token) : json_object_new_string("UNKNOWN"))); + json_object_object_add(l_json_obj_datum, "from ", json_object_new_string(l_src_addr_str)); + json_object_array_add(json_arr_out, l_json_obj_datum); } } - 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) { - uint16_t l_tmp = 0; - a_token_item->auth_signs_valid = _dap_tsd_get_scalar(l_new_signs_valid, &l_tmp); - } - - if (l_added_pkeys) dap_list_free(l_added_pkeys); - if (l_remove_pkeys) dap_list_free(l_remove_pkeys); - return 0; + dap_list_free(l_list_out_items); } -int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size) +json_object *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only) { - dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(a_token, &a_token_size); + json_object * json_arr_out = json_object_new_array(); + if (!json_arr_out) { + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + return NULL; + } - if (dap_chain_net_get_load_mode(a_ledger->net)) { - dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token->ticker); - if (l_token_item - && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE - && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE - && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE) { - DAP_DELETE(l_token); - return 0; - } + dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp; + dap_ledger_private_t * l_ledger_pvt = PVT(a_ledger); + + pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); + HASH_ITER(hh, l_ledger_pvt->ledger_items, l_tx_item, l_tx_tmp) { + s_dump_datum_tx_for_addr(l_tx_item, a_unspent_only, a_ledger, a_addr, a_hash_out_type, json_arr_out); + } + pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); + + // if no history + if(!json_arr_out) + { + json_object * json_obj_addr = json_object_new_object(); + json_object_object_add(json_obj_addr, "status:", json_object_new_string("empty")); + json_object_array_add(json_arr_out, json_obj_addr); } - return dap_ledger_token_add(a_ledger, l_token, a_token_size); + return json_arr_out; } json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger, size_t a_limit, size_t a_offset) @@ -2165,45 +2182,31 @@ json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger, size_t a_limit, siz } /** - * @breif dap_ledger_token_auth_signs_valid + * @breif dap_ledger_token_get_auth_signs_valid * @param a_ledger * @param a_token_ticker * @return 0 if no ticker found */ -size_t dap_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker) +size_t dap_ledger_token_get_auth_signs_valid(dap_ledger_t *a_ledger, const char *a_token_ticker) { - dap_ledger_token_item_t *l_token_item, *l_tmp_item; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - size_t l_res = 0; - HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { - if (!dap_strcmp(l_token_item->ticker, a_token_ticker)) { - l_res = l_token_item->auth_signs_valid; - break; - } - } - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - return l_res; + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token_ticker); + if (!l_token_item) + return 0; + return l_token_item->auth_signs_valid; } /** - * @breif dap_ledger_token_auth_signs_total + * @breif dap_ledger_token_get_auth_signs_total * @param a_ledger * @param a_token_ticker * @return */ -size_t dap_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker) +size_t dap_ledger_token_get_auth_signs_total(dap_ledger_t *a_ledger, const char *a_token_ticker) { - dap_ledger_token_item_t *l_token_item, *l_tmp_item; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - size_t l_res = 0; - HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { - if (!dap_strcmp(l_token_item->ticker, a_token_ticker)) { - l_res = l_token_item->auth_signs_total; - break; - } - } - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - return l_res; + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token_ticker); + if (!l_token_item) + return 0; + return l_token_item->auth_signs_total; } /** @@ -2212,96 +2215,65 @@ size_t dap_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_ * @param a_token_ticker * @return */ -dap_list_t * dap_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker) +dap_list_t *dap_ledger_token_get_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char *a_token_ticker) { - dap_list_t * l_ret = NULL; - dap_ledger_token_item_t *l_token_item, *l_tmp_item; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { - 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_pkeys_hash[i])); - } - break; - } - } - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + dap_list_t *l_ret = NULL; + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token_ticker); + if (!l_token_item) + return l_ret; + 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, l_token_item->auth_pkey_hashes + i); return l_ret; } -json_object *s_token_item_to_json(dap_ledger_token_item_t *a_token_item) { +uint256_t dap_ledger_token_get_emission_rate(dap_ledger_t *a_ledger, const char *a_token_ticker) +{ + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token_ticker); + if (!l_token_item || !l_token_item->is_delegated) + return uint256_0; + return l_token_item->emission_rate; +} + +json_object *s_token_item_to_json(dap_ledger_token_item_t *a_token_item) +{ json_object *json_obj_datum = json_object_new_object(); - const char *l_type_str; - switch (a_token_item->type) { - case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: { - switch (a_token_item->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: - l_type_str = "SIMPLE"; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: - l_type_str = "PRIVATE"; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - l_type_str = "CF20"; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: - l_type_str = "PUBLIC"; break; - default: l_type_str = "UNKNOWN"; break; - } - }break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: { - switch (a_token_item->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: - l_type_str = "SIMPLE"; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: - l_type_str = "PRIVATE_UPDATE"; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - l_type_str = "CF20_UPDATE"; break; - default: l_type_str = "UNKNOWN"; break; - } - } break; - default: - l_type_str = "UNKNOWN"; break; - } - if ((a_token_item->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE) - || (a_token_item->type != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC)) { - char *l_balance_cur = dap_chain_balance_print(a_token_item->current_supply); - char *l_balance_total = dap_chain_balance_print(a_token_item->total_supply); - json_object_object_add(json_obj_datum, "-->Token name", json_object_new_string(a_token_item->ticker)); - json_object_object_add(json_obj_datum, "type", json_object_new_string(l_type_str)); + const char *l_type_str = NULL; + switch (a_token_item->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: + l_type_str = "SIMPLE"; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: + l_type_str = "PRIVATE"; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: + l_type_str = "CF20"; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: + l_type_str = "PUBLIC"; break; + default: l_type_str = "UNKNOWN"; break; + } + json_object_object_add(json_obj_datum, "-->Token name", json_object_new_string(a_token_item->ticker)); + json_object_object_add(json_obj_datum, "type", json_object_new_string(l_type_str)); + if (a_token_item->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE && a_token_item->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC) { json_object_object_add(json_obj_datum, "flags", json_object_new_string(s_flag_str_from_code(a_token_item->datum_token->header_native_decl.flags))); - json_object_object_add(json_obj_datum, "description", a_token_item->description_token_size != 0 ? - json_object_new_string(a_token_item->description_token) : + json_object_object_add(json_obj_datum, "description", a_token_item->description ? + json_object_new_string(a_token_item->description) : json_object_new_string("The token description is not set")); - json_object_object_add(json_obj_datum, "Supply current", json_object_new_string(l_balance_cur)); - json_object_object_add(json_obj_datum, "Supply total", json_object_new_string(l_balance_total)); - json_object_object_add(json_obj_datum, "Decimals", json_object_new_string("18")); - json_object_object_add(json_obj_datum, "Auth signs valid", json_object_new_int(a_token_item->auth_signs_valid)); - json_object_object_add(json_obj_datum, "Auth signs total", json_object_new_int(a_token_item->auth_signs_total)); - json_object_object_add(json_obj_datum, "TSD and Signs", json_object_new_string("")); - dap_datum_token_dump_tsd_to_json(json_obj_datum, a_token_item->datum_token, a_token_item->datum_token_size, "hex"); - size_t l_certs_field_size = a_token_item->datum_token_size - sizeof(*a_token_item->datum_token) - a_token_item->datum_token->header_native_decl.tsd_total_size; - dap_chain_datum_token_certs_dump_to_json(json_obj_datum, a_token_item->datum_token->data_n_tsd + a_token_item->datum_token->header_native_decl.tsd_total_size, - l_certs_field_size, "hex"); - json_object_object_add(json_obj_datum, "and TSD and Signs", json_object_new_string("")); - json_object_object_add(json_obj_datum, "Total emissions", json_object_new_int(HASH_COUNT(a_token_item->token_emissions))); - DAP_DEL_Z(l_balance_cur); - DAP_DEL_Z(l_balance_total); - } else { - char *l_balance_cur = dap_chain_balance_print(a_token_item->current_supply); - char *l_balance_total = dap_chain_balance_print(a_token_item->total_supply); - json_object_object_add(json_obj_datum, "-->Token name", json_object_new_string(a_token_item->ticker)); - json_object_object_add(json_obj_datum, "Supply current", json_object_new_string(l_balance_cur)); - json_object_object_add(json_obj_datum, "Supply total", json_object_new_string(l_balance_total)); - json_object_object_add(json_obj_datum, "Decimals", json_object_new_string("18")); - json_object_object_add(json_obj_datum, "Auth signs valid", json_object_new_int(a_token_item->auth_signs_valid)); - json_object_object_add(json_obj_datum, "Auth signs total", json_object_new_int(a_token_item->auth_signs_total)); - json_object_object_add(json_obj_datum, "Signs", json_object_new_string("")); - size_t l_certs_field_size = a_token_item->datum_token_size - sizeof(*a_token_item->datum_token); - dap_chain_datum_token_certs_dump_to_json(json_obj_datum, a_token_item->datum_token->data_n_tsd, - l_certs_field_size, "hex"); - json_object_object_add(json_obj_datum, "Total emissions", json_object_new_int(HASH_COUNT(a_token_item->token_emissions))); - DAP_DEL_Z(l_balance_cur); - DAP_DEL_Z(l_balance_total); } + json_object_object_add(json_obj_datum, "Supply current", json_object_new_string(dap_uint256_to_char(a_token_item->current_supply, NULL))); + json_object_object_add(json_obj_datum, "Supply total", json_object_new_string(dap_uint256_to_char(a_token_item->total_supply, NULL))); + json_object_object_add(json_obj_datum, "Decimals", json_object_new_string("18")); + json_object_object_add(json_obj_datum, "Auth signs valid", json_object_new_int(a_token_item->auth_signs_valid)); + json_object_object_add(json_obj_datum, "Auth signs total", json_object_new_int(a_token_item->auth_signs_total)); + json_object *l_json_arr_pkeys = json_object_new_array(); + for (uint16_t i = 0; i < a_token_item->auth_signs_total; i++) { + json_object *l_json_obj_out = json_object_new_object(); + json_object_object_add(l_json_obj_out, "line", json_object_new_int(i)); + json_object_object_add(l_json_obj_out, "hash", json_object_new_string(dap_hash_fast_to_str_static(a_token_item->auth_pkey_hashes + i))); + json_object_object_add(l_json_obj_out, "pkey_type", json_object_new_string(dap_pkey_type_to_str(a_token_item->auth_pkeys[i]->header.type))); + json_object_object_add(l_json_obj_out, "bytes", json_object_new_int(a_token_item->auth_pkeys[i]->header.size)); + json_object_array_add(l_json_arr_pkeys, l_json_obj_out); + } + json_object_object_add(json_obj_datum, "Signature public keys", l_json_arr_pkeys); + json_object_object_add(json_obj_datum, "Total emissions", json_object_new_int(HASH_COUNT(a_token_item->token_emissions))); return json_obj_datum; } @@ -2333,16 +2305,15 @@ json_object *dap_ledger_token_info(dap_ledger_t *a_ledger, size_t a_limit, size_ l_arr_end = HASH_COUNT(PVT(a_ledger)->tokens); } } - size_t i_tmp = 0; + size_t i = 0; HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { - if (i_tmp < l_arr_start || i_tmp >= l_arr_end) { - i_tmp++; + if (i < l_arr_start || i >= l_arr_end) { + i++; continue; } json_obj_datum = s_token_item_to_json(l_token_item); json_object_array_add(json_arr_out, json_obj_datum); - i_tmp++; - + i++; } pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); return json_arr_out; @@ -2695,15 +2666,10 @@ static bool s_load_cache_gdb_loaded_tokens_callback(dap_global_db_instance_t *a_ log_it(L_WARNING, "Corrupted token with ticker [%s], need to 'ledger reload' to update cache", a_values[i].key); continue; } - // TODO: rework! Old token types may be passed unchecked! - dap_ledger_token_add(l_ledger, l_token, l_token_size); - dap_ledger_token_item_t *l_token_item = NULL; - HASH_FIND_STR(l_ledger_pvt->tokens, l_token->ticker, l_token_item); - if (!l_token_item) { - log_it(L_WARNING, "Can't load token with ticker [%s], need to 'ledger reload' to update cache", l_token->ticker); - continue; - } - l_token_item->current_supply = *(uint256_t*)a_values[i].value; + dap_ledger_token_add(l_ledger, (byte_t *)l_token, l_token_size); + dap_ledger_token_item_t *l_token_item = s_ledger_find_token(l_ledger, l_token->ticker); + if (l_token_item) + l_token_item->current_supply = *(uint256_t*)a_values[i].value; } char *l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_LEDGER_EMISSIONS_STR); @@ -2755,6 +2721,7 @@ dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags) l_ledger_pvt->check_cells_ds = a_flags & DAP_LEDGER_CHECK_CELLS_DS; l_ledger_pvt->check_token_emission = a_flags & DAP_LEDGER_CHECK_TOKEN_EMISSION; l_ledger_pvt->cached = a_flags & DAP_LEDGER_CACHE_ENABLED; + l_ledger_pvt->mapped = a_flags & DAP_LEDGER_MAPPED; pthread_cond_init(&l_ledger_pvt->load_cond, NULL); pthread_mutex_init(&l_ledger_pvt->load_mutex, NULL); @@ -2806,19 +2773,93 @@ dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags) return l_ledger; } +enum ledger_permissions { + LEDGER_PERMISSION_RECEIVER_ALLOWED, + LEDGER_PERMISSION_RECEIVER_BLOCKED, + LEDGER_PERMISSION_SENDER_ALLOWED, + LEDGER_PERMISSION_SENDER_BLOCKED +}; + +/** + * @brief dap_ledger_permissions_check + * @param a_token_item + * @param a_permission_id + * @param a_data + * @param a_data_size + * @return + */ +static bool s_ledger_permissions_check(dap_ledger_token_item_t *a_token_item, enum ledger_permissions a_permission_id, dap_chain_addr_t *a_addr) +{ + dap_chain_addr_t *l_addrs = NULL; + size_t l_addrs_count = 0; + switch (a_permission_id) { + case LEDGER_PERMISSION_RECEIVER_ALLOWED: + l_addrs = a_token_item->tx_recv_allow; + l_addrs_count = a_token_item->tx_recv_allow_size; + break; + case LEDGER_PERMISSION_RECEIVER_BLOCKED: + l_addrs = a_token_item->tx_recv_block; + l_addrs_count = a_token_item->tx_recv_block_size; + break; + case LEDGER_PERMISSION_SENDER_ALLOWED: + l_addrs = a_token_item->tx_send_allow; + l_addrs_count = a_token_item->tx_send_allow_size; + break; + case LEDGER_PERMISSION_SENDER_BLOCKED: + l_addrs = a_token_item->tx_send_block; + l_addrs_count = a_token_item->tx_send_block_size; + break; + } + for (size_t n = 0; n < l_addrs_count; n++) + if (dap_chain_addr_compare(l_addrs + n, a_addr)) + return true; + return false; +} + +int s_ledger_addr_check(dap_ledger_token_item_t *a_token_item, dap_chain_addr_t *a_addr, bool a_receive) +{ + dap_return_val_if_fail(a_token_item && a_addr, DAP_LEDGER_CHECK_INVALID_ARGS); + if (dap_chain_addr_is_blank(a_addr)) + return DAP_LEDGER_CHECK_OK; + if (a_receive) { + if ((a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED) || + (a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN)) { + // Check we are in white list + if (!s_ledger_permissions_check(a_token_item, LEDGER_PERMISSION_RECEIVER_ALLOWED, a_addr)) + return DAP_LEDGER_CHECK_ADDR_FORBIDDEN; + } else if ((a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED) || + (a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_UNFROZEN)) { + // Check we are in black list + if (s_ledger_permissions_check(a_token_item, LEDGER_PERMISSION_RECEIVER_BLOCKED, a_addr)) + return DAP_LEDGER_CHECK_ADDR_FORBIDDEN; + } + } else { + if ((a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED) || + (a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_FROZEN)) { + // Check we are in white list + if (!s_ledger_permissions_check(a_token_item, LEDGER_PERMISSION_SENDER_ALLOWED, a_addr)) + return DAP_LEDGER_CHECK_ADDR_FORBIDDEN; + } else if ((a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED) || + (a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN)) { + // Check we are in black list + if (s_ledger_permissions_check(a_token_item, LEDGER_PERMISSION_SENDER_BLOCKED, a_addr)) + return DAP_LEDGER_CHECK_ADDR_FORBIDDEN; + } + } + return DAP_LEDGER_CHECK_OK; +} + int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash) { - if (!a_token_emission || !a_token_emission_size) - return DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL; + dap_return_val_if_fail(a_token_emission && a_token_emission_size, DAP_LEDGER_CHECK_INVALID_ARGS); - int l_ret = DAP_LEDGER_EMISSION_ADD_OK; + int l_ret = DAP_LEDGER_CHECK_OK; dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - const char *l_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker; dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token_ticker); if (!l_token_item) { log_it(L_ERROR, "Check emission: token %s was not found", l_token_ticker); - return DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN; + return DAP_LEDGER_CHECK_TICKER_NOT_FOUND; } dap_ledger_token_emission_item_t * l_token_emission_item = NULL; @@ -2831,22 +2872,16 @@ int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_ pthread_rwlock_unlock(l_token_item ? &l_token_item->token_emissions_rwlock : &l_ledger_pvt->threshold_emissions_rwlock); if (l_token_emission_item) { - if(s_debug_more) { - char l_token_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(a_emission_hash, l_token_hash_str, sizeof(l_token_hash_str)); - if ( l_token_emission_item->datum_token_emission->hdr.version >= 2 ) { - log_it(L_ERROR, "Can't add token emission datum of %s %s ( %s ): already present in cache", - dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, NULL), - l_token_ticker, l_token_hash_str); - } else - log_it(L_ERROR, "Can't add token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s ): already present in cache", - l_token_emission_item->datum_token_emission->hdr.value64, l_token_ticker, l_token_hash_str); - } - l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED; - }else if ( (! l_token_item) && ( l_threshold_emissions_count >= s_threshold_emissions_max)) { - if(s_debug_more) - log_it(L_WARNING,"Emissions threshold overflow, max %zu items", s_threshold_emissions_max); - l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW; + debug_if(s_debug_more, L_ERROR, "Can't add token emission datum of %s %s ( %s ): already present in cache", + dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.version >= 2 + ? l_token_emission_item->datum_token_emission->hdr.value + : GET_256_FROM_64(l_token_emission_item->datum_token_emission->hdr.value64), + NULL), + l_token_ticker, dap_chain_hash_fast_to_str_static(a_emission_hash)); + l_ret = DAP_LEDGER_CHECK_ALREADY_CACHED; + } else if ( (! l_token_item) && ( l_threshold_emissions_count >= s_threshold_emissions_max)) { + debug_if(s_debug_more, L_WARNING, "Emissions threshold overflow, max %zu items", s_threshold_emissions_max); + l_ret = DAP_LEDGER_EMISSION_CHECK_THRESHOLD_OVERFLOW; } if (l_ret || !PVT(a_ledger)->check_token_emission) return l_ret; @@ -2857,7 +2892,7 @@ int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_ if (l_hash_found) { char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str)); - debug_if(s_debug_more, L_MSG, "Event %s is whitelisted", l_hash_str); + debug_if(s_debug_more, L_MSG, "Datum %s is whitelisted", l_hash_str); return l_ret; } } @@ -2869,24 +2904,26 @@ int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_ if (IS_ZERO_256((l_emission->hdr.value))) { log_it(L_ERROR, "Emission check: zero %s emission value", l_token_item->ticker); DAP_DELETE(l_emission); - return DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE; + return DAP_LEDGER_CHECK_ZERO_VALUE; } if (!s_ledger_token_supply_check(l_token_item, l_emission->hdr.value)) - return DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY; + return DAP_LEDGER_EMISSION_CHECK_VALUE_EXCEEDS_CURRENT_SUPPLY; //additional check for private tokens - if ((l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE) + if((l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE) || (l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE)) { - //s_ledger_permissions_check(l_token_item) - // return -5; - + if ((l_ret = s_ledger_addr_check(l_token_item, &((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.address, true))) { + log_it(L_WARNING, "Address %s is not in allowed to receive for emission of token %s", + dap_chain_addr_to_str(&((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.address), l_token_item->ticker); + DAP_DELETE(l_emission); + return l_ret; + } } switch (l_emission->hdr.type){ - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH:{ + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH:{ dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_emission->hdr.ticker); if (l_token_item) { - assert(l_token_item->datum_token); dap_sign_t *l_sign = (dap_sign_t *)(l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size); size_t l_offset = (byte_t *)l_sign - (byte_t *)l_emission; uint16_t l_aproves = 0, l_aproves_valid = l_token_item->auth_signs_valid; @@ -2902,16 +2939,13 @@ int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_ } for (uint16_t i = 0; i < l_sign_auth_count && l_offset < l_emission_size; i++) { if (dap_sign_verify_size(l_sign, l_emission_size - l_offset)) { - dap_chain_hash_fast_t l_sign_pkey_hash; - 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_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)) { + // Find pkey in auth pkeys + for (uint16_t k = 0; k < l_token_item->auth_signs_total; k++) { + if (dap_pkey_compare_with_sign(l_token_item->auth_pkeys[k], l_sign)) { + // Verify if token emission is signed + if (!dap_sign_verify(l_sign, l_emi_ptr_check_size, l_sign_data_check_size)) l_aproves++; - break; - } + break; } } size_t l_sign_size = dap_sign_get_size(l_sign); @@ -2928,16 +2962,15 @@ int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_ debug_if(s_debug_more, L_WARNING, "Emission of %s datoshi of %s:%s is wrong: only %u valid aproves when %u need", dap_uint256_to_char(l_emission->hdr.value, NULL), a_ledger->net->pub.name, l_emission->hdr.ticker, l_aproves, l_aproves_valid); - l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS; + l_ret = DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS; char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str)); log_it(L_MSG, "!!! Datum hash for HAL: %s", l_hash_str); } }else{ - debug_if(s_debug_more, L_WARNING,"Can't find token declaration %s:%s thats pointed in token emission datum", - a_ledger->net->pub.name, l_emission->hdr.ticker); - - l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN; + debug_if(s_debug_more, L_WARNING, "Can't find token declaration %s:%s thats pointed in token emission datum", + a_ledger->net->pub.name, l_emission->hdr.ticker); + l_ret = DAP_LEDGER_CHECK_TICKER_NOT_FOUND; } }break; default:{} @@ -2946,50 +2979,6 @@ int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_ return l_ret; } -bool s_ledger_token_address_check(dap_chain_addr_t * a_addrs, dap_chain_datum_token_emission_t *a_token_emission, size_t a_addrs_count) -{ - // if l_addrs is empty - nothing to check - dap_return_val_if_pass(!a_addrs, true); - - for(size_t n = 0; n < a_addrs_count; n++ ){ - dap_chain_addr_t l_addr = a_addrs[n]; - if (memcmp(&l_addr,&a_token_emission->hdr.address,sizeof(dap_chain_addr_t))==0) - return true; - } - - return false; -} - -bool s_ledger_token_tsd_check(dap_ledger_token_item_t * a_token_item, dap_chain_datum_token_emission_t *a_token_emission) -{ - if (!a_token_item){ - log_it(L_WARNING, "Token object is null. Probably, you set unknown token ticker in -token parameter"); - return false; - } - - // tsd section was parsed in s_token_tsd_parse - - if ((a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED) || - (a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN)) { // in white list - if (!s_ledger_token_address_check(a_token_item->tx_recv_allow, a_token_emission, a_token_item->tx_recv_allow_size)){ - log_it(L_WARNING, "Address %s is not in tx_recv_allow for emission for token %s", - dap_chain_addr_to_str(&a_token_emission->hdr.address), a_token_item->ticker); - return false; - } - return true; - } - - if (a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED) { - if (s_ledger_token_address_check(a_token_item->tx_recv_block, a_token_emission, a_token_item->tx_recv_block_size)){ - log_it(L_WARNING, "Address %s is in tx_recv_block for emission for token %s", - dap_chain_addr_to_str(&a_token_emission->hdr.address), a_token_item->ticker); - return false; - } - } - - return true; -} - static void s_ledger_emission_cache_update(dap_ledger_t *a_ledger, dap_ledger_token_emission_item_t *a_emission_item) { if (!PVT(a_ledger)->cached) @@ -3019,8 +3008,6 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); dap_ledger_token_emission_item_t * l_token_emission_item = NULL; - char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str)); int l_ret = dap_ledger_token_emission_add_check(a_ledger, a_token_emission, a_token_emission_size, a_emission_hash); if (l_ret) { if (l_ret == DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE) { // TODO remove emissions threshold @@ -3028,13 +3015,13 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi l_token_emission_item = DAP_NEW_Z(dap_ledger_token_emission_item_t); if ( !l_token_emission_item ) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; + return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; } l_token_emission_item->datum_token_emission = DAP_DUP_SIZE(a_token_emission, a_token_emission_size); if ( !l_token_emission_item->datum_token_emission ) { DAP_DELETE(l_token_emission_item); log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; + return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; } l_token_emission_item->datum_token_emission_size = a_token_emission_size; dap_hash_fast_t l_emi_hash = {0}; @@ -3056,7 +3043,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi const char *c_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker; dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, c_token_ticker); if (!l_token_item && a_from_threshold) - return DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN; + return DAP_LEDGER_CHECK_TICKER_NOT_FOUND; // check if such emission is already present in table pthread_rwlock_rdlock( l_token_item ? &l_token_item->token_emissions_rwlock @@ -3069,29 +3056,19 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi l_token_emission_item = DAP_NEW_Z(dap_ledger_token_emission_item_t); if ( !l_token_emission_item ) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; + return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; } l_token_emission_item->datum_token_emission_size = a_token_emission_size; l_token_emission_item->datum_token_emission_hash = *a_emission_hash; if (l_token_item) { l_token_emission_item->datum_token_emission = dap_chain_datum_emission_read(a_token_emission, &l_token_emission_item->datum_token_emission_size); - - //additional check for private tokens - if((l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE) - || (l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE)) { - if (!s_ledger_token_tsd_check(l_token_item, (dap_chain_datum_token_emission_t *)a_token_emission)) { - DAP_DELETE(l_token_emission_item->datum_token_emission); - DAP_DELETE(l_token_emission_item); - return DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED; - } - } //Update value in ledger memory object if (!s_ledger_token_supply_check_update(a_ledger, l_token_item, l_token_emission_item->datum_token_emission->hdr.value, false)) { DAP_DELETE(l_token_emission_item->datum_token_emission); DAP_DELETE(l_token_emission_item); - return DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY; + return DAP_LEDGER_EMISSION_CHECK_VALUE_EXCEEDS_CURRENT_SUPPLY; } pthread_rwlock_wrlock(&l_token_item->token_emissions_rwlock); @@ -3119,7 +3096,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi HASH_ADD(hh, l_ledger_pvt->threshold_emissions, datum_token_emission_hash, sizeof(*a_emission_hash), l_token_emission_item); pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock); - l_ret = -5; + l_ret = DAP_LEDGER_EMISSION_CHECK_THRESHOLDED; if (s_debug_more) { const char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance); log_it(L_NOTICE, "Added token emission datum to emissions threshold: type=%s value=%s token=%s to_addr=%s ", @@ -3133,7 +3110,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi if(s_debug_more) log_it(L_WARNING,"threshold for emissions is overfulled (%zu max), dropping down new data, added nothing", s_threshold_emissions_max); - l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW; + l_ret = DAP_LEDGER_EMISSION_CHECK_THRESHOLD_OVERFLOW; } } else { if (l_token_item) { @@ -3149,7 +3126,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value64, c_token_ticker, l_hash_str); } } - l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED; + l_ret = DAP_LEDGER_CHECK_ALREADY_CACHED; } return l_ret; } @@ -3236,12 +3213,6 @@ int dap_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emiss return dap_ledger_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, a_token_emission_hash, false); } -char *dap_ledger_token_emission_err_code_to_str(int a_code) { - return (a_code >= DAP_LEDGER_EMISSION_ADD_OK && a_code < DAP_LEDGER_EMISSION_ADD_UNKNOWN) - ? (char*)s_ledger_emission_add_err_str[(dap_ledger_emission_err_code_t)a_code] - : dap_itoa(a_code); -} - dap_ledger_token_emission_item_t *s_emission_item_find(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash, dap_ledger_token_item_t **a_token_item) { @@ -3309,65 +3280,6 @@ const char* dap_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_ch return l_item ? l_item->cache_data.token_ticker : NULL; } -/** - * @brief dap_ledger_addr_get_token_ticker_all_depricated - * @param a_addr - * @param a_tickers - * @param a_tickers_size - */ -void dap_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, - char *** a_tickers, size_t * a_tickers_size) -{ - dap_chain_hash_fast_t l_tx_first_hash = { 0 }; - const dap_ledger_tx_item_t * l_tx_item = tx_item_find_by_addr(a_ledger, a_addr,NULL, &l_tx_first_hash); - char ** l_tickers = NULL; - size_t l_tickers_size = 10; - size_t l_tickers_pos = 0; - - if(l_tx_item) { - l_tickers = DAP_NEW_Z_SIZE(char *, l_tickers_size * sizeof(char*)); - if ( !l_tickers ) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return; - } - while(l_tx_item) { - bool l_is_not_in_list = true; - for(size_t i = 0; i < l_tickers_size; i++) { - if (l_tickers[i]==NULL) - break; - if(l_tickers[i] && strcmp(l_tickers[i], l_tx_item->cache_data.token_ticker) == 0) { - l_is_not_in_list = false; - break; - } - } - if(l_is_not_in_list) { - if((l_tickers_pos + 1) == l_tickers_size) { - l_tickers_size += (l_tickers_size / 2); - l_tickers = DAP_REALLOC(l_tickers, l_tickers_size); - if ( !l_tickers ) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return; - } - } - l_tickers[l_tickers_pos] = dap_strdup(l_tx_item->cache_data.token_ticker); - l_tickers_pos++; - } - dap_chain_hash_fast_t* l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx_item->tx); - l_tx_item = tx_item_find_by_addr(a_ledger, a_addr, NULL, l_tx_hash); - DAP_DELETE(l_tx_hash); - } - l_tickers_size = l_tickers_pos + 1; - l_tickers = DAP_REALLOC(l_tickers, l_tickers_size * sizeof(char*)); - if ( !l_tickers ) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return; - } - } - *a_tickers = l_tickers; - *a_tickers_size = l_tickers_pos; -} - - /** * @brief Get list of all tickets for ledger and address. If address is NULL returns all the tockens present in system * @param a_ledger @@ -3431,7 +3343,7 @@ void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr const char *dap_ledger_get_description_by_ticker(dap_ledger_t *a_ledger, const char *a_token_ticker){ if (!a_ledger || !a_token_ticker) return NULL; - return s_ledger_find_token(a_ledger, a_token_ticker)->description_token; + return s_ledger_find_token(a_ledger, a_token_ticker)->description; } /** @@ -3579,108 +3491,6 @@ bool dap_ledger_is_used_reward(dap_ledger_t *a_ledger, dap_hash_fast_t *a_block_ return s_find_reward(a_ledger, &l_search_key); } -/** - * @brief dap_ledger_permissions_check - * @param a_token_item - * @param a_permission_id - * @param a_data - * @param a_data_size - * @return - */ -static int s_ledger_permissions_check(dap_ledger_token_item_t * a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size ) -{ - dap_chain_addr_t * l_addrs = NULL; - size_t l_addrs_count =0; - switch (a_permission_id) { - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD: - l_addrs = a_token_item->tx_recv_allow; - l_addrs_count = a_token_item->tx_recv_allow_size; - break; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD: - l_addrs = a_token_item->tx_recv_block; - l_addrs_count = a_token_item->tx_recv_block_size; - break; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD: - l_addrs = a_token_item->tx_send_allow; - l_addrs_count = a_token_item->tx_send_allow_size; - break; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD: - l_addrs = a_token_item->tx_send_block; - l_addrs_count = a_token_item->tx_send_block_size; - break; - } - if ( l_addrs && l_addrs_count){ - if (a_data_size != sizeof (dap_chain_addr_t)){ - log_it(L_ERROR,"Wrong data size %zd for ledger permission check", a_data_size); - return -2; - } - for(size_t n=0; n<l_addrs_count;n++ ){ - if (memcmp(&l_addrs[n],a_data,a_data_size)==0) - return 0; - } - return -1; - } - return -10; -} - -/** - * Match the signature of the emission with the transaction - * - * return true or false - */ -bool s_tx_match_sign(dap_chain_datum_token_emission_t *a_datum_emission, dap_chain_datum_tx_t *a_tx) -{ - if(!a_datum_emission || !a_tx) { - return false; - } - // First emission sign - dap_sign_t *l_emission_sign = (dap_sign_t*) (a_datum_emission->tsd_n_signs + a_datum_emission->data.type_auth.tsd_total_size); - size_t l_emission_sign_offset = (byte_t*) l_emission_sign - (byte_t*) a_datum_emission; - int l_emission_sign_num = a_datum_emission->data.type_auth.signs_count; - - // Get all tx signs - int l_tx_sign_num = 0; - dap_list_t *l_list_sig = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_SIG, &l_tx_sign_num); - - if(!l_emission_sign_num || !l_tx_sign_num) - return false; - - size_t l_emission_size = dap_chain_datum_emission_get_size((uint8_t*) a_datum_emission); - dap_sign_t *l_sign = (dap_sign_t*) (a_datum_emission->tsd_n_signs + a_datum_emission->data.type_auth.tsd_total_size); - size_t l_offset = (byte_t*) l_sign - (byte_t*) a_datum_emission; - for(uint16_t i = 0; i < a_datum_emission->data.type_auth.signs_count && l_offset < l_emission_size; i++) { - if(dap_sign_verify_size(l_sign, l_emission_size - l_offset)) { - dap_chain_hash_fast_t l_sign_pkey_hash; - dap_sign_get_pkey_hash(l_sign, &l_sign_pkey_hash); - - size_t l_sign_size = dap_sign_get_size(l_sign); - l_offset += l_sign_size; - l_sign = (dap_sign_t*) ((byte_t*) a_datum_emission + l_offset); - } else - break; - } - // For each emission signs - for(int l_sign_em_num = 0; l_sign_em_num < l_emission_sign_num && l_emission_sign_offset < l_emission_size; l_sign_em_num++) { - // For each tx signs - for(dap_list_t *it = l_list_sig; it; it = dap_list_next(it)) { - dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) it->data; - // Get sign from sign item - dap_sign_t *l_tx_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*) l_tx_sig); - // Compare signs - if(dap_sign_compare_pkeys(l_emission_sign, l_tx_sign)) { - dap_list_free(l_list_sig); - return true; - } - } - // Go to the next emission sign - size_t l_sign_size = dap_sign_get_size(l_emission_sign); - l_emission_sign_offset += l_sign_size; - l_emission_sign = (dap_sign_t*) ((byte_t*) a_datum_emission + l_emission_sign_offset); - } - dap_list_free(l_list_sig); - return false; -} - static int s_callback_sign_compare(dap_list_t *a_list_elem, dap_list_t *a_sign_elem) { dap_pkey_t *l_key = (dap_pkey_t *)a_list_elem->data; @@ -3689,7 +3499,7 @@ static int s_callback_sign_compare(dap_list_t *a_list_elem, dap_list_t *a_sign_e log_it(L_CRITICAL, "Invalid argument"); return -1; } - return !dap_pkey_match_sign(l_key, l_sign); + return !dap_pkey_compare_with_sign(l_key, l_sign); } bool dap_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) @@ -3761,7 +3571,6 @@ bool dap_ledger_tx_service_info(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_ha { //find tx dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_datum_tx_t *l_tx_ret = NULL; dap_ledger_tx_item_t *l_tx_item; pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); HASH_FIND(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item); @@ -3842,21 +3651,18 @@ bool dap_ledger_deduct_tx_tag(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx * return 0 OK, otherwise error */ // Checking a new transaction before adding to the cache -int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, - dap_chain_datum_tx_t *a_tx, - dap_hash_fast_t *a_tx_hash, - bool a_from_threshold, - dap_list_t **a_list_bound_items, - dap_list_t **a_list_tx_out, - char **a_main_ticker, - dap_chain_net_srv_uid_t *a_tag, - dap_chain_tx_tag_action_type_t *a_action, - bool a_check_for_removing) +static int s_tx_cache_check(dap_ledger_t *a_ledger, + dap_chain_datum_tx_t *a_tx, + dap_hash_fast_t *a_tx_hash, + bool a_from_threshold, + dap_list_t **a_list_bound_items, + dap_list_t **a_list_tx_out, + char **a_main_ticker, + dap_chain_net_srv_uid_t *a_tag, + dap_chain_tx_tag_action_type_t *a_action, + bool a_check_for_removing) { - if (!a_tx) { - log_it(L_DEBUG, "NULL transaction, check broken"); - return DAP_LEDGER_TX_CHECK_NULL_TX; - } + dap_return_val_if_fail(a_ledger && a_tx && a_tx_hash, DAP_LEDGER_CHECK_INVALID_ARGS); if (!dap_chain_net_get_load_mode(a_ledger->net) && !a_from_threshold && !a_check_for_removing) { dap_ledger_tx_item_t *l_ledger_item; pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock); @@ -3870,7 +3676,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, if (a_tag) *a_tag = l_ledger_item->cache_data.tag; if (a_action) *a_action = l_ledger_item->cache_data.action; } - return DAP_LEDGER_TX_ALREADY_CACHED; + return DAP_LEDGER_CHECK_ALREADY_CACHED; } } /* @@ -3898,12 +3704,12 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, *l_value_cur = NULL, *l_tmp = NULL, *l_res = NULL; const char *l_token = NULL, *l_main_ticker = NULL; - int l_err_num = DAP_LEDGER_TX_CHECK_OK; + int l_err_num = DAP_LEDGER_CHECK_OK; int l_prev_tx_count = 0; // 1. Verify signature in current transaction if (!a_from_threshold && dap_chain_datum_tx_verify_sign(a_tx)) - return DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN; + return DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS; // ---------------------------------------------------------------- // find all 'in' && 'in_cond' && 'in_ems' && 'in_reward' items in current transaction @@ -3924,7 +3730,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_ledger_tx_bound_t *l_bound_item = DAP_NEW_Z(dap_ledger_tx_bound_t); if (!l_bound_item) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); - l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM; + l_err_num = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; break; } l_list_bound_items = dap_list_append(l_list_bound_items, l_bound_item); @@ -3943,7 +3749,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_tx_in_ems_t *l_tx_in_ems = it->data; l_token = l_tx_in_ems->header.ticker; if (!s_ledger_check_token_ticker(l_token)) { - l_err_num = DAP_LEDGER_TX_CHECK_INVALID_TICKER; + l_err_num = DAP_LEDGER_CHECK_TICKER_NOT_FOUND; break; } dap_hash_fast_t *l_emission_hash = &l_tx_in_ems->header.token_emission_hash; @@ -3990,31 +3796,26 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION; break; } - dap_tsd_t *l_tsd; + dap_ledger_token_item_t *l_delegated_item = s_ledger_find_token(a_ledger, l_token); if (!l_delegated_item) { debug_if(s_debug_more, L_WARNING, "Token [%s] not found", l_token); - l_err_num = DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND; + l_err_num = DAP_LEDGER_CHECK_TICKER_NOT_FOUND; break; } - dap_chain_datum_token_t *l_datum_token = l_delegated_item->datum_token; - if (l_datum_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE || - !(l_tsd = dap_tsd_find(l_datum_token->data_n_tsd, - l_datum_token->header_native_decl.tsd_total_size, - DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK))) { + if (!l_delegated_item->is_delegated) { debug_if(s_debug_more, L_WARNING, "Token [%s] not valid for stake_lock transaction", l_token); l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN; break; } - 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); - if (!dap_ledger_token_ticker_check(a_ledger, (char*)l_tsd_section->ticker_token_from)) { - debug_if(s_debug_more, L_WARNING, "Token [%s] not found", l_tsd_section->ticker_token_from); - l_err_num = DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND; + if (!dap_ledger_token_ticker_check(a_ledger, l_delegated_item->delegated_from)) { + debug_if(s_debug_more, L_WARNING, "Token [%s] not found", l_delegated_item->delegated_from); + l_err_num = DAP_LEDGER_CHECK_TICKER_NOT_FOUND; break; } if (l_girdled_ems) - l_main_ticker = (const char *)l_tsd_section->ticker_token_from; + l_main_ticker = l_delegated_item->delegated_from; dap_chain_tx_out_cond_t *l_tx_stake_lock_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_stake_lock, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, NULL); if (!l_tx_stake_lock_out_cond) { @@ -4023,16 +3824,15 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, break; } uint256_t l_value_expected ={}; - if (MULT_256_COIN(l_tx_stake_lock_out_cond->header.value, l_tsd_section->emission_rate, &l_value_expected)!=0){ - if(s_debug_more){ - char * l_emission_rate_str = dap_chain_balance_print(l_tsd_section->emission_rate); - char * l_locked_value_str = dap_chain_balance_print(l_tx_stake_lock_out_cond->header.value); - log_it( L_WARNING, "Multiplication overflow for %s emission: locked value %s emission rate %s" - , l_tx_in_ems->header.ticker, l_locked_value_str, l_emission_rate_str); + if (MULT_256_COIN(l_tx_stake_lock_out_cond->header.value, l_delegated_item->emission_rate, &l_value_expected)) { + if (s_debug_more) { + char *l_emission_rate_str = dap_chain_balance_to_coins(l_delegated_item->emission_rate); + const char *l_locked_value_str; dap_uint256_to_char(l_tx_stake_lock_out_cond->header.value, &l_locked_value_str); + log_it( L_WARNING, "Multiplication overflow for %s emission: locked value %s emission rate %s", + l_tx_in_ems->header.ticker, l_locked_value_str, l_emission_rate_str); DAP_DEL_Z(l_emission_rate_str); - DAP_DEL_Z(l_locked_value_str); } - l_err_num = DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE; + l_err_num = DAP_LEDGER_CHECK_INTEGER_OVERFLOW; break; } dap_chain_tx_out_ext_t *l_tx_out_ext = NULL; @@ -4060,7 +3860,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, } else l_stake_lock_ems_value = l_tx_out_ext->header.value; if (!s_ledger_token_supply_check(l_delegated_item, l_stake_lock_ems_value)) { - l_err_num = DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY; + l_err_num = DAP_LEDGER_EMISSION_CHECK_VALUE_EXCEEDS_CURRENT_SUPPLY; break; } if (!EQUAL_256(l_value_expected, l_stake_lock_ems_value)) { @@ -4084,10 +3884,10 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_emission_hash); if (!l_tx_ticker) { debug_if(s_debug_more, L_WARNING, "No ticker found for stake_lock tx [expected '%s']", l_tx_in_ems->header.ticker); - l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND; + l_err_num = DAP_LEDGER_CHECK_TICKER_NOT_FOUND; break; } - if (strcmp(l_tx_ticker, (char *)l_tsd_section->ticker_token_from)) { + if (strcmp(l_tx_ticker, l_delegated_item->delegated_from)) { debug_if(s_debug_more, L_WARNING, "Ticker '%s' != expected '%s'", l_tx_ticker, l_tx_in_ems->header.ticker); l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED; break; @@ -4180,11 +3980,11 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token); if (!l_token_item) { debug_if(s_debug_more, L_ERROR, "Native token ticker not found"); - l_err_num = DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND; + l_err_num = DAP_LEDGER_CHECK_TICKER_NOT_FOUND; break; } if (!s_ledger_token_supply_check(l_token_item, l_value) && !a_check_for_removing) { - l_err_num = DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY; + l_err_num = DAP_LEDGER_EMISSION_CHECK_VALUE_EXCEEDS_CURRENT_SUPPLY; break; } l_bound_item->token_item = l_token_item; @@ -4319,38 +4119,21 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, if ( !l_token || !*l_token ) { log_it(L_WARNING, "No token ticker found in previous transaction"); - l_err_num = DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND; + l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; break; } // Get permissions dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token); if (!l_token_item) { debug_if(s_debug_more, L_WARNING, "Token with ticker %s not found", l_token); - l_err_num = DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND; + l_err_num = DAP_LEDGER_CHECK_TICKER_NOT_FOUND; 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 - - if (!dap_chain_addr_is_blank(l_addr_from) && s_ledger_permissions_check(l_token_item, - DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD, l_addr_from, - sizeof(*l_addr_from)) != 0 ){ - const char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from); - debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)"); - l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED; - break; - } - } - if ((l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED ) || // If all is allowed - check if we're - (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN ) ){ // in black list - if (s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD, l_addr_from, - sizeof(*l_addr_from)) == 0 ){ - const char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from); - debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)"); - l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED; - break; - } + if (s_ledger_addr_check(l_token_item, l_addr_from, false) == DAP_LEDGER_CHECK_ADDR_FORBIDDEN) { + debug_if(s_debug_more, L_WARNING, "No permission to send for addr %s", dap_chain_addr_to_str(l_addr_from)); + l_err_num = DAP_LEDGER_CHECK_ADDR_FORBIDDEN; + break; } } else { // l_cond_type == TX_ITEM_TYPE_IN_COND if(*(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT_COND) { @@ -4360,6 +4143,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *l_tx_prev_out_cond = NULL; l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out; + // 5a. Check for condition owner // Get owner tx dap_hash_fast_t *l_owner_tx_hash = dap_ledger_get_first_chain_tx_hash(a_ledger, l_tx_prev, l_tx_prev_out_cond); dap_chain_datum_tx_t *l_owner_tx = l_tx_prev; @@ -4367,9 +4151,6 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, l_owner_tx = dap_ledger_tx_find_by_hash(a_ledger, l_owner_tx_hash); DAP_DEL_Z(l_owner_tx_hash); } - - // 5a. Check for condition owner - dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_tx_prev, NULL, TX_ITEM_TYPE_SIG, NULL); dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL); dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); dap_chain_tx_sig_t *l_owner_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_owner_tx, NULL, TX_ITEM_TYPE_SIG, NULL); @@ -4390,9 +4171,10 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, l_err_num = DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET; break; } - if (l_verificator->callback(a_ledger, l_tx_prev_out_cond, a_tx, l_owner) == false) { - debug_if(s_debug_more, L_WARNING, "Verificator check error for conditional output %s", - dap_chain_tx_out_cond_subtype_to_str(l_sub_tmp)); + int l_verificator_error = l_verificator->callback(a_ledger, l_tx_prev_out_cond, a_tx, l_owner); + if (l_verificator_error != DAP_LEDGER_CHECK_OK) { // TODO add string representation for verificator return codes + debug_if(s_debug_more, L_WARNING, "Verificator check error %d for conditional output %s", + l_verificator_error, dap_chain_tx_out_cond_subtype_to_str(l_sub_tmp)); l_err_num = DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE; break; } @@ -4419,7 +4201,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, // If not checked earlier if (!l_token || !*l_token) { log_it(L_WARNING, "No token ticker found in previous transaction"); - l_err_num = DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND; + l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; break; } } @@ -4428,7 +4210,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t); if ( !l_value_cur ) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); - l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM; + l_err_num = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; break; } strcpy(l_value_cur->token_ticker, l_token); @@ -4438,7 +4220,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, if (SUM_256_256(l_value_cur->sum, l_value, &l_value_cur->sum)) { debug_if(s_debug_more, L_WARNING, "Sum result overflow for tx_add_check with ticker %s", l_value_cur->token_ticker); - l_err_num = -88; + l_err_num = DAP_LEDGER_CHECK_INTEGER_OVERFLOW; break; } } @@ -4472,7 +4254,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t); if ( !l_value_cur ) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); - l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM; + l_err_num = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; if ( l_list_bound_items ) dap_list_free_full(l_list_bound_items, NULL); HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { @@ -4502,7 +4284,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, case TX_ITEM_TYPE_OUT_OLD: { dap_chain_tx_out_old_t *l_tx_out = (dap_chain_tx_out_old_t *)it->data; if (l_multichannel) { // token ticker is mandatory for multichannel transactions - l_err_num = -16; + l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; break; } l_value = dap_chain_uint256_from(l_tx_out->header.value); @@ -4515,7 +4297,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, if (l_main_ticker) l_token = l_main_ticker; else { - l_err_num = -16; + l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; break; } } @@ -4525,8 +4307,8 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, } break; case TX_ITEM_TYPE_OUT_EXT: { // 256 dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)it->data; - if (!l_multichannel) { // token ticker is depricated for single-channel transactions - l_err_num = -16; + if (!l_multichannel) { // token ticker is forbiden for single-channel transactions + l_err_num = DAP_LEDGER_TX_CHECK_UNEXPECTED_TOKENIZED_OUT; break; } l_value = l_tx_out->header.value; @@ -4543,7 +4325,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, l_token = l_main_ticker; else { log_it(L_WARNING, "No conditional output support for multichannel transaction"); - l_err_num = -18; + l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; break; } } @@ -4552,7 +4334,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, if (l_tax_check && l_tx_out->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE && SUBTRACT_256_256(l_taxed_value, l_value, &l_taxed_value)) { log_it(L_WARNING, "Fee is greater than sum of inputs"); - l_err_num = -98; + l_err_num = DAP_LEDGER_CHECK_INTEGER_OVERFLOW; break; } } break; @@ -4566,7 +4348,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t); if ( !l_value_cur ) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); - l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM; + l_err_num = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; break; } strcpy(l_value_cur->token_ticker, l_token); @@ -4576,41 +4358,23 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, if (SUM_256_256(l_value_cur->sum, l_value, &l_value_cur->sum)) { debug_if(s_debug_more, L_WARNING, "Sum result overflow for tx_add_check with ticker %s", l_value_cur->token_ticker); - l_err_num = -77; + l_err_num = DAP_LEDGER_CHECK_INTEGER_OVERFLOW; break; } - // Get permissions for token + // Find token item dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token); if (!l_token_item) { debug_if(s_debug_more, L_WARNING, "Token with ticker %s not found", l_token); - l_err_num = -15; + l_err_num = DAP_LEDGER_CHECK_TICKER_NOT_FOUND; break; } // Check permissions - - if ( (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED )|| // If all is blocked or frozen - (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN) ){ // check if we're in white list - if(!dap_chain_addr_is_blank(&l_tx_out_to) && s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD,&l_tx_out_to , - sizeof (l_tx_out_to)) != 0 ){ - const char *l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to); - debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_out_to?l_tmp_tx_out_to:"(null)"); - l_err_num = -20; - break; - } - } - if ( (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED )|| - (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_UNFROZEN ) - ){ // If all is allowed - check if we're in black list - if(s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD ,&l_tx_out_to, - sizeof (l_tx_out_to)) == 0 ){ - const char *l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to); - debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_out_to?l_tmp_tx_out_to:"(null)"); - l_err_num = -22; - break; - } + if (s_ledger_addr_check(l_token_item, &l_tx_out_to, true) == DAP_LEDGER_CHECK_ADDR_FORBIDDEN) { + debug_if(s_debug_more, L_WARNING, "No permission to receive for addr %s", dap_chain_addr_to_str(&l_tx_out_to)); + l_err_num = DAP_LEDGER_CHECK_ADDR_FORBIDDEN; + break; } - if (l_fee_check && dap_chain_addr_compare(&l_tx_out_to, &a_ledger->net->pub.fee_addr) && !dap_strcmp(l_value_cur->token_ticker, a_ledger->net->pub.native_ticker)) SUM_256_256(l_fee_sum, l_value, &l_fee_sum); @@ -4650,13 +4414,13 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, char *l_current_fee = dap_chain_balance_to_coins(l_fee_sum); char *l_expected_fee = dap_chain_balance_to_coins(a_ledger->net->pub.fee_value); log_it(L_WARNING, "Fee value is invalid, expected %s pointed %s", l_expected_fee, l_current_fee); - l_err_num = -54; + l_err_num = DAP_LEDGER_TX_CHECK_NOT_ENOUGH_FEE; DAP_DEL_Z(l_current_fee); DAP_DEL_Z(l_expected_fee); } if (l_tax_check && SUBTRACT_256_256(l_taxed_value, l_fee_sum, &l_taxed_value)) { log_it(L_WARNING, "Fee is greater than sum of inputs"); - l_err_num = -89; + l_err_num = DAP_LEDGER_CHECK_INTEGER_OVERFLOW; } } @@ -4668,7 +4432,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, char *l_current_tax_str = dap_chain_balance_to_coins(l_tax_sum); char *l_expected_tax_str = dap_chain_balance_to_coins(l_expected_tax); log_it(L_WARNING, "Tax value is invalid, expected %s pointed %s", l_expected_tax_str, l_current_tax_str); - l_err_num = -55; + l_err_num = DAP_LEDGER_TX_CHECK_NOT_ENOUGH_TAX; DAP_DEL_Z(l_current_tax_str); DAP_DEL_Z(l_expected_tax_str); } @@ -4734,20 +4498,18 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, */ int dap_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash) { - dap_return_val_if_pass(!a_tx, DAP_LEDGER_TX_CHECK_NULL_TX); + dap_return_val_if_fail(a_tx && a_ledger, DAP_LEDGER_CHECK_INVALID_ARGS); size_t l_tx_size = dap_chain_datum_tx_get_size(a_tx); if (l_tx_size != a_datum_size) { log_it (L_WARNING, "Inconsistent datum TX: datum size %zu != tx size %zu", a_datum_size, l_tx_size); - return DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE; + return DAP_LEDGER_CHECK_INVALID_SIZE; } - - int l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_datum_hash, - false, NULL, NULL, NULL, NULL, NULL, false); + int l_ret_check = s_tx_cache_check(a_ledger, a_tx, a_datum_hash, false, NULL, NULL, NULL, NULL, NULL, false); if(s_debug_more) { if (l_ret_check) log_it(L_NOTICE, "Ledger TX adding check not passed for TX %s: error %s", - dap_chain_hash_fast_to_str_static(a_datum_hash), dap_ledger_tx_check_err_str(l_ret_check)); + dap_chain_hash_fast_to_str_static(a_datum_hash), dap_ledger_check_error_str(l_ret_check)); else log_it(L_INFO, "Ledger TX adding check passed for TX %s", dap_chain_hash_fast_to_str_static(a_datum_hash)); } @@ -4816,7 +4578,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha dap_chain_net_srv_uid_t l_tag = { .uint64 = 0 }; dap_chain_tx_tag_action_type_t l_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; - if( (l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_tx_hash, a_from_threshold, + if( (l_ret_check = s_tx_cache_check(a_ledger, a_tx, a_tx_hash, a_from_threshold, &l_list_bound_items, &l_list_tx_out, &l_main_token_ticker, &l_tag, &l_action, false))) { if (l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS || @@ -4855,7 +4617,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha } } else { debug_if(s_debug_more, L_WARNING, "dap_ledger_tx_add() tx %s not passed the check: %s ", l_tx_hash_str, - dap_ledger_tx_check_err_str(l_ret_check)); + dap_ledger_check_error_str(l_ret_check)); } if ( l_list_bound_items ) @@ -5197,11 +4959,11 @@ int dap_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap // Get boundary items list into l_list_bound_items // Get tx outs list into l_list_tx_out int l_ret_check; - if( (l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_tx_hash, false, + if( (l_ret_check = s_tx_cache_check(a_ledger, a_tx, a_tx_hash, false, &l_list_bound_items, &l_list_tx_out, &l_main_token_ticker, NULL, NULL, true))) { debug_if(s_debug_more, L_WARNING, "dap_ledger_tx_remove() tx %s not passed the check: %s ", l_tx_hash_str, - dap_ledger_tx_check_err_str(l_ret_check)); + dap_ledger_check_error_str(l_ret_check)); return l_ret_check; } @@ -5478,7 +5240,7 @@ int dap_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_c HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_item); if (l_tx_item) { pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); - return DAP_LEDGER_TX_ALREADY_CACHED; + return DAP_LEDGER_CHECK_ALREADY_CACHED; } HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->threshold_txs, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_item); pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); @@ -5552,7 +5314,7 @@ void dap_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_pkeys); - DAP_DELETE(l_token_current->auth_pkeys_hash); + DAP_DELETE(l_token_current->auth_pkey_hashes); 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); @@ -6556,8 +6318,8 @@ const char *dap_ledger_tx_calculate_main_ticker(dap_ledger_t *a_ledger, dap_chai { char *l_main_ticker = NULL; dap_chain_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx); - int l_rc = dap_ledger_tx_cache_check(a_ledger, a_tx, l_tx_hash, false, NULL, NULL, &l_main_ticker, NULL, NULL, false); - if (l_rc == DAP_LEDGER_TX_ALREADY_CACHED) + int l_rc = s_tx_cache_check(a_ledger, a_tx, l_tx_hash, false, NULL, NULL, &l_main_ticker, NULL, NULL, false); + if (l_rc == DAP_LEDGER_CHECK_ALREADY_CACHED) l_main_ticker = (char *)dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_tx_hash); DAP_DEL_Z(l_tx_hash); diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 570b45583fa91dc3865d3fb1b926dd506c9742fc..f6e2b577971868399474b47462176370aa6d8515 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -574,10 +574,10 @@ int s_link_manager_fill_net_info(dap_link_t *a_link) return 0; } -json_object *s_net_sync_status(dap_chain_net_t *a_net) { -// sanity check +json_object *s_net_sync_status(dap_chain_net_t *a_net) +{ + // sanity check dap_return_val_if_pass(!a_net, NULL); - size_t l_count_atoms = 0; json_object *l_jobj_chains_array = json_object_new_object(); dap_chain_t *l_chain = NULL; @@ -2127,10 +2127,14 @@ int s_net_init(const char *a_net_name, uint16_t a_acl_idx) default: l_ledger_flags |= DAP_LEDGER_CHECK_CELLS_DS | DAP_LEDGER_CHECK_TOKEN_EMISSION; } - // init LEDGER model - l_net->pub.ledger = dap_ledger_create(l_net, l_ledger_flags); + if (dap_config_get_item_bool_default(g_config, "ledger", "mapped", true)) + l_ledger_flags |= DAP_LEDGER_MAPPED; for (dap_chain_t *l_chain = l_net->pub.chains; l_chain; l_chain = l_chain->next) { + if (l_chain->callback_load_from_gdb) { + l_ledger_flags &= ~DAP_LEDGER_MAPPED; + continue; + } if (!l_chain->callback_get_poa_certs) continue; l_net->pub.keys = l_chain->callback_get_poa_certs(l_chain, NULL, NULL); @@ -2140,6 +2144,8 @@ int s_net_init(const char *a_net_name, uint16_t a_acl_idx) if (!l_net->pub.keys) log_it(L_WARNING, "PoA certificates for net %s not found", l_net->pub.name); + // init LEDGER model + l_net->pub.ledger = dap_ledger_create(l_net, l_ledger_flags); // Decrees initializing dap_chain_net_decree_init(l_net); @@ -2977,7 +2983,7 @@ void dap_chain_net_proc_mempool(dap_chain_net_t *a_net) * @brief dap_chain_net_verify_datum_for_add * process datum verification process. Can be: * if DAP_CHAIN_DATUM_TX, called dap_ledger_tx_add_check - * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_ledger_token_decl_add_check + * if DAP_CHAIN_DATUM_TOKEN, called dap_ledger_token_add_check * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_ledger_token_emission_add_check * if DAP_CHAIN_DATUM_DECREE * @param a_net @@ -2994,8 +3000,8 @@ int dap_chain_net_verify_datum_for_add(dap_chain_t *a_chain, dap_chain_datum_t * switch (a_datum->header.type_id) { case DAP_CHAIN_DATUM_TX: return dap_ledger_tx_add_check(l_net->pub.ledger, (dap_chain_datum_tx_t *)a_datum->data, a_datum->header.data_size, a_datum_hash); - case DAP_CHAIN_DATUM_TOKEN_DECL: - return dap_ledger_token_decl_add_check(l_net->pub.ledger, (dap_chain_datum_token_t *)a_datum->data, a_datum->header.data_size); + case DAP_CHAIN_DATUM_TOKEN: + return dap_ledger_token_add_check(l_net->pub.ledger, a_datum->data, a_datum->header.data_size); case DAP_CHAIN_DATUM_TOKEN_EMISSION: return dap_ledger_token_emission_add_check(l_net->pub.ledger, a_datum->data, a_datum->header.data_size, a_datum_hash); case DAP_CHAIN_DATUM_DECREE: @@ -3013,14 +3019,12 @@ int dap_chain_net_verify_datum_for_add(dap_chain_t *a_chain, dap_chain_datum_t * return 0; } -char *dap_chain_net_verify_datum_err_code_to_str(dap_chain_datum_t *a_datum, int a_code){ +const char *dap_chain_net_verify_datum_err_code_to_str(dap_chain_datum_t *a_datum, int a_code){ switch (a_datum->header.type_id) { case DAP_CHAIN_DATUM_TX: - return dap_ledger_tx_check_err_str(a_code); - case DAP_CHAIN_DATUM_TOKEN_DECL: - return dap_ledger_token_decl_add_err_code_to_str(a_code); + case DAP_CHAIN_DATUM_TOKEN: case DAP_CHAIN_DATUM_TOKEN_EMISSION: - return dap_ledger_token_emission_err_code_to_str(a_code); + return dap_ledger_check_error_str(a_code); default: return !a_code ? "DAP_CHAIN_DATUM_VERIFY_OK" : dap_itoa(a_code); @@ -3211,7 +3215,7 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t } return dap_chain_net_anchor_load(l_anchor, a_chain, a_datum_hash); } - case DAP_CHAIN_DATUM_TOKEN_DECL: + case DAP_CHAIN_DATUM_TOKEN: return dap_ledger_token_load(l_ledger, a_datum->data, a_datum->header.data_size); case DAP_CHAIN_DATUM_TOKEN_EMISSION: @@ -3267,7 +3271,7 @@ int dap_chain_datum_remove(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, siz } return dap_chain_net_anchor_unload(l_anchor, a_chain, a_datum_hash); } - case DAP_CHAIN_DATUM_TOKEN_DECL: + case DAP_CHAIN_DATUM_TOKEN: return 0; case DAP_CHAIN_DATUM_TOKEN_EMISSION: diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c index 46d6c126472ff3e5c110872b348a772d2e4116d5..f8ae4a95ce09ddb10667a3e41439f75529b175c4 100644 --- a/modules/net/dap_chain_net_decree.c +++ b/modules/net/dap_chain_net_decree.c @@ -316,7 +316,7 @@ int dap_chain_net_decree_load(dap_chain_datum_decree_t * a_decree, dap_chain_t * size_t l_data_size = dap_chain_datum_decree_get_size(a_decree); if ((ret_val = s_decree_verify(l_net, a_decree, l_data_size, a_decree_hash, true)) != 0) { - log_it(L_ERROR, "Decree verification failed!"); + //log_it(L_ERROR, "Decree verification failed!"); return ret_val; } diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c index 3ab907653d4e1793692bf5e5ada09723fb71a6b1..1603d8fdbf88ab95364dda0360d4d3bc1f2efcf2 100644 --- a/modules/net/dap_chain_node.c +++ b/modules/net/dap_chain_node.c @@ -262,7 +262,7 @@ bool dap_chain_node_mempool_process(dap_chain_t *a_chain, dap_chain_datum_t *a_d log_it(L_WARNING, "Can't get datum hash from hash string"); return false; } - dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_real_hash); + dap_chain_datum_calc_hash(a_datum, &l_real_hash); if (!dap_hash_fast_compare(&l_datum_hash, &l_real_hash)) { log_it(L_WARNING, "Datum hash from mempool key and real datum hash are different"); return false; diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index d712c847fd89b06bfd1475e4d56f9e869e93c556..89c504dc313be30eaac4748f3090b01b9c653066 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -2395,7 +2395,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(*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); + memcpy(l_datum_token->tsd_n_signs + *l_datum_signs_offset, l_sign, l_sign_size); *l_datum_signs_offset += l_sign_size; DAP_DELETE(l_sign); log_it(L_DEBUG,"<-- Signed with '%s'", l_certs[i]->name); @@ -2489,8 +2489,7 @@ int com_token_decl_sign(int a_argc, char **a_argv, void **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 || - l_datum->header.type_id == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) { + if(l_datum->header.type_id == DAP_CHAIN_DATUM_TOKEN) { 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) @@ -2501,7 +2500,7 @@ int com_token_decl_sign(int a_argc, char **a_argv, void **a_str_reply) uint16_t l_tmp_signs_total = l_datum_token->signs_total; l_datum_token->signs_total = 0; for (i = 1; i <= l_tmp_signs_total; i++){ - dap_sign_t *l_sign = (dap_sign_t *)(l_datum_token->data_n_tsd + l_tsd_size + l_signs_size); + dap_sign_t *l_sign = (dap_sign_t *)(l_datum_token->tsd_n_signs + l_tsd_size + l_signs_size); if( dap_sign_verify(l_sign, l_datum_token, sizeof(*l_datum_token) + l_tsd_size) ) { log_it(L_WARNING, "Wrong signature %zu for datum_token with key %s in mempool!", i, l_datum_hash_out_str); dap_cli_server_cmd_set_reply_text(a_str_reply, @@ -2526,7 +2525,7 @@ int com_token_decl_sign(int a_argc, char **a_argv, void **a_str_reply) &l_sign_counter); l_datum_token->signs_total += l_sign_counter; size_t l_token_size = sizeof(*l_datum_token) + l_data_size; - dap_chain_datum_t * l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN_DECL, + dap_chain_datum_t * l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN, l_datum_token, l_token_size); DAP_DELETE(l_datum_token); // Calc datum's hash @@ -2670,7 +2669,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a const char *l_datum_type = dap_chain_datum_type_id_to_str(l_datum->header.type_id); dap_hash_fast_t l_datum_real_hash = {0}; dap_hash_fast_t l_datum_hash_from_key = {0}; - dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_datum_real_hash); + dap_chain_datum_calc_hash(l_datum, &l_datum_real_hash); dap_chain_hash_fast_from_str(l_objs[i].key, &l_datum_hash_from_key); char buff_time[DAP_TIME_STR_SIZE]; dap_time_to_str_rfc822(buff_time, DAP_TIME_STR_SIZE, l_datum->header.ts_create); @@ -2750,10 +2749,10 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a dap_chain_addr_t l_addr_from; dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *) l_datum->data; - int l_ledger_rc = DAP_LEDGER_TX_CHECK_NULL_TX; + int l_ledger_rc = DAP_LEDGER_CHECK_INVALID_ARGS; const char *l_main_ticker = dap_ledger_tx_calculate_main_ticker(a_net->pub.ledger, l_tx, &l_ledger_rc); - char *l_ledger_rc_str = dap_ledger_tx_check_err_str(l_ledger_rc); + const char *l_ledger_rc_str = dap_ledger_check_error_str(l_ledger_rc); json_object *l_jobj_main_ticker = json_object_new_string( l_main_ticker ? l_main_ticker : "UNKNOWN"); @@ -3353,7 +3352,7 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char dap_chain_hash_fast_to_str(&l_atom_hash, l_atom_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); json_object *l_obj_atom = json_object_new_object(); json_object *l_jobj_atom_hash = json_object_new_string(l_atom_hash_str); - json_object *l_jobj_atom_err = json_object_new_string(dap_ledger_tx_check_err_str(l_ret_code)); + json_object *l_jobj_atom_err = json_object_new_string(dap_ledger_check_error_str(l_ret_code)); if (!l_obj_atom || !l_jobj_atom_hash || !l_jobj_atom_err) { json_object_put(l_jobj_datum); json_object_put(l_obj_atom); @@ -3460,7 +3459,7 @@ int _cmd_mempool_proc(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char * DAP_DELETE(l_gdb_group_mempool); return DAP_COM_MEMPOOL_PROC_LIST_ERROR_CAN_NOT_CONVERT_DATUM_HASH_TO_DIGITAL_FORM; } - dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_real_hash); + dap_chain_datum_calc_hash(l_datum, &l_real_hash); if (!dap_hash_fast_compare(&l_datum_hash, &l_real_hash)) { dap_json_rpc_error_add(DAP_COM_MEMPOOL_PROC_LIST_ERROR_REAL_HASH_DATUM_DOES_NOT_MATCH_HASH_DATA_STRING, "Error! Datum's real hash doesn't match datum's hash string %s", @@ -4147,8 +4146,8 @@ static int s_parse_additional_token_decl_arg(int a_argc, char ** a_argv, void ** 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); - const char *l_description_token = NULL; - dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-description", &l_description_token); + const char *l_description = NULL; + dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-description", &l_description); //Added remove signs if (l_remove_signs) { @@ -4188,8 +4187,8 @@ static int s_parse_additional_token_decl_arg(int a_argc, char ** a_argv, void ** } DAP_DEL_Z(l_new_certs); } - if (l_description_token) { - dap_tsd_t *l_desc_token = dap_tsd_create_string(DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION, l_description_token); + if (l_description) { + dap_tsd_t *l_desc_token = dap_tsd_create_string(DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION, l_description); l_tsd_list = dap_list_append(l_tsd_list, l_desc_token); l_tsd_total_size += dap_tsd_size(l_desc_token); a_params->ext.parsed_tsd_size += dap_tsd_size(l_desc_token); @@ -4522,11 +4521,11 @@ int com_token_decl(int a_argc, char ** a_argv, void **a_str_reply) 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); - memcpy(l_datum_token->data_n_tsd + l_datum_data_offset, l_tsd, l_tsd_size); + memcpy(l_datum_token->tsd_n_signs + l_datum_data_offset, l_tsd, l_tsd_size); l_datum_data_offset += l_tsd_size; } if (l_params->ext.parsed_tsd) { - memcpy(l_datum_token->data_n_tsd + l_datum_data_offset, + memcpy(l_datum_token->tsd_n_signs + l_datum_data_offset, l_params->ext.parsed_tsd, l_params->ext.tsd_total_size); l_datum_data_offset += l_params->ext.tsd_total_size; @@ -4574,7 +4573,7 @@ int com_token_decl(int a_argc, char ** a_argv, void **a_str_reply) return -9; } - dap_chain_datum_t * l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN_DECL, + dap_chain_datum_t * l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN, l_datum_token, sizeof(*l_datum_token) + l_datum_data_offset); DAP_DELETE(l_datum_token); @@ -4582,7 +4581,7 @@ int com_token_decl(int a_argc, char ** a_argv, void **a_str_reply) // Calc datum's hash dap_chain_hash_fast_t l_key_hash; - dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_key_hash); + dap_chain_datum_calc_hash(l_datum, &l_key_hash); char *l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash); const char *l_key_str_out = dap_strcmp(l_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_key_hash) : l_key_str; @@ -4737,7 +4736,7 @@ int com_token_update(int a_argc, char ** a_argv, void **a_str_reply) // Add TSD sections in the end // Add TSD sections in the end if (l_params->ext.tsd_total_size) { - memcpy(l_datum_token->data_n_tsd, l_params->ext.parsed_tsd, l_params->ext.parsed_tsd_size); + memcpy(l_datum_token->tsd_n_signs, l_params->ext.parsed_tsd, l_params->ext.parsed_tsd_size); DAP_DELETE(l_params->ext.parsed_tsd); } log_it(L_DEBUG, "%s token declaration update '%s' initialized", ( l_params->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE) ? @@ -4779,7 +4778,7 @@ int com_token_update(int a_argc, char ** a_argv, void **a_str_reply) return -9; } - dap_chain_datum_t * l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN_DECL, + dap_chain_datum_t * l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN, l_datum_token, sizeof(*l_datum_token) + l_datum_data_offset); DAP_DELETE(l_datum_token); @@ -4787,7 +4786,7 @@ int com_token_update(int a_argc, char ** a_argv, void **a_str_reply) // Calc datum's hash dap_chain_hash_fast_t l_key_hash; - dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_key_hash); + dap_chain_datum_calc_hash(l_datum, &l_key_hash); char *l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash); const char *l_key_str_out = dap_strcmp(l_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_key_hash) : l_key_str; @@ -4803,7 +4802,7 @@ int com_token_update(int a_argc, char ** a_argv, void **a_str_reply) } bool l_placed = !dap_global_db_set_sync(l_gdb_group_mempool, l_key_str, (uint8_t *)l_datum, l_datum_size, false); DAP_DELETE(l_gdb_group_mempool); - dap_cli_server_cmd_set_reply_text(a_str_reply, "Datum %s with token update datum for ticker %s is%s placed in datum pool", + dap_cli_server_cmd_set_reply_text(a_str_reply, "Datum %s with token update for ticker %s is%s placed in datum pool", l_key_str_out, l_ticker, l_placed ? "" : " not"); DAP_DELETE(l_key_str); DAP_DELETE(l_datum); @@ -7071,7 +7070,7 @@ int com_tx_verify(int a_argc, char **a_argv, void **reply) if (l_ret) { l_jobj_verfiy = json_object_new_boolean(false); l_jobj_error = json_object_new_object(); - json_object *l_jobj_err_str = json_object_new_string(dap_ledger_tx_check_err_str(l_ret)); + json_object *l_jobj_err_str = json_object_new_string(dap_ledger_check_error_str(l_ret)); json_object *l_jobj_err_code = json_object_new_int64(l_ret); json_object_object_add(l_jobj_error, "code", l_jobj_err_code); json_object_object_add(l_jobj_error, "message", l_jobj_err_str); @@ -7948,7 +7947,7 @@ static int s_check_cmd(int a_arg_index, int a_argc, char **a_argv, void **a_str_ goto end; } - dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_hash_tmp); + dap_chain_datum_calc_hash(l_datum, &l_hash_tmp); } dap_chain_atom_iter_t *l_iter = NULL; @@ -7963,7 +7962,7 @@ static int s_check_cmd(int a_arg_index, int a_argc, char **a_argv, void **a_str_ for (size_t i = 0; i < l_datums_count; i++) { dap_chain_datum_t *l_datum = l_datums[i]; dap_hash_fast_t l_hash; - dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_hash); + dap_chain_datum_calc_hash(l_datum, &l_hash); if (!memcmp(l_hash_tmp.raw, l_hash.raw, DAP_CHAIN_HASH_FAST_SIZE)) { dap_cli_server_cmd_set_reply_text(a_str_reply, "found!"); found = 1; diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 30b35d585fa78d48c264c1e1eb7ef4b81a87d96e..e988cb3ed57fde2c6f93eb627054f0b545631a08 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -25,7 +25,7 @@ #include <stdbool.h> #include <stddef.h> #include <pthread.h> - +#include "uthash.h" #include "dap_cli_server.h" #include "dap_common.h" #include "dap_enc_base58.h" @@ -34,7 +34,6 @@ #include "dap_list.h" #include "dap_hash.h" #include "dap_time.h" - #include "dap_chain_cell.h" #include "dap_chain_datum.h" #include "dap_chain_datum_token.h" @@ -46,22 +45,10 @@ #include "dap_chain_net_decree.h" #include "dap_chain_mempool.h" #include "dap_math_convert.h" - #include "dap_json_rpc_errors.h" #define LOG_TAG "chain_node_cli_cmd_tx" -#include "uthash.h" -// for dap_db_history_filter() -typedef struct dap_tx_data { - dap_chain_hash_fast_t tx_hash; - char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; - dap_chain_datum_t *datum; - UT_hash_handle hh; - //useless - char tx_hash_str[70]; - dap_chain_addr_t addr; -} dap_tx_data_t; /** @@ -193,7 +180,7 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, : json_object_new_null()); json_object_object_add(json_obj_datum, "ret_code", json_object_new_int(l_ret_code)); - json_object_object_add(json_obj_datum, "ret_code_str", json_object_new_string(dap_ledger_tx_check_err_str(l_ret_code))); + json_object_object_add(json_obj_datum, "ret_code_str", json_object_new_string(dap_ledger_check_error_str(l_ret_code))); dap_chain_net_srv_uid_t uid; char *service_name; @@ -291,7 +278,7 @@ static void s_tx_header_print(json_object* json_obj_datum, dap_chain_tx_hash_pro json_object_object_add(json_obj_datum, "hash", json_object_new_string(l_tx_hash_str)); json_object_object_add(json_obj_datum, "atom_hash", json_object_new_string(l_atom_hash_str)); json_object_object_add(json_obj_datum, "ret_code", json_object_new_int(a_ret_code)); - json_object_object_add(json_obj_datum, "ret_code_str", json_object_new_string(dap_ledger_tx_check_err_str(a_ret_code))); + json_object_object_add(json_obj_datum, "ret_code_str", json_object_new_string(dap_ledger_check_error_str(a_ret_code))); dap_chain_net_srv_uid_t uid; @@ -834,7 +821,7 @@ static json_object* dap_db_chain_history_token_list(dap_chain_t * a_chain, const dap_chain_datum_iter_t *l_datum_iter = a_chain->callback_datum_iter_create(a_chain); for (dap_chain_datum_t *l_datum = a_chain->callback_datum_iter_get_first(l_datum_iter); l_datum; l_datum = a_chain->callback_datum_iter_get_next(l_datum_iter)) { - if (l_datum->header.type_id != DAP_CHAIN_DATUM_TOKEN_DECL) + if (l_datum->header.type_id != DAP_CHAIN_DATUM_TOKEN) continue; size_t l_token_size = l_datum->header.data_size; dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(l_datum->data, &l_token_size); @@ -915,161 +902,6 @@ static size_t dap_db_net_history_token_list(dap_chain_net_t * l_net, const char return l_token_num_total; } -/** - * @brief dap_db_history_filter - * Get data according the history log - * - * return history string - * @param a_chain - * @param a_ledger - * @param a_filter_token_name - * @param a_filtr_addr_base58 - * @param a_hash_out_type - * @param a_datum_start - * @param a_datum_end - * @param a_total_datums - * @param a_tx_hash_processed - * @return char* - */ -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) -{ - if (!a_chain->callback_atom_get_datums) { - log_it(L_WARNING, "Not defined callback_atom_get_datums for chain \"%s\"", a_chain->name); - return NULL; - } - dap_string_t *l_str_out = dap_string_new(NULL); - if (!l_str_out) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return NULL; - } - // list all transactions - dap_tx_data_t *l_tx_data_hash = NULL; - dap_chain_cell_t *l_cell = a_chain->cells; - do { - // load transactions - size_t l_atom_size = 0; - dap_chain_atom_iter_t *l_atom_iter = a_chain->callback_atom_iter_create(a_chain, l_cell->id, NULL); - size_t l_datum_num = 0, l_token_num = 0, l_emission_num = 0, l_tx_num = 0; - size_t l_datum_num_global = a_total_datums ? *a_total_datums : 0; - for (dap_chain_atom_ptr_t l_atom = a_chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size); - l_atom && l_atom_size; l_atom = a_chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size)) { - size_t l_datums_count = 0; - dap_chain_datum_t **l_datums = a_chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count); - if (!l_datums || !l_datums_count) - continue; - 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) - continue; - char l_time_str[DAP_TIME_STR_SIZE]; - // get time of create datum - if(dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, l_datum->header.ts_create) < 1) - l_time_str[0] = '\0'; - switch (l_datum->header.type_id) { - // token - case DAP_CHAIN_DATUM_TOKEN_DECL: { - // no token necessary for addr - if(a_filtr_addr_base58) - break; - dap_chain_datum_token_t *l_token = (dap_chain_datum_token_t*) l_datum->data; - //if(a_datum_start < 0 || (l_datum_num >= a_datum_start && l_datum_num < a_datum_end)) - // 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++; - break; - } - if(!a_filter_token_name || !dap_strcmp(l_token->ticker, a_filter_token_name)) { - dap_chain_datum_dump(l_str_out, l_datum, a_hash_out_type, a_chain->net_id); - dap_string_append(l_str_out, "\n"); - l_token_num++; - } - } break; - - // emission - case DAP_CHAIN_DATUM_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_emission_num++; - break; - } - dap_chain_datum_token_emission_t *l_token_em = (dap_chain_datum_token_emission_t *)l_datum->data; - if(!a_filter_token_name || !dap_strcmp(l_token_em->hdr.ticker, a_filter_token_name)) { - // filter for addr - if (a_filtr_addr_base58 && dap_strcmp(a_filtr_addr_base58, dap_chain_addr_to_str(&(l_token_em->hdr.address)))) { - break; - } - dap_chain_datum_dump(l_str_out, l_datum, a_hash_out_type, a_chain->net_id); - dap_string_append(l_str_out, "\n"); - l_emission_num++; - } - } break; - - // transaction - case DAP_CHAIN_DATUM_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; - //calc tx hash - dap_chain_hash_fast_t l_tx_hash; - dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); - dap_chain_tx_hash_processed_ht_t *l_sht = NULL; - HASH_FIND(hh, a_tx_hash_processed, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_sht); - json_object * l_json_obj_datum = json_object_new_object(); - if (l_sht != NULL || - !s_dap_chain_datum_tx_out_data(l_tx, a_ledger, l_json_obj_datum, a_hash_out_type, &l_tx_hash)) { - l_datum_num--; - break; - } - l_sht = DAP_NEW_Z(dap_chain_tx_hash_processed_ht_t); - if (!l_sht) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return NULL; - } - l_sht->hash = l_tx_hash; - HASH_ADD(hh, a_tx_hash_processed, hash, sizeof(dap_chain_hash_fast_t), l_sht); - l_tx_num++; - } break; - - default: { - const char *l_type_str; - DAP_DATUM_TYPE_STR(l_datum->header.type_id, l_type_str); - dap_string_append_printf(l_str_out, "datum type %s\n", l_type_str); - } break; - } - l_datum_num++; - } - } - a_chain->callback_atom_iter_delete(l_atom_iter); - //total - dap_string_append_printf(l_str_out, - "---------------\ntokens: %zu\nemissions: %zu\ntransactions: %zu\ntotal datums: %zu", l_token_num, - l_emission_num, l_tx_num, l_datum_num); - - // return total datums - if(a_total_datums) - *a_total_datums = l_datum_num; - // delete hashes - dap_tx_data_t *l_iter_current, *l_item_tmp; - HASH_ITER(hh, l_tx_data_hash , l_iter_current, l_item_tmp) - { - HASH_DEL(l_tx_data_hash, l_iter_current); - // delete datum - DAP_DELETE(l_iter_current->datum); - // delete struct - DAP_DELETE(l_iter_current); - } - l_cell = l_cell->hh.next; - } while (l_cell); - - // if no history - if(!l_str_out->len) - dap_string_append(l_str_out, "empty"); - char *l_ret_str = l_str_out ? dap_string_free(l_str_out, false) : NULL; - return l_ret_str; -} /** * @brief com_ledger @@ -1085,13 +917,10 @@ int com_ledger(int a_argc, char ** a_argv, void **reply) json_object ** json_arr_reply = (json_object **) reply; enum { CMD_NONE, CMD_LIST, CMD_TX_INFO }; int arg_index = 1; - const char *l_addr_base58 = NULL; - const char *l_wallet_name = NULL; const char *l_net_str = NULL; const char *l_tx_hash_str = NULL; const char *l_hash_out_type = NULL; - dap_chain_net_t * l_net = NULL; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); if(!l_hash_out_type) l_hash_out_type = "hex"; @@ -1294,13 +1123,13 @@ int com_token(int a_argc, char ** a_argv, void **a_str_reply) const char *l_token_name_str = NULL; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-name", &l_token_name_str); if(!l_token_name_str) { - dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TOKEN_PARAM_ERR, "command requires parameter '-name' <token name>"); - return -DAP_CHAIN_NODE_CLI_COM_TOKEN_PARAM_ERR; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TOKEN_PARAM_ERR, "command requires parameter '-name' <token name>"); + return -DAP_CHAIN_NODE_CLI_COM_TOKEN_PARAM_ERR; } - json_object* json_obj_tx = json_object_new_object(); - if(!dap_db_net_history_token_list(l_net, l_token_name_str, l_hash_out_type, json_obj_tx)){ - json_object_put(json_obj_tx); - dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TOKEN_FOUND_ERR, "token '%s' not found\n", l_token_name_str); + json_object *json_obj_tx = json_object_new_object(); + if (!dap_db_net_history_token_list(l_net, l_token_name_str, l_hash_out_type, json_obj_tx)) { + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TOKEN_FOUND_ERR, "token '%s' not found\n", l_token_name_str);\ + return -DAP_CHAIN_NODE_CLI_COM_TOKEN_UNKNOWN; } json_object_array_add(*json_arr_reply, json_obj_tx); return DAP_CHAIN_NODE_CLI_COM_TOKEN_OK; diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h index 57a457f65c424d6b64f86821ea42a3de5043083a..b54200afe368c4e63b633eef83c91e2ec8821ac4 100644 --- a/modules/net/include/dap_chain_ledger.h +++ b/modules/net/include/dap_chain_ledger.h @@ -48,25 +48,30 @@ typedef struct dap_ledger { /** * @brief Error codes for accepting a transaction to the ledger. */ -typedef enum dap_ledger_tx_check{ - DAP_LEDGER_TX_CHECK_OK = 0, - DAP_LEDGER_TX_CHECK_NULL_TX, - DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE, - DAP_LEDGER_TX_ALREADY_CACHED, - DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN, +typedef enum dap_ledger_check_error { + DAP_LEDGER_CHECK_OK = 0, + DAP_LEDGER_CHECK_INVALID_ARGS, + DAP_LEDGER_CHECK_INVALID_SIZE, + DAP_LEDGER_CHECK_ALREADY_CACHED, + DAP_LEDGER_CHECK_PARSE_ERROR, + DAP_LEDGER_CHECK_APPLY_ERROR, + DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY, + DAP_LEDGER_CHECK_INTEGER_OVERFLOW, + DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS, + DAP_LEDGER_CHECK_TICKER_NOT_FOUND, + DAP_LEDGER_CHECK_ZERO_VALUE, + DAP_LEDGER_CHECK_ADDR_FORBIDDEN, + DAP_LEDGER_CHECK_WHITELISTED, + /* TX check return codes */ DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED, DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED, DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND, DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS, - DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND, DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN, DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS, - DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE, DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS, DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX, - DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY, DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE, - DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND, DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED, DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED, DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND, @@ -76,46 +81,84 @@ typedef enum dap_ledger_tx_check{ DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX, DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET, DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE, - DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND, - DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND, - DAP_LEDGER_PERMISSION_CHECK_FAILED, DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS, DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED, DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL, - DAP_LEDGER_TX_CHECK_INVALID_TICKER, - DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM, - /* add custom codes here */ - - DAP_LEDGER_TX_CHECK_UNKNOWN /* MAX */ -} dap_ledger_tx_check_t; - -typedef enum dap_ledger_emission_err{ - DAP_LEDGER_EMISSION_ADD_OK = 0, - DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL, - DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED, - DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW, - DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY, - DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS, - DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN, - DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE, - DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED, - /* add custom codes here */ - DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM, - DAP_LEDGER_EMISSION_ADD_UNKNOWN /* MAX */ -} dap_ledger_emission_err_code_t; - -typedef enum dap_ledger_token_decl_add_err{ - DAP_LEDGER_TOKEN_DECL_ADD_OK = 0, - DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL, - DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE, - DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK, - DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN, - DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN, - DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS, - /* add custom codes here */ - - DAP_LEDGER_TOKEN_DECL_ADD_UNKNOWN /* MAX */ -} dap_ledger_token_decl_add_err_t; + DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER, + DAP_LEDGER_TX_CHECK_UNEXPECTED_TOKENIZED_OUT, + DAP_LEDGER_TX_CHECK_NOT_ENOUGH_FEE, + DAP_LEDGER_TX_CHECK_NOT_ENOUGH_TAX, + /* Emisssion check return codes */ + DAP_LEDGER_EMISSION_CHECK_THRESHOLDED, + DAP_LEDGER_EMISSION_CHECK_THRESHOLD_OVERFLOW, + DAP_LEDGER_EMISSION_CHECK_VALUE_EXCEEDS_CURRENT_SUPPLY, + /* Token declaration/update return codes */ + DAP_LEDGER_TOKEN_ADD_CHECK_NOT_ENOUGH_UNIQUE_SIGNS, + DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_SUPPLY, + DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR, + DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH, + DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH, + DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN, + DAP_LEDGER_TOKEN_ADD_CHECK_TSD_OTHER_TICKER_EXPECTED +} dap_ledger_check_error_t; + +DAP_STATIC_INLINE const char *dap_ledger_check_error_str(dap_ledger_check_error_t a_error) +{ + switch (a_error) { + case DAP_LEDGER_CHECK_OK: return "No error"; + case DAP_LEDGER_CHECK_INVALID_ARGS: return "Invalid arguments"; + case DAP_LEDGER_CHECK_INVALID_SIZE: return "Incorrect size of datum or datum's content"; + case DAP_LEDGER_CHECK_ALREADY_CACHED: return "Datum already cached in ledger"; + case DAP_LEDGER_CHECK_PARSE_ERROR: return "Incorrect datum interrnal structure, can't pasre it"; + case DAP_LEDGER_CHECK_APPLY_ERROR: return "Datum can't be applied"; + case DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY: return "Not enough memory"; + case DAP_LEDGER_CHECK_INTEGER_OVERFLOW: return "Incorrect datum values relationship lead to integer overflow, can't process"; + case DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS: return "No enough valid signatures in datum"; + case DAP_LEDGER_CHECK_TICKER_NOT_FOUND: return "Can't find specified token ticker"; + case DAP_LEDGER_CHECK_ZERO_VALUE: return "Unacceptable zero value"; + case DAP_LEDGER_CHECK_ADDR_FORBIDDEN: return "Specified address is forbidden"; + case DAP_LEDGER_CHECK_WHITELISTED: return "Datum is in hard accept list"; + /* TX check return codes */ + case DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED: return "Double spend attempt for emission"; + case DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED: return "Double spend attempt for stake-lock emission"; + case DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND: return "Specified emission not found in ledger"; + case DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS: return "Transaction has no valid inputs, can't process"; + case DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN: return "Incorrect deledated token specified in stake-lock transaction"; + case DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS: return "Condtional output for stake-lock emission not found"; + case DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS: return "Tokenized output for stake-lock girdled emission not found"; + case DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX: return "Output for basic transaction not found"; + case DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE: return "Incorrect value for stake-lock emission, should be stake * rate"; + case DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED: return "Incorrect token ticker for stake-lock emission"; + case DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED: return "Double spend attempt for transaction output"; + case DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND: return "No previous transaction found"; + case DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND: return "Specified output number not found in previous transaction"; + case DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_MISSTYPED: return "Previuos transaction output has unknown type, possible ledger corruption"; + case DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH: return "Trying to spend transaction output from wrongful wallet"; + case DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX: return "Double spend attempt within single transaction"; + case DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET: return "No verificator found for specified conditional ipnput"; + case DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE: return "Verificator check return error"; + case DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS: return "Sum of transaction outputs isn't equal to sum of its inputs"; + case DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED: return "Double spend attempt for reward"; + case DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL: return "Wrongful reward item in transaction"; + case DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER: return "Can't calculate main ticker found for transaction"; + case DAP_LEDGER_TX_CHECK_UNEXPECTED_TOKENIZED_OUT: return "Tokenized out is forbidden for single-channel trandactions"; + case DAP_LEDGER_TX_CHECK_NOT_ENOUGH_FEE: return "Not enough network fee for transaction processing"; + case DAP_LEDGER_TX_CHECK_NOT_ENOUGH_TAX: return "Not enough sovereign tax provided with current transaction"; + /* Emisssion check return codes */ + case DAP_LEDGER_EMISSION_CHECK_THRESHOLDED: return "No token ticker found for emission, move it to the threshold"; + case DAP_LEDGER_EMISSION_CHECK_THRESHOLD_OVERFLOW: return "Emissions threshold overfulled"; + case DAP_LEDGER_EMISSION_CHECK_VALUE_EXCEEDS_CURRENT_SUPPLY: return "Value of emission execeeds current token supply"; + /* Token declaration/update return codes */ + case DAP_LEDGER_TOKEN_ADD_CHECK_NOT_ENOUGH_UNIQUE_SIGNS: return "Not all token signs is unique"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_SUPPLY: return "Specified supply must be greater than current one"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR: return "Specified address has invalid format"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH: return "Specified address can't be processed cause double (for adding) or absent (for removing)"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH: return "Specified public key or its hash can't be processed cause double (for adding) or absent (for removing)"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN: return "Specified TSD section type is not allowed in datum token of specified type"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_OTHER_TICKER_EXPECTED: return "Incorrect token ticker for delegated token"; + default: return "Unknown error"; + } +} typedef enum dap_chan_ledger_notify_opcodes{ DAP_LEDGER_NOTIFY_OPCODE_ADDED = 'a', // 0x61 @@ -151,7 +194,7 @@ typedef struct dap_ledger_datum_iter { void *cur_ledger_tx_item; } dap_ledger_datum_iter_t; -typedef bool (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); +typedef int (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); typedef void (*dap_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_cond); typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chan_ledger_notify_opcodes_t a_opcode); typedef void (* dap_ledger_bridged_tx_notify_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg, dap_chan_ledger_notify_opcodes_t a_opcode); @@ -166,22 +209,24 @@ typedef bool (*dap_ledger_tag_check_callback_t)(dap_ledger_t *a_ledger, dap_chai #define DAP_LEDGER_CACHE_RELOAD_ONCE_UUID "0c92b759-a565-448f-b8bd-99103dacf7fc" // Checks the emission of the token, usualy on zero chain -#define DAP_LEDGER_CHECK_TOKEN_EMISSION 0x0001 +#define DAP_LEDGER_CHECK_TOKEN_EMISSION 0x0001 // Check double spending in local cell -#define DAP_LEDGER_CHECK_LOCAL_DS 0x0002 +#define DAP_LEDGER_CHECK_LOCAL_DS 0x0002 // Check the double spending in all cells -#define DAP_LEDGER_CHECK_CELLS_DS 0x0100 +#define DAP_LEDGER_CHECK_CELLS_DS 0x0100 + +#define DAP_LEDGER_CACHE_ENABLED 0x0200 -#define DAP_LEDGER_CACHE_ENABLED 0x0200 +#define DAP_LEDGER_MAPPED 0x0400 // Error code for no previous transaction (for stay in mempool) #define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND // Error code for no emission for a transaction (for stay in mempool) #define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND // Error code for not enough valid emission signs (for stay in mempool) -#define DAP_CHAIN_CS_VERIFY_CODE_NOT_ENOUGH_SIGNS DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS +#define DAP_CHAIN_CS_VERIFY_CODE_NOT_ENOUGH_SIGNS DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS // Error code for no decree for anchor (for stay in mempool) #define DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE -1113 @@ -205,21 +250,6 @@ void dap_ledger_handle_free(dap_ledger_t *a_ledger); void dap_ledger_set_local_cell_id(dap_ledger_t *a_ledger, dap_chain_cell_id_t a_local_cell_id); -/** - * @brief dap_chain_node_datum_tx_calc_hash - * @param a_tx - * @return - */ -DAP_STATIC_INLINE dap_chain_hash_fast_t* dap_chain_node_datum_tx_calc_hash(dap_chain_datum_tx_t *a_tx) -{ - dap_chain_hash_fast_t *tx_hash = DAP_NEW_Z(dap_chain_hash_fast_t); - if (!tx_hash) { - return NULL; - } - dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), tx_hash); - return tx_hash; -} - DAP_STATIC_INLINE char *dap_ledger_get_gdb_group(dap_ledger_t *a_ledger, const char *a_suffix) { return a_ledger && a_ledger->net->pub.name && a_suffix @@ -238,8 +268,6 @@ int dap_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap int dap_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash); -char* dap_ledger_tx_check_err_str(int a_code); - /** * Print list transaction from ledger * @@ -259,10 +287,9 @@ dap_chain_datum_token_t *dap_ledger_token_ticker_check(dap_ledger_t * a_ledger, * */ -int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); +int dap_ledger_token_add(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size); int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size); -int dap_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); -char *dap_ledger_token_decl_add_err_code_to_str(int a_code); +int dap_ledger_token_add_check(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size); json_object *dap_ledger_token_info(dap_ledger_t *a_ledger, size_t a_limit, size_t a_offset); json_object *dap_ledger_token_info_by_name(dap_ledger_t *a_ledger, const char *a_token_ticker); @@ -273,9 +300,10 @@ json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger, size_t a_limit, s json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_tx_treshold_hash, size_t a_limit, size_t a_offset); json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger, size_t a_limit, size_t a_offset); -size_t dap_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker); -size_t dap_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker); -dap_list_t * dap_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker); +size_t dap_ledger_token_get_auth_signs_valid(dap_ledger_t *a_ledger, const char *a_token_ticker); +size_t dap_ledger_token_get_auth_signs_total(dap_ledger_t *a_ledger, const char *a_token_ticker); +dap_list_t *dap_ledger_token_get_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char *a_token_ticker); +uint256_t dap_ledger_token_get_emission_rate(dap_ledger_t *a_ledger, const char *a_token_ticker); /** * Add token emission datum @@ -283,9 +311,8 @@ dap_list_t * dap_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const ch int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_hash_fast_t *a_emission_hash, bool a_from_threshold); int dap_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_hash_fast_t *a_token_emission_hash); -char *dap_ledger_token_emission_err_code_to_str(int a_code); -// Check if it addable +// Checking a new transaction before adding to the cache int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash); /* Add stake-lock item */ @@ -316,18 +343,6 @@ bool dap_ledger_tx_service_info(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_ha int dap_ledger_service_add(dap_chain_net_srv_uid_t a_uid, char *tag_str, dap_ledger_tag_check_callback_t a_callback); - -// Checking a new transaction before adding to the cache -int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, - dap_chain_datum_tx_t *a_tx, - dap_hash_fast_t *a_tx_hash, - bool a_from_threshold, - dap_list_t **a_list_bound_items, - dap_list_t **a_list_tx_out, - char **a_main_ticker, - dap_chain_net_srv_uid_t *a_tag, - dap_chain_tx_tag_action_type_t *a_action, bool a_check_for_removing); - const char *dap_ledger_tx_calculate_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc); /** diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 6e62d461f70fb3948bcfad59038a16bd2368dedb..5cfa52d7c014c2f8aa05af933eedc7ddd03c112a 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -54,7 +54,7 @@ typedef enum dap_chain_net_state { NET_STATE_ONLINE } dap_chain_net_state_t; -typedef struct dap_chain_net{ +typedef struct dap_chain_net { struct { dap_chain_net_id_t id; char * name; @@ -181,7 +181,7 @@ dap_chain_net_t *dap_chain_net_iter_start(); dap_chain_net_t *dap_chain_net_iter_next(dap_chain_net_t*); int dap_chain_net_verify_datum_for_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, dap_hash_fast_t *a_datum_hash); -char *dap_chain_net_verify_datum_err_code_to_str(dap_chain_datum_t *a_datum, int a_code); +const char *dap_chain_net_verify_datum_err_code_to_str(dap_chain_datum_t *a_datum, int a_code); void dap_chain_add_mempool_notify_callback(dap_chain_t *a_chain, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg); void dap_chain_net_add_nodelist_notify_callback(dap_chain_net_t *a_net, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg); @@ -235,4 +235,4 @@ enum dap_chain_net_json_rpc_error_list{ dap_chain_net_decree_t *dap_chain_net_get_net_decree(dap_chain_net_t *a_net); void dap_chain_net_set_net_decree(dap_chain_net_t *a_net, dap_chain_net_decree_t *a_decree); decree_table_t **dap_chain_net_get_decrees(dap_chain_net_t *a_net); -anchor_table_t **dap_chain_net_get_anchors(dap_chain_net_t *a_net); \ No newline at end of file +anchor_table_t **dap_chain_net_get_anchors(dap_chain_net_t *a_net); diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c index a99b12f0c1091883f3985b8ec8e79a9020536774..8e55f3f3175e698d97497aff3eb96844f3179412 100644 --- a/modules/net/srv/dap_chain_net_srv.c +++ b/modules/net/srv/dap_chain_net_srv.c @@ -78,9 +78,9 @@ static int s_cli_net_srv(int argc, char **argv, void **reply); static void s_load(const char * a_path); static void s_load_all(); -static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_cond_t *a_cond, +static int s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); -static bool s_fee_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_cond_t *a_cond, +static int s_fee_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); static int s_str_to_price_unit(const char *a_price_unit_str, dap_chain_net_srv_price_unit_uid_t *a_price_unit); @@ -649,7 +649,7 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply) * @param a_owner * @return */ -static bool s_fee_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t UNUSED_ARG *a_cond, +static int s_fee_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t UNUSED_ARG *a_cond, dap_chain_datum_tx_t *a_tx_in, bool UNUSED_ARG a_owner) { dap_chain_net_t *l_net = a_ledger->net; @@ -660,9 +660,9 @@ static bool s_fee_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_ continue; dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0); if (!l_tx_in_cond) - return false; + return -1; if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash)) - return false; + return -2; size_t l_block_size = 0; dap_chain_block_t *l_block = (dap_chain_block_t *)l_chain->callback_block_find_by_tx_hash( l_chain, &l_tx_in_cond->header.tx_prev_hash, &l_block_size); @@ -670,14 +670,14 @@ static bool s_fee_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_ continue; dap_sign_t *l_sign_block = dap_chain_block_sign_get(l_block, l_block_size, 0); if (!l_sign_block) - return false; + return -3; // TX sign is already verified, just compare pkeys dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, TX_ITEM_TYPE_SIG, NULL); dap_sign_t *l_sign_tx = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig); - return dap_sign_compare_pkeys(l_sign_block, l_sign_tx); + return dap_sign_compare_pkeys(l_sign_block, l_sign_tx) ? 0 : -5; } - return false; + return -4; } /** @@ -689,16 +689,16 @@ static bool s_fee_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_ * @param a_owner * @return */ -static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_cond_t *a_cond, +static int s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner) { if (a_owner) - return true; + return 0; dap_chain_datum_tx_receipt_t *l_receipt = (dap_chain_datum_tx_receipt_t *) dap_chain_datum_tx_item_get(a_tx_in, NULL, TX_ITEM_TYPE_RECEIPT, NULL); if (!l_receipt){ log_it(L_ERROR, "Can't find receipt."); - return false; + return -1; } // Check provider sign @@ -706,12 +706,12 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out if (!l_sign){ log_it(L_ERROR, "Can't get provider sign from receipt."); - return false; + return -2; } if (dap_sign_verify_all(l_sign, dap_sign_get_size(l_sign), &l_receipt->receipt_info, sizeof(l_receipt->receipt_info))){ log_it(L_ERROR, "Provider sign in receipt not passed verification."); - return false; + return -3; } // Checking the signature matches the provider's signature @@ -719,7 +719,7 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out dap_hash_fast_t l_provider_pkey_hash = {}; if (!dap_sign_get_pkey_hash(l_sign, &l_provider_pkey_hash)){ log_it(L_ERROR, "Can't get pkey hash from provider sign."); - return false; + return -4; } int l_item_size = 0; @@ -732,34 +732,34 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_sig); if (!l_sign){ log_it(L_ERROR, "Provider sign from tx sig_item"); - return false; + return -5; } if(!dap_sign_get_pkey_hash(l_sign, &l_tx_sign_pkey_hash)){ log_it(L_ERROR, "Can't get pkey hash from tx provider signature"); - return false; + return -6; } if(!dap_hash_fast_compare(&l_tx_sign_pkey_hash, &l_provider_pkey_hash)){ log_it(L_ERROR, "Provider signature in receipt and tx is different."); - return false; + return -7; } // Check client sign l_sign = dap_chain_datum_tx_receipt_sign_get(l_receipt, l_receipt->size, 1); if (!l_sign){ log_it(L_ERROR, "Can't get client signature from receipt."); - return false; + return -8; } dap_hash_fast_t l_pkey_hash = {}; if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash)){ log_it(L_ERROR, "Can't get pkey hash from receipt client signature"); - return false; + return -9; } if(!dap_hash_fast_compare(&l_pkey_hash, &a_cond->subtype.srv_pay.pkey_hash)){ log_it(L_ERROR, "Client signature in receipt is invalid!"); - return false; + return -10; } // Check price is less than maximum @@ -771,13 +771,13 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out if (l_receipt->receipt_info.units != 0){ DIV_256(l_receipt->receipt_info.value_datoshi, GET_256_FROM_64(l_receipt->receipt_info.units), &l_unit_price); } else { - return false; + return -11; } if( !IS_ZERO_256(l_prev_out_cond->subtype.srv_pay.unit_price_max_datoshi) && compare256(l_unit_price, l_prev_out_cond->subtype.srv_pay.unit_price_max_datoshi) > 0){ log_it(L_ERROR, "Value in receipt is exceed max allowable price."); - return false; + return -12; } // check remainder on srv pay cond out is valid @@ -814,10 +814,10 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out if (compare256(l_value, l_cond_out_value)){ log_it(L_ERROR, "Value in tx out is invalid!"); dap_list_free(l_list_out); - return false; + return -13; } dap_list_free(l_list_out); - return true; + return 0; } dap_chain_net_srv_price_t * dap_chain_net_srv_get_price_from_order(dap_chain_net_srv_t *a_srv, const char *a_config_section, dap_chain_hash_fast_t* a_order_hash){ diff --git a/modules/service/stake/dap_chain_net_srv_stake_lock.c b/modules/service/stake/dap_chain_net_srv_stake_lock.c index a4eaa6675376fc3c32503a85fb57f25d8e4eb60c..7c6651107e2aea476f78f921fe10ea76d3ea1b1e 100644 --- a/modules/service/stake/dap_chain_net_srv_stake_lock.c +++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c @@ -108,7 +108,7 @@ dap_chain_datum_t *s_stake_unlock_datum_create(dap_chain_net_t *a_net, dap_enc_k const char *a_delegated_ticker_str, uint256_t a_delegated_value,int *res); // Callbacks static void s_stake_lock_callback_updater(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_out_item); -static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); +static int s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); static inline int s_tsd_str_cmp(const byte_t *a_tsdata, size_t a_tsdsize, const char *str ) { size_t l_strlen = (size_t)strlen(str); @@ -251,19 +251,10 @@ int dap_chain_net_srv_stake_lock_init() { dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, s_stake_lock_callback_verificator, s_stake_lock_callback_updater, NULL); dap_cli_server_cmd_add("stake_lock", s_cli_stake_lock, "Stake lock service commands", - "Command:" - "stake_lock hold\n" - "Required parameters:\n" - "-net <net name> -w <wallet name> -time_staking <in YYMMDD>\n" - "-token <ticker> -value <value> -fee <value>\n" - "Optional parameters:\n" - "-chain <chain> -reinvest <percentage from 1 to 100>\n" - "Command:" - "stake_lock take\n" - "Required parameters:\n" - "-net <net name> -w <wallet name> -tx <transaction hash> -fee <value>\n" - "Optional parameters:\n" - "-chain <chain>\n" + "stake_lock hold -net <net_name> -w <wallet_name> -time_staking <YYMMDD> -token <ticker> -value <value> -fee <value>" + "[-chain <chain_name>] [-reinvest <percentage>]\n" + "stake_lock take -net <net_name> -w <wallet_name> -tx <transaction_hash> -fee <value>" + "[-chain <chain_name>]\n" ); s_debug_more = dap_config_get_item_bool_default(g_config, "ledger", "debug_more", false); @@ -310,8 +301,6 @@ static enum error_code s_cli_hold(int a_argc, char **a_argv, int a_arg_index, da dap_chain_wallet_t *l_wallet; dap_chain_addr_t *l_addr_holder; dap_chain_datum_token_t *l_delegated_token; - dap_tsd_t *l_tsd; - dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section; dap_string_append_printf(output_line, "---> HOLD <---\n"); @@ -352,24 +341,14 @@ static enum error_code s_cli_hold(int a_argc, char **a_argv, int a_arg_index, da dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker_str, l_ticker_str); - if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str)) - || (l_delegated_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE) - || !l_delegated_token->header_native_decl.tsd_total_size - || NULL == (l_tsd = dap_tsd_find(l_delegated_token->data_n_tsd, l_delegated_token->header_native_decl.tsd_total_size, - DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK))) { - dap_string_append_printf(output_line, "'%s'", l_delegated_ticker_str); + if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str))) return NO_DELEGATED_TOKEN_ERROR; - } - - l_tsd_section = _dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t); - if (!l_tsd_section || strcmp(l_ticker_str, (char*)l_tsd_section->ticker_token_from)) - return TOKEN_ERROR; - if (IS_ZERO_256(l_tsd_section->emission_rate)) + uint256_t l_emission_rate = dap_ledger_token_get_emission_rate(l_ledger, l_delegated_ticker_str); + if (IS_ZERO_256(l_emission_rate)) return TOKEN_ERROR; - MULT_256_COIN(l_value, l_tsd_section->emission_rate, &l_value_delegated); - if (IS_ZERO_256(l_value_delegated)) + if (MULT_256_COIN(l_value, l_emission_rate, &l_value_delegated) || IS_ZERO_256(l_value_delegated)) return COINS_FORMAT_ERROR; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-cert", &l_cert_str); @@ -418,7 +397,7 @@ static enum error_code s_cli_hold(int a_argc, char **a_argv, int a_arg_index, da dap_time_t l_time_now = dap_time_now(); if (l_time_staking < l_time_now) return TIME_ERROR; - l_time_staking -= l_time_now; + l_time_staking -= l_time_now; if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-reinvest", &l_reinvest_percent_str) && NULL != l_reinvest_percent_str) { @@ -499,8 +478,6 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da dap_chain_datum_t *l_datum; dap_chain_t *l_chain; dap_chain_datum_token_t *l_delegated_token; - dap_tsd_t *l_tsd; - dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section; dap_string_append_printf(output_line, "---> TAKE <---\n"); @@ -558,25 +535,15 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker_str, l_ticker_str); - if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str)) - || (l_delegated_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE) - || !l_delegated_token->header_native_decl.tsd_total_size - || NULL == (l_tsd = dap_tsd_find(l_delegated_token->data_n_tsd, - l_delegated_token->header_native_decl.tsd_total_size, - DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK))) { - dap_string_append_printf(output_line, "'%s'", l_delegated_ticker_str); + if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str))) return NO_DELEGATED_TOKEN_ERROR; - } - l_tsd_section = _dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t); - if (!l_tsd_section || strcmp(l_ticker_str, (char*)l_tsd_section->ticker_token_from)) - return TOKEN_ERROR; + uint256_t l_emission_rate = dap_ledger_token_get_emission_rate(l_ledger, l_delegated_ticker_str); - if (!IS_ZERO_256(l_tsd_section->emission_rate)) { - MULT_256_COIN(l_tx_out_cond->header.value, l_tsd_section->emission_rate, &l_value_delegated); - if (IS_ZERO_256(l_value_delegated)) - return COINS_FORMAT_ERROR; - } + if (IS_ZERO_256(l_emission_rate) || + MULT_256_COIN(l_tx_out_cond->header.value, l_emission_rate, &l_value_delegated) || + IS_ZERO_256(l_value_delegated)) + return COINS_FORMAT_ERROR; } if (!dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-w", &l_wallet_str) @@ -1019,65 +986,56 @@ static char *s_update_date_by_using_month_count(char *time, uint8_t month_count) * @param a_owner * @return */ -static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner) +static int s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner) { dap_chain_datum_tx_t *l_burning_tx = NULL; dap_chain_datum_tx_receipt_t *l_receipt = NULL; uint256_t l_value_delegated = {}; dap_hash_fast_t l_burning_tx_hash; - dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section; - dap_tsd_t *l_tsd; dap_chain_tx_in_cond_t *l_tx_in_cond; const char *l_prev_tx_ticker; dap_chain_datum_token_t *l_delegated_token; char l_delegated_ticker_str[DAP_CHAIN_TICKER_SIZE_MAX]; if (!a_owner) - return false; + return -1; + + if (a_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_BY_TIME && + a_cond->subtype.srv_stake_lock.time_unlock > dap_time_now()) + return -2; - if (a_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_BY_TIME) { - if (a_cond->subtype.srv_stake_lock.time_unlock > dap_time_now()) - return false; - } if (NULL == (l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get( a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0))) - return false; + return -3; if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash)) return false; if (NULL == (l_prev_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash( a_ledger, &l_tx_in_cond->header.tx_prev_hash))) - return false; + return -4; dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker_str, l_prev_tx_ticker); if (a_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_CREATE_BASE_TX || a_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_EMIT) { - if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(a_ledger, l_delegated_ticker_str)) - || (l_delegated_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE) - || !l_delegated_token->header_native_decl.tsd_total_size - || NULL == (l_tsd = dap_tsd_find(l_delegated_token->data_n_tsd, - l_delegated_token->header_native_decl.tsd_total_size, - DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK))) { - return false; - } + if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(a_ledger, l_delegated_ticker_str))) + return -5; - l_tsd_section = _dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t); + uint256_t l_emission_rate = dap_ledger_token_get_emission_rate(a_ledger, l_delegated_ticker_str); - if (!IS_ZERO_256(l_tsd_section->emission_rate)) { - MULT_256_COIN(a_cond->header.value, l_tsd_section->emission_rate, &l_value_delegated); - if (IS_ZERO_256(l_value_delegated)) - return false; - } + if (IS_ZERO_256(l_emission_rate) || + MULT_256_COIN(a_cond->header.value, l_emission_rate, &l_value_delegated) || + IS_ZERO_256(l_value_delegated)) + return -6; l_receipt = (dap_chain_datum_tx_receipt_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_RECEIPT, 0); if (l_receipt) { if (!dap_chain_net_srv_uid_compare_scalar(l_receipt->receipt_info.srv_uid, DAP_CHAIN_NET_SRV_STAKE_LOCK_ID)) - return false; + return -7; if (!l_receipt->exts_size) - return false; + return -8; l_burning_tx_hash = *(dap_hash_fast_t*)l_receipt->exts_n_signs; if (dap_hash_fast_is_blank(&l_burning_tx_hash)) - return false; + return -9; l_burning_tx = dap_ledger_tx_find_by_hash(a_ledger, &l_burning_tx_hash); if (!l_burning_tx) { char l_burning_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; @@ -1086,7 +1044,7 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_ dap_get_data_hash_str_static(a_tx_in, dap_chain_datum_tx_get_size(a_tx_in), l_take_tx_hash_str); debug_if(s_debug_more, L_ERROR, "[Legacy] Can't find burning tx with hash %s, obtained from the receipt of take tx %s", l_burning_tx_hash_str, l_take_tx_hash_str); - return false; + return -10; } } else l_burning_tx = a_tx_in; @@ -1113,7 +1071,7 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_ dap_list_free(l_outs_list); if (IS_ZERO_256(l_blank_out_value)) { log_it(L_ERROR, "Can't find OUT with BLANK addr in burning TX"); - return false; + return -11; } if (s_debug_more) { @@ -1131,12 +1089,12 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_ SUM_256_256(l_value_delegated, GET_256_FROM_64(10), &l_value_delegated); if (!EQUAL_256(l_blank_out_value, l_value_delegated)) { log_it(L_ERROR, "Burning and delegated value mismatch"); - return false; + return -12; } } } - return true; + return 0; } /** diff --git a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c index bf15114299f40463be651107d60a5b19b553e62e..cd25bbb34f3c2ebec37003596d1339507e55d950 100644 --- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c +++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c @@ -48,7 +48,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply); -static bool s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, +static int s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); static void s_stake_updater_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_cond); @@ -197,21 +197,21 @@ void dap_chain_net_srv_stake_pos_delegate_deinit() s_srv_stake_list = NULL; } -static bool s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, +static int s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner) { dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_ledger->net->pub.id); - dap_return_val_if_fail(l_srv_stake, false); + dap_return_val_if_fail(l_srv_stake, -1); // It's a order conditional TX if (dap_chain_addr_is_blank(&a_cond->subtype.srv_stake_pos_delegate.signing_addr) || a_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64 == 0) { if (a_owner) - return true; + return 0; int l_out_idx = 0; dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_datum_tx_out_cond_get(a_tx_in, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, &l_out_idx); if (!l_tx_out_cond) { log_it(L_ERROR, "Condition not found in conditional tx"); - return false; + return -2; } if (compare256(l_tx_out_cond->header.value, a_cond->header.value)) { char *l_in_value = dap_chain_balance_to_coins(l_tx_out_cond->header.value); @@ -219,35 +219,35 @@ static bool s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_ou log_it(L_WARNING, "In value %s is not equal to out value %s", l_in_value, l_out_value); DAP_DELETE(l_in_value); DAP_DELETE(l_out_value); - return false; + return -3; } if (l_tx_out_cond->tsd_size != a_cond->tsd_size || memcmp(l_tx_out_cond->tsd, a_cond->tsd, a_cond->tsd_size)) { log_it(L_WARNING, "Conditional out and conditional in have different TSD sections"); - return false; + return -4; } if (dap_chain_addr_is_blank(&l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr) || l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64 == 0) { log_it(L_WARNING, "Not blank address or key fields in order conditional tx"); - return false; + return -5; } - return true; + return 0; } // It's a delegation conitional TX dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0); if (!l_tx_in_cond) { log_it(L_ERROR, "Conditional in item not found in checking tx"); - return false; + return -6; } dap_hash_fast_t *l_prev_hash = &l_tx_in_cond->header.tx_prev_hash; if (dap_hash_fast_is_blank(l_prev_hash)) { log_it(L_ERROR, "Blank hash of prev tx in tx_in_cond"); - return false; + return -7; } dap_chain_datum_tx_t *l_prev_tx = dap_ledger_tx_find_by_hash(a_ledger, l_prev_hash); if (!l_prev_tx) { log_it(L_ERROR, "Previous tx not found for now but is found in ledger before"); - return false; + return -8; } bool l_owner = false; dap_chain_tx_in_cond_t *l_tx_prev_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(l_prev_tx, 0, TX_ITEM_TYPE_IN_COND, 0); @@ -259,28 +259,28 @@ static bool s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_ou dap_sign_t *l_owner_sign = dap_chain_datum_tx_get_sign(l_owner_tx, 0); if (!l_owner_sign) { log_it(L_ERROR, "Can't get owner sign"); - return false; + return -9; } dap_sign_t *l_taker_sign = dap_chain_datum_tx_get_sign(a_tx_in, 0); if (!l_taker_sign) { log_it(L_ERROR, "Can't get taker sign"); - return false; + return -10; } l_owner = dap_sign_compare_pkeys(l_taker_sign, l_owner_sign); } if (!l_owner) { log_it(L_WARNING, "Trying to spend conditional tx not by owner"); - return false; + return -11; } if (a_tx_in->header.ts_created < 1706227200) // Jan 26 2024 00:00:00 GMT, old policy rules - return true; + return 0; dap_chain_net_srv_stake_item_t *l_stake; HASH_FIND(ht, l_srv_stake->tx_itemlist, l_prev_hash, sizeof(dap_hash_t), l_stake); if (l_stake) { log_it(L_WARNING, "Key is active with delegation decree, need to revoke it first"); - return false; + return -12; } - return true; + return 0; } static void s_stake_updater_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_cond) diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index 18c75acb556405503da65da0899da6e2c00f38e6..674a158492f94896347f7e16932eb77b3becc3ff 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -60,7 +60,7 @@ static dap_chain_net_srv_fee_item_t *s_service_fees = NULL; // Governance statem static pthread_rwlock_t s_service_fees_rwlock = PTHREAD_RWLOCK_INITIALIZER; static void s_callback_decree (dap_chain_net_srv_t * a_srv, dap_chain_net_t *a_net, dap_chain_t * a_chain, dap_chain_datum_decree_t * a_decree, size_t a_decree_size); -static bool s_xchange_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_cond_t *a_cond, +static int s_xchange_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); const dap_chain_net_srv_uid_t c_dap_chain_net_srv_xchange_uid = {.uint64= DAP_CHAIN_NET_SRV_XCHANGE_ID}; @@ -241,22 +241,22 @@ void dap_chain_net_srv_xchange_deinit() * @param a_owner * @return */ -static bool s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, +static int s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner) { if (a_owner) - return true; + return 0; if(!a_tx_in || !a_tx_out_cond) - return false; + return -1; dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0); if (!l_tx_in_cond) - return false; + return -2; if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash)) - return false; + return -3; const char *l_sell_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_in_cond->header.tx_prev_hash); if (!l_sell_ticker) - return false; + return -4; const char *l_buy_ticker = a_tx_out_cond->subtype.srv_xchange.buy_token; uint256_t l_buy_val = {}, l_fee_val = {}, @@ -318,11 +318,11 @@ static bool s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_ uint256_t l_sell_val, l_buyer_val_expected; if (compare256(l_sell_again_val, a_tx_out_cond->header.value) >= 0) - return false; + return -5; SUBTRACT_256_256(a_tx_out_cond->header.value, l_sell_again_val, &l_sell_val); MULT_256_COIN(l_sell_val, a_tx_out_cond->subtype.srv_xchange.rate, &l_buyer_val_expected); if (compare256(l_buyer_val_expected, l_buy_val) > 0) - return false; + return -6; /* Check the condition for fee verification success * out_ext.fee_addr(fee_ticker).value >= fee_value @@ -331,9 +331,9 @@ static bool s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_ if (l_service_fee_type == SERIVCE_FEE_NATIVE_PERCENT || l_service_fee_type == SERVICE_FEE_OWN_PERCENT) MULT_256_COIN(l_service_fee_val, l_sell_val, &l_service_fee_val); if (compare256(l_fee_val, l_service_fee_val) < 0) - return false; + return -7; } - return true; + return 0; } /** diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c index 760f1b45fc045830008a5a843da9b391b122155b..dc602a255c339bcea7e0b091fd6543eb2491123f 100644 --- a/modules/type/blocks/dap_chain_block.c +++ b/modules/type/blocks/dap_chain_block.c @@ -66,7 +66,7 @@ dap_chain_block_t *dap_chain_block_new(dap_chain_hash_fast_t *a_prev_block, size return NULL; } l_block->hdr.signature = DAP_CHAIN_BLOCK_SIGNATURE; - l_block->hdr.version = 1; + l_block->hdr.version = 2; l_block->hdr.ts_created = time(NULL); size_t l_block_size = sizeof(l_block->hdr); @@ -371,7 +371,7 @@ bool dap_chain_block_sign_match_pkey(const dap_chain_block_t *a_block, size_t a_ log_it(L_WARNING, "Empty or corrupted sign"); return false; } - if (dap_pkey_match_sign(a_sign_pkey, l_sign)) + if (dap_pkey_compare_with_sign(a_sign_pkey, l_sign)) return true; l_offset += l_sign_size; } diff --git a/modules/type/blocks/tests/dap_chain_blocks_test.c b/modules/type/blocks/tests/dap_chain_blocks_test.c index 289a18c3e170273816afe78593de3dbb38912460..1faa1f2e7e92ab83b2d12f607809b0ec39cd3617 100644 --- a/modules/type/blocks/tests/dap_chain_blocks_test.c +++ b/modules/type/blocks/tests/dap_chain_blocks_test.c @@ -36,7 +36,7 @@ bool dap_chain_block_test_compare_chain_hash_lists(dap_chain_t* a_chain, dap_lis dap_chain_atom_ptr_t l_atom = a_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter); for (dap_list_t *l_branch_temp = a_atoms_hash_list; l_branch_temp && l_atom; l_branch_temp = l_branch_temp->next, l_atom = a_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)){ - dap_test_msg("Check block %s : num %d and %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash), l_iter->cur_num, + dap_test_msg("Check block %s : num %" DAP_UINT64_FORMAT_U " and %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash), l_iter->cur_num, dap_chain_hash_fast_to_str_static((dap_hash_fast_t*)l_branch_temp->data)); if (!dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data)){ a_chain->callback_atom_iter_delete(l_iter); @@ -186,4 +186,4 @@ void dap_chain_blocks_test() dap_assert_PIF(ret_val == ATOM_PASS, "Add existing block into middle of forked chain. Must be passed: "); dap_pass_msg("Fork handling test: ") -} \ No newline at end of file +} diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 0ce700904af8229199d96890c481b74bc9d344d8..81c8c3552e8efd8522c46b5e5330a3c2a13c2df4 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -404,7 +404,7 @@ static int s_dap_chain_add_atom_to_events_table(dap_chain_cs_dag_t *a_dag, dap_c return -1; } dap_hash_fast_t l_datum_hash; - dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_datum_hash); + dap_chain_datum_calc_hash(l_datum, &l_datum_hash); int l_ret = dap_chain_datum_add(a_dag->chain, l_datum, l_datum_size, &l_datum_hash); if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX) // && l_ret == 0 PVT(a_dag)->tx_count++; @@ -611,7 +611,7 @@ static bool s_chain_callback_datums_pool_proc(dap_chain_t *a_chain, dap_chain_da dap_chain_cs_dag_t * l_dag = DAP_CHAIN_CS_DAG(a_chain); /* If datum passes thru rounds, let's check if it wasn't added before */ dap_chain_hash_fast_t l_datum_hash; - dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_datum_hash); + dap_chain_datum_calc_hash(a_datum, &l_datum_hash); if (!l_dag->is_add_directly) { bool l_dup_found = false; size_t l_objs_count = 0; @@ -774,8 +774,9 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_verify(dap_chain_t *a_c return ATOM_ACCEPT; } } - if (dap_chain_cs_dag_event_calc_size(l_event, a_atom_size) != a_atom_size) { - debug_if(s_debug_more, L_WARNING, "Event size not equal to expected"); + size_t l_atom_size = dap_chain_cs_dag_event_calc_size(l_event, a_atom_size); + if (l_atom_size != a_atom_size) { + log_it(L_WARNING, "Event size %zu not equal to expected %zu", l_atom_size, a_atom_size); return ATOM_REJECT; } @@ -804,26 +805,24 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_verify(dap_chain_t *a_c } //chain coherence - if (! PVT(l_dag)->events ){ - res = ATOM_MOVE_TO_THRESHOLD; - //log_it(L_DEBUG, "*** event %p goes to threshold", l_event); - } else { - //log_it(L_DEBUG, "*** event %p hash count %d",l_event, l_event->header.hash_count); - for (size_t i = 0; i< l_event->header.hash_count; i++) { - dap_chain_hash_fast_t * l_hash = ((dap_chain_hash_fast_t *) l_event->hashes_n_datum_n_signs) + i; - dap_chain_cs_dag_event_item_t * l_event_search = NULL; - pthread_mutex_lock(l_events_mutex); - HASH_FIND(hh, PVT(l_dag)->events ,l_hash ,sizeof (*l_hash), l_event_search); - pthread_mutex_unlock(l_events_mutex); - if (l_event_search == NULL) { - if(s_debug_more) { - char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(l_hash, l_hash_str, sizeof(l_hash_str)); - log_it(L_WARNING, "Hash %s wasn't in hashtable of previously parsed", l_hash_str); - } - res = ATOM_MOVE_TO_THRESHOLD; - break; + if (! PVT(l_dag)->events ) + return ATOM_MOVE_TO_THRESHOLD; + + for (size_t i = 0; i< l_event->header.hash_count; i++) { + dap_chain_hash_fast_t * l_hash = ((dap_chain_hash_fast_t *) l_event->hashes_n_datum_n_signs) + i; + dap_chain_cs_dag_event_item_t * l_event_search = NULL; + pthread_mutex_lock(l_events_mutex); + HASH_FIND(hh, PVT(l_dag)->events ,l_hash ,sizeof (*l_hash), l_event_search); + pthread_mutex_unlock(l_events_mutex); + if (l_event_search == NULL) { + if(s_debug_more) { + char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_chain_hash_fast_to_str(l_hash, l_hash_str, sizeof(l_hash_str)); + log_it(L_WARNING, "Hash %s wasn't in hashtable of previously parsed, event %s goes to threshold", + l_hash_str, dap_hash_fast_to_str_static(a_atom_hash)); } + res = ATOM_MOVE_TO_THRESHOLD; + break; } } @@ -938,7 +937,7 @@ dap_chain_cs_dag_event_item_t* s_dag_proc_treshold(dap_chain_cs_dag_t * a_dag) dap_chain_cs_dag_event_item_t * l_event_item = NULL, * l_event_item_tmp = NULL; pthread_mutex_lock(&PVT(a_dag)->events_mutex); int l_count = HASH_COUNT(PVT(a_dag)->events_treshold); - log_it(L_DEBUG, "*** %d events in threshold", l_count); + debug_if(s_debug_more, L_DEBUG, "*** %d events in threshold", l_count); HASH_ITER(hh, PVT(a_dag)->events_treshold, l_event_item, l_event_item_tmp) { dap_dag_threshold_verification_res_t ret = dap_chain_cs_dag_event_verify_hashes_with_treshold(a_dag, l_event_item->event); if (ret == DAP_THRESHOLD_OK) { diff --git a/modules/type/none/dap_chain_cs_none.c b/modules/type/none/dap_chain_cs_none.c index e6d7b4d14c0e1672fa57fa6dab2fd1d6e8dfdb61..65b7dc8771afa0cedf4492b89bbdaf9a8a429719 100644 --- a/modules/type/none/dap_chain_cs_none.c +++ b/modules/type/none/dap_chain_cs_none.c @@ -88,7 +88,7 @@ static dap_chain_datum_t *s_nonconsensus_callback_datum_iter_get_first(dap_chain static dap_chain_datum_t *s_nonconsensus_callback_datum_iter_get_next(dap_chain_datum_iter_t *a_datum_iter); static dap_chain_datum_t *s_nonconsensus_callback_datum_find_by_hash(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_datum_hash, dap_chain_hash_fast_t *a_atom_hash, int *a_ret_code); - +static uint64_t s_nonconsensus_callback_get_count_atom(dap_chain_t *a_chain); static int s_cs_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg); static void s_nonconsensus_delete(dap_chain_t *a_chain); @@ -123,12 +123,12 @@ static void s_nonconsensus_callback_mempool_notify(dap_store_obj_t *a_obj, void static void s_changes_callback_notify(dap_store_obj_t *a_obj, void *a_arg) { - dap_return_if_fail(dap_store_obj_get_type(a_obj) == DAP_GLOBAL_DB_OPTYPE_ADD && a_obj->value_len && a_obj->value); + dap_return_if_fail(a_obj->value_len && a_obj->value); dap_chain_t *l_chain = a_arg; if (dap_store_obj_get_type(a_obj) == DAP_GLOBAL_DB_OPTYPE_DEL) return; dap_hash_fast_t l_hash = {}; - dap_hash_fast(a_obj->value, a_obj->value_len, &l_hash); + dap_chain_hash_fast_from_hex_str(a_obj->key, &l_hash); s_nonconsensus_callback_atom_add(l_chain, (dap_chain_datum_t *)a_obj->value, a_obj->value_len, &l_hash); } @@ -195,7 +195,8 @@ static int s_cs_callback_new(dap_chain_t *a_chain, dap_config_t UNUSED_ARG *a_ch a_chain->callback_atom_get_datums = s_nonconsensus_callback_atom_get_datum; a_chain->callback_atom_get_timestamp = s_nonconsensus_callback_atom_get_timestamp; - + // Get atom count in chain + a_chain->callback_count_atom = s_nonconsensus_callback_get_count_atom; // Datum callbacks a_chain->callback_datum_iter_create = s_nonconsensus_callback_datum_iter_create; a_chain->callback_datum_iter_delete = s_nonconsensus_callback_datum_iter_delete; @@ -264,7 +265,7 @@ static void s_nonconsensus_ledger_load(dap_chain_t *a_chain) dap_global_db_obj_t *it = l_values + i; // load ledger dap_hash_fast_t l_hash = {}; - dap_hash_fast(it->value, it->value_len, &l_hash); + dap_chain_hash_fast_from_hex_str(it->key, &l_hash); s_nonconsensus_callback_atom_add(a_chain, it->value, it->value_len, &l_hash); log_it(L_DEBUG,"Load mode, doesn't save item %s:%s", it->key, l_nochain_pvt->group_datums); } @@ -286,7 +287,7 @@ static size_t s_nonconsensus_callback_datums_pool_proc(dap_chain_t * a_chain, da dap_chain_datum_t *l_datum = a_datums[i]; dap_hash_fast_t l_datum_hash; char l_db_key[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_datum_hash); + dap_chain_datum_calc_hash(l_datum, &l_datum_hash); dap_chain_hash_fast_to_str(&l_datum_hash, l_db_key, sizeof(l_db_key)); int l_rc = dap_chain_net_verify_datum_for_add(a_chain, l_datum, &l_datum_hash); if (l_rc != 0) { @@ -521,6 +522,16 @@ static dap_chain_datum_t **s_nonconsensus_callback_atom_get_datum(dap_chain_atom return NULL; } +static uint64_t s_nonconsensus_callback_get_count_atom(dap_chain_t *a_chain) +{ + dap_return_val_if_fail(a_chain, 0); + dap_nonconsensus_datum_hash_item_t *l_head = PVT(DAP_NONCONSENSUS(a_chain))->hash_items; + dap_nonconsensus_datum_hash_item_t *tmp; + uint64_t l_counter; + DL_COUNT(l_head, tmp, l_counter); + return l_counter; +} + static dap_chain_datum_iter_t *s_nonconsensus_callback_datum_iter_create(dap_chain_t *a_chain) { dap_chain_datum_iter_t *l_ret = DAP_NEW_Z(dap_chain_datum_iter_t); diff --git a/project.yaml b/project.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b6755cc4839b38db5664ad426d50f56ff3698ff8 --- /dev/null +++ b/project.yaml @@ -0,0 +1,20 @@ + +build_dependencies: + deb: + - 'build-essential' + - 'cmake' + - 'libmagic-dev' + - 'libsqlite3-dev' + - 'libjson-c-dev' + - 'libffi-dev' + - 'file' + - 'python3-dev' + - 'curl' + - 'jq' + - 'xsltproc' + + +deploy_dependencies: + deb: + - 'ssh' +