1
0
Fork 0
forked from lthn/blockchain

check_tx_explicit_asset_id_rules(), is_asset_emitting_transaction()

This commit is contained in:
sowle 2023-04-07 06:04:00 +02:00
parent c5ff48b9a5
commit 447b09f400
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
4 changed files with 65 additions and 7 deletions

View file

@ -4425,6 +4425,34 @@ bool blockchain_storage::print_tx_outputs_lookup(const crypto::hash& tx_id)const
return true;
}
//------------------------------------------------------------------
bool check_tx_explicit_asset_id_rules(const transaction& tx, bool all_tx_ins_have_explicit_asset_ids)
{
if (tx.version <= TRANSACTION_VERSION_PRE_HF4)
return true;
// ( assuming that post-HF4 txs can only have tx_out_zarcanum outs )
bool r = false;
// if all tx inputs have explicit asset id AND it does not emit a new asset THEN all outputs must have explicit asset id (native coin)
if (all_tx_ins_have_explicit_asset_ids && !is_asset_emitting_transaction(tx))
{
for(size_t j = 0, k = tx.vout.size(); j < k; ++j)
{
r = crypto::point_t(boost::get<tx_out_zarcanum>(tx.vout[j]).blinded_asset_id).modify_mul8().to_public_key() == native_coin_asset_id;
CHECK_AND_ASSERT_MES(r, false, "output #" << j << " has a non-explicit asset id");
}
}
else // otherwise all outputs must have hidden asset id
{
for(size_t j = 0, k = tx.vout.size(); j < k; ++j)
{
r = crypto::point_t(boost::get<tx_out_zarcanum>(tx.vout[j]).blinded_asset_id).modify_mul8().to_public_key() != native_coin_asset_id;
CHECK_AND_ASSERT_MES(r, false, "output #" << j << " has an explicit asset id");
}
}
return true;
}
//------------------------------------------------------------------
bool blockchain_storage::have_tx_keyimges_as_spent(const transaction &tx) const
{
// check all tx's inputs for being already spent
@ -4465,6 +4493,7 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha
{
size_t sig_index = 0;
max_used_block_height = 0;
bool all_tx_ins_have_explicit_asset_ids = true;
auto local_check_key_image = [&](const crypto::key_image& ki) -> bool
{
@ -4526,7 +4555,7 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha
if (!local_check_key_image(in_zc.k_image))
return false;
if (!check_tx_input(tx, sig_index, in_zc, tx_prefix_hash, max_used_block_height))
if (!check_tx_input(tx, sig_index, in_zc, tx_prefix_hash, max_used_block_height, all_tx_ins_have_explicit_asset_ids))
{
LOG_ERROR("Failed to validate zc input #" << sig_index << " in tx: " << tx_prefix_hash);
return false;
@ -4548,6 +4577,8 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha
bool r = validate_attachment_info(tx.extra, tx.attachment, false);
CHECK_AND_ASSERT_MES(r, false, "Failed to validate attachments in tx " << tx_prefix_hash << ": incorrect extra_attachment_info in tx.extra");
}
CHECK_AND_ASSERT_MES(check_tx_explicit_asset_id_rules(tx, all_tx_ins_have_explicit_asset_ids), false, "tx does not comply with explicit asset id rules");
}
TIME_MEASURE_FINISH_PD(tx_check_inputs_attachment_check);
return true;
@ -4929,7 +4960,8 @@ bool blockchain_storage::check_tx_input(const transaction& tx, size_t in_index,
return check_input_signature(tx, in_index, txin.amount, txin.k_image, txin.etc_details, tx_prefix_hash, output_keys_ptrs);
}
//------------------------------------------------------------------
bool blockchain_storage::check_tx_input(const transaction& tx, size_t in_index, const txin_zc_input& zc_in, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height) const
bool blockchain_storage::check_tx_input(const transaction& tx, size_t in_index, const txin_zc_input& zc_in, const crypto::hash& tx_prefix_hash,
uint64_t& max_related_block_height, bool& all_tx_ins_have_explicit_asset_ids) const
{
CRITICAL_REGION_LOCAL(m_read_lock);
@ -4947,7 +4979,8 @@ bool blockchain_storage::check_tx_input(const transaction& tx, size_t in_index,
return false;
}
// @#@
if (m_is_in_checkpoint_zone) // TODO @#@# reconsider placement of this check
return true;
// here we don't need to check zc_in.k_image validity because it is checked in verify_CLSAG_GG()
@ -4959,7 +4992,11 @@ bool blockchain_storage::check_tx_input(const transaction& tx, size_t in_index,
vector<crypto::CLSAG_GGX_input_ref_t> ring;
ring.reserve(scan_contex.zc_outs.size());
for(auto& zc_out : scan_contex.zc_outs)
{
ring.emplace_back(zc_out.stealth_address, zc_out.amount_commitment, zc_out.blinded_asset_id);
if (all_tx_ins_have_explicit_asset_ids && crypto::point_t(zc_out.blinded_asset_id).modify_mul8().to_public_key() != native_coin_asset_id)
all_tx_ins_have_explicit_asset_ids = false;
}
// calculate corresponding tx prefix hash
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, in_index, tx_prefix_hash);
@ -4967,12 +5004,12 @@ bool blockchain_storage::check_tx_input(const transaction& tx, size_t in_index,
const ZC_sig& sig = boost::get<ZC_sig>(tx.signatures[in_index]);
//TIME_MEASURE_START_PD(tx_input_check_clsag_gg);
//TIME_MEASURE_START_PD(tx_input_check_clsag_ggx);
bool r = crypto::verify_CLSAG_GGX(tx_hash_for_signature, ring, sig.pseudo_out_amount_commitment, sig.pseudo_out_blinded_asset_id, zc_in.k_image, sig.clsags_ggx);
CHECK_AND_ASSERT_MES(r, false, "verify_CLSAG_GGX failed");
//TIME_MEASURE_FINISH_PD(tx_input_check_clsag_gg);
//TIME_MEASURE_FINISH_PD(tx_input_check_clsag_ggx);
return true;
}
@ -7035,7 +7072,8 @@ bool blockchain_storage::validate_alt_block_input(const transaction& input_tx,
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);
bool all_tx_ins_have_explicit_asset_ids = true; // stub for now, TODO @#@#
r = check_tx_input(input_tx, input_index, input_zc, input_tx_hash, max_related_block_height, all_tx_ins_have_explicit_asset_ids);
CHECK_AND_ASSERT_MES(r, false, "check_tx_input failed");
}
VARIANT_CASE_OTHER()

View file

@ -293,7 +293,7 @@ namespace currency
bool check_tx_input(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase)const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_multisig& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height)const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_htlc& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height)const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_zc_input& zc_in, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height) const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_zc_input& zc_in, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height, bool& tx_has_explicit_asset_ids_in_all_ins) const;
bool check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash, uint64_t& max_used_block_height)const;
bool check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash) const;
bool check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash, uint64_t& max_used_block_height, crypto::hash& max_used_block_id)const;

View file

@ -319,6 +319,25 @@ namespace currency
return true;
}
//---------------------------------------------------------------
bool is_asset_emitting_transaction(const transaction& tx, asset_descriptor_operation* p_ado /* = nullptr */)
{
if (tx.version <= TRANSACTION_VERSION_PRE_HF4)
return false;
asset_descriptor_operation local_ado{};
if (p_ado == nullptr)
p_ado = &local_ado;
if (!get_type_in_variant_container(tx.extra, *p_ado))
return false;
// TODO @#@# change to ASSET_DESCRIPTOR_OPERATION_EMMIT !
if (p_ado->operation_type != ASSET_DESCRIPTOR_OPERATION_REGISTER)
return false;
return true;
}
//---------------------------------------------------------------
// Prepapres vector of output_entry to be used in key_offsets in a transaction input:
// 1) sort all entries by gindex (while moving all ref_by_id to the end, keeping they relative order)
// 2) convert absolute global indices to relative key_offsets

View file

@ -201,6 +201,7 @@ namespace currency
bool tx_to_blob(const transaction& b, blobdata& b_blob);
bool read_keyimages_from_tx(const transaction& tx, std::list<crypto::key_image>& kil);
bool validate_inputs_sorting(const transaction& tx);
bool is_asset_emitting_transaction(const transaction& tx, asset_descriptor_operation* p_ado = nullptr);
std::vector<tx_source_entry::output_entry> prepare_outputs_entries_for_key_offsets(const std::vector<tx_source_entry::output_entry>& outputs, size_t old_real_index, size_t& new_real_index) noexcept;