diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index c5e5e5be..3db26cfc 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -4312,19 +4312,30 @@ struct outputs_visitor return false; } } - - if (out.target.type() == typeid(txout_htlc)) + if (out.target.type() == typeid(txout_to_key)) + { + crypto::public_key pk = boost::get(out.target).key; + m_results_collector.push_back(pk); + } + else if (out.target.type() == typeid(txout_htlc)) { m_scan_context.htlc_outs.push_back(boost::get(out.target)); - - }else if (out.target.type() != typeid(txout_to_key)) + crypto::public_key pk = null_pkey; + if (m_scan_context.htlc_is_expired) + { + pk = boost::get(out.target).pkey_after_expiration; + } + else + { + pk = boost::get(out.target).pkey_before_expiration; + } + m_results_collector.push_back(pk); + }else { LOG_PRINT_L0("Output have wrong type id, which=" << out.target.which()); return false; } - crypto::public_key pk = boost::get(out.target).key; - m_results_collector.push_back(pk); return true; } }; @@ -4364,7 +4375,6 @@ bool blockchain_storage::check_input_signature(const transaction& tx, size_t in_ //------------------------------------------------------------------ bool blockchain_storage::check_input_signature(const transaction& tx, size_t in_index, -// const std::vector& in_key_offsets, uint64_t in_amount, const crypto::key_image& in_k_image, const std::vector& in_etc_details, diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index b5aa0c98..66fd5a72 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -135,6 +135,7 @@ namespace currency struct scan_for_keys_context { + bool htlc_is_expired; std::list htlc_outs; }; @@ -683,7 +684,7 @@ namespace currency } //------------------------------------------------------------------ template - bool blockchain_storage::scan_outputkeys_for_indexes(const transaction &validated_tx, const txin_v& verified_input, visitor_t& vis, uint64_t& max_related_block_height, scan_for_keys_context& /*scan_context*/) const + bool blockchain_storage::scan_outputkeys_for_indexes(const transaction &validated_tx, const txin_v& verified_input, visitor_t& vis, uint64_t& max_related_block_height, scan_for_keys_context& scan_context) const { std::vector key_offsets_dummy; uint64_t amount = 0; @@ -749,15 +750,40 @@ namespace currency //check mix_attr TIME_MEASURE_FINISH_PD(tx_check_inputs_loop_scan_outputkeys_loop_find_tx); - CHECKED_GET_SPECIFIC_VARIANT(tx_ptr->tx.vout[n].target, const txout_to_key, outtk, false); - //explanation of this code will be provided later with public announce - patch_out_if_needed(const_cast(outtk), tx_id, n); - - - + //CHECKED_GET_SPECIFIC_VARIANT(tx_ptr->tx.vout[n].target, const txout_to_key, outtk, false); CHECK_AND_ASSERT_MES(key_offsets.size() >= 1, false, "internal error: tx input has empty key_offsets"); // should never happen as input correctness must be handled by the caller - bool mixattr_ok = is_mixattr_applicable_for_fake_outs_counter(outtk.mix_attr, key_offsets.size() - 1); - CHECK_AND_ASSERT_MES(mixattr_ok, false, "tx output #" << output_index << " violates mixin restrictions: mix_attr = " << static_cast(outtk.mix_attr) << ", key_offsets.size = " << key_offsets.size()); + + if (tx_ptr->tx.vout[n].target.type() == typeid(txout_to_key)) + { + //HTLC input CAN'T refer to regular to_key output + CHECK_AND_ASSERT_MES(verified_input.type() != typeid(txin_htlc), false, "[TXOUT_TO_KEY]: Unexpected output type of HTLC input"); + //fix for burned money + patch_out_if_needed(const_cast(outtk), tx_id, n); + + bool mixattr_ok = is_mixattr_applicable_for_fake_outs_counter(outtk.mix_attr, key_offsets.size() - 1); + CHECK_AND_ASSERT_MES(mixattr_ok, false, "tx output #" << output_index << " violates mixin restrictions: mix_attr = " << static_cast(outtk.mix_attr) << ", key_offsets.size = " << key_offsets.size()); + } + else if (tx_ptr->tx.vout[n].target.type() == typeid(txout_htlc)) + { + const txout_htlc& htlc_out = boost::get(tx_ptr->tx.vout[n].target); + if (htlc_out.expiration > get_current_blockchain_size() - tx_ptr->m_keeper_block_height) + { + //HTLC IS NOT expired, can be used ONLY by pkey_before_expiration and ONLY by HTLC input + CHECK_AND_ASSERT_MES(verified_input.type() == typeid(txin_htlc), false, "[TXOUT_HTLC]: Unexpected output type of non-HTLC input"); + scan_context.htlc_is_expired = false; + } + else + { + //HTLC IS expired, can be used ONLY by pkey_after_expiration and ONLY by to_key input + CHECK_AND_ASSERT_MES(verified_input.type() == typeid(txin_to_key), false, "[TXOUT_HTLC]: Unexpected output type of HTLC input"); + scan_context.htlc_is_expired = true; + } + }else + { + LOG_ERROR("[scan_outputkeys_for_indexes]: Wrong output type in : " << tx_ptr->tx.vout[n].target.type().name()); + return false; + } + TIME_MEASURE_START_PD(tx_check_inputs_loop_scan_outputkeys_loop_handle_output); if (!vis.handle_output(tx_ptr->tx, validated_tx, tx_ptr->tx.vout[n], n)) diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index 292627d0..a0c16f56 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -273,13 +273,15 @@ namespace currency crypto::hash htlc_hash; uint8_t flags; //select type of the hash, may be some extra info in future uint64_t expiration; - crypto::public_key pkey; + crypto::public_key pkey_before_expiration; + crypto::public_key pkey_after_expiration; BEGIN_SERIALIZE_OBJECT() FIELD(htlc_hash) FIELD(flags) VARINT_FIELD(expiration) - FIELD(pkey) + FIELD(pkey_before_expiration) + FIELD(pkey_after_expiration) END_SERIALIZE() }; @@ -802,7 +804,7 @@ SET_VARIANT_TAGS(currency::tx_receiver, 32, "receiver2"); SET_VARIANT_TAGS(currency::extra_alias_entry, 33, "alias_entry2"); //htlc -SET_VARIANT_TAGS(currency::txin_htlc, 34, "txin_to_htlc"); +SET_VARIANT_TAGS(currency::txin_htlc, 34, "txin_htlc"); SET_VARIANT_TAGS(currency::txout_htlc, 35, "txout_htlc"); diff --git a/src/currency_core/currency_boost_serialization.h b/src/currency_core/currency_boost_serialization.h index 4b0cb8ac..ec70a988 100644 --- a/src/currency_core/currency_boost_serialization.h +++ b/src/currency_core/currency_boost_serialization.h @@ -62,7 +62,8 @@ namespace boost a & x.expiration; a & x.flags; a & x.htlc_hash; - a & x.pkey; + a & x.pkey_before_expiration; + a & x.pkey_after_expiration; } template