From 7d57e8a9936702ebaf3bb9546541950c807dd6e2 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 23 Sep 2022 18:45:22 +0200 Subject: [PATCH 1/6] coretests: chaingen PoS refactored, mining outside-of-wallet2 eliminated, code unified --- src/currency_core/currency_basic.h | 3 +- tests/CMakeLists.txt | 3 +- tests/core_tests/chaingen.cpp | 242 ++++++++++++++++++----------- tests/core_tests/chaingen.h | 16 +- tests/core_tests/chaingen_main.cpp | 4 +- tests/core_tests/chaingen_pch.cpp | 5 + 6 files changed, 165 insertions(+), 108 deletions(-) create mode 100644 tests/core_tests/chaingen_pch.cpp diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index 375dd6e6..afc3803b 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -989,7 +989,8 @@ namespace currency uint64_t tx_out_index; // stake output local index in its tx //not for serialization - uint64_t wallet_index; + + uint64_t wallet_index; // transfer id index BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(amount) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2ebb23bf..183cc861 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -62,8 +62,9 @@ add_test(coretests coretests) # set PCH for core_tests if(MSVC AND USE_PCH) + add_definitions("/DUSE_PCH") set_property(TARGET coretests APPEND_STRING PROPERTY COMPILE_FLAGS " /Yuchaingen.h /Zm1000") - set_property(SOURCE "core_tests/chaingen.cpp" APPEND_STRING PROPERTY COMPILE_FLAGS " /Ycchaingen.h /Zm1000") + set_property(SOURCE "core_tests/chaingen_pch.cpp" APPEND_STRING PROPERTY COMPILE_FLAGS " /Ycchaingen.h /Zm1000") set_property(TARGET coretests functional_tests hash-target-tests performance_tests unit_tests APPEND_STRING PROPERTY LINK_FLAGS "$(MSBuildProjectDirectory)/../src/$(ConfigurationName)/stdafx.obj") set_property(TARGET db_tests APPEND_STRING PROPERTY LINK_FLAGS "$(MSBuildProjectDirectory)/../../src/$(ConfigurationName)/stdafx.obj") endif() diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 41c149bc..ba41b14e 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -6,6 +6,8 @@ #define USE_INSECURE_RANDOM_RPNG_ROUTINES // turns on pseudorandom number generator manupulations for tests +#include "chaingen.h" + #include #include #include @@ -20,7 +22,6 @@ #include "currency_core/miner.h" #include "currency_core/bc_offers_service.h" #include "wallet/wallet2.h" -#include "chaingen.h" #include "wallet_test_core_proxy.h" #include "pos_block_builder.h" @@ -50,7 +51,6 @@ const crypto::signature invalid_signature = create_invalid_signature(); test_generator::test_generator() : m_wallet_test_core_proxy(new wallet_test_core_proxy()) , m_ignore_last_pow_in_wallets(false) - , m_last_found_timestamp(0) { } @@ -216,6 +216,7 @@ bool test_generator::construct_block(currency::block& blk, const std::list& tx_list, const std::list& coin_stake_sources)//in case of PoS block { + bool r = false; // if (height > m_hardfork_01_after_heigh) // blk.major_version = CURRENT_BLOCK_MAJOR_VERSION; // else @@ -229,7 +230,7 @@ bool test_generator::construct_block(currency::block& blk, crypto::hash kernerl_hash = null_hash; blk.tx_hashes.reserve(tx_list.size()); - BOOST_FOREACH(const transaction &tx, tx_list) + for(const transaction &tx : tx_list) { crypto::hash tx_hash; get_transaction_hash(tx, tx_hash); @@ -238,7 +239,7 @@ bool test_generator::construct_block(currency::block& blk, uint64_t total_fee = 0; size_t txs_size = 0; - BOOST_FOREACH(auto& tx, tx_list) + for(auto& tx : tx_list) { uint64_t fee = 0; bool r = get_tx_fee(tx, fee); @@ -281,19 +282,19 @@ bool test_generator::construct_block(currency::block& blk, size_t target_block_size = txs_size + 0; // zero means no cost for ordinary coinbase while (true) { - if (!construct_miner_tx(height, misc_utils::median(block_sizes), + r = construct_miner_tx(height, misc_utils::median(block_sizes), already_generated_coins, - target_block_size, - total_fee, - miner_acc.get_keys().account_address, + target_block_size, + total_fee, miner_acc.get_keys().account_address, - blk.miner_tx, + miner_acc.get_keys().account_address, + blk.miner_tx, get_tx_version(height, m_hardforks), blobdata(), test_generator::get_test_gentime_settings().miner_tx_max_outs, - static_cast(coin_stake_sources.size()), - pe)) - return false; + static_cast(coin_stake_sources.size()), + pe); + CHECK_AND_ASSERT_MES(r, false, "construct_miner_tx failed"); size_t coinbase_size = get_object_blobsize(blk.miner_tx); if (coinbase_size <= CURRENCY_COINBASE_BLOB_RESERVED_SIZE) // if less than that constant then coinbase goes for free @@ -381,7 +382,7 @@ bool test_generator::sign_block(currency::block& b, return true; } -bool test_generator::build_wallets(const blockchain_vector& blocks, +bool test_generator::build_wallets(const blockchain_vector& blockchain, const std::list& accs, const tx_global_indexes& txs_outs, wallets_vector& wallets, @@ -390,9 +391,14 @@ bool test_generator::build_wallets(const blockchain_vector& blocks, struct stub_core_proxy: public tools::i_core_proxy { const tx_global_indexes& m_txs_outs; - stub_core_proxy(const tx_global_indexes& txs_outs) : m_txs_outs(txs_outs) + const blockchain_vector& m_blockchain; + + stub_core_proxy(const blockchain_vector& blockchain, const tx_global_indexes& txs_outs) + : m_blockchain(blockchain) + , m_txs_outs(txs_outs) {} - virtual bool call_COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES(const currency::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& rqt, currency::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& rsp) + + bool call_COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES(const currency::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& rqt, currency::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& rsp) override { rsp.tx_global_outs.resize(rqt.txids.size()); size_t i = 0; @@ -406,9 +412,47 @@ bool test_generator::build_wallets(const blockchain_vector& blocks, rsp.status = API_RETURN_CODE_OK; return true; } + + bool call_COMMAND_RPC_GET_POS_MINING_DETAILS(const currency::COMMAND_RPC_GET_POS_MINING_DETAILS::request& req, currency::COMMAND_RPC_GET_POS_MINING_DETAILS::response& rsp) override + { + rsp.pos_mining_allowed = true; + if (!rsp.pos_mining_allowed) + { + rsp.status = API_RETURN_CODE_NOT_FOUND; + return true; + } + + build_stake_modifier(rsp.sm, m_blockchain); + + //rsp.pos_basic_difficulty = m_core.get_blockchain_storage().get_next_diff_conditional(true).convert_to(); + //rsp.starter_timestamp = m_core.get_blockchain_storage().get_last_timestamps_check_window_median(); + //uint64_t i_last_pos_block = get_last_block_of_type(true, m_blockchain); + //uint64_t last_pos_block_timestamp = 0; + //if(i_last_pos_block) + // last_pos_block_timestamp = m_blockchain[i_last_pos_block]->b.timestamp; + //else + // last_pos_block_timestamp = m_blockchain.back()->b.timestamp - DIFFICULTY_POS_TARGET/2; + //uint64_t starter_timestamp = last_pos_block_timestamp + DIFFICULTY_POS_TARGET; + //uint64_t median_timestamp = get_timestamps_median(m_blockchain); + //if (starter_timestamp < median_timestamp) + // starter_timestamp = median_timestamp; + //if (basic_diff < 10) + // starter_timestamp -= 90; + //starter_timestamp = POS_SCAN_STEP - (starter_timestamp%POS_SCAN_STEP) + starter_timestamp; + + uint64_t median_timestamp = get_timestamps_median(m_blockchain); + rsp.starter_timestamp = median_timestamp; // the core uses median timestamp as starter timestamp, here we mimic this behaviour -- sowle + + wide_difficulty_type basic_diff = get_difficulty_for_next_block(m_blockchain, false); + rsp.pos_basic_difficulty = basic_diff.convert_to(); + + rsp.status = API_RETURN_CODE_OK; + return true; + } + }; - std::shared_ptr tmp_proxy(new stub_core_proxy(txs_outs)); + std::shared_ptr tmp_proxy(new stub_core_proxy(blockchain, txs_outs)); //build wallets wallets.clear(); @@ -423,13 +467,15 @@ bool test_generator::build_wallets(const blockchain_vector& blocks, pc.min_coinstake_age = TESTS_POS_CONFIG_MIN_COINSTAKE_AGE; pc.pos_minimum_heigh = TESTS_POS_CONFIG_POS_MINIMUM_HEIGH; pc.hard_forks = m_hardforks; + pc.get_core_time = test_core_time::get_time; + wallets.back()->set_core_runtime_config(pc); } for (auto& w : wallets) { uint64_t height = 0; - for (auto& b : blocks) + for (auto& b : blockchain) { uint64_t h = get_block_height(b->b); if (!h) @@ -481,7 +527,7 @@ size_t test_generator::get_tx_out_gindex(const crypto::hash& blockchain_head, co } -uint64_t test_generator::get_timestamps_median(const blockchain_vector& blck_chain, size_t window_size /* = BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW */) +/* static */ uint64_t test_generator::get_timestamps_median(const blockchain_vector& blck_chain, size_t window_size /* = BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW */) { std::vector timestamps; for(size_t i = blck_chain.size() - std::min(blck_chain.size(), window_size); i < blck_chain.size(); ++i) @@ -507,65 +553,111 @@ bool test_generator::find_kernel(const std::list& accs, uint64_t& found_timestamp, crypto::hash& found_kh) { + bool r = false; // TODO: consiger removing this function completely in order to unify pos mining code -- sowle - //bool is_after_hardfork_01 = m_hardforks.is_hardfork_active_for_height(1, blck_chain.size()); - uint64_t median_timestamp = get_timestamps_median(blck_chain); - wide_difficulty_type basic_diff = 0; - + /* uint64_t i_last_pos_block = get_last_block_of_type(true, blck_chain); - uint64_t last_pos_block_timestamp = 0; if(i_last_pos_block) last_pos_block_timestamp = blck_chain[i_last_pos_block]->b.timestamp; else last_pos_block_timestamp = blck_chain.back()->b.timestamp - DIFFICULTY_POS_TARGET/2; - uint64_t starter_timestamp = last_pos_block_timestamp + DIFFICULTY_POS_TARGET; - + uint64_t median_timestamp = get_timestamps_median(blck_chain); if (starter_timestamp < median_timestamp) starter_timestamp = median_timestamp; - - m_last_found_timestamp = 0; - basic_diff = get_difficulty_for_next_block(blck_chain, false); + wide_difficulty_type basic_diff = get_difficulty_for_next_block(blck_chain, false); if (basic_diff < 10) - { starter_timestamp -= 90; - } - - //adjust timestamp starting from timestamp%POS_SCAN_STEP = 0 - //starter_timestamp = starter_timestamp - POS_SCAN_WINDOW; starter_timestamp = POS_SCAN_STEP - (starter_timestamp%POS_SCAN_STEP) + starter_timestamp; + */ - for (uint64_t ts = starter_timestamp; ts < starter_timestamp + POS_SCAN_WINDOW/2; ts += POS_SCAN_STEP) + //for (uint64_t ts = starter_timestamp; ts < starter_timestamp + POS_SCAN_WINDOW/2; ts += POS_SCAN_STEP) + + uint64_t last_block_ts = !blck_chain.empty() ? blck_chain.back()->b.timestamp : test_core_time::get_time(); + + //lets try to find block + for (size_t wallet_index = 0, size = wallets.size(); wallet_index < size; ++wallet_index) { - //lets try to find block - for (auto& w : wallets) + std::shared_ptr w = wallets[wallet_index]; + //set m_last_pow_block_h to big value, to let wallet to use any available outputs, including the those which is not behind last pow block + if (m_ignore_last_pow_in_wallets) + w->m_last_pow_block_h = CURRENCY_MAX_BLOCK_NUMBER; + + tools::wallet2::mining_context context = AUTO_VAL_INIT(context); + w->fill_mining_context(context); + + std::atomic stop(false); + + //if (test_core_time::get_time() < last_block_ts) + test_core_time::adjust(last_block_ts); + + if (w->scan_pos(context, stop, [](){ return true; }, w->get_core_runtime_config())) { - //set m_last_pow_block_h to big value, to let wallet to use any available outputs, including the those which is not behind last pow block - if (m_ignore_last_pow_in_wallets) - w->m_last_pow_block_h = CURRENCY_MAX_BLOCK_NUMBER; + //found kernel + found_wallet_index = wallet_index; + found_kh = crypto::cn_fast_hash(&context.sk, sizeof(context.sk)); // TODO: consider passing kernel_hash from scan_pos and do_pos_mining_iteration + found_timestamp = context.sk.block_timestamp; - std::vector pos_entries; - bool r = w->get_pos_entries(pos_entries); - CHECK_AND_ASSERT_THROW_MES(r, "Failed to get_pos_entries"); + tools::wallet2::transfer_details td = AUTO_VAL_INIT(td); + r = w->get_transfer_info_by_index(context.index, td); + CHECK_AND_NO_ASSERT_MES(r, false, "get_transfer_info_by_index() failed for index " << context.index); + + pe.amount = td.amount(); + pe.block_timestamp = context.sk.block_timestamp; + pe.g_index = td.m_global_output_index; + pe.keyimage = td.m_key_image; + pe.stake_unlock_time = context.stake_unlock_time; + pe.tx_id = td.tx_hash(); + pe.tx_out_index = td.m_internal_output_index; + pe.wallet_index = context.index; + + LOG_PRINT_GREEN("Found kernel: amount=" << print_money_brief(pe.amount) + << ", index=" << pe.g_index + << ", key_image" << pe.keyimage + /*<< ", diff: " << this_coin_diff*/, LOG_LEVEL_0); + + return true; + } + + /* + uint64_t h = 0; + uint64_t out_i = 0; + const transaction * pts = nullptr; + crypto::public_key source_tx_pub_key = null_pkey; + crypto::public_key out_key = null_pkey; + r = get_output_details_by_global_index(blck_chain, + indexes, + pos_entries[i].amount, + pos_entries[i].g_index, + h, + pts, + out_i, + source_tx_pub_key, + out_key); + CHECK_AND_ASSERT_THROW_MES(r,"Failed to get_output_details_by_global_index()"); + sk.block_timestamp = ts; + sk.kimage = pos_entries[i].keyimage; + //build_stake_modifier(sk.stake_modifier, blck_chain); + sk.stake_modifier = stake_modifier_type(); + uint64_t last_pos_i = get_last_block_of_type(true, blck_chain); + uint64_t last_pow_i = get_last_block_of_type(false, blck_chain); + if (last_pos_i) + { + sk.stake_modifier.last_pos_kernel_id = blck_chain[last_pos_i]->ks_hash; + } + else + { + r = string_tools::parse_tpod_from_hex_string(POS_STARTER_KERNEL_HASH, sk.stake_modifier.last_pos_kernel_id); + CHECK_AND_ASSERT_MES(r, false, "Failed to parse POS_STARTER_KERNEL_HASH"); + } + sk.stake_modifier.last_pow_id = get_block_hash(blck_chain[last_pow_i]->b); - for (size_t i = 0; i != pos_entries.size(); i++) - { - stake_kernel sk = AUTO_VAL_INIT(sk); - build_kernel(pos_entries[i].amount, - pos_entries[i].g_index, - pos_entries[i].keyimage, - sk, - blck_chain, - indexes, - ts); crypto::hash kernel_hash = crypto::cn_fast_hash(&sk, sizeof(sk)); wide_difficulty_type this_coin_diff = basic_diff / pos_entries[i].amount; - if (!check_hash(kernel_hash, this_coin_diff)) - continue; - else + if (check_hash(kernel_hash, this_coin_diff)) { //found kernel LOG_PRINT_GREEN("Found kernel: amount=" << print_money(pos_entries[i].amount) @@ -580,6 +672,7 @@ bool test_generator::find_kernel(const std::list& accs, } } } + */ } return false; @@ -645,41 +738,6 @@ bool test_generator::get_output_details_by_global_index(const test_generator::bl return true; } //------------------------------------------------------------------ -bool test_generator::build_kernel(uint64_t amount, - uint64_t global_index, - const crypto::key_image& ki, - stake_kernel& kernel, - const test_generator::blockchain_vector& blck_chain, - const test_generator::outputs_index& indexes, - uint64_t timestamp) -{ - kernel = stake_kernel(); - kernel.kimage = ki; - - //get block related with coinstake source transaction - uint64_t h = 0; - uint64_t out_i = 0; - const transaction * pts = nullptr; - crypto::public_key source_tx_pub_key = null_pkey; - crypto::public_key out_key = null_pkey; - - bool r = get_output_details_by_global_index(blck_chain, - indexes, - amount, - global_index, - h, - pts, - out_i, - source_tx_pub_key, - out_key); - CHECK_AND_ASSERT_THROW_MES(r,"Failed to get_output_details_by_global_index()"); - - kernel.block_timestamp = timestamp; - - build_stake_modifier(kernel.stake_modifier, blck_chain); - return true; -} - bool test_generator::build_stake_modifier(stake_modifier_type& sm, const test_generator::blockchain_vector& blck_chain) { @@ -697,8 +755,6 @@ bool test_generator::build_stake_modifier(stake_modifier_type& sm, const test_ge } sm.last_pow_id = get_block_hash(blck_chain[last_pow_i]->b); - - return true; } @@ -710,7 +766,7 @@ currency::wide_difficulty_type test_generator::get_difficulty_for_next_block(con return get_difficulty_for_next_block(blocks, pow); } -currency::wide_difficulty_type test_generator::get_difficulty_for_next_block(const std::vector& blocks, bool pow) const +/* static */ currency::wide_difficulty_type test_generator::get_difficulty_for_next_block(const std::vector& blocks, bool pow) { std::vector timestamps; std::vector commulative_difficulties; diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index b7f4e97d..24026886 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -390,7 +390,7 @@ public: test_generator(); //----------- - currency::wide_difficulty_type get_difficulty_for_next_block(const std::vector& blocks, bool pow = true) const; + static currency::wide_difficulty_type get_difficulty_for_next_block(const std::vector& blocks, bool pow = true); currency::wide_difficulty_type get_difficulty_for_next_block(const crypto::hash& head_id, bool pow = true) const; currency::wide_difficulty_type get_cumul_difficulty_for_next_block(const crypto::hash& head_id, bool pow = true) const; void get_block_chain(std::vector& blockchain, const crypto::hash& head, size_t n) const; @@ -403,14 +403,7 @@ public: //POS - bool build_stake_modifier(currency::stake_modifier_type& sm, const test_generator::blockchain_vector& blck_chain); - bool build_kernel(uint64_t amount, - uint64_t global_index, - const crypto::key_image& ki, - currency::stake_kernel& kernel, - const blockchain_vector& blck_chain, - const outputs_index& indexes, - uint64_t timestamp); + static bool build_stake_modifier(currency::stake_modifier_type& sm, const test_generator::blockchain_vector& blck_chain); bool find_kernel(const std::list& accs, const blockchain_vector& blck_chain, @@ -457,7 +450,7 @@ public: uint64_t get_already_generated_coins(const currency::block& blk) const; currency::wide_difficulty_type get_block_difficulty(const crypto::hash& blk_id) const; currency::wide_difficulty_type get_cumul_difficulty(const crypto::hash& head_id) const; - uint64_t get_timestamps_median(const blockchain_vector& blck_chain, size_t window_size = BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW); + static uint64_t get_timestamps_median(const blockchain_vector& blck_chain, size_t window_size = BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW); uint64_t get_timestamps_median(const crypto::hash& blockchain_head, size_t window_size = BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW); bool build_outputs_indext_for_chain(const std::vector& blocks, outputs_index& index, tx_global_indexes& txs_outs) const; @@ -533,7 +526,6 @@ public: private: bool m_ignore_last_pow_in_wallets; - uint64_t m_last_found_timestamp; currency::hard_forks_descriptor m_hardforks; @@ -1090,7 +1082,7 @@ void append_vector_by_another_vector(U& dst, const V& src) VEC_EVENTS.push_back(event_core_time(next_block.timestamp - 10)); \ VEC_EVENTS.push_back(next_block); \ BLK_NAME = next_block; \ - } + } #define REWIND_BLOCKS(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC) REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, CURRENCY_MINED_MONEY_UNLOCK_WINDOW) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index f5feb5c9..12a0de86 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -129,7 +129,9 @@ bool generate_and_play(const char* const genclass_name) LOG_ERROR(genclass_name << " generation failed: generic exception"); } - std::cout << concolor::bright_white << "#TEST# " << genclass_name << ": start replaying events" << concolor::normal << std::endl; + std::cout << concolor::bright_white << std::string(100, '=') << std::endl << + "#TEST# >>>> " << genclass_name << " <<<< start replaying events" << std::endl << + std::string(100, '=') << concolor::normal << std::endl; if (generated && do_replay_events(events, g)) { diff --git a/tests/core_tests/chaingen_pch.cpp b/tests/core_tests/chaingen_pch.cpp new file mode 100644 index 00000000..11878762 --- /dev/null +++ b/tests/core_tests/chaingen_pch.cpp @@ -0,0 +1,5 @@ +// Copyright (c) 2022 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#pragma once +#include "chaingen.h" From 0bfe224b6698abe2e99806286f66df9ff9cd3b2f Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 23 Sep 2022 18:45:59 +0200 Subject: [PATCH 2/6] minor fixes --- src/crypto/crypto-sugar.h | 6 ++++-- src/currency_core/blockchain_storage.cpp | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index 280a8f79..b1ff763e 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -28,7 +28,8 @@ namespace crypto size_t len = sizeof h; std::string s(len * 2, ' '); - for (size_t i = 0; i < len; ++i) { + for (size_t i = 0; i < len; ++i) + { s[2 * i] = hexmap[data[len - 1 - i] >> 4]; s[2 * i + 1] = hexmap[data[len - 1 - i] & 0x0F]; } @@ -44,7 +45,8 @@ namespace crypto size_t len = sizeof h; std::string s(len * 2, ' '); - for (size_t i = 0; i < len; ++i) { + for (size_t i = 0; i < len; ++i) + { s[2 * i] = hexmap[data[i] >> 4]; s[2 * i + 1] = hexmap[data[i] & 0x0F]; } diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 2bc96086..17a31453 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -4880,7 +4880,7 @@ bool blockchain_storage::check_block_timestamp_main(const block& b) const } if (is_pos_block(b) && b.timestamp > get_adjusted_time() + CURRENCY_POS_BLOCK_FUTURE_TIME_LIMIT) { - LOG_PRINT_L0("Timestamp of PoS block with id: " << get_block_hash(b) << ", " << b.timestamp << ", bigger than adjusted time + " + epee::misc_utils::get_time_interval_string(CURRENCY_POS_BLOCK_FUTURE_TIME_LIMIT) + ": " << get_adjusted_time() << " (" << b.timestamp - get_adjusted_time() << ")"); + LOG_PRINT_L0("Timestamp of PoS block with id: " << get_block_hash(b) << ", " << b.timestamp << ", bigger than adjusted time + " + epee::misc_utils::get_time_interval_string(CURRENCY_POS_BLOCK_FUTURE_TIME_LIMIT) + ": " << get_adjusted_time() + CURRENCY_POS_BLOCK_FUTURE_TIME_LIMIT << " (" << b.timestamp - get_adjusted_time() - CURRENCY_POS_BLOCK_FUTURE_TIME_LIMIT << ")"); return false; } @@ -5590,8 +5590,8 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt if(!check_block_timestamp_main(bl)) { LOG_PRINT_L0("Block with id: " << id << ENDL - << "have invalid timestamp: " << bl.timestamp); - //add_block_as_invalid(bl, id);//do not add blocks to invalid storage befor proof of work check was passed + << "has invalid timestamp: " << bl.timestamp); + // do not add this block to invalid block list prior to proof of work check bvc.m_verification_failed = true; return false; } From 078440a815336b07e6e4b7c63627ab435b1f1d7b Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 23 Sep 2022 22:18:22 +0200 Subject: [PATCH 3/6] zarcanum WIP (use standard derivation to scalar conversion to simplify things) + minor --- src/currency_core/currency_format_utils.cpp | 6 ++- src/currency_core/tx_semantic_validation.cpp | 2 +- src/wallet/wallet2.cpp | 2 +- tests/core_tests/chaingen.cpp | 46 ++++++++++---------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 3292ab8c..16a2729b 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -912,7 +912,8 @@ namespace currency { // normal output crypto::public_key derivation = (crypto::scalar_t(tx_sec_key) * crypto::point_t(apa.view_public_key)).modify_mul8().to_public_key(); // d = 8 * r * V - crypto::scalar_t h = crypto::hash_helper_t::hs(derivation, output_index); + crypto::scalar_t h; // = crypto::hash_helper_t::hs(derivation, output_index); + crypto::derivation_to_scalar((const crypto::key_derivation&)derivation, output_index, h.as_secret_key()); // h = Hs(8 * r * V, i) out.stealth_address = (h * crypto::c_point_G + crypto::point_t(apa.spend_public_key)).to_public_key(); out.concealing_point = (crypto::c_scalar_1div8 * crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_CONCEALING_POINT, h) * crypto::point_t(apa.view_public_key)).to_public_key(); // Q = 1/8 * Hs(domain_sep, h) * V @@ -2452,7 +2453,8 @@ namespace currency bool is_out_to_acc(const account_keys& acc, const tx_out_zarcanum& zo, const crypto::key_derivation& derivation, size_t output_index, uint64_t& decoded_amount, crypto::scalar_t& blinding_mask) { - crypto::scalar_t h = crypto::hash_helper_t::hs(reinterpret_cast(derivation), output_index); // h = Hs(8 * r * V, i) + crypto::scalar_t h; // = crypto::hash_helper_t::hs(reinterpret_cast(derivation), output_index); // h = Hs(8 * r * V, i) + crypto::derivation_to_scalar(derivation, output_index, h.as_secret_key()); // h = Hs(8 * r * V, i) crypto::point_t P_prime = h * crypto::c_point_G + crypto::point_t(acc.account_address.spend_public_key); // P =? Hs(8rV, i) * G + S if (P_prime.to_public_key() != zo.stealth_address) diff --git a/src/currency_core/tx_semantic_validation.cpp b/src/currency_core/tx_semantic_validation.cpp index ec7019f4..269652f7 100644 --- a/src/currency_core/tx_semantic_validation.cpp +++ b/src/currency_core/tx_semantic_validation.cpp @@ -68,7 +68,7 @@ namespace currency if (!check_tx_balance(tx)) { - LOG_PRINT_RED_L0("tx balance check failed, tx id= " << get_transaction_hash(tx)); + LOG_PRINT_RED_L0("balance check failed for tx " << get_transaction_hash(tx)); return false; } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 4aa78072..d79093aa 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -714,7 +714,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t if (out_type_to_key || out_type_zc) { - WLT_LOG_L0("Received money, transfer #" << transfer_index << ", amount: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx) << ", at height " << height); + WLT_LOG_L0("Received money, transfer #" << transfer_index << ", amount: " << print_money_brief(td.amount()) << (out_type_zc ? " (hidden)" : "") << ", with tx: " << get_transaction_hash(tx) << ", at height " << height); } else if (out_is_to_htlc(out_v)) { diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index ba41b14e..8f48d338 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -217,13 +217,9 @@ bool test_generator::construct_block(currency::block& blk, const std::list& coin_stake_sources)//in case of PoS block { bool r = false; -// if (height > m_hardfork_01_after_heigh) -// blk.major_version = CURRENT_BLOCK_MAJOR_VERSION; -// else -// blk.major_version = BLOCK_MAJOR_VERSION_INITIAL; + bool pos = coin_stake_sources.size() > 0; blk.major_version = m_hardforks.get_block_major_version_by_height(height); - blk.minor_version = CURRENT_BLOCK_MINOR_VERSION; blk.timestamp = timestamp; blk.prev_id = prev_id; @@ -259,21 +255,21 @@ bool test_generator::construct_block(currency::block& blk, size_t won_walled_index = 0; pos_entry pe = AUTO_VAL_INIT(pe); - if (coin_stake_sources.size()) + if (pos) { //build outputs index build_outputs_indext_for_chain(blocks, oi, txs_outs); //build wallets build_wallets(blocks, coin_stake_sources, txs_outs, wallets); - bool r = find_kernel(coin_stake_sources, - blocks, - oi, - wallets, - pe, - won_walled_index, - blk.timestamp, - kernerl_hash); + r = find_kernel(coin_stake_sources, + blocks, + oi, + wallets, + pe, + won_walled_index, + blk.timestamp, + kernerl_hash); CHECK_AND_ASSERT_THROW_MES(r, "failed to find_kernel "); blk.flags = CURRENCY_BLOCK_FLAG_POS_BLOCK; } @@ -325,7 +321,7 @@ bool test_generator::construct_block(currency::block& blk, CHECK_AND_ASSERT_MES(a_diffic, false, "get_difficulty_for_next_block for test blocks returned 0!"); // Nonce search... blk.nonce = 0; - if (!coin_stake_sources.size()) + if (!pos) { //pow block while (!find_nounce(blk, blocks, a_diffic, height)) @@ -334,7 +330,7 @@ bool test_generator::construct_block(currency::block& blk, else { //need to build pos block - bool r = sign_block(blk, pe, *wallets[won_walled_index], blocks, oi); + r = sign_block(blk, pe, *wallets[won_walled_index], blocks, oi); CHECK_AND_ASSERT_MES(r, false, "Failed to find_kernel_and_sign()"); } @@ -392,10 +388,12 @@ bool test_generator::build_wallets(const blockchain_vector& blockchain, { const tx_global_indexes& m_txs_outs; const blockchain_vector& m_blockchain; + const core_runtime_config& m_core_runtime_config; - stub_core_proxy(const blockchain_vector& blockchain, const tx_global_indexes& txs_outs) + stub_core_proxy(const blockchain_vector& blockchain, const tx_global_indexes& txs_outs, const core_runtime_config& crc) : m_blockchain(blockchain) , m_txs_outs(txs_outs) + , m_core_runtime_config(crc) {} bool call_COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES(const currency::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& rqt, currency::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& rsp) override @@ -415,10 +413,10 @@ bool test_generator::build_wallets(const blockchain_vector& blockchain, bool call_COMMAND_RPC_GET_POS_MINING_DETAILS(const currency::COMMAND_RPC_GET_POS_MINING_DETAILS::request& req, currency::COMMAND_RPC_GET_POS_MINING_DETAILS::response& rsp) override { - rsp.pos_mining_allowed = true; + rsp.pos_mining_allowed = m_blockchain.size() >= m_core_runtime_config.pos_minimum_heigh; if (!rsp.pos_mining_allowed) { - rsp.status = API_RETURN_CODE_NOT_FOUND; + rsp.status = API_RETURN_CODE_FAIL; return true; } @@ -452,7 +450,7 @@ bool test_generator::build_wallets(const blockchain_vector& blockchain, }; - std::shared_ptr tmp_proxy(new stub_core_proxy(blockchain, txs_outs)); + std::shared_ptr tmp_proxy(new stub_core_proxy(blockchain, txs_outs, cc)); //build wallets wallets.clear(); @@ -597,8 +595,8 @@ bool test_generator::find_kernel(const std::list& accs, { //found kernel found_wallet_index = wallet_index; - found_kh = crypto::cn_fast_hash(&context.sk, sizeof(context.sk)); // TODO: consider passing kernel_hash from scan_pos and do_pos_mining_iteration found_timestamp = context.sk.block_timestamp; + found_kh = crypto::cn_fast_hash(&context.sk, sizeof(context.sk)); // TODO: consider passing kernel_hash from scan_pos and do_pos_mining_iteration tools::wallet2::transfer_details td = AUTO_VAL_INIT(td); r = w->get_transfer_info_by_index(context.index, td); @@ -614,9 +612,9 @@ bool test_generator::find_kernel(const std::list& accs, pe.wallet_index = context.index; LOG_PRINT_GREEN("Found kernel: amount=" << print_money_brief(pe.amount) - << ", index=" << pe.g_index - << ", key_image" << pe.keyimage - /*<< ", diff: " << this_coin_diff*/, LOG_LEVEL_0); + << ", gindex=" << pe.g_index + << ", key_image=" << pe.keyimage + /*<< ", diff: " << this_coin_diff*/, LOG_LEVEL_1); return true; } From 5d349a963d927adf5f6be2ac86487b45a381770a Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 27 Sep 2022 03:06:10 +0200 Subject: [PATCH 4/6] 1) construct_miner_tx now supports post-HF4 PoW 2) new HF4 core rules: at least 2 outputs for each tx; tx.version > 1 --- src/currency_core/blockchain_storage.cpp | 9 ++++- src/currency_core/currency_format_utils.cpp | 37 +++++++++------------ src/currency_core/miner.h | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 17a31453..b339e020 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -4028,9 +4028,13 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const TIME_MEASURE_FINISH_PD_COND(need_to_profile, tx_store_db); TIME_MEASURE_START_PD(tx_print_log); + static const std::string hidden("hidden"); LOG_PRINT_L1("Added tx to blockchain: " << tx_id << " via block at " << bl_height << " id " << print16(bl_id) - << ", ins: " << tx.vin.size() << ", outs: " << tx.vout.size() << ", outs sum: " << print_money_brief(get_outs_money_amount(tx)) << " (fee: " << (is_coinbase(tx) ? "0[coinbase]" : print_money_brief(get_tx_fee(tx))) << ")"); + << ", ins: " << tx.vin.size() << ", outs: " << tx.vout.size() + << ", outs sum: " << (tx.version > TRANSACTION_VERSION_PRE_HF4 ? hidden : print_money_brief(get_outs_money_amount(tx))) + << " (fee: " << (is_coinbase(tx) ? "0 [coinbase]" : print_money_brief(get_tx_fee(tx))) << ")"); TIME_MEASURE_FINISH_PD_COND(need_to_profile, tx_print_log); + //@#@ del me // LOG_PRINT_L0("APPEND_TX_TIME_INNER: " << m_performance_data.tx_append_rl_wait.get_last_val() // << " | " << m_performance_data.tx_append_is_expired.get_last_val() @@ -5225,6 +5229,9 @@ bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transacti if (var_is_after_hardfork_4_zone) { + CHECK_AND_ASSERT_MES(tx.version > TRANSACTION_VERSION_PRE_HF4, false, "HF4: tx with version " << tx.version << " is not allowed"); + CHECK_AND_ASSERT_MES(tx.vout.size() >= CURRENCY_TX_MIN_ALLOWED_OUTS, false, "HF4: tx.vout has " << tx.vout.size() << " element(s), while required minimum is " << CURRENCY_TX_MIN_ALLOWED_OUTS); + if(!validate_inputs_sorting(tx)) { return false; diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 16a2729b..4bf3ad8c 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -188,7 +188,8 @@ namespace currency bool pos, const pos_entry& pe) { - CHECK_AND_ASSERT_THROW_MES(!pos || tx.version <= TRANSACTION_VERSION_PRE_HF4, "PoS miner tx is currently unsupported for HF4 -- sowle"); + bool r = false; + CHECK_AND_ASSERT_THROW_MES(!pos || tx_version <= TRANSACTION_VERSION_PRE_HF4, "PoS miner tx is currently unsupported for HF4 -- sowle"); uint64_t block_reward = 0; if (!get_block_reward(pos, median_size, current_block_size, already_generated_coins, block_reward, height)) @@ -203,7 +204,7 @@ namespace currency // // 1. split block_reward into out_amounts std::vector out_amounts; - if (tx.version > TRANSACTION_VERSION_PRE_HF4) + if (tx_version > TRANSACTION_VERSION_PRE_HF4) { // randomly split into CURRENCY_TX_MIN_ALLOWED_OUTS outputs // TODO: consider refactoring @@ -297,34 +298,28 @@ namespace currency } } - uint64_t no = 0; - std::set deriv_cache; - uint64_t summary_outs_money = 0; - //fill outputs - finalized_tx result = AUTO_VAL_INIT(result); - uint8_t tx_outs_attr = 0; - - size_t output_index = tx.vout.size(); // in case of append mode we need to start output indexing from the last one + 1 - uint64_t range_proof_start_index = output_index; - crypto::scalar_vec_t blinding_masks(tx.vout.size() + destinations.size()); // vector of secret blinging masks for each output. For range proof generation - crypto::scalar_vec_t amounts(tx.vout.size() + destinations.size()); // vector of amounts, converted to scalars. For ranage proof generation + // fill outputs + crypto::scalar_vec_t blinding_masks(destinations.size()); // vector of secret blinging masks for each output. For range proof generation + crypto::scalar_vec_t amounts(destinations.size()); // vector of amounts, converted to scalars. For ranage proof generation crypto::scalar_t blinding_masks_sum = 0; + uint64_t output_index = 0; for (auto& d : destinations) { - - bool r = construct_tx_out(d, txkey.sec, no, tx, deriv_cache, account_keys(), blinding_masks[no], result, tx_outs_attr); - CHECK_AND_ASSERT_MES(r, false, "Failed to contruct miner tx out"); - amounts[output_index - range_proof_start_index] = d.amount; - summary_outs_money += d.amount; + std::set deriv_cache; + finalized_tx result = AUTO_VAL_INIT(result); + uint8_t tx_outs_attr = 0; + r = construct_tx_out(d, txkey.sec, output_index, tx, deriv_cache, account_keys(), blinding_masks[output_index], result, tx_outs_attr); + CHECK_AND_ASSERT_MES(r, false, "construct_tx_out failed, output #" << output_index << ", amount: " << print_money_brief(d.amount)); + amounts[output_index] = d.amount; blinding_masks_sum += blinding_masks[output_index]; - no++; + ++output_index; } if (tx.version > TRANSACTION_VERSION_PRE_HF4) { //add range proofs currency::zarcanum_outs_range_proof range_proofs = AUTO_VAL_INIT(range_proofs); - bool r = generate_zarcanum_outs_range_proof(range_proof_start_index, amounts.size(), amounts, blinding_masks, tx.vout, range_proofs); + bool r = generate_zarcanum_outs_range_proof(0, amounts.size(), amounts, blinding_masks, tx.vout, range_proofs); CHECK_AND_ASSERT_MES(r, false, "Failed to generate zarcanum_outs_range_proof()"); tx.attachment.push_back(range_proofs); @@ -377,7 +372,7 @@ namespace currency outs_commitments_sum.modify_mul8(); uint64_t fee = 0; - CHECK_AND_ASSERT_MES(get_tx_fee(tx, fee), false, "unable to get tx fee"); + CHECK_AND_ASSERT_MES(get_tx_fee(tx, fee) || additional_inputs_amount_and_fees_for_mining_tx > 0, false, "unable to get fee for a non-mining tx"); CHECK_AND_ASSERT_MES(additional_inputs_amount_and_fees_for_mining_tx == 0 || fee == 0, false, "invalid tx: fee = " << print_money_brief(fee) << ", additional inputs + fees = " << print_money_brief(additional_inputs_amount_and_fees_for_mining_tx)); diff --git a/src/currency_core/miner.h b/src/currency_core/miner.h index ec011801..94caea2b 100644 --- a/src/currency_core/miner.h +++ b/src/currency_core/miner.h @@ -68,7 +68,7 @@ namespace currency crypto::hash h = get_block_longhash(height, bd_hash, bl.nonce); if(check_hash(h, diffic)) { - LOG_PRINT_L0("Found nonce for block: " << get_block_hash(bl) << "[" << height << "]: PoW:" << h << "(diff:" << diffic << "), ts: " << bl.timestamp); + LOG_PRINT_L1("Found nonce for block: " << get_block_hash(bl) << "[" << height << "]: PoW:" << h << " (diff:" << diffic << "), ts: " << bl.timestamp); return true; } } From b6694013327c80fdea93af4d38495574e5b97c5c Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 28 Sep 2022 03:45:10 +0200 Subject: [PATCH 5/6] 1) balance proof and explicit fee for post-HF4 txs; 2) multiple range proofs verification fixed; 3) zarcanum_outs_range_proof -> zc_outs_range_proof --- src/currency_core/blockchain_storage.cpp | 30 ++++++++-------- src/currency_core/blockchain_storage.h | 2 +- src/currency_core/currency_basic.h | 6 ++-- src/currency_core/currency_format_utils.cpp | 40 ++++++++++++--------- src/currency_core/currency_format_utils.h | 12 +++---- src/wallet/wallet2.cpp | 5 +-- 6 files changed, 51 insertions(+), 44 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index b339e020..aefd7a0e 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1308,7 +1308,7 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t if (is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM)) { CHECK_AND_ASSERT_MES(b.miner_tx.attachment.size() == 2, false, "coinbase transaction has incorrect number of attachments (" << b.miner_tx.attachment.size() << "), expected 2"); - CHECK_AND_ASSERT_MES(b.miner_tx.attachment[0].type() == typeid(zarcanum_outs_range_proof), false, "coinbase transaction wrong attachment #0 type (expected: zarcanum_outs_range_proof)"); + CHECK_AND_ASSERT_MES(b.miner_tx.attachment[0].type() == typeid(zc_outs_range_proof), false, "coinbase transaction wrong attachment #0 type (expected: zc_outs_range_proof)"); CHECK_AND_ASSERT_MES(b.miner_tx.attachment[1].type() == typeid(zc_balance_proof), false, "coinbase transaction wrong attachmenttype #1 (expected: zc_balance_proof)"); } else @@ -5548,7 +5548,7 @@ bool get_tx_from_cache(const crypto::hash& tx_id, transactions_map& tx_cache, tr return true; } //------------------------------------------------------------------ -bool blockchain_storage::collect_rangeproofs_data_from_tx(std::vector& agregated_proofs, const transaction& tx /*, std::vector& tx_outs_commitments*/) +bool blockchain_storage::collect_rangeproofs_data_from_tx(std::vector& agregated_proofs, const transaction& tx) { if (tx.version <= TRANSACTION_VERSION_PRE_HF4) { @@ -5557,12 +5557,12 @@ bool blockchain_storage::collect_rangeproofs_data_from_tx(std::vector(a); + const zc_outs_range_proof& zcrp = boost::get(a); agregated_proofs.emplace_back(zcrp); for (uint8_t i = 0; i != zcrp.outputs_count; i++) { @@ -5586,17 +5586,20 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt TIME_MEASURE_START_PD_MS(block_processing_time_0_ms); CRITICAL_REGION_LOCAL(m_read_lock); TIME_MEASURE_START_PD(block_processing_time_1); + + uint64_t height = get_current_blockchain_size(); // height <-> block height correspondence is validated in prevalidate_miner_transaction() + if(bl.prev_id != get_top_block_id()) { - LOG_PRINT_L0("Block with id: " << id << ENDL - << "have wrong prev_id: " << bl.prev_id << ENDL + LOG_PRINT_L0("Block with id: " << id << " @ " << height << ENDL + << "has wrong prev_id: " << bl.prev_id << ENDL << "expected: " << get_top_block_id()); return false; } if(!check_block_timestamp_main(bl)) { - LOG_PRINT_L0("Block with id: " << id << ENDL + LOG_PRINT_L0("Block with id: " << id << " @ " << height << ENDL << "has invalid timestamp: " << bl.timestamp); // do not add this block to invalid block list prior to proof of work check bvc.m_verification_failed = true; @@ -5608,7 +5611,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt m_is_in_checkpoint_zone = true; if (!m_checkpoints.check_block(get_current_blockchain_size(), id)) { - LOG_ERROR("CHECKPOINT VALIDATION FAILED"); + LOG_ERROR("CHECKPOINT VALIDATION FAILED @ " << height); bvc.m_verification_failed = true; return false; } @@ -5657,8 +5660,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt if (!prevalidate_miner_transaction(bl, m_db_blocks.size(), is_pos_bl)) { - LOG_PRINT_L0("Block with id: " << id - << " failed to pass prevalidation"); + LOG_PRINT_L0("Block with id: " << id << " @ " << height << " failed to pass miner tx prevalidation"); bvc.m_verification_failed = true; return false; } @@ -5681,7 +5683,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt TIME_MEASURE_START_PD(all_txs_insert_time_5); if (!add_transaction_from_block(bl.miner_tx, get_transaction_hash(bl.miner_tx), id, get_current_blockchain_size(), get_block_datetime(bl))) { - LOG_PRINT_L0("Block with id: " << id << " failed to add transaction to blockchain storage"); + LOG_PRINT_L0("Block with id: " << id << " failed to add miner transaction to the blockchain storage"); bvc.m_verification_failed = true; return false; } @@ -5697,7 +5699,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt uint64_t burned_coins = 0; std::list block_summary_kimages; - std::vector range_proofs_agregated; + std::vector range_proofs_agregated; for(const crypto::hash& tx_id : bl.tx_hashes) { @@ -5836,7 +5838,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt //validate range proofs - if (!verify_multiple_zarcanum_outs_range_proofs(range_proofs_agregated)) + if (!verify_multiple_zc_outs_range_proofs(range_proofs_agregated)) { LOG_PRINT_L0("Block with id: " << id << " have failed to verify multiple rangeproofs"); diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index d96bdf67..15d027bb 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -584,7 +584,7 @@ namespace currency wide_difficulty_type get_next_difficulty_for_alternative_chain(const alt_chain_type& alt_chain, block_extended_info& bei, bool pos) const; bool handle_block_to_main_chain(const block& bl, block_verification_context& bvc); bool handle_block_to_main_chain(const block& bl, const crypto::hash& id, block_verification_context& bvc); - bool collect_rangeproofs_data_from_tx(std::vector& agregated_proofs, const transaction& tx/*, std::vector& tx_outs_commitments*/); + bool collect_rangeproofs_data_from_tx(std::vector& agregated_proofs, const transaction& tx); std::string print_alt_chain(alt_chain_type alt_chain); bool handle_alternative_block(const block& b, const crypto::hash& id, block_verification_context& bvc); bool is_reorganize_required(const block_extended_info& main_chain_bei, const alt_chain_type& alt_chain, const crypto::hash& proof_alt); diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index afc3803b..6148830b 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -436,7 +436,7 @@ namespace currency // non-consoditated txs must have one of this objects in the attachments (outputs_count == vout.size()) // consolidated -- one pre consolidated part (sum(outputs_count) == vout.size()) - struct zarcanum_outs_range_proof + struct zc_outs_range_proof { crypto::bpp_signature_serialized bpp; uint8_t outputs_count; // how many outputs are included in the proof @@ -754,7 +754,7 @@ namespace currency typedef boost::mpl::vector24< tx_service_attachment, tx_comment, tx_payer_old, tx_receiver_old, tx_derivation_hint, std::string, tx_crypto_checksum, etc_tx_time, etc_tx_details_unlock_time, etc_tx_details_expiration_time, etc_tx_details_flags, crypto::public_key, extra_attachment_info, extra_alias_entry_old, extra_user_data, extra_padding, etc_tx_flags16_t, etc_tx_details_unlock_time2, - tx_payer, tx_receiver, extra_alias_entry, zarcanum_tx_data_v1, zarcanum_outs_range_proof, zc_balance_proof + tx_payer, tx_receiver, extra_alias_entry, zarcanum_tx_data_v1, zc_outs_range_proof, zc_balance_proof > all_payload_types; typedef boost::make_variant_over::type payload_items_v; @@ -1077,7 +1077,7 @@ SET_VARIANT_TAGS(crypto::bppe_signature_serialized, 41, "bppe_signature_serializ SET_VARIANT_TAGS(currency::NLSAG_sig, 42, "NLSAG_sig"); SET_VARIANT_TAGS(currency::ZC_sig, 43, "ZC_sig"); SET_VARIANT_TAGS(currency::void_sig, 44, "void_sig"); -SET_VARIANT_TAGS(currency::zarcanum_outs_range_proof, 45, "zarcanum_outs_range_proof"); +SET_VARIANT_TAGS(currency::zc_outs_range_proof, 45, "zc_outs_range_proof"); SET_VARIANT_TAGS(currency::zc_balance_proof, 46, "zc_balance_proof"); SET_VARIANT_TAGS(currency::open_asset_id, 47, "asset_id"); diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 4bf3ad8c..3851dd92 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -68,8 +68,8 @@ namespace currency //-------------------------------------------------------------------------------- - bool generate_zarcanum_outs_range_proof(size_t out_index_start, size_t outs_count, const crypto::scalar_vec_t& amounts, const crypto::scalar_vec_t& blinding_masks, - const std::vector& vouts, zarcanum_outs_range_proof& result) + bool generate_zc_outs_range_proof(size_t out_index_start, size_t outs_count, const crypto::scalar_vec_t& amounts, const crypto::scalar_vec_t& blinding_masks, + const std::vector& vouts, zc_outs_range_proof& result) { //TODO: review for Andre CHECK_AND_ASSERT_MES(amounts.size() == outs_count, false, ""); @@ -318,9 +318,9 @@ namespace currency if (tx.version > TRANSACTION_VERSION_PRE_HF4) { //add range proofs - currency::zarcanum_outs_range_proof range_proofs = AUTO_VAL_INIT(range_proofs); - bool r = generate_zarcanum_outs_range_proof(0, amounts.size(), amounts, blinding_masks, tx.vout, range_proofs); - CHECK_AND_ASSERT_MES(r, false, "Failed to generate zarcanum_outs_range_proof()"); + currency::zc_outs_range_proof range_proofs = AUTO_VAL_INIT(range_proofs); + bool r = generate_zc_outs_range_proof(0, amounts.size(), amounts, blinding_masks, tx.vout, range_proofs); + CHECK_AND_ASSERT_MES(r, false, "Failed to generate zc_outs_range_proof()"); tx.attachment.push_back(range_proofs); if (!pos) @@ -1708,7 +1708,8 @@ namespace currency const uint8_t& tx_outs_attr = ftp.tx_outs_attr; const bool& shuffle = ftp.shuffle; const uint64_t& flags = ftp.flags; - + + bool r = false; transaction& tx = result.tx; crypto::secret_key& one_time_secret_key = result.one_time_key; @@ -1929,7 +1930,7 @@ namespace currency for(const tx_destination_entry& dst_entr : shuffled_dsts) { CHECK_AND_ASSERT_MES(dst_entr.amount > 0, false, "Destination with wrong amount: " << dst_entr.amount); // <<-- TODO @#@# consider removing this check - bool r = construct_tx_out(dst_entr, txkey.sec, output_index, tx, deriv_cache, sender_account_keys, blinding_masks[output_index], result, tx_outs_attr); + r = construct_tx_out(dst_entr, txkey.sec, output_index, tx, deriv_cache, sender_account_keys, blinding_masks[output_index], result, tx_outs_attr); CHECK_AND_ASSERT_MES(r, false, "Failed to construct tx out"); amounts[output_index - range_proof_start_index] = dst_entr.amount; summary_outs_money += dst_entr.amount; @@ -1959,7 +1960,7 @@ namespace currency { CHECK_AND_ASSERT_MES(tsa.security.size() == 1, false, "Wrong tsa.security.size() = " << tsa.security.size()); - bool r = derive_public_key_from_target_address(sender_account_keys.account_address, one_time_secret_key, att_count, tsa.security.back()); + r = derive_public_key_from_target_address(sender_account_keys.account_address, one_time_secret_key, att_count, tsa.security.back()); CHECK_AND_ASSERT_MES(r, false, "Failed to derive_public_key_from_target_address"); } att_count++; @@ -1980,11 +1981,18 @@ namespace currency if (tx.version > TRANSACTION_VERSION_PRE_HF4) { - //add range proofs - currency::zarcanum_outs_range_proof range_proofs = AUTO_VAL_INIT(range_proofs); - bool r = generate_zarcanum_outs_range_proof(range_proof_start_index, amounts.size(), amounts, blinding_masks, tx.vout, range_proofs); - CHECK_AND_ASSERT_MES(r, false, "Failed to generate zarcanum_outs_range_proof()"); + // add range proofs + currency::zc_outs_range_proof range_proofs = AUTO_VAL_INIT(range_proofs); + bool r = generate_zc_outs_range_proof(range_proof_start_index, amounts.size(), amounts, blinding_masks, tx.vout, range_proofs); + CHECK_AND_ASSERT_MES(r, false, "Failed to generate zc_outs_range_proof()"); tx.attachment.push_back(range_proofs); + + // add explicit fee info + r = add_tx_fee_amount_to_extra(tx, summary_inputs_money - summary_outs_money); + CHECK_AND_ASSERT_MES(r, false, "add_tx_fee_amount_to_extra failed"); + + r = generate_tx_balance_proof(tx, blinding_masks_sum); + CHECK_AND_ASSERT_MES(r, false, "generate_tx_balance_proof failed"); } if (flags & TX_FLAG_SIGNATURE_MODE_SEPARATE) @@ -2018,7 +2026,7 @@ namespace currency //size_t input_index = input_starter_index; //size_t in_context_index = 0; crypto::scalar_t local_blinding_masks_sum = 0; // ZC only - bool r = false; + r = false; for (size_t i = 0; i != sources.size(); i++) { const tx_source_entry& source_entry = sources[inputs_mapping[i]]; @@ -3299,9 +3307,9 @@ namespace currency tv.details_view = tv.short_view; return true; } - bool operator()(const zarcanum_outs_range_proof& rp) + bool operator()(const zc_outs_range_proof& rp) { - tv.type = "zarcanum_outs_range_proof"; + tv.type = "zc_outs_range_proof"; tv.short_view = "outputs_count = " + std::to_string(rp.outputs_count); return true; } @@ -3889,7 +3897,7 @@ namespace currency } //-------------------------------------------------------------------------------- - bool verify_multiple_zarcanum_outs_range_proofs(const std::vector& range_proofs) + bool verify_multiple_zc_outs_range_proofs(const std::vector& range_proofs) { if (range_proofs.empty()) return true; diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 0e0da357..566efc5f 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -215,20 +215,20 @@ namespace currency }; - struct zarcanum_outs_range_proof_commit_ref_t + struct zc_outs_range_proofs_with_commitments { - zarcanum_outs_range_proof_commit_ref_t(const zarcanum_outs_range_proof& range_proof, const std::vector& amount_commitments) + zc_outs_range_proofs_with_commitments(const zc_outs_range_proof& range_proof, const std::vector& amount_commitments) : range_proof(range_proof) , amount_commitments(amount_commitments) {} - zarcanum_outs_range_proof_commit_ref_t(const zarcanum_outs_range_proof& range_proof) + zc_outs_range_proofs_with_commitments(const zc_outs_range_proof& range_proof) : range_proof(range_proof) {} - const zarcanum_outs_range_proof& range_proof; - std::vector amount_commitments; + zc_outs_range_proof range_proof; + std::vector amount_commitments; }; - bool verify_multiple_zarcanum_outs_range_proofs(const std::vector& range_proofs); + bool verify_multiple_zc_outs_range_proofs(const std::vector& range_proofs); bool check_tx_balance(const transaction& tx, uint64_t additional_inputs_amount_and_fees_for_mining_tx = 0); //--------------------------------------------------------------- bool construct_miner_tx(size_t height, size_t median_size, const boost::multiprecision::uint128_t& already_generated_coins, diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index d79093aa..4b390e96 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5536,10 +5536,7 @@ bool wallet2::get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) c //---------------------------------------------------------------------------------------------------- bool wallet2::is_need_to_split_outputs() { - if (this->m_core_runtime_config.hard_forks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, this->get_blockchain_current_size())) - return false; - else - return true; + return !is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM); } //---------------------------------------------------------------------------------------------------- void wallet2::prepare_tx_destinations(const assets_selection_context& needed_money_map, From 369b40b7a0054cefb7f4e2fb991662d2acba652c Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 28 Sep 2022 03:46:20 +0200 Subject: [PATCH 6/6] coretests: fixes and improvements for zarcanum_test --- tests/core_tests/zarcanum_test.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/core_tests/zarcanum_test.cpp b/tests/core_tests/zarcanum_test.cpp index ca06eae1..73760667 100644 --- a/tests/core_tests/zarcanum_test.cpp +++ b/tests/core_tests/zarcanum_test.cpp @@ -87,8 +87,8 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect alice_wlt->refresh(); uint64_t unlocked = 0; - uint64_t balance = alice_wlt->balance(unlocked); - CHECK_AND_ASSERT_MES(unlocked == transfer_amount, false, "wrong amount"); + //uint64_t balance = alice_wlt->balance(unlocked); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", transfer_amount * 4, UINT64_MAX, transfer_amount * 4), false, ""); account_base bob_acc; bob_acc.generate(); @@ -107,8 +107,9 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); bob_wlt->refresh(); - balance = bob_wlt->balance(unlocked); - CHECK_AND_ASSERT_MES(unlocked == transfer_amount2, false, "wrong amount"); + //balance = bob_wlt->balance(unlocked); + //CHECK_AND_ASSERT_MES(unlocked == transfer_amount2, false, "wrong amount"); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt, "Bob", transfer_amount2, UINT64_MAX, transfer_amount2), false, ""); account_base staker_benefeciary_acc; staker_benefeciary_acc.generate(); @@ -153,8 +154,9 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect bob_wlt->refresh(); - balance = bob_wlt->balance(unlocked); - CHECK_AND_ASSERT_MES(unlocked == transfer_amount2*3, false, "wrong amount"); + //balance = bob_wlt->balance(unlocked); + //CHECK_AND_ASSERT_MES(unlocked == transfer_amount2*3, false, "wrong amount"); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt, "Bob", transfer_amount2*3, UINT64_MAX, transfer_amount2*3), false, ""); //try to make pre-zarcanum block after hardfork 4 currency::core_runtime_config rc = alice_wlt->get_core_runtime_config();