From ec07a63f1ed710e5d4f6dd126bc0b783ef0fe279 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 21 Nov 2022 18:39:39 +0100 Subject: [PATCH 1/7] chaingen: fix for test_generator::build_wallets() + more verbose error logging when didn't find a kernel --- tests/core_tests/chaingen.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index c47cb79a..0e5270de 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -448,7 +448,7 @@ bool test_generator::build_wallets(const blockchain_vector& blockchain, const out_index_info& oii = it->second[gindex]; if (rqt.height_upper_limit != 0 && oii.block_height > rqt.height_upper_limit) continue; - const transaction& tx = oii.in_block_tx_index == 0 ? m_blockchain[oii.block_height]->b.miner_tx : m_blockchain[oii.block_height]->m_transactions[oii.in_block_tx_index]; + const transaction& tx = oii.in_block_tx_index == 0 ? m_blockchain[oii.block_height]->b.miner_tx : m_blockchain[oii.block_height]->m_transactions[oii.in_block_tx_index - 1]; auto& out_v = tx.vout[oii.in_tx_out_index]; uint8_t mix_attr = 0; if (!get_mix_attr_from_tx_out_v(out_v, mix_attr)) @@ -591,6 +591,7 @@ bool test_generator::find_kernel(const std::list& accs, { bool r = false; uint64_t last_block_ts = !blck_chain.empty() ? blck_chain.back()->b.timestamp : test_core_time::get_time(); + uint64_t iterations_processed_total = 0; //lets try to find block for (size_t wallet_index = 0, size = wallets.size(); wallet_index < size; ++wallet_index) @@ -636,8 +637,11 @@ bool test_generator::find_kernel(const std::list& accs, return true; } + iterations_processed_total += context.iterations_processed; } + LOG_PRINT_RED("PoS mining iteration failed, kernel was not found. Iterations processed across " << wallets.size() << " wallet(s): " << iterations_processed_total, LOG_LEVEL_0); + return false; } //------------------------------------------------------------------ From ce36a659942cda3935ad3a1979403baeb02e94de Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 21 Nov 2022 18:43:36 +0100 Subject: [PATCH 2/7] Zarcanum PoS: fix for alt blocks validation --- src/currency_core/blockchain_storage.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index ad2e0a40..97ab6ad0 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -6975,9 +6975,16 @@ bool blockchain_storage::validate_alt_block_input(const transaction& input_tx, r = check_input_signature(input_tx, input_index, input_to_key, input_tx_hash, pub_key_pointers); CHECK_AND_ASSERT_MES(r, false, "to_key input validation failed"); VARIANT_CASE_CONST(txin_zc_input, input_zc); - uint64_t max_related_block_height = 0; - r = check_tx_input(input_tx, input_index, input_zc, input_tx_hash, max_related_block_height); - CHECK_AND_ASSERT_MES(r, false, "check_tx_input failed"); + if (is_pos_miner_tx(input_tx)) + { + // TODO @#@# Special case: handling Zarcanum PoS block input + } + else + { + uint64_t max_related_block_height = 0; + r = check_tx_input(input_tx, input_index, input_zc, input_tx_hash, max_related_block_height); + CHECK_AND_ASSERT_MES(r, false, "check_tx_input failed"); + } VARIANT_CASE_OTHER() LOG_ERROR("unexpected input type: " << input_v.type().name()); return false; @@ -7313,7 +7320,7 @@ bool blockchain_storage::validate_alt_block_txs(const block& b, const crypto::ha CHECK_AND_ASSERT_MES(tx.signatures.size() == tx.vin.size(), false, "invalid tx: signatures.size() == " << tx.signatures.size() << ", tx.vin.size() == " << tx.vin.size()); for (size_t n = 0; n < tx.vin.size(); ++n) { - if (tx.vin[n].type() == typeid(txin_to_key) || tx.vin[n].type() == typeid(txin_htlc)) + if (tx.vin[n].type() == typeid(txin_to_key) || tx.vin[n].type() == typeid(txin_htlc) || tx.vin[n].type() == typeid(txin_zc_input)) { uint64_t ki_lookup = 0; r = validate_alt_block_input(tx, collected_keyimages, alt_chain_tx_ids, id, tx_id, n, split_height, alt_chain, alt_chain_block_ids, ki_lookup); From d06aa7796edecfa5e8e6bdf843270693b1cded74 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 21 Nov 2022 20:38:56 +0100 Subject: [PATCH 3/7] bcs: purge_altblock_keyimages_from_big_heap adapted --- src/currency_core/blockchain_storage.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 97ab6ad0..5209057c 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1654,9 +1654,10 @@ bool blockchain_storage::purge_altblock_keyimages_from_big_heap(const block& b, { if (is_pos_block(b)) { - CHECK_AND_ASSERT_MES(b.miner_tx.vin.size()>=2, false, "paranoid check failed"); - CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(txin_to_key), false, "paranoid type check failed"); - purge_keyimage_from_big_heap(boost::get(b.miner_tx.vin[1]).k_image, block_id); + CHECK_AND_ASSERT_MES(b.miner_tx.vin.size() == 2, false, "paranoid check failed"); + crypto::key_image ki{}; + CHECK_AND_ASSERT_MES(get_key_image_from_txin_v(b.miner_tx.vin[1], ki), false, "cannot get key image from input #1"); + purge_keyimage_from_big_heap(ki, block_id); } for (auto tx_id : b.tx_hashes) { From a0125f81e951173c4c248470b154a11343f64b41 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 21 Nov 2022 20:40:14 +0100 Subject: [PATCH 4/7] bcs: prevalidate_miner_transaction moved to be called before heavy PoW/PoS (now for alt blocks as well) --- src/currency_core/blockchain_storage.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 5209057c..615143ac 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1810,9 +1810,16 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto:: //check if PoS block allowed on this height CHECK_AND_ASSERT_MES_CUSTOM(!(pos_block && abei.height < m_core_runtime_config.pos_minimum_heigh), false, bvc.m_verification_failed = true, "PoS block is not allowed on this height"); + // miner tx prevalidation (light checks) + if (!prevalidate_miner_transaction(b, abei.height, pos_block)) + { + LOG_PRINT_RED_L0("Alternative block " << id << " @ " << coinbase_height << "has invalid miner transaction."); + bvc.m_verification_failed = true; + return false; + } + // PoW / PoS validation (heavy checks) wide_difficulty_type current_diff = get_next_diff_conditional2(pos_block, alt_chain, connection_height, abei); - CHECK_AND_ASSERT_MES_CUSTOM(current_diff, false, bvc.m_verification_failed = true, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!"); crypto::hash proof_of_work = null_hash; @@ -1841,13 +1848,6 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto:: // } - if (!prevalidate_miner_transaction(b, abei.height, pos_block)) - { - LOG_PRINT_RED_L0("Block with id: " << string_tools::pod_to_hex(id) - << " (as alternative) have wrong miner transaction."); - bvc.m_verification_failed = true; - return false; - } std::unordered_set alt_block_keyimages; uint64_t ki_lookup_total = 0; if (!validate_alt_block_txs(b, id, alt_block_keyimages, abei, alt_chain, connection_height, ki_lookup_total)) From 88e3190aad6df4462b2c4255399312ab461a2e9e Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 21 Nov 2022 21:49:11 +0100 Subject: [PATCH 5/7] bcs: more verbose logging --- src/currency_core/blockchain_storage.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 615143ac..54e3a85b 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -802,8 +802,8 @@ bool blockchain_storage::purge_transaction_from_blockchain(const crypto::hash& t CHECK_AND_ASSERT_MES_NO_RET(res, "pop_transaction_from_global_index failed for tx " << tx_id); bool res_erase = m_db_transactions.erase_validate(tx_id); CHECK_AND_ASSERT_MES_NO_RET(res_erase, "Failed to m_transactions.erase with id = " << tx_id); - - LOG_PRINT_L1("transaction " << tx_id << (added_to_the_pool ? " was removed from blockchain history -> to the pool" : " was removed from blockchain history")); + + LOG_PRINT_L1("transaction " << tx_id << " from block @ " << tx_res_ptr->m_keeper_block_height << (added_to_the_pool ? " was removed from blockchain history -> to the pool" : " was removed from blockchain history")); return res; } @@ -1012,7 +1012,7 @@ bool blockchain_storage::rollback_blockchain_switching(std::list& CHECK_AND_ASSERT_MES(r && bvc.m_added_to_main_chain, false, "PANIC!!! failed to add (again) block while chain switching during the rollback!"); } - LOG_PRINT_L0("Rollback success."); + LOG_PRINT_L0("Rollback succeeded."); return true; } //------------------------------------------------------------------ @@ -1125,6 +1125,7 @@ bool blockchain_storage::switch_to_alternative_blockchain(alt_chain_type& alt_ch //when machine time was wrongly set for a few hours back, then blocks which was detached from main chain //couldn't be added as alternative due to timestamps validation(timestamps assumed as from future) //thanks @Gigabyted for reporting this problem + LOG_PRINT("REORGANIZE FAILED because ex-main block wasn't added as alt, but we pretend it was successfull (see also comments in sources)", LOG_LEVEL_0); break; } } @@ -1918,7 +1919,7 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto:: << ENDL << "id:\t" << id << ENDL << "prev\t" << abei.bl.prev_id << ENDL << ss_pow_pos_info.str() - << ENDL << "HEIGHT " << abei.height << ", difficulty: " << abei.difficulty << ", cumul_diff_precise: " << abei.cumulative_diff_precise << ", cumul_diff_adj: " << abei.cumulative_diff_adjusted << " (current mainchain cumul_diff_adj: " << m_db_blocks.back()->cumulative_diff_adjusted << ", ki lookup total: " << ki_lookup_total <<")" + << ENDL << "HEIGHT " << abei.height << ", difficulty: " << abei.difficulty << ", cumul_diff_precise: " << abei.cumulative_diff_precise << ", cumul_diff_adj: " << abei.cumulative_diff_adjusted << ", txs: " << abei.bl.tx_hashes.size() << " (current mainchain cumul_diff_adj: " << m_db_blocks.back()->cumulative_diff_adjusted << ", total ki lookups: " << ki_lookup_total <<")" , LOG_LEVEL_0); if (is_reorganize_required(*m_db_blocks.back(), alt_chain, proof)) From 8ca9e1261d5dfd462e31ed03452ed841baa2520b Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 21 Nov 2022 22:55:59 +0100 Subject: [PATCH 6/7] 1) fill_tx_rpc_inputs adapted; 2) earlier deprecated get_to_key_input_from_txin_v removed completely --- src/currency_core/currency_format_utils.cpp | 27 ++++++++++--------- .../currency_format_utils_abstract.h | 19 ------------- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index e59b846f..2512a41c 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -3451,45 +3451,46 @@ namespace currency for (auto in : tx.vin) { tei.ins.push_back(tx_in_rpc_entry()); + tx_in_rpc_entry& entry_to_fill = tei.ins.back(); if (in.type() == typeid(txin_gen)) { - tei.ins.back().amount = 0; + entry_to_fill.amount = 0; } - else if (in.type() == typeid(txin_to_key) || in.type() == typeid(txin_htlc)) + else if (in.type() == typeid(txin_to_key) || in.type() == typeid(txin_htlc) || in.type() == typeid(txin_zc_input)) { //TODO: add htlc info - const txin_to_key& tk = get_to_key_input_from_txin_v(in); - tei.ins.back().amount = tk.amount; - tei.ins.back().kimage_or_ms_id = epee::string_tools::pod_to_hex(tk.k_image); - std::vector absolute_offsets = relative_output_offsets_to_absolute(tk.key_offsets); + entry_to_fill.amount = get_amount_from_variant(in); + entry_to_fill.kimage_or_ms_id = epee::string_tools::pod_to_hex(get_key_image_from_txin_v(in)); + const std::vector& key_offsets = get_key_offsets_from_txin_v(in); + std::vector absolute_offsets = relative_output_offsets_to_absolute(key_offsets); for (auto& ao : absolute_offsets) { - tei.ins.back().global_indexes.push_back(0); + entry_to_fill.global_indexes.push_back(0); if (ao.type() == typeid(uint64_t)) { - tei.ins.back().global_indexes.back() = boost::get(ao); + entry_to_fill.global_indexes.back() = boost::get(ao); } else// if (ao.type() == typeid(ref_by_id)) { //disable for the reset at the moment - tei.ins.back().global_indexes.back() = std::numeric_limits::max(); + entry_to_fill.global_indexes.back() = std::numeric_limits::max(); } } if (in.type() == typeid(txin_htlc)) { - tei.ins.back().htlc_origin = epee::string_tools::buff_to_hex_nodelimer(boost::get(in).hltc_origin); + entry_to_fill.htlc_origin = epee::string_tools::buff_to_hex_nodelimer(boost::get(in).hltc_origin); } //tk.etc_details -> visualize it may be later } else if (in.type() == typeid(txin_multisig)) { txin_multisig& tms = boost::get(in); - tei.ins.back().amount = tms.amount; - tei.ins.back().kimage_or_ms_id = epee::string_tools::pod_to_hex(tms.multisig_out_id); + entry_to_fill.amount = tms.amount; + entry_to_fill.kimage_or_ms_id = epee::string_tools::pod_to_hex(tms.multisig_out_id); if (tx.signatures.size() >= tei.ins.size() && tx.signatures[tei.ins.size() - 1].type() == typeid(NLSAG_sig)) { - tei.ins.back().multisig_count = boost::get(tx.signatures[tei.ins.size() - 1]).s.size(); + entry_to_fill.multisig_count = boost::get(tx.signatures[tei.ins.size() - 1]).s.size(); } } diff --git a/src/currency_core/currency_format_utils_abstract.h b/src/currency_core/currency_format_utils_abstract.h index 152407c6..c27551a6 100644 --- a/src/currency_core/currency_format_utils_abstract.h +++ b/src/currency_core/currency_format_utils_abstract.h @@ -174,25 +174,6 @@ namespace currency return found; } //--------------------------------------------------------------- - // DEPRECATED, should be removed soon -- sowle - inline - const txin_to_key& get_to_key_input_from_txin_v(const txin_v& in_v) - { - if (in_v.type() == typeid(txin_to_key)) - { - return boost::get(in_v); - } - else if (in_v.type() == typeid(txin_htlc)) - { - const txin_htlc& in = boost::get(in_v); - return static_cast(in); - } - else - { - ASSERT_MES_AND_THROW("[get_to_key_input_from_txin_v] Wrong type " << in_v.type().name()); - } - } - //--------------------------------------------------------------- inline bool get_key_image_from_txin_v(const txin_v& in_v, crypto::key_image& result) noexcept { From 0b2fef7642daa16bbaa868fea9886ce1f0dce1a4 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 21 Nov 2022 22:57:05 +0100 Subject: [PATCH 7/7] alt block tx validation fixed for htlc --- src/currency_core/blockchain_storage.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 54e3a85b..8ac1b3cc 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -6976,6 +6976,9 @@ bool blockchain_storage::validate_alt_block_input(const transaction& input_tx, VARIANT_CASE_CONST(txin_to_key, input_to_key) r = check_input_signature(input_tx, input_index, input_to_key, input_tx_hash, pub_key_pointers); CHECK_AND_ASSERT_MES(r, false, "to_key input validation failed"); + VARIANT_CASE_CONST(txin_htlc, input_htlc); + r = check_input_signature(input_tx, input_index, input_htlc, input_tx_hash, pub_key_pointers); + CHECK_AND_ASSERT_MES(r, false, "to_key input validation failed"); VARIANT_CASE_CONST(txin_zc_input, input_zc); if (is_pos_miner_tx(input_tx)) {