From 4f80c7c334af7fe651b374e6ef043fee7400b1a7 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sun, 19 Jun 2022 19:47:43 +0200 Subject: [PATCH 1/4] signature refactoring with [] --- src/currency_core/blockchain_storage.cpp | 122 ++++++------------ src/currency_core/blockchain_storage.h | 2 +- src/currency_core/currency_basic.h | 20 ++- .../currency_boost_serialization.h | 2 +- src/currency_core/currency_format_utils.cpp | 29 +++-- tests/core_tests/chaingen.cpp | 4 +- tests/core_tests/chaingen.h | 6 +- tests/core_tests/chaingen_helpers.h | 6 +- tests/core_tests/chaingen_main.cpp | 4 +- tests/core_tests/checkpoints_tests.cpp | 10 +- tests/core_tests/escrow_wallet_common.h | 4 +- tests/core_tests/multisig_wallet_tests.cpp | 12 +- tests/core_tests/pos_block_builder.cpp | 6 +- tests/core_tests/pos_validation.cpp | 2 +- tests/core_tests/pruning_ring_signatures.cpp | 4 +- tests/core_tests/transaction_tests.cpp | 2 +- tests/core_tests/tx_builder.h | 6 +- tests/core_tests/tx_validation.cpp | 38 +++--- .../performance_tests/check_ring_signature.h | 2 +- 19 files changed, 130 insertions(+), 151 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index f4427a2f..420a9f36 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -610,17 +610,9 @@ bool blockchain_storage::prune_ring_signatures_and_attachments(uint64_t height, "is mot equal to height = " << height << " in blockchain index, for block on height = " << height); transaction_chain_entry lolcal_chain_entry = *it; - VARIANT_SWITCH_BEGIN(lolcal_chain_entry.tx.signature); - VARIANT_CASE_CONST(void_sig, v); - VARIANT_CASE(NLSAG_sig, signatures) - { - signatures_pruned += signatures.s.size(); - signatures.s.clear(); - } - VARIANT_CASE_CONST(zarcanum_sig, s); - //@#@ - VARIANT_SWITCH_END(); - + signatures_pruned = lolcal_chain_entry.tx.signatures.size(); + lolcal_chain_entry.tx.signatures.clear(); + attachments_pruned += lolcal_chain_entry.tx.attachment.size(); lolcal_chain_entry.tx.attachment.clear(); @@ -4352,15 +4344,7 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha TIME_MEASURE_START_PD(tx_check_inputs_attachment_check); if (!m_is_in_checkpoint_zone) { - VARIANT_SWITCH_BEGIN(tx.signature); - VARIANT_CASE_CONST(NLSAG_sig, signatures) - { - CHECK_AND_ASSERT_MES(signatures.s.size() == sig_index, false, "tx signatures count differs from inputs"); - } - VARIANT_CASE_CONST(zarcanum_sig, s); - //@#@ - VARIANT_CASE_THROW_ON_OTHER(); - VARIANT_SWITCH_END(); + CHECK_AND_ASSERT_MES(tx.signatures.s.size() == sig_index, false, "tx signatures count differs from inputs"); if (!(get_tx_flags(tx) & TX_FLAG_SIGNATURE_MODE_SEPARATE)) { bool r = validate_attachment_info(tx.extra, tx.attachment, false); @@ -4509,15 +4493,19 @@ bool blockchain_storage::check_input_signature(const transaction& tx, if(m_is_in_checkpoint_zone) return true; - CHECK_AND_ASSERT_MES(tx.signature.type() == typeid(NLSAG_sig), false, "Unexpected type of sig in check_input_signature: " << tx.signature.type().name()); - auto s = boost::get(tx.signature).s; uint64_t actual_sig_index = in_index; if (is_pos_coinbase(tx)) { actual_sig_index = 0; } - CHECK_AND_ASSERT_MES(s.size() > actual_sig_index, false, "Failed to check s.size(){" << s.size() << "} > actual_sig_index {" << actual_sig_index << "}" ); - const std::vector& sig = s[actual_sig_index]; + + + + CHECK_AND_ASSERT_MES(tx.signatures.size() > actual_sig_index, false, "Failed to check s.size(){" << tx.signatures.size() << "} > actual_sig_index {" << actual_sig_index << "}" ); + + CHECK_AND_ASSERT_MES(tx.signatures[actual_sig_index].type() == typeid(NLSAG_sig), false, "Unexpected type of sig in check_input_signature: " << tx.signatures[actual_sig_index].type().name()); + const std::vector& sig = boost::get(tx.signatures[actual_sig_index]).s; + if (get_tx_flags(tx) & TX_FLAG_SIGNATURE_MODE_SEPARATE) { // check attachments, mentioned directly in this input @@ -4605,12 +4593,15 @@ bool blockchain_storage::check_ms_input(const transaction& tx, size_t in_index, LOC_CHK(!have_type_in_variant_container(txin.etc_details), "Incorrect using of extra_attachment_info in etc_details in input #" << in_index << " for tx " << tx_prefix_hash); } bool need_to_check_extra_sign = false; - VARIANT_SWITCH_BEGIN(tx.signature); + + LOC_CHK(tx.signatures.size() > in_index, "ms input index is out of signatures container bounds, signatures.size() = " << tx.signatures.size()); + + //@#@ + VARIANT_SWITCH_BEGIN(tx.signatures[in_index]); VARIANT_CASE_CONST(void_sig, v); - VARIANT_CASE_CONST(NLSAG_sig, signatures) - { - LOC_CHK(signatures.s.size() > in_index, "ms input index is out of signatures container bounds, signatures.size() = " << signatures.s.size()); - const std::vector& input_signatures = signatures.s[in_index]; + VARIANT_CASE_CONST(NLSAG_sig, sig) + { + const std::vector& input_signatures = sig.s; size_t expected_signatures_count = txin.sigs_count; if (get_tx_flags(tx)&TX_FLAG_SIGNATURE_MODE_SEPARATE && in_index == tx.vin.size() - 1) // last input in TX_FLAG_SIGNATURE_MODE_SEPARATE must contain one more signature to ensure that tx was completed by an authorized subject @@ -4644,24 +4635,19 @@ bool blockchain_storage::check_ms_input(const transaction& tx, size_t in_index, out_key_index++; } } + + if (need_to_check_extra_sign) + { + //here we check extra signature to validate that transaction was finilized by authorized subject + bool r = crypto::check_signature(tx_prefix_hash, get_tx_pub_key_from_extra(tx), input_signatures.back()); + LOC_CHK(r, "failed to check extra signature for last out with TX_FLAG_SIGNATURE_MODE_SEPARATE"); + } } VARIANT_CASE_CONST(zarcanum_sig, s); //@#@ + //TODO: don't forget about need_to_check_extra_sign VARIANT_SWITCH_END(); - if (need_to_check_extra_sign) - { - VARIANT_SWITCH_BEGIN(tx.signature); - VARIANT_CASE_CONST(void_sig, v); - VARIANT_CASE_CONST(NLSAG_sig, signatures) - { - //here we check extra signature to validate that transaction was finilized by authorized subject - bool r = crypto::check_signature(tx_prefix_hash, get_tx_pub_key_from_extra(tx), signatures.s[in_index].back()); - LOC_CHK(r, "failed to check extra signature for last out with TX_FLAG_SIGNATURE_MODE_SEPARATE"); - } - VARIANT_CASE_CONST(zarcanum_sig, s); - //@#@ - VARIANT_SWITCH_END(); } @@ -4738,7 +4724,6 @@ bool blockchain_storage::check_tx_input(const transaction& tx, size_t in_index, //TIME_MEASURE_FINISH_PD(tx_check_inputs_loop_ch_in_get_keys_loop); - std::vector output_keys_ptrs; output_keys_ptrs.reserve(output_keys.size()); @@ -4746,19 +4731,9 @@ bool blockchain_storage::check_tx_input(const transaction& tx, size_t in_index, output_keys_ptrs.push_back(&ptr); CHECK_AND_ASSERT_THROW_MES(output_keys_ptrs.size() == 1, "Internal error: output_keys_ptrs.size() is not equal 1 for HTLC"); - - VARIANT_SWITCH_BEGIN(tx.signature); - VARIANT_CASE_CONST(NLSAG_sig, signatures); - { - CHECK_AND_ASSERT_MES(signatures.s.size() > in_index, false, "Unexpeted number of singatures in NLSAG_sig: " << signatures.s.size() << ", expected at least: " << in_index); - return check_input_signature(tx, in_index, txin.amount, txin.k_image, txin.etc_details, tx_prefix_hash, output_keys_ptrs); - } - VARIANT_CASE_CONST(zarcanum_sig, s); - //@#@ TODO - return false; - VARIANT_CASE_THROW_ON_OTHER(); - VARIANT_SWITCH_END(); - return false; + + + return check_input_signature(tx, in_index, txin.amount, txin.k_image, txin.etc_details, tx_prefix_hash, output_keys_ptrs); } //------------------------------------------------------------------ uint64_t blockchain_storage::get_adjusted_time() const @@ -5536,13 +5511,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt //If we under checkpoints, ring signatures should be pruned if(m_is_in_checkpoint_zone) { - VARIANT_SWITCH_BEGIN(tx.signature); - VARIANT_CASE(NLSAG_sig, signatures) - signatures.s.clear(); - VARIANT_CASE_CONST(zarcanum_sig, s); - //@#@ - VARIANT_SWITCH_END(); - + tx.signatures.clear(); tx.attachment.clear(); } TIME_MEASURE_START_PD(tx_add_one_tx_time); @@ -6734,11 +6703,9 @@ bool blockchain_storage::validate_alt_block_ms_input(const transaction& input_tx CRITICAL_REGION_LOCAL(m_read_lock); bool r = false; CHECK_AND_ASSERT_MES(input_index < input_tx.vin.size() - && input_tx.vin[input_index].type() == typeid(txin_multisig) - && input_tx.signature.type() == typeid(NLSAG_sig), false, "invalid ms input index: " << input_index << " or type"); + && input_tx.vin[input_index].type() == typeid(txin_multisig), false, "invalid ms input index: " << input_index << " or type"); const txin_multisig& input = boost::get(input_tx.vin[input_index]); - //const std::vector& input_sigs = boost::get(input_tx.signature).s[input_index]; // check corresponding ms out in the main chain auto p = m_db_multisig_outs.get(input.multisig_out_id); if (p != nullptr) @@ -6930,17 +6897,10 @@ bool blockchain_storage::validate_alt_block_txs(const block& b, const crypto::ha uint64_t ki_lookup = 0; // check PoS block miner tx in a special way - VARIANT_SWITCH_BEGIN(b.miner_tx.signature); - VARIANT_CASE_CONST(void_sig, v); - VARIANT_CASE_CONST(NLSAG_sig, signatures); - { - CHECK_AND_ASSERT_MES(signatures.s.size() == 1 && b.miner_tx.vin.size() == 2, false, "invalid PoS block's miner_tx, signatures size = " << signatures.s.size() << ", miner_tx.vin.size() = " << b.miner_tx.vin.size()); - r = validate_alt_block_input(b.miner_tx, collected_keyimages, alt_chain_tx_ids, id, get_block_hash(b), 1, split_height, alt_chain, alt_chain_block_ids, ki_lookup, &max_related_block_height); - CHECK_AND_ASSERT_MES(r, false, "miner tx " << get_transaction_hash(b.miner_tx) << ": validation failed"); - } - VARIANT_CASE_CONST(zarcanum_sig, s); - //@#@ - VARIANT_SWITCH_END(); + CHECK_AND_ASSERT_MES(b.miner_tx.signatures.size() == 1 && b.miner_tx.vin.size() == 2, false, "invalid PoS block's miner_tx, signatures size = " << b.miner_tx.signatures.size() << ", miner_tx.vin.size() = " << b.miner_tx.vin.size()); + + r = validate_alt_block_input(b.miner_tx, collected_keyimages, alt_chain_tx_ids, id, get_block_hash(b), 1, split_height, alt_chain, alt_chain_block_ids, ki_lookup, &max_related_block_height); + CHECK_AND_ASSERT_MES(r, false, "miner tx " << get_transaction_hash(b.miner_tx) << ": validation failed"); ki_lookup_time_total += ki_lookup; // check stake age @@ -6961,10 +6921,8 @@ bool blockchain_storage::validate_alt_block_txs(const block& b, const crypto::ha CHECK_AND_ASSERT_MES(get_transaction_from_pool_or_db(tx_id, tx_ptr, split_height), false, "failed to get alt block tx " << tx_id << " with split_height == " << split_height); } const transaction& tx = it == abei.onboard_transactions.end() ? *tx_ptr : it->second; - if (tx.signature.type() == typeid(NLSAG_sig)) - { - CHECK_AND_ASSERT_MES(boost::get(tx.signature).s.size() == tx.vin.size(), false, "invalid tx: signatures.size() == " << boost::get(tx.signature).s.size() << ", tx.vin.size() == " << tx.vin.size()); - } + + 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)) @@ -6976,7 +6934,7 @@ bool blockchain_storage::validate_alt_block_txs(const block& b, const crypto::ha } else if (tx.vin[n].type() == typeid(txin_multisig)) { - r = validate_alt_block_ms_input(tx, tx_id, n, tx.signature, split_height, alt_chain); + r = validate_alt_block_ms_input(tx, tx_id, n, split_height, alt_chain); CHECK_AND_ASSERT_MES(r, false, "tx " << tx_id << ", input #" << n << " (multisig): validation failed"); } else if (tx.vin[n].type() == typeid(txin_gen)) diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 9bd6cdc4..39156314 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -605,7 +605,7 @@ namespace currency bool validate_alt_block_ms_input(const transaction& input_tx, const crypto::hash& input_tx_hash, size_t input_index, - const signature_v& input_sigs,//const std::vector& input_sigs, + //const signature_v& input_sigs,//const std::vector& input_sigs, uint64_t split_height, const alt_chain_type& alt_chain) const; bool validate_alt_block_txs(const block& b, const crypto::hash& id, std::unordered_set& collected_keyimages, alt_block_extended_info& abei, const alt_chain_type& alt_chain, uint64_t split_height, uint64_t& ki_lookup_time_total) const; diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index 85641f31..623f4117 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -658,7 +658,7 @@ namespace currency //classic CryptoNote signature by Nicolas Van Saberhagen struct NLSAG_sig { - std::vector > s; + std::vector s; BEGIN_SERIALIZE_OBJECT() FIELD(s) @@ -679,6 +679,21 @@ namespace currency END_BOOST_SERIALIZATION() }; + //TODO: @val, should we call it something like schnorr_sig ? + struct simple_sig + { + crypto::signature s; + + BEGIN_SERIALIZE_OBJECT() + FIELD(s) + END_SERIALIZE() + + BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(s) + END_BOOST_SERIALIZATION() + }; + + struct void_sig { //TODO: @@ -689,6 +704,7 @@ namespace currency END_BOOST_SERIALIZATION() }; + typedef boost::variant signature_v; @@ -734,7 +750,7 @@ namespace currency class transaction: public transaction_prefix { public: - signature_v signature; + std::vector signatures; std::vector attachment; transaction(); diff --git a/src/currency_core/currency_boost_serialization.h b/src/currency_core/currency_boost_serialization.h index 76cefc06..b25b1b10 100644 --- a/src/currency_core/currency_boost_serialization.h +++ b/src/currency_core/currency_boost_serialization.h @@ -227,7 +227,7 @@ namespace boost a & x.vin; a & x.vout; a & x.extra; - a & x.signature; + a & x.signatures; a & x.attachment; } diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 7b5cd146..f9ed697c 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -196,9 +196,10 @@ namespace currency posin.k_image = pe.keyimage; tx.vin.push_back(posin); //reserve place for ring signature - tx.signature = NLSAG_sig(); - boost::get(tx.signature).s.resize(1); - boost::get(tx.signature).s[0].resize(posin.key_offsets.size()); + //tx.signature = NLSAG_sig(); + tx.signatures.resize(1); + tx.signatures[0] = NLSAG_sig(); + boost::get(tx.signatures[0]).s.resize(posin.key_offsets.size()); } uint64_t no = 0; @@ -1283,7 +1284,6 @@ namespace currency { tx.vin.clear(); tx.vout.clear(); - tx.signature = NLSAG_sig(); tx.extra = extra; tx.version = ftp.tx_version; @@ -1536,8 +1536,8 @@ namespace currency crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, input_index, tx_prefix_hash); CHECK_AND_ASSERT_MES(tx_hash_for_signature != null_hash, false, "failed to prepare_prefix_hash_for_sign"); - boost::get(tx.signature).s.push_back(std::vector()); - std::vector& sigs = boost::get(tx.signature).s.back(); + tx.signatures.push_back(NLSAG_sig()); + std::vector& sigs = boost::get(tx.signatures.back()).s; if(src_entr.is_multisig()) { @@ -1688,12 +1688,13 @@ namespace currency size_t participant_index = std::find(out_ms.keys.begin(), out_ms.keys.end(), ms_in_ephemeral_key.pub) - out_ms.keys.begin(); LOC_CHK(participant_index < out_ms.keys.size(), "Can't find given participant's ms key in ms output keys list"); - //@#@ - LOC_CHK(tx.signature.type() == typeid(NLSAG_sig), "Wrong type of signature"); - LOC_CHK(ms_input_index < boost::get(tx.signature).s.size(), "transaction does not have signatures vector entry for ms input #" << ms_input_index); - auto& sigs = boost::get(tx.signature).s[ms_input_index]; + //@#@ + LOC_CHK(ms_input_index < tx.signatures.size(), "transaction does not have signatures vector entry for ms input #" << ms_input_index); + + LOC_CHK(tx.signatures[ms_input_index].type() == typeid(NLSAG_sig), "Wrong type of signature"); + auto& sigs = boost::get(tx.signatures[ms_input_index]); LOC_CHK(!sigs.empty(), "empty signatures container"); bool extra_signature_expected = (get_tx_flags(tx) & TX_FLAG_SIGNATURE_MODE_SEPARATE) && ms_input_index == tx.vin.size() - 1; @@ -2866,8 +2867,12 @@ namespace currency 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); - if (tx.signature.type() == typeid(NLSAG_sig) && boost::get(tx.signature).s.size() >= tei.ins.size()) - tei.ins.back().multisig_count = boost::get(tx.signature).s[tei.ins.size() - 1].size(); + 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(); + } + } } return true; diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index b4d8993b..f42d5e6a 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -1835,9 +1835,9 @@ bool sign_multisig_input_in_tx_custom(currency::transaction& tx, size_t ms_input bool r = currency::derive_ephemeral_key_helper(keys, source_tx_pub_key, ms_out_index, ms_in_ephemeral_key); LOC_CHK(r, "derive_ephemeral_key_helper failed"); - LOC_CHK(ms_input_index < boost::get(tx.signature).s.size(), "transaction does not have signatures vectory entry for ms input #" << ms_input_index); + LOC_CHK(ms_input_index < tx.signatures.size(), "transaction does not have signatures vectory entry for ms input #" << ms_input_index); - auto& sigs = boost::get(tx.signature).s[ms_input_index]; + auto& sigs = boost::get(tx.signatures[ms_input_index]).s; LOC_CHK(!sigs.empty(), "empty signatures container"); bool extra_signature_expected = (get_tx_flags(tx) & TX_FLAG_SIGNATURE_MODE_SEPARATE) && ms_input_index == tx.vin.size() - 1; size_t allocated_sigs_for_participants = extra_signature_expected ? sigs.size() - 1 : sigs.size(); diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index c1a9a9e7..2b1574c2 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -744,7 +744,7 @@ bool construct_broken_tx(const currency::account_keys& sender_account_keys, cons { tx.vin.clear(); tx.vout.clear(); - boost::get(tx.signature).s.clear(); + tx.signatures.clear(); tx.extra = extra; tx.version = TRANSACTION_VERSION_PRE_HF4; @@ -846,8 +846,8 @@ bool construct_broken_tx(const currency::account_keys& sender_account_keys, cons ss_ring_s << o.second << ENDL; } - boost::get(tx.signature).s.push_back(std::vector()); - std::vector& sigs = boost::get(tx.signature).s.back(); + tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + std::vector& sigs = boost::get(tx.signatures.back()).s; sigs.resize(src_entr.outputs.size()); crypto::generate_ring_signature(tx_prefix_hash, boost::get(tx.vin[i]).k_image, keys_ptrs, in_contexts[i].in_ephemeral.sec, src_entr.real_output, sigs.data()); ss_ring_s << "signatures:" << ENDL; diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h index 1f4a45f1..f77d6b56 100644 --- a/tests/core_tests/chaingen_helpers.h +++ b/tests/core_tests/chaingen_helpers.h @@ -218,7 +218,7 @@ inline bool resign_tx(const currency::account_keys& sender_keys, const std::vect if (sources.size() != tx.vin.size()) return false; - boost::get(tx.signature).s.clear(); + tx.signatures.clear(); crypto::hash tx_prefix_hash = get_transaction_hash(tx); size_t i = 0; @@ -234,8 +234,8 @@ inline bool resign_tx(const currency::account_keys& sender_keys, const std::vect return false; crypto::derive_secret_key(recv_derivation, se.real_output_in_tx_index, sender_keys.spend_secret_key, in_ephemeral_sec); - boost::get(tx.signature).s.push_back(std::vector()); - std::vector& sigs = boost::get(tx.signature).s.back(); + tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + std::vector& sigs = boost::get(tx.signatures.back()).s; if (se.is_multisig()) { diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 9339c9a3..d09d1558 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -308,7 +308,7 @@ public: return; // skip certainly invalid txs bool b_cp = c.get_blockchain_storage().is_in_checkpoint_zone(); - if (b_cp && boost::get(tx.signature).s.empty() && tx.attachment.empty()) + if (b_cp && tx.signatures.empty() && tx.attachment.empty()) return; // skip pruned txs in CP zone size_t tx_expected_blob_size = get_object_blobsize(tx); @@ -328,7 +328,7 @@ public: { // tx seems to be correct ( tx_expected_blob_size == blob.size() ) or BCS is in CP zone, prune sigs and attachments and check again currency::transaction pruned_tx = tx; - boost::get(pruned_tx.signature).s.clear(); + pruned_tx.signatures.clear(); pruned_tx.attachment.clear(); size_t pruned_tx_expected_blob_size = get_object_blobsize(pruned_tx); diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp index debf4200..9049ee6e 100644 --- a/tests/core_tests/checkpoints_tests.cpp +++ b/tests/core_tests/checkpoints_tests.cpp @@ -121,7 +121,7 @@ bool gen_checkpoints_attachments_basic::check_tx(currency::core& c, size_t ev_in bool r = c.get_transaction(m_tx_hash, tx); CHECK_AND_ASSERT_MES(r, false, "can't get transaction"); - CHECK_AND_ASSERT_MES(boost::get(tx.signature).s.empty(), false, "tx has non-empty sig"); + CHECK_AND_ASSERT_MES(tx.signatures.empty(), false, "tx has non-empty sig"); CHECK_AND_ASSERT_MES(tx.attachment.empty(), false, "tx has non-empty attachments"); return true; } @@ -443,12 +443,12 @@ bool gen_checkpoints_prun_txs_after_blockchain_load::check_txs(currency::core& c transaction tx_0, tx_1; bool r = c.get_transaction(m_tx0_id, tx_0); CHECK_AND_ASSERT_MES(r, false, "can't get transaction tx_0"); - CHECK_AND_ASSERT_MES(boost::get(tx_0.signature).s.empty(), false, "tx_0 has non-empty sig"); + CHECK_AND_ASSERT_MES(tx_0.signatures.empty(), false, "tx_0 has non-empty sig"); CHECK_AND_ASSERT_MES(tx_0.attachment.empty(), false, "tx_0 has non-empty attachments"); r = c.get_transaction(m_tx1_id, tx_1); CHECK_AND_ASSERT_MES(r, false, "can't get transaction tx_1"); - CHECK_AND_ASSERT_MES(!boost::get(tx_1.signature).s.empty(), false, "tx_1 has empty sig"); + CHECK_AND_ASSERT_MES(!tx_1.signatures.empty(), false, "tx_1 has empty sig"); CHECK_AND_ASSERT_MES(!tx_1.attachment.empty(), false, "tx_1 has empty attachments"); return true; @@ -595,7 +595,7 @@ bool gen_checkpoints_pos_validation_on_altchain::generate(std::vector(pb.m_block.miner_tx.signature).s[0].clear(); // just to make sure + boost::get(pb.m_block.miner_tx.signatures[0]).s.clear(); // just to make sure blk_2 = pb.m_block; } @@ -875,7 +875,7 @@ bool gen_checkpoints_and_invalid_tx_to_pool::generate(std::vector(tx_0.signature).s.clear(); + tx_0.signatures.clear(); DO_CALLBACK(events, "mark_unverifiable_tx"); events.push_back(tx_0); diff --git a/tests/core_tests/escrow_wallet_common.h b/tests/core_tests/escrow_wallet_common.h index 813e2597..d23f5140 100644 --- a/tests/core_tests/escrow_wallet_common.h +++ b/tests/core_tests/escrow_wallet_common.h @@ -253,8 +253,8 @@ inline bool build_custom_escrow_template(const std::vector& ev if (custom_config_mask & eccf_template_no_a_sigs) { - boost::get(escrow_template_tx.signature).s.clear(); - boost::get(escrow_template_tx.signature).s.push_back(std::vector()); + escrow_template_tx.signatures.clear(); + escrow_template_tx.signatures.push_back(currency::NLSAG_sig(std::vector())); } append_vector_by_another_vector(used_sources, sources); diff --git a/tests/core_tests/multisig_wallet_tests.cpp b/tests/core_tests/multisig_wallet_tests.cpp index eec48869..ca43c559 100644 --- a/tests/core_tests/multisig_wallet_tests.cpp +++ b/tests/core_tests/multisig_wallet_tests.cpp @@ -1037,7 +1037,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons CHECK_AND_ASSERT_MES(r && !tx_fully_signed, false, "sign_multisig_input_in_tx failed, tx_fully_signed : " << tx_fully_signed); r = sign_multisig_input_in_tx_custom(tx_7, ms_6_out_idx, miner_acc.get_keys(), tx_6, &tx_fully_signed, false); CHECK_AND_ASSERT_MES(r && !tx_fully_signed, false, "sign_multisig_input_in_tx failed, tx_fully_signed : " << tx_fully_signed); - boost::get(tx_7.signature).s[0].push_back(invalid_signature); // instead of 4th sig just add invalid sig + boost::get(tx_7.signatures[0]).s.push_back(invalid_signature); // instead of 4th sig just add invalid sig DO_CALLBACK(events, "mark_invalid_tx"); events.push_back(tx_7); @@ -1073,7 +1073,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_9, get_tx_version_from_events(events), 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); - boost::get(tx_9.signature).s[0].resize(redundant_keys_count, invalid_signature); + boost::get(tx_9.signatures[0]).s.resize(redundant_keys_count, invalid_signature); r = sign_multisig_input_in_tx_custom(tx_9, ms_8_out_idx, bob_acc.get_keys(), tx_8, &tx_fully_signed, false); CHECK_AND_ASSERT_MES(r && !tx_fully_signed, false, "sign_multisig_input_in_tx failed, tx_fully_signed : " << tx_fully_signed); @@ -1847,7 +1847,7 @@ bool multisig_and_checkpoints_bad_txs::generate(std::vector& e transaction tx_2 = AUTO_VAL_INIT(tx_2); r = make_tx_multisig_to_key(tx_1, get_tx_out_index_by_amount(tx_1, amount), std::list({ alice_acc.get_keys() }), bob_acc.get_public_address(), tx_2); CHECK_AND_ASSERT_MES(r, false, "make_tx_multisig_to_key failed"); - boost::get(tx_2.signature).s.resize(10); + tx_2.signatures.resize(10); boost::get(tx_2.vin[0]).sigs_count = 10; DO_CALLBACK(events, "mark_invalid_tx"); @@ -1863,7 +1863,7 @@ bool multisig_and_checkpoints_bad_txs::generate(std::vector& e transaction tx_3 = AUTO_VAL_INIT(tx_3); r = make_tx_multisig_to_key(tx_1, get_tx_out_index_by_amount(tx_1, amount), std::list({ alice_acc.get_keys() }), bob_acc.get_public_address(), tx_3); CHECK_AND_ASSERT_MES(r, false, "make_tx_multisig_to_key failed"); - boost::get(tx_3.signature).s.clear(); + tx_3.signatures.clear(); boost::get(tx_3.vin[0]).sigs_count = 0; events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true)); @@ -1895,7 +1895,7 @@ bool multisig_and_checkpoints_bad_txs::generate(std::vector& e boost::get(boost::get(txb.m_tx.vout[0]).target).keys.resize(1500, k); txb.step4_calc_hash(); txb.step5_sign(sources); - boost::get(txb.m_tx.signature).s.clear(); + txb.m_tx.signatures.clear(); transaction tx_6 = txb.m_tx; events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true)); events.push_back(tx_6); @@ -2116,7 +2116,7 @@ bool ref_by_id_basics::generate(std::vector& events) const r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, 0, CURRENCY_TO_KEY_OUT_RELAXED, true); CHECK_AND_ASSERT_MES(r, false, "construct_tx"); - r = check_ring_signature_at_gen_time(events, get_block_hash(blk_0r), boost::get(tx_1.vin[0]), get_transaction_hash(tx_1), boost::get(tx_1.signature).s[0]); + r = check_ring_signature_at_gen_time(events, get_block_hash(blk_0r), boost::get(tx_1.vin[0]), get_transaction_hash(tx_1), boost::get(tx_1.signatures[0]).s); CHECK_AND_ASSERT_MES(r, false, "check_ring_signature_at_gen_time failed"); events.push_back(tx_1); diff --git a/tests/core_tests/pos_block_builder.cpp b/tests/core_tests/pos_block_builder.cpp index a7367922..acdd9322 100644 --- a/tests/core_tests/pos_block_builder.cpp +++ b/tests/core_tests/pos_block_builder.cpp @@ -173,7 +173,7 @@ void pos_block_builder::step5_sign(const crypto::public_key& stake_tx_pub_key, s // sign block actually in coinbase transaction crypto::hash block_hash = currency::get_block_hash(m_block); std::vector keys_ptrs(1, &stake_tx_out_pub_key); - crypto::generate_ring_signature(block_hash, m_stake_kernel.kimage, keys_ptrs, derived_secret_ephemeral_key, 0, &boost::get(m_block.miner_tx.signature).s[0][0]); + crypto::generate_ring_signature(block_hash, m_stake_kernel.kimage, keys_ptrs, derived_secret_ephemeral_key, 0, &boost::get(m_block.miner_tx.signatures[0]).s[0]); m_step = 5; } @@ -272,8 +272,8 @@ bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const bo posin.k_image = pos_stake_keyimage; tx.vin.push_back(posin); //reserve place for ring signature - boost::get(tx.signature).s.resize(1); - boost::get(tx.signature).s[0].resize(posin.key_offsets.size()); + tx.signatures.resize(1); + boost::get(tx.signatures[0]).s.resize(posin.key_offsets.size()); return true; } diff --git a/tests/core_tests/pos_validation.cpp b/tests/core_tests/pos_validation.cpp index ce02e351..0cfb69ff 100644 --- a/tests/core_tests/pos_validation.cpp +++ b/tests/core_tests/pos_validation.cpp @@ -358,7 +358,7 @@ bool gen_pos_invalid_coinbase::generate(std::vector& events) c pb.step4_generate_coinbase_tx(generator.get_timestamps_median(prev_id), generator.get_already_generated_coins(prev_block), alice_acc.get_public_address()); pb.step5_sign(stake_tx_pub_key, stake_output_idx, stake_output_pubkey, miner_acc); - boost::get(pb.m_block.miner_tx.signature).s.clear(); // remove signatures + pb.m_block.miner_tx.signatures.clear(); // remove signatures block blk_1 = pb.m_block; diff --git a/tests/core_tests/pruning_ring_signatures.cpp b/tests/core_tests/pruning_ring_signatures.cpp index 5f2b3c46..aedebf6f 100644 --- a/tests/core_tests/pruning_ring_signatures.cpp +++ b/tests/core_tests/pruning_ring_signatures.cpp @@ -25,8 +25,8 @@ struct ev_visitor : public boost::static_visitor { size_t real_bloc_size = t_serializable_object_to_blob(t).size(); - std::cout << "prunging sigs: " << boost::get(t.signature).s.size() << ENDL; - boost::get(t.signature).s.clear(); + std::cout << "prunging sigs: " << t.signatures.size() << ENDL; + t.signatures.clear(); //check tx pruning correctnes if (real_bloc_size != get_object_blobsize(t)) diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp index b9a278d9..29adf651 100644 --- a/tests/core_tests/transaction_tests.cpp +++ b/tests/core_tests/transaction_tests.cpp @@ -110,7 +110,7 @@ bool test_transaction_generation_and_ring_signature() output_keys.push_back(&boost::get(boost::get(tx_mine_4.vout[0]).target).key); output_keys.push_back(&boost::get(boost::get(tx_mine_5.vout[0]).target).key); output_keys.push_back(&boost::get(boost::get(tx_mine_6.vout[0]).target).key); - r = crypto::check_ring_signature(pref_hash, boost::get(tx_rc1.vin[0]).k_image, output_keys, &boost::get(tx_rc1.signature).s[0][0]); + r = crypto::check_ring_signature(pref_hash, boost::get(tx_rc1.vin[0]).k_image, output_keys, &boost::get(tx_rc1.signatures[0]).s[0]); CHECK_AND_ASSERT_MES(r, false, "failed to check ring signature"); std::vector outs; diff --git a/tests/core_tests/tx_builder.h b/tests/core_tests/tx_builder.h index 00aff6b0..1cfb8ffd 100644 --- a/tests/core_tests/tx_builder.h +++ b/tests/core_tests/tx_builder.h @@ -98,7 +98,7 @@ struct tx_builder void step5_sign(const std::vector& sources) { - boost::get(m_tx.signature).s.clear(); + m_tx.signatures.clear(); size_t i = 0; for(const currency::tx_source_entry& src_entr : sources) @@ -109,8 +109,8 @@ struct tx_builder keys_ptrs.push_back(&o.second); } - boost::get(m_tx.signature).s.push_back(std::vector()); - std::vector& sigs = boost::get(m_tx.signature).s.back(); + m_tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + std::vector& sigs = boost::get(m_tx.signatures.back()).s; sigs.resize(src_entr.outputs.size()); generate_ring_signature(m_tx_prefix_hash, boost::get(m_tx.vin[i]).k_image, keys_ptrs, m_in_contexts[i].sec, src_entr.real_output, sigs.data()); i++; diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index 0a15203b..7ec03b6a 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -370,9 +370,9 @@ bool gen_tx_key_image_not_derive_from_tx_key::generate(std::vector(builder.m_tx.signature).s.resize(1); - boost::get(builder.m_tx.signature).s[0].resize(1); - boost::get(builder.m_tx.signature).s[0][0] = boost::value_initialized(); + builder.m_tx.signatures.resize(1); + boost::get(builder.m_tx.signatures[0]).s.resize(1); + boost::get(builder.m_tx.signatures[0]).s[0] = boost::value_initialized(); DO_CALLBACK(events, "mark_invalid_tx"); events.push_back(builder.m_tx); @@ -404,9 +404,9 @@ bool gen_tx_key_image_is_invalid::generate(std::vector& events builder.step4_calc_hash(); // Tx with invalid key image can't be subscribed, so create empty signature - boost::get(builder.m_tx.signature).s.resize(1); - boost::get(builder.m_tx.signature).s[0].resize(1); - boost::get(builder.m_tx.signature).s[0][0] = boost::value_initialized(); + builder.m_tx.signatures.resize(1); + boost::get(builder.m_tx.signatures[0]).s.resize(1); + boost::get(builder.m_tx.signatures[0]).s[0] = boost::value_initialized(); DO_CALLBACK(events, "mark_invalid_tx"); events.push_back(builder.m_tx); @@ -633,62 +633,62 @@ bool gen_tx_signatures_are_invalid::generate(std::vector& even // create reference transaction tx_0, Carol->Alice, nmix=0 MAKE_TX(events, tx_0, carol_account, alice_account, amount, blk_1r_f); events.pop_back(); - CHECK_AND_ASSERT_MES(tx_0.vin.size() > 1 && tx_0.vout.size() > 1 && boost::get(tx_0.signature).s.size() > 1, false, "tx_0 is incorrect"); // need > 1 for this test + CHECK_AND_ASSERT_MES(tx_0.vin.size() > 1 && tx_0.vout.size() > 1 && tx_0.signatures.size() > 1, false, "tx_0 is incorrect"); // need > 1 for this test // create reference transaction tx_1, Dan->Alice, nmix=1 MAKE_TX_MIX(events, tx_1, dan_account, alice_account, amount, 1, blk_1r_f); events.pop_back(); - CHECK_AND_ASSERT_MES(tx_1.vin.size() > 1 && tx_1.vout.size() > 1 && boost::get(tx_1.signature).s.size() > 1, false, "tx_1 is incorrect"); // need > 1 for this test + CHECK_AND_ASSERT_MES(tx_1.vin.size() > 1 && tx_1.vout.size() > 1 && tx_1.signatures.size() > 1, false, "tx_1 is incorrect"); // need > 1 for this test const block& prev_block = blk_1r_f; transaction broken_tx; // Tx with nmix = 0 without signatures broken_tx = tx_0; - boost::get(broken_tx.signature).s.clear(); + broken_tx.signatures.clear(); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); // Tx with nmix = 0 have a few inputs, and not enough signatures broken_tx = tx_0; - boost::get(broken_tx.signature).s.resize(boost::get(broken_tx.signature).s.size() - 1); + broken_tx.signatures.resize(broken_tx.signatures.size() - 1); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); // Tx with nmix = 0 have a few inputs, and too many signatures (1/2) broken_tx = tx_0; - boost::get(broken_tx.signature).s.back().push_back(invalid_signature); + boost::get(broken_tx.signatures.back()).s.push_back(invalid_signature); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); // Tx with nmix = 0 have a few inputs, and too many signatures (2/2) broken_tx = tx_0; - boost::get(broken_tx.signature).s.push_back(std::vector()); - boost::get(broken_tx.signature).s.back().push_back(invalid_signature); + broken_tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + boost::get(broken_tx.signatures.back()).s.push_back(invalid_signature); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); // Tx with nmix = 1 without signatures broken_tx = tx_1; - boost::get(broken_tx.signature).s.clear(); + broken_tx.signatures.clear(); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); // Tx with nmix = 1 have not enough signatures (1/2) broken_tx = tx_1; - boost::get(broken_tx.signature).s.resize(boost::get(broken_tx.signature).s.size() - 1); + broken_tx.signatures.resize(broken_tx.signatures.size() - 1); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); // Tx with nmix = 1 have not enough signatures (2/2) broken_tx = tx_1; - boost::get(broken_tx.signature).s.back().resize(boost::get(broken_tx.signature).s.back().size() - 1); + broken_tx.signatures.back().resize(boost::get(broken_tx.signatures.back()).s.size() - 1); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); // Tx with nmix = 1 have too many signatures (1/2) broken_tx = tx_1; - boost::get(broken_tx.signature).s.back().push_back(invalid_signature); + boost::get(broken_tx.signatures.back()).s.push_back(invalid_signature); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); // Tx with nmix = 1 have too many signatures (2/2) broken_tx = tx_1; - boost::get(broken_tx.signature).s.push_back(std::vector()); - boost::get(broken_tx.signature).s.back().push_back(invalid_signature); + broken_tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + boost::get(broken_tx.signatures.back()).s.push_back(invalid_signature); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); diff --git a/tests/performance_tests/check_ring_signature.h b/tests/performance_tests/check_ring_signature.h index d63ec01f..d53b70bf 100644 --- a/tests/performance_tests/check_ring_signature.h +++ b/tests/performance_tests/check_ring_signature.h @@ -47,7 +47,7 @@ public: bool test() { const currency::txin_to_key& txin = boost::get(m_tx.vin[0]); - return crypto::check_ring_signature(m_tx_prefix_hash, txin.k_image, this->m_public_key_ptrs, ring_size, boost::get(m_tx.signature)[0].data()); + return crypto::check_ring_signature(m_tx_prefix_hash, txin.k_image, this->m_public_key_ptrs, ring_size, boost::get(m_tx.signatures[0]).s.data()); } private: From fa4b8ab130efb9af7b4845509e932a1d1d333d92 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 23 Jun 2022 16:22:55 +0200 Subject: [PATCH 2/4] signature refactoring: pre-core tests --- src/currency_core/blockchain_storage.cpp | 2 +- src/currency_core/currency_basic.h | 4 +- .../currency_basic_backward_comp.inl | 20 +++-- src/currency_core/currency_format_utils.cpp | 1 - src/currency_core/currency_format_utils.h | 4 +- src/wallet/wallet2.cpp | 9 ++- src/wallet/wallet2_escrow.cpp | 31 +++---- tests/unit_tests/serialization.cpp | 80 ++++++++++++------- 8 files changed, 92 insertions(+), 59 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 420a9f36..ce804515 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -6673,7 +6673,7 @@ bool blockchain_storage::is_output_allowed_for_input(const output_key_or_htlc_v& } } //------------------------------------------------------------------ -bool blockchain_storage::validate_alt_block_ms_input(const transaction& input_tx, const crypto::hash& input_tx_hash, size_t input_index, const signature_v& input_sigs_v, uint64_t split_height, const alt_chain_type& alt_chain) const +bool blockchain_storage::validate_alt_block_ms_input(const transaction& input_tx, const crypto::hash& input_tx_hash, size_t input_index, uint64_t split_height, const alt_chain_type& alt_chain) const { // Main and alt chain outline: // diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index 623f4117..e0ff6f82 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -759,7 +759,7 @@ namespace currency FIELDS(*static_cast(this)) CHAIN_TRANSITION_VER(TRANSACTION_VERSION_INITAL, transaction_v1) CHAIN_TRANSITION_VER(TRANSACTION_VERSION_PRE_HF4, transaction_v1) - FIELD(signature) + FIELD(signatures) FIELD(attachment) END_SERIALIZE() }; @@ -774,7 +774,7 @@ namespace currency vin.clear(); vout.clear(); extra.clear(); - signature = NLSAG_sig(); + signatures.clear(); attachment.clear(); } diff --git a/src/currency_core/currency_basic_backward_comp.inl b/src/currency_core/currency_basic_backward_comp.inl index 4e3bf92a..1dd09309 100644 --- a/src/currency_core/currency_basic_backward_comp.inl +++ b/src/currency_core/currency_basic_backward_comp.inl @@ -90,13 +90,15 @@ template bool transition_convert(const transaction_current_t& from, transaction_v1& to) { to.attachment = from.attachment; - if (from.signature.type() == typeid(NLSAG_sig)) + for (const auto& s : from.signatures) { - to.signatures = boost::get(from.signature).s; - } - else - { - throw std::runtime_error("Unexpected type in signature_v"); + if (s.type() == typeid(NLSAG_sig)) + { + to.signatures.push_back(boost::get(s).s); ; + }else + { + throw std::runtime_error("Unexpected type in signature_v"); + } } return true; } @@ -106,6 +108,10 @@ bool transition_convert(const transaction_v1& from, transaction_current_t& to) { // TODO: consider using move semantic for 'from' to.attachment = from.attachment; - to.signature = NLSAG_sig({from.signatures}); + to.signatures.resize(from.signatures.size()); + for (size_t i = 0; i != from.signatures.size(); i++) + { + boost::get(to.signatures[i]).s = from.signatures[i]; + } return true; } diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index f9ed697c..2a374c53 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -196,7 +196,6 @@ namespace currency posin.k_image = pe.keyimage; tx.vin.push_back(posin); //reserve place for ring signature - //tx.signature = NLSAG_sig(); tx.signatures.resize(1); tx.signatures[0] = NLSAG_sig(); boost::get(tx.signatures[0]).s.resize(posin.key_offsets.size()); diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 21e0cea4..a6271037 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -56,7 +56,9 @@ namespace currency bool operator ==(const currency::transaction& a, const currency::transaction& b); bool operator ==(const currency::block& a, const currency::block& b); bool operator ==(const currency::extra_attachment_info& a, const currency::extra_attachment_info& b); - + bool operator ==(const currency::NLSAG_sig& a, const currency::NLSAG_sig& b); + bool operator ==(const currency::void_sig& a, const currency::void_sig& b); + bool operator ==(const currency::zarcanum_sig& a, const currency::zarcanum_sig& b); typedef boost::multiprecision::uint128_t uint128_tl; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 02a3267f..164432d9 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3507,8 +3507,9 @@ bool wallet2::prepare_and_sign_pos_block(currency::block& b, return false; // to get rid of warning }else { - NLSAG_sig& signatures = boost::get(b.miner_tx.signature); - WLT_CHECK_AND_ASSERT_MES(signatures.s.size() == 1 && signatures.s[0].size() == txin.key_offsets.size(), + WLT_CHECK_AND_ASSERT_MES(b.miner_tx.signatures.size() == 1 && + b.miner_tx.signatures[0].type() == typeid(NLSAG_sig) && + boost::get(b.miner_tx.signatures[0]).s.size() == txin.key_offsets.size(), false, "Wrong signatures amount in coinbase transacton"); @@ -3536,12 +3537,12 @@ bool wallet2::prepare_and_sign_pos_block(currency::block& b, keys_ptrs, derived_secret_ephemeral_key, 0, - &signatures.s[0][0]); + &boost::get(b.miner_tx.signatures[0]).s[0]); WLT_LOG_L4("GENERATED RING SIGNATURE: block_id " << block_hash << "txin.k_image" << txin.k_image << "key_ptr:" << *keys_ptrs[0] - << "signature:" << signatures.s[0][0]); + << "signature:" << boost::get(b.miner_tx.signatures[0]).s); return true; } diff --git a/src/wallet/wallet2_escrow.cpp b/src/wallet/wallet2_escrow.cpp index af4f735e..542db5f2 100644 --- a/src/wallet/wallet2_escrow.cpp +++ b/src/wallet/wallet2_escrow.cpp @@ -234,14 +234,14 @@ bool wallet2::validate_escrow_release(const transaction& tx, bool release_type_n // (5/5) signatures - VARIANT_SWITCH_BEGIN(tx.signature); - VARIANT_CASE_CONST(NLSAG_sig, signatures) - { - LOC_CHK(signatures.s.size() == 1, "invalid singatures size: " << signatures.s.size()); // only 1 input means only 1 signature vector + LOC_CHK(tx.signatures.size() == 1, "invalid singatures size: " << tx.signatures.size()); // only 1 input means only 1 signature vector - // As we don't have b_keys we can't be sure which signature is B's and which is reserved for A (should be a null-placeholder, if present). - // Having a_keys, we determine index of A key in multisig output keys array. - // Thus it's possible to determine the order of signatures (A, B or B, A), and, eventually, validate B signature. + VARIANT_SWITCH_BEGIN(tx.signatures[0]); + VARIANT_CASE_CONST(NLSAG_sig, signature) + { + // As we don't have b_keys we can't be sure which signature is B's and which is reserved for A (should be a null-placeholder, if present). + // Having a_keys, we determine index of A key in multisig output keys array. + // Thus it's possible to determine the order of signatures (A, B or B, A), and, eventually, validate B signature. crypto::public_key source_tx_pub_key = get_tx_pub_key_from_extra(source_tx); r = crypto::generate_key_derivation(source_tx_pub_key, a_keys.view_secret_key, der); LOC_CHK(r, "generate_key_derivation failed"); @@ -250,14 +250,14 @@ bool wallet2::validate_escrow_release(const transaction& tx, bool release_type_n LOC_CHK(r, "derive_public_key failed"); LOC_CHK(source_ms_out.keys.size() == 2, "internal error: invalid ms output keys array, size: " << source_ms_out.keys.size()); - LOC_CHK(signatures.s[0].size() == 2, "internal error: invalid signature size for input #0: " << signatures.s[0].size()) + LOC_CHK(signature.size() == 2, "internal error: invalid signature size for input #0: " << signature.size()) size_t ms_out_key_a_index = std::find(source_ms_out.keys.begin(), source_ms_out.keys.end(), ephemeral_pub_key) - source_ms_out.keys.begin(); LOC_CHK(ms_out_key_a_index < source_ms_out.keys.size(), "internal error: can't find A ephemeral pub key within ms output keys"); size_t ms_out_key_b_index = 1 - ms_out_key_a_index; - // in this particular case (source_ms_out.minimum_sigs == source_ms_out.keys.size() == 2) index in 'keys' is the same as index in signatures.s[0] + // in this particular case (source_ms_out.minimum_sigs == source_ms_out.keys.size() == 2) index in 'keys' is the same as index in signature crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, 0, get_transaction_hash(tx)); - r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[ms_out_key_b_index], signatures.s[0][ms_out_key_b_index]); + r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[ms_out_key_b_index], signature[ms_out_key_b_index]); LOC_CHK(r, "B signature for multisig input is invalid"); } VARIANT_CASE_CONST(zarcanum_sig, s); @@ -418,17 +418,18 @@ bool wallet2::validate_escrow_cancel_release(const currency::transaction& tx, co // (5/5) signatures - VARIANT_SWITCH_BEGIN(tx.signature); + LOC_CHK(tx.signatures.size() == 1, "invalid singatures size: " << tx.signatures.size()); // only 1 input means only 1 signature vector + VARIANT_SWITCH_BEGIN(tx.signatures[0]); VARIANT_CASE_CONST(NLSAG_sig, signatures) { - LOC_CHK(signatures.s.size() == 1, "invalid singatures size: " << signatures.s.size()); // only 1 input means only 1 signature vector - LOC_CHK(signatures.s[0].size() == 2, "invalid signature[0] size: " << signatures.s[0].size()); // it's expected to contain A-party signature and null-sig placeholder + + LOC_CHK(signature.size() == 2, "invalid signature[0] size: " << signature.size()); // it's expected to contain A-party signature and null-sig placeholder LOC_CHK(source_ms_out.keys.size() == 2, "internal error: invalid source ms output keys array, size: " << source_ms_out.keys.size()); - size_t a_sign_index = (signatures.s[0][0] != null_sig) ? 0 : 1; + size_t a_sign_index = (signature[0] != null_sig) ? 0 : 1; crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, 0, get_transaction_hash(tx)); - r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[a_sign_index], signatures.s[0][a_sign_index]); + r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[a_sign_index], signature[a_sign_index]); LOC_CHK(r, "A signature for multisig input is invalid"); } VARIANT_CASE_CONST(zarcanum_sig, s); diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp index 24e950d8..ea6e9c3f 100644 --- a/tests/unit_tests/serialization.cpp +++ b/tests/unit_tests/serialization.cpp @@ -26,6 +26,12 @@ struct Struct char blob[8]; }; + +std::ostream& operator <<(std::ostream& o, const currency::signature_v& v) +{ + return o; +} + template struct serializer { @@ -270,6 +276,18 @@ namespace } return res; } + + template + std::vector linearize_vector2(const std::vector< currency::signature_v >& vec_vec) + { + std::vector res; + BOOST_FOREACH(const auto& vec, vec_vec) + { + res.insert(res.end(), vec.begin(), vec.end()); + } + return res; + } + } bool test_get_varint_packed_size_for_num(uint64_t n) @@ -330,7 +348,8 @@ TEST(Serialization, serializes_transacion_signatures_correctly) ASSERT_TRUE(false); } - ASSERT_EQ(linearize_vector2(boost::get(tx.signature).s), linearize_vector2(boost::get(tx1.signature).s)); + ASSERT_EQ(tx.signatures, tx1.signatures); + //ASSERT_EQ(linearize_vector2(boost::get(tx.signature).s), linearize_vector2(boost::get(tx1.signature).s)); // Miner tx without signatures txin_gen txin_gen1; @@ -344,10 +363,11 @@ TEST(Serialization, serializes_transacion_signatures_correctly) { ASSERT_TRUE(false); } - ASSERT_EQ(linearize_vector2(boost::get(tx.signature).s), linearize_vector2(boost::get(tx1.signature).s)); + ASSERT_EQ(tx.signatures, tx1.signatures); + //ASSERT_EQ(linearize_vector2(boost::get(tx.signature).s), linearize_vector2(boost::get(tx1.signature).s)); // Miner tx with empty signatures 2nd vector - boost::get(tx.signature).s.resize(1); + tx.signatures.resize(1); ASSERT_TRUE(serialization::dump_binary(tx, blob)); ASSERT_EQ(9, blob.size()); // 5 bytes + 2 bytes vin[0] + 0 bytes extra + 0 bytes signatures + counter ASSERT_TRUE(serialization::parse_binary(blob, tx1)); @@ -355,29 +375,30 @@ TEST(Serialization, serializes_transacion_signatures_correctly) { ASSERT_TRUE(false); } - ASSERT_EQ(linearize_vector2(boost::get(tx.signature).s), linearize_vector2(boost::get(tx1.signature).s)); + ASSERT_EQ(tx.signatures, tx1.signatures); + //ASSERT_EQ(linearize_vector2(boost::get(tx.signature).s), linearize_vector2(boost::get(tx1.signature).s)); //TX VALIDATION REMOVED FROM SERIALIZATION /* // Miner tx with one signature - boost::get(tx.signature).s[0].resize(1); + tx.signatures[0].resize(1); ASSERT_FALSE(serialization::dump_binary(tx, blob)); // Miner tx with 2 empty vectors - boost::get(tx.signature).s.resize(2); - boost::get(tx.signature).s[0].resize(0); - boost::get(tx.signature).s[1].resize(0); + tx.signatures.resize(2); + tx.signatures[0].resize(0); + tx.signatures[1].resize(0); ASSERT_FALSE(serialization::dump_binary(tx, blob)); // Miner tx with 2 signatures - boost::get(tx.signature).s[0].resize(1); - boost::get(tx.signature).s[1].resize(1); + tx.signatures[0].resize(1); + tx.signatures[1].resize(1); ASSERT_FALSE(serialization::dump_binary(tx, blob)); */ // Two txin_gen, no signatures tx.vin.push_back(txin_gen1); - boost::get(tx.signature).s.resize(0); + tx.signatures.resize(0); ASSERT_TRUE(serialization::dump_binary(tx, blob)); ASSERT_EQ(10, blob.size()); // 5 bytes + 2 * 2 bytes vins + 0 bytes extra + 0 bytes signatures ASSERT_TRUE(serialization::parse_binary(blob, tx1)); @@ -385,14 +406,15 @@ TEST(Serialization, serializes_transacion_signatures_correctly) { ASSERT_TRUE(false); } - ASSERT_EQ(linearize_vector2(boost::get(tx.signature).s), linearize_vector2(boost::get(tx1.signature).s)); + ASSERT_EQ(tx.signatures, tx1.signatures); + //ASSERT_EQ(linearize_vector2(boost::get(tx.signature).s), linearize_vector2(boost::get(tx1.signature).s)); // Two txin_gen, signatures vector contains only one empty element //signatures.resize(1); //ASSERT_FALSE(serialization::dump_binary(tx, blob)); // Two txin_gen, signatures vector contains two empty elements - boost::get(tx.signature).s.resize(2); + tx.signatures.resize(2); ASSERT_TRUE(serialization::dump_binary(tx, blob)); ASSERT_EQ(12, blob.size()); // 5 bytes + 2 * 2 bytes vins + 0 bytes extra + 0 bytes signatures ASSERT_TRUE(serialization::parse_binary(blob, tx1)); @@ -400,7 +422,9 @@ TEST(Serialization, serializes_transacion_signatures_correctly) { ASSERT_TRUE(false); } - ASSERT_EQ(linearize_vector2(boost::get(tx.signature).s), linearize_vector2(boost::get(tx1.signature).s)); + + ASSERT_EQ(tx.signatures, tx1.signatures); + //ASSERT_EQ(linearize_vector2(boost::get(tx.signature).s), linearize_vector2(boost::get(tx1.signature).s)); // Two txin_gen, signatures vector contains three empty elements //signatures.resize(3); @@ -415,7 +439,7 @@ TEST(Serialization, serializes_transacion_signatures_correctly) // A few bytes instead of signature tx.vin.clear(); tx.vin.push_back(txin_gen1); - boost::get(tx.signature).s.clear(); + tx.signatures.clear(); ASSERT_TRUE(serialization::dump_binary(tx, blob)); blob.append(std::string(sizeof(crypto::signature) / 2, 'x')); ASSERT_FALSE(serialization::parse_binary(blob, tx1)); @@ -438,28 +462,28 @@ TEST(Serialization, serializes_transacion_signatures_correctly) /* // Too much signatures for two inputs - boost::get(tx.signature).s.resize(3); - boost::get(tx.signature).s[0].resize(2); - boost::get(tx.signature).s[1].resize(2); - boost::get(tx.signature).s[2].resize(2); + tx.signatures.resize(3); + tx.signatures[0].resize(2); + tx.signatures[1].resize(2); + tx.signatures[2].resize(2); ASSERT_FALSE(serialization::dump_binary(tx, blob)); // First signatures vector contains too little elements - boost::get(tx.signature).s.resize(2); - boost::get(tx.signature).s[0].resize(1); - boost::get(tx.signature).s[1].resize(2); + tx.signatures.resize(2); + tx.signatures[0].resize(1); + tx.signatures[1].resize(2); ASSERT_FALSE(serialization::dump_binary(tx, blob)); // First signatures vector contains too much elements - boost::get(tx.signature).s.resize(2); - boost::get(tx.signature).s[0].resize(3); - boost::get(tx.signature).s[1].resize(2); + tx.signatures.resize(2); + tx.signatures[0].resize(3); + tx.signatures[1].resize(2); ASSERT_FALSE(serialization::dump_binary(tx, blob)); // There are signatures for each input - boost::get(tx.signature).s.resize(2); - boost::get(tx.signature).s[0].resize(2); - boost::get(tx.signature).s[1].resize(2); + tx.signatures.resize(2); + tx.signatures[0].resize(2); + tx.signatures[1].resize(2); ASSERT_TRUE(serialization::dump_binary(tx, blob)); ASSERT_TRUE(serialization::parse_binary(blob, tx1)); ASSERT_EQ(tx, tx1); From e94e5c0a970df182181cc29eed677968f30245e0 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 25 Jun 2022 00:06:26 +0200 Subject: [PATCH 3/4] multiple fixes over sig refactoring --- src/currency_core/blockchain_storage.cpp | 4 ++-- src/currency_core/currency_format_utils.cpp | 2 +- src/currency_core/currency_format_utils.h | 1 + src/currency_core/currency_format_utils_transactions.cpp | 1 + src/wallet/wallet2_escrow.cpp | 7 ++++--- tests/core_tests/chaingen.h | 2 +- tests/core_tests/chaingen_helpers.h | 2 +- tests/core_tests/escrow_wallet_common.h | 2 +- tests/core_tests/tx_builder.h | 2 +- tests/core_tests/tx_validation.cpp | 6 +++--- 10 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index ce804515..2544a096 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -4344,7 +4344,7 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha TIME_MEASURE_START_PD(tx_check_inputs_attachment_check); if (!m_is_in_checkpoint_zone) { - CHECK_AND_ASSERT_MES(tx.signatures.s.size() == sig_index, false, "tx signatures count differs from inputs"); + CHECK_AND_ASSERT_MES(tx.signatures.size() == sig_index, false, "tx signatures count differs from inputs"); if (!(get_tx_flags(tx) & TX_FLAG_SIGNATURE_MODE_SEPARATE)) { bool r = validate_attachment_info(tx.extra, tx.attachment, false); @@ -4649,7 +4649,7 @@ bool blockchain_storage::check_ms_input(const transaction& tx, size_t in_index, VARIANT_SWITCH_END(); - } + return true; #undef LOC_CHK diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 2a374c53..97b6a90e 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1693,7 +1693,7 @@ namespace currency LOC_CHK(ms_input_index < tx.signatures.size(), "transaction does not have signatures vector entry for ms input #" << ms_input_index); LOC_CHK(tx.signatures[ms_input_index].type() == typeid(NLSAG_sig), "Wrong type of signature"); - auto& sigs = boost::get(tx.signatures[ms_input_index]); + auto& sigs = boost::get(tx.signatures[ms_input_index]).s; LOC_CHK(!sigs.empty(), "empty signatures container"); bool extra_signature_expected = (get_tx_flags(tx) & TX_FLAG_SIGNATURE_MODE_SEPARATE) && ms_input_index == tx.vin.size() - 1; diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index a6271037..701bd267 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -667,6 +667,7 @@ namespace currency size_t operator()(const txin_to_key& txin) const { return txin.key_offsets.size(); } size_t operator()(const txin_multisig& txin) const { return txin.sigs_count; } size_t operator()(const txin_htlc& txin) const { return 1; } + size_t operator()(const tx_in_zarcanum& txin) const { throw std::runtime_error("Not implemented yet"); return 0; } //@#@ }; return boost::apply_visitor(txin_signature_size_visitor(), tx_in); diff --git a/src/currency_core/currency_format_utils_transactions.cpp b/src/currency_core/currency_format_utils_transactions.cpp index bb12d893..6e31904d 100644 --- a/src/currency_core/currency_format_utils_transactions.cpp +++ b/src/currency_core/currency_format_utils_transactions.cpp @@ -237,6 +237,7 @@ namespace currency ++sig_count; // count in one more signature for the last input in a complete separately signed tx tx_blob_size += tools::get_varint_packed_size(sig_count); // size of transaction::signatures[i] tx_blob_size += sizeof(crypto::signature) * sig_count; // size of signatures' data itself + tx_blob_size += sizeof(binary_archive::variant_tag_type); //tools::get_varint_packed_size(variant_serialization_traits, currency::NLSAG_sig>::get_tag()); // sizeof variant tag } // 2. attachments (try to find extra_attachment_info in tx prefix and count it in if succeed) diff --git a/src/wallet/wallet2_escrow.cpp b/src/wallet/wallet2_escrow.cpp index 542db5f2..f59f828e 100644 --- a/src/wallet/wallet2_escrow.cpp +++ b/src/wallet/wallet2_escrow.cpp @@ -237,8 +237,9 @@ bool wallet2::validate_escrow_release(const transaction& tx, bool release_type_n LOC_CHK(tx.signatures.size() == 1, "invalid singatures size: " << tx.signatures.size()); // only 1 input means only 1 signature vector VARIANT_SWITCH_BEGIN(tx.signatures[0]); - VARIANT_CASE_CONST(NLSAG_sig, signature) + VARIANT_CASE_CONST(NLSAG_sig, signature_NLSAG) { + auto& signature = signature_NLSAG.s; // As we don't have b_keys we can't be sure which signature is B's and which is reserved for A (should be a null-placeholder, if present). // Having a_keys, we determine index of A key in multisig output keys array. // Thus it's possible to determine the order of signatures (A, B or B, A), and, eventually, validate B signature. @@ -420,9 +421,9 @@ bool wallet2::validate_escrow_cancel_release(const currency::transaction& tx, co // (5/5) signatures LOC_CHK(tx.signatures.size() == 1, "invalid singatures size: " << tx.signatures.size()); // only 1 input means only 1 signature vector VARIANT_SWITCH_BEGIN(tx.signatures[0]); - VARIANT_CASE_CONST(NLSAG_sig, signatures) + VARIANT_CASE_CONST(NLSAG_sig, signature_NLSAG) { - + auto& signature = signature_NLSAG.s; LOC_CHK(signature.size() == 2, "invalid signature[0] size: " << signature.size()); // it's expected to contain A-party signature and null-sig placeholder LOC_CHK(source_ms_out.keys.size() == 2, "internal error: invalid source ms output keys array, size: " << source_ms_out.keys.size()); diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 2b1574c2..999ed870 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -846,7 +846,7 @@ bool construct_broken_tx(const currency::account_keys& sender_account_keys, cons ss_ring_s << o.second << ENDL; } - tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + tx.signatures.push_back(currency::NLSAG_sig()); std::vector& sigs = boost::get(tx.signatures.back()).s; sigs.resize(src_entr.outputs.size()); crypto::generate_ring_signature(tx_prefix_hash, boost::get(tx.vin[i]).k_image, keys_ptrs, in_contexts[i].in_ephemeral.sec, src_entr.real_output, sigs.data()); diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h index f77d6b56..f56a87e8 100644 --- a/tests/core_tests/chaingen_helpers.h +++ b/tests/core_tests/chaingen_helpers.h @@ -234,7 +234,7 @@ inline bool resign_tx(const currency::account_keys& sender_keys, const std::vect return false; crypto::derive_secret_key(recv_derivation, se.real_output_in_tx_index, sender_keys.spend_secret_key, in_ephemeral_sec); - tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + tx.signatures.push_back(currency::NLSAG_sig()); std::vector& sigs = boost::get(tx.signatures.back()).s; if (se.is_multisig()) diff --git a/tests/core_tests/escrow_wallet_common.h b/tests/core_tests/escrow_wallet_common.h index d23f5140..85264e9b 100644 --- a/tests/core_tests/escrow_wallet_common.h +++ b/tests/core_tests/escrow_wallet_common.h @@ -254,7 +254,7 @@ inline bool build_custom_escrow_template(const std::vector& ev if (custom_config_mask & eccf_template_no_a_sigs) { escrow_template_tx.signatures.clear(); - escrow_template_tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + escrow_template_tx.signatures.push_back(currency::NLSAG_sig()); } append_vector_by_another_vector(used_sources, sources); diff --git a/tests/core_tests/tx_builder.h b/tests/core_tests/tx_builder.h index 1cfb8ffd..ed171b64 100644 --- a/tests/core_tests/tx_builder.h +++ b/tests/core_tests/tx_builder.h @@ -109,7 +109,7 @@ struct tx_builder keys_ptrs.push_back(&o.second); } - m_tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + m_tx.signatures.push_back(currency::NLSAG_sig()); std::vector& sigs = boost::get(m_tx.signatures.back()).s; sigs.resize(src_entr.outputs.size()); generate_ring_signature(m_tx_prefix_hash, boost::get(m_tx.vin[i]).k_image, keys_ptrs, m_in_contexts[i].sec, src_entr.real_output, sigs.data()); diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index 7ec03b6a..71b92a71 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -660,7 +660,7 @@ bool gen_tx_signatures_are_invalid::generate(std::vector& even // Tx with nmix = 0 have a few inputs, and too many signatures (2/2) broken_tx = tx_0; - broken_tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + broken_tx.signatures.push_back(currency::NLSAG_sig()); boost::get(broken_tx.signatures.back()).s.push_back(invalid_signature); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); @@ -677,7 +677,7 @@ bool gen_tx_signatures_are_invalid::generate(std::vector& even // Tx with nmix = 1 have not enough signatures (2/2) broken_tx = tx_1; - broken_tx.signatures.back().resize(boost::get(broken_tx.signatures.back()).s.size() - 1); + boost::get(broken_tx.signatures.back()).s.resize(boost::get(broken_tx.signatures.back()).s.size() - 1); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); // Tx with nmix = 1 have too many signatures (1/2) @@ -687,7 +687,7 @@ bool gen_tx_signatures_are_invalid::generate(std::vector& even // Tx with nmix = 1 have too many signatures (2/2) broken_tx = tx_1; - broken_tx.signatures.push_back(currency::NLSAG_sig(std::vector())); + broken_tx.signatures.push_back(currency::NLSAG_sig()); boost::get(broken_tx.signatures.back()).s.push_back(invalid_signature); check_broken_tx(events, broken_tx, prev_block, miner_account, generator); From dfac17daeb01759b3124e2254cecd5698162640a Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sun, 26 Jun 2022 01:13:19 +0200 Subject: [PATCH 4/4] fixed all core tests --- src/currency_core/currency_format_utils.cpp | 1 + src/currency_core/currency_format_utils_transactions.cpp | 2 +- tests/core_tests/chaingen_main.cpp | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 97b6a90e..162849c6 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1284,6 +1284,7 @@ namespace currency tx.vin.clear(); tx.vout.clear(); tx.extra = extra; + tx.signatures.clear(); tx.version = ftp.tx_version; if (unlock_time != 0) diff --git a/src/currency_core/currency_format_utils_transactions.cpp b/src/currency_core/currency_format_utils_transactions.cpp index 6e31904d..46130401 100644 --- a/src/currency_core/currency_format_utils_transactions.cpp +++ b/src/currency_core/currency_format_utils_transactions.cpp @@ -237,7 +237,7 @@ namespace currency ++sig_count; // count in one more signature for the last input in a complete separately signed tx tx_blob_size += tools::get_varint_packed_size(sig_count); // size of transaction::signatures[i] tx_blob_size += sizeof(crypto::signature) * sig_count; // size of signatures' data itself - tx_blob_size += sizeof(binary_archive::variant_tag_type); //tools::get_varint_packed_size(variant_serialization_traits, currency::NLSAG_sig>::get_tag()); // sizeof variant tag + //tx_blob_size += sizeof(binary_archive::variant_tag_type); //tools::get_varint_packed_size(variant_serialization_traits, currency::NLSAG_sig>::get_tag()); // sizeof variant tag } // 2. attachments (try to find extra_attachment_info in tx prefix and count it in if succeed) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index d09d1558..439d8482 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -314,8 +314,10 @@ public: size_t tx_expected_blob_size = get_object_blobsize(tx); if (!b_cp && tx_expected_blob_size != blob.size()) { + size_t prefix_blobsize = currency::get_object_blobsize(static_cast(tx)); currency::blobdata prefix_blob = t_serializable_object_to_blob(static_cast(tx)); + currency::blobdata full_blob_test = t_serializable_object_to_blob(tx); std::stringstream s; s << "CP zone: " << b_cp << ", transaction: " << get_transaction_hash(tx) << ENDL <<