diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 1247420e..ca203bbc 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -6067,7 +6067,7 @@ void blockchain_storage::calculate_local_gindex_lookup_table_for_height(uint64_t } //------------------------------------------------------------------ bool blockchain_storage::validate_alt_block_input(const transaction& input_tx, - const std::unordered_set& collected_keyimages, + std::unordered_set& collected_keyimages, const txs_by_id_and_height_altchain& alt_chain_tx_ids, const crypto::hash& bl_id, const crypto::hash& input_tx_hash, @@ -6245,7 +6245,7 @@ bool blockchain_storage::validate_alt_block_input(const transaction& input_tx, else { const txout_htlc& out_htlc = boost::get(out_in_alt); - bool htlc_expired = htlc.expiration > (height_of_current_alt_block - height_of_source_block) ? false:true; + bool htlc_expired = out_htlc.expiration > (height_of_current_alt_block - height_of_source_block) ? false:true; pk = htlc_expired ? out_htlc.pkey_after_expiration : out_htlc.pkey_before_expiration; //input_v } @@ -6286,12 +6286,14 @@ bool blockchain_storage::validate_alt_block_input(const transaction& input_tx, TO_KEY | TO_KEY | YES */ - bool r = is_output_allowed_for_input(out_target_v, input_v, height_of_current_alt_block - height_of_source_block); - CHECK_AND_ASSERT_MES(r, false, "Input and output incompatible type"); - //source tx found in altchain CHECK_AND_ASSERT_MES(it->second.first.vout.size() > out_n, false, "Internal error: out_n(" << out_n << ") >= it->second.vout.size()(" << it->second.first.vout.size() << ")"); txout_target_v out_target_v = it->second.first.vout[out_n].target; + + bool r = is_output_allowed_for_input(out_target_v, input_v, height_of_current_alt_block - height_of_source_block); + CHECK_AND_ASSERT_MES(r, false, "Input and output incompatible type"); + + if (out_target_v.type() == typeid(txout_htlc)) { //source is hltc out @@ -6331,6 +6333,7 @@ bool blockchain_storage::validate_alt_block_input(const transaction& input_tx, TO_KEY | TO_KEY | YES */ uint64_t height_of_source_block = p->m_keeper_block_height; + CHECK_AND_ASSERT_MES(height_of_current_alt_block > height_of_source_block, false, "Intenral error: height_of_current_alt_block > height_of_source_block failed"); bool r = is_output_allowed_for_input(t, input_v, height_of_current_alt_block - height_of_source_block); CHECK_AND_ASSERT_MES(r, false, "Input and output incompatible type"); @@ -6374,7 +6377,7 @@ bool blockchain_storage::validate_alt_block_input(const transaction& input_tx, return true; } //------------------------------------------------------------------ -bool blockchain_storage::is_output_allowed_for_input(const txout_target_v& out_v, const txin_v& in_v, uint64_t top_minus_source_height) +bool blockchain_storage::is_output_allowed_for_input(const txout_target_v& out_v, const txin_v& in_v, uint64_t top_minus_source_height)const { /* @@ -6403,10 +6406,10 @@ bool blockchain_storage::is_output_allowed_for_input(const txout_target_v& out_v return true; } //------------------------------------------------------------------ -bool blockchain_storage::is_output_allowed_for_input(const txout_htlc& out_v, const txin_v& in_v, uint64_t top_minus_source_height) +bool blockchain_storage::is_output_allowed_for_input(const txout_htlc& out_v, const txin_v& in_v, uint64_t top_minus_source_height)const { bool htlc_expired = out_v.expiration > (top_minus_source_height) ? false : true; - if (!hltc_expired) + if (!htlc_expired) { //HTLC IS NOT expired, can be used ONLY by pkey_before_expiration and ONLY by HTLC input CHECK_AND_ASSERT_MES(in_v.type() == typeid(txin_htlc), false, "[TXOUT_HTLC]: Unexpected output type of non-HTLC input"); @@ -6419,13 +6422,28 @@ bool blockchain_storage::is_output_allowed_for_input(const txout_htlc& out_v, co return true; } //------------------------------------------------------------------ -bool blockchain_storage::is_output_allowed_for_input(const txout_to_key& out_v, const txin_v& in_v) +bool blockchain_storage::is_output_allowed_for_input(const txout_to_key& out_v, const txin_v& in_v)const { //HTLC input CAN'T refer to regular to_key output CHECK_AND_ASSERT_MES(in_v.type() != typeid(txin_htlc), false, "[TXOUT_TO_KEY]: Unexpected output type of HTLC input"); return true; } //------------------------------------------------------------------ +bool blockchain_storage::is_output_allowed_for_input(const output_key_or_htlc_v& out_v, const txin_v& in_v, uint64_t top_minus_source_height)const +{ + if (out_v.type() == typeid(crypto::public_key)) + { + return is_output_allowed_for_input(txout_to_key(), in_v); + } + else if (out_v.type() == typeid(txout_htlc)) + { + return is_output_allowed_for_input(boost::get(out_v), in_v, top_minus_source_height); + } + else { + ASSERT_MES_AND_THROW("Unexpected type in output_key_or_htlc_v: " << out_v.type().name()); + } +} +//------------------------------------------------------------------ bool blockchain_storage::validate_alt_block_ms_input(const transaction& input_tx, const crypto::hash& input_tx_hash, size_t input_index, const std::vector& input_sigs, uint64_t split_height, const alt_chain_type& alt_chain) const { // Main and alt chain outline: diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 7220d3cf..b20c2965 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -588,7 +588,18 @@ namespace currency bool purge_keyimage_from_big_heap(const crypto::key_image& ki, const crypto::hash& id); bool purge_altblock_keyimages_from_big_heap(const block& b, const crypto::hash& id); bool append_altblock_keyimages_to_big_heap(const crypto::hash& block_id, const std::unordered_set& alt_block_keyimages); - bool validate_alt_block_input(const transaction& input_tx, std::unordered_set& collected_keyimages, const txs_by_id_and_height_altchain& alt_chain_tx_ids, const crypto::hash& bl_id, const crypto::hash& input_tx_hash, size_t input_index, const std::vector& input_sigs, uint64_t split_height, const alt_chain_type& alt_chain, const std::unordered_set& alt_chain_block_ids, uint64_t& ki_lookuptime, uint64_t* p_max_related_block_height = nullptr) const; + bool validate_alt_block_input(const transaction& input_tx, + std::unordered_set& collected_keyimages, + const txs_by_id_and_height_altchain& alt_chain_tx_ids, + const crypto::hash& bl_id, + const crypto::hash& input_tx_hash, + size_t input_index, + const std::vector& input_sigs, + uint64_t split_height, + const alt_chain_type& alt_chain, + const std::unordered_set& alt_chain_block_ids, + uint64_t& ki_lookuptime, + uint64_t* p_max_related_block_height = nullptr) const; bool validate_alt_block_ms_input(const transaction& input_tx, const crypto::hash& input_tx_hash, size_t input_index, 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; bool update_alt_out_indexes_for_tx_in_block(const transaction& tx, alt_block_extended_info& abei)const; @@ -643,9 +654,10 @@ namespace currency void calculate_local_gindex_lookup_table_for_height(uint64_t split_height, std::map& increments) const; void do_erase_altblock(alt_chain_container::iterator it); uint64_t get_blockchain_launch_timestamp()const; - bool is_output_allowed_for_input(const txout_target_v& out_v, const txin_v& in_v, uint64_t top_minus_source_height); - bool is_output_allowed_for_input(const txout_to_key& out_v, const txin_v& in_v); - bool is_output_allowed_for_input(const txout_htlc& out_v, const txin_v& in_v, uint64_t top_minus_source_height); + bool is_output_allowed_for_input(const txout_target_v& out_v, const txin_v& in_v, uint64_t top_minus_source_height)const; + bool is_output_allowed_for_input(const output_key_or_htlc_v& out_v, const txin_v& in_v, uint64_t top_minus_source_height)const; + bool is_output_allowed_for_input(const txout_to_key& out_v, const txin_v& in_v)const; + bool is_output_allowed_for_input(const txout_htlc& out_v, const txin_v& in_v, uint64_t top_minus_source_height)const;