1
0
Fork 0
forked from lthn/blockchain

htlc in work: orderliness between htlc and to_key entities

This commit is contained in:
cryptozoidberg 2021-01-06 05:15:01 +01:00
parent b2a7423ab4
commit 93aacf3bec
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
4 changed files with 59 additions and 20 deletions

View file

@ -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<txout_to_key>(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<txout_htlc>(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<txout_htlc>(out.target).pkey_after_expiration;
}
else
{
pk = boost::get<txout_htlc>(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<txout_to_key>(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<txout_ref_v>& in_key_offsets,
uint64_t in_amount,
const crypto::key_image& in_k_image,
const std::vector<txin_etc_details_v>& in_etc_details,

View file

@ -135,6 +135,7 @@ namespace currency
struct scan_for_keys_context
{
bool htlc_is_expired;
std::list<txout_htlc> htlc_outs;
};
@ -683,7 +684,7 @@ namespace currency
}
//------------------------------------------------------------------
template<class visitor_t>
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<txout_ref_v> 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<txout_to_key&>(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<uint32_t>(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<txout_to_key&>(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<uint32_t>(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<txout_htlc>(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))

View file

@ -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");

View file

@ -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 <class Archive>