1
0
Fork 0
forked from lthn/blockchain

txin_zarcanum_inputs -> txin_zc_input refactoring, including CLSAG_GG gen/verify + check_tx_input for txin_zc_input

This commit is contained in:
sowle 2022-08-03 14:00:39 +02:00
parent b1888e58ad
commit 59f8ae5fe7
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
7 changed files with 177 additions and 125 deletions

View file

@ -746,7 +746,7 @@ bool blockchain_storage::purge_transaction_keyimages_from_blockchain(const trans
{
return this->operator()(static_cast<const txin_to_key&>(inp));
}
bool operator()(const txin_zarcanum_inputs& inp) const
bool operator()(const txin_zc_input& inp) const
{
// TODO: #@#@
return false;
@ -1646,12 +1646,10 @@ bool blockchain_storage::purge_altblock_keyimages_from_big_heap(const block& b,
{
purge_keyimage_from_big_heap(get_to_key_input_from_txin_v(tx.vin[n]).k_image, block_id);
}
else if (tx.vin[n].type() == typeid(txin_zarcanum_inputs))
else if (tx.vin[n].type() == typeid(txin_zc_input))
{
// TODO @#@# consider refactoring
const txin_zarcanum_inputs& zins = boost::get<txin_zarcanum_inputs>(tx.vin[n]);
for(const auto& el : zins.elements)
purge_keyimage_from_big_heap(el.k_image, block_id);
const txin_zc_input& zcin = boost::get<txin_zc_input>(tx.vin[n]);
purge_keyimage_from_big_heap(zcin.k_image, block_id);
}
}
}
@ -3947,15 +3945,9 @@ namespace currency
}
return true;
}
bool operator()(const txin_zarcanum_inputs& in) const
bool operator()(const txin_zc_input& in) const
{
// TODO: @#@# should check for hardfork here?
for(auto& el : in.elements)
{
if (!visit(0, el.k_image, el.key_offsets))
return false;
}
return true;
return visit(0, in.k_image, in.key_offsets);
}
};
}
@ -4309,14 +4301,11 @@ bool blockchain_storage::have_tx_keyimges_as_spent(const transaction &tx) const
if (is_multisig_output_spent(boost::get<const txin_multisig>(in).multisig_out_id))
return true;
}
else if (in.type() == typeid(txin_zarcanum_inputs))
else if (in.type() == typeid(txin_zc_input))
{
const auto& zins = boost::get<txin_zarcanum_inputs>(in);
for(auto& el: zins.elements)
{
if (have_tx_keyimg_as_spent(el.k_image))
return true;
}
const auto& zcin = boost::get<txin_zc_input>(in);
if (have_tx_keyimg_as_spent(zcin.k_image))
return true;
}
else if (in.type() == typeid(txin_gen))
{
@ -4340,7 +4329,19 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha
{
size_t sig_index = 0;
max_used_block_height = 0;
auto local_check_key_image = [&](const crypto::key_image& ki) -> bool
{
TIME_MEASURE_START_PD(tx_check_inputs_loop_kimage_check);
if (have_tx_keyimg_as_spent(ki))
{
LOG_ERROR("Key image was already spent in blockchain: " << string_tools::pod_to_hex(ki) << " for input #" << sig_index << " tx: " << tx_prefix_hash);
return false;
}
TIME_MEASURE_FINISH_PD(tx_check_inputs_loop_kimage_check);
return true;
};
TIME_MEASURE_START_PD(tx_check_inputs_loop);
for(const auto& txin : tx.vin)
{
@ -4348,13 +4349,9 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha
VARIANT_CASE_CONST(txin_to_key, in_to_key)
{
CHECK_AND_ASSERT_MES(in_to_key.key_offsets.size(), false, "Empty in_to_key.key_offsets for input #" << sig_index << " tx: " << tx_prefix_hash);
TIME_MEASURE_START_PD(tx_check_inputs_loop_kimage_check);
if (have_tx_keyimg_as_spent(in_to_key.k_image))
{
LOG_ERROR("Key image was already spent in blockchain: " << string_tools::pod_to_hex(in_to_key.k_image) << " for input #" << sig_index << " tx: " << tx_prefix_hash);
if (!local_check_key_image(in_to_key.k_image))
return false;
}
TIME_MEASURE_FINISH_PD(tx_check_inputs_loop_kimage_check);
uint64_t max_unlock_time = 0;
if (!check_tx_input(tx, sig_index, in_to_key, tx_prefix_hash, max_used_block_height, max_unlock_time))
{
@ -4372,23 +4369,30 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha
}
VARIANT_CASE_CONST(txin_htlc, in_htlc)
{
if (!is_hardfork_active(3))
if (!is_hardfork_active(3)) // @#@ CZ, consider removing this to validate_tx_for_hardfork_specific_terms
{
LOG_ERROR("Error: Transaction with txin_htlc before hardfork 3 (before height " << m_core_runtime_config.hard_forks.get_str_height_the_hardfork_active_after(3) << ")");
return false;
}
CHECK_AND_ASSERT_MES(in_htlc.key_offsets.size(), false, "Empty in_to_key.key_offsets for input #" << sig_index << " tx: " << tx_prefix_hash);
TIME_MEASURE_START_PD(tx_check_inputs_loop_kimage_check);
if (have_tx_keyimg_as_spent(in_htlc.k_image))
{
LOG_ERROR("Key image was already spent in blockchain: " << string_tools::pod_to_hex(in_htlc.k_image) << " for input #" << sig_index << " tx: " << tx_prefix_hash);
if (!local_check_key_image(in_htlc.k_image))
return false;
}
TIME_MEASURE_FINISH_PD(tx_check_inputs_loop_kimage_check);
if (!check_tx_input(tx, sig_index, in_htlc, tx_prefix_hash, max_used_block_height))
{
LOG_ERROR("Failed to validate multisig input #" << sig_index << " (ms out id: " << obj_to_json_str(in_htlc) << ") in tx: " << tx_prefix_hash);
LOG_ERROR("Failed to validate htlc input #" << sig_index << " in tx: " << tx_prefix_hash << ", htlc json: " << ENDL << obj_to_json_str(in_htlc));
return false;
}
}
VARIANT_CASE_CONST(txin_zc_input, in_zc)
{
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))
{
LOG_ERROR("Failed to validate zc input #" << sig_index << " in tx: " << tx_prefix_hash);
return false;
}
}
@ -4784,6 +4788,54 @@ 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
{
CRITICAL_REGION_LOCAL(m_read_lock);
// somehow we need to get a list<tx_out_zarcanum> this input is referring to
// and make sure that all of them are good (i.e. check 1) source tx unlock time validity; 2) mixin restrictions; 3) general gindex/ref_by_id corectness)
//
// get_output_keys_for_input_with_checks may be used for that, but at that time it needs refactoring
//
std::vector<crypto::public_key> output_keys; // won't be used
scan_for_keys_context scan_contex = AUTO_VAL_INIT(scan_contex);
uint64_t source_max_unlock_time_for_pos_coinbase_dummy = 0;
if (!get_output_keys_for_input_with_checks(tx, zc_in, output_keys, max_related_block_height, source_max_unlock_time_for_pos_coinbase_dummy, scan_contex))
{
LOG_PRINT_L0("get_output_keys_for_input_with_checks failed for input #" << in_index << ", key_offset.size = " << zc_in.key_offsets.size() << ")");
return false;
}
// @#@
// here we don't need to check zc_in.k_image validity because it is checked in verify_CLSAG_GG()
CHECK_AND_ASSERT_MES(scan_contex.zc_outs.size() > 0, false, "zero referenced outputs found");
CHECK_AND_ASSERT_MES(in_index < tx.signatures.size(), false, "tx.signatures.size (" << tx.signatures.size() << ") is less than or equal to in_index (" << in_index << ")");
// TODO: consider additional checks here
// build a ring of references
vector<crypto::CLSAG_GG_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);
// calculate corresponding tx prefix hash
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, in_index, tx_prefix_hash);
CHECK_AND_ASSERT_MES(tx_hash_for_signature != null_hash, false, "prepare_prefix_hash_for_sign failed");
const ZC_sig& sig = boost::get<ZC_sig>(tx.signatures[in_index]);
//TIME_MEASURE_START_PD(tx_input_check_clsag_gg);
bool r = crypto::verify_CLSAG_GG(tx_hash_for_signature, ring, sig.pseudo_out_amount_commitment, zc_in.k_image, sig.clsags_gg);
CHECK_AND_ASSERT_MES(r, false, "verify_CLSAG_GG failed");
//TIME_MEASURE_FINISH_PD(tx_input_check_clsag_gg);
return true;
}
//------------------------------------------------------------------
uint64_t blockchain_storage::get_adjusted_time() const
{
//TODO: add collecting median time
@ -4915,16 +4967,13 @@ std::shared_ptr<const transaction_chain_entry> blockchain_storage::find_key_imag
return tx_chain_entry;
}
}
else if (in.type() == typeid(txin_zarcanum_inputs))
else if (in.type() == typeid(txin_zc_input))
{
const auto& zins = boost::get<txin_zarcanum_inputs>(in);
for(auto& el: zins.elements)
const auto& zc_in = boost::get<txin_zc_input>(in);
if (zc_in.k_image == ki)
{
if (el.k_image == ki)
{
id_result = tx_id;
return tx_chain_entry;
}
id_result = tx_id;
return tx_chain_entry;
}
}
}
@ -5098,7 +5147,7 @@ bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transacti
VARIANT_CASE_CONST(txin_htlc, in_htlc)
if (!var_is_after_hardfork_3_zone)
return false;
VARIANT_CASE_CONST(txin_zarcanum_inputs, in_zins)
VARIANT_CASE_CONST(txin_zc_input, in_zins)
if (!var_is_after_hardfork_4_zone)
return false;
VARIANT_SWITCH_END();

View file

@ -139,6 +139,7 @@ namespace currency
{
bool htlc_is_expired;
std::list<txout_htlc> htlc_outs;
std::list<tx_out_zarcanum> zc_outs;
};
// == Output indexes local lookup table conception ==
@ -290,6 +291,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_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

@ -303,6 +303,7 @@ namespace currency
// Zarcanum structures
//
//#pragma pack(push, 1)
/*
struct zarcanum_input : public referring_input
{
zarcanum_input() {}
@ -345,6 +346,32 @@ namespace currency
BOOST_SERIALIZE(etc_details)
END_BOOST_SERIALIZATION()
};
*/
struct txin_zc_input : public referring_input
{
txin_zc_input() {}
// Boost's Assignable concept
txin_zc_input(const txin_zc_input&) = default;
txin_zc_input& operator=(const txin_zc_input&)= default;
crypto::key_image k_image;
std::vector<txin_etc_details_v> etc_details;
BEGIN_SERIALIZE_OBJECT()
FIELD(key_offsets) // referring_input
FIELD(k_image)
FIELD(etc_details)
END_SERIALIZE()
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(key_offsets) // referring_input
BOOST_SERIALIZE(k_image)
BOOST_SERIALIZE(etc_details)
END_BOOST_SERIALIZATION()
};
struct tx_out_zarcanum
{
@ -412,36 +439,22 @@ namespace currency
// Zarcanum-aware CLSAG signature
struct ZC_sig
{
struct input_proofs_t
{
crypto::public_key pseudo_out_amount_commitment;
// crypto::public_key real_out_token_masked_generator;
BEGIN_SERIALIZE_OBJECT()
FIELD(pseudo_out_amount_commitment)
END_SERIALIZE()
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(pseudo_out_amount_commitment)
END_BOOST_SERIALIZATION()
};
std::vector<input_proofs_t> input_proofs; // for each input
std::vector<crypto::CLSAG_GG_signature_serialized> clsags_gg;
crypto::public_key pseudo_out_amount_commitment;
crypto::CLSAG_GG_signature_serialized clsags_gg;
BEGIN_SERIALIZE_OBJECT()
FIELD(input_proofs)
FIELD(pseudo_out_amount_commitment)
FIELD(clsags_gg)
END_SERIALIZE()
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(input_proofs)
BOOST_SERIALIZE(pseudo_out_amount_commitment)
BOOST_SERIALIZE(clsags_gg)
END_BOOST_SERIALIZATION()
};
//#pragma pack(pop)
typedef boost::variant<txin_gen, txin_to_key, txin_multisig, txin_htlc, txin_zarcanum_inputs> txin_v;
typedef boost::variant<txin_gen, txin_to_key, txin_multisig, txin_htlc, txin_zc_input> txin_v;
typedef boost::variant<tx_out_bare, tx_out_zarcanum> tx_out_v;
@ -1019,7 +1032,7 @@ SET_VARIANT_TAGS(currency::txout_htlc, 35, "txout_htlc");
SET_VARIANT_TAGS(currency::tx_out_bare, 36, "tx_out_bare");
// Zarcanum
SET_VARIANT_TAGS(currency::txin_zarcanum_inputs, 37, "txin_zarcanum_inputs");
SET_VARIANT_TAGS(currency::txin_zc_input, 37, "txin_zc_input");
SET_VARIANT_TAGS(currency::tx_out_zarcanum, 38, "tx_out_zarcanum");
SET_VARIANT_TAGS(currency::zarcanum_tx_data_v1, 39, "zarcanum_tx_data_v1");
SET_VARIANT_TAGS(crypto::bpp_signature_serialized, 40, "bpp_signature_serialized");

View file

@ -1320,42 +1320,35 @@ namespace currency
//std::vector<keypair> participants_derived_keys;
};
//--------------------------------------------------------------------------------
bool generate_ZC_sig(const crypto::hash& tx_prefix_hash, const std::vector<const tx_source_entry*>& sources, const account_keys& sender_account_keys,
bool generate_ZC_sigs(const crypto::hash& tx_prefix_hash, const std::vector<const tx_source_entry*>& sources, size_t input_starter_index, const account_keys& sender_account_keys,
const std::vector<input_generation_context_data>& in_contexts, const crypto::scalar_t& blinding_masks_sum, const uint64_t tx_flags, transaction& tx)
{
bool watch_only_mode = sender_account_keys.spend_secret_key == null_skey;
CHECK_AND_ASSERT_MES(tx.vin.back().type() == typeid(txin_zarcanum_inputs), false, "Unexpected input type");
txin_zarcanum_inputs& zarcanum_inputs = boost::get<txin_zarcanum_inputs>(tx.vin.back());
CHECK_AND_ASSERT_MES(zarcanum_inputs.elements.size() == sources.size(), false, "sources size differs from zarcanum_inputs.elements size");
CHECK_AND_ASSERT_MES(zarcanum_inputs.elements.size() == in_contexts.size(), false, "in_contexts size differs from zarcanum_inputs.elements size");
tx.signatures.push_back(ZC_sig());
ZC_sig& sig = boost::get<ZC_sig>(tx.signatures.back());
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, tx.vin.size() - 1, tx_prefix_hash);
CHECK_AND_ASSERT_MES(tx_hash_for_signature != null_hash, false, "prepare_prefix_hash_for_sign failed");
CHECK_AND_ASSERT_MES(tx.vin.size() == input_starter_index + sources.size(), false, "tx.vin size (" << tx.vin.size() << ") != input_starter_index (" << input_starter_index << ") + sources.size (" << sources.size() << ")");
CHECK_AND_ASSERT_MES(sources.size() == in_contexts.size(), false, "in_contexts size differs from sources size");
crypto::scalar_t local_blinding_masks_sum = 0;
size_t ring_size = 0;
for(size_t i = 0; i < sources.size(); ++i)
{
size_t input_index = input_starter_index + i;
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, "prepare_prefix_hash_for_sign failed");
CHECK_AND_ASSERT_MES(sources[i] != nullptr, false, "sources[" << i << "] contains nullptr");
const tx_source_entry& se = *sources[i];
CHECK_AND_ASSERT_MES(se.is_zarcanum(), false, "sources[" << i << "] contains a non-zarcanum input");
zarcanum_input& in = zarcanum_inputs.elements[i];
sig.input_proofs.emplace_back();
ZC_sig::input_proofs_t zsip = sig.input_proofs.back();
sig.clsags_gg.emplace_back();
crypto::CLSAG_GG_signature& clsag_gg = sig.clsags_gg.back();
CHECK_AND_ASSERT_MES(tx.vin[input_index].type() == typeid(txin_zc_input), false, "Unexpected type of input #" << input_index);
txin_zc_input& in = boost::get<txin_zc_input>(tx.vin[input_index]);
tx.signatures.emplace_back();
ZC_sig& sig = boost::get<ZC_sig>(tx.signatures.back());
if (watch_only_mode)
return true; // in this mode just append empty signatures
if (ring_size == 0)
ring_size = se.outputs.size();
else
CHECK_AND_ASSERT_MES(ring_size == se.outputs.size(), false, "sources[" << i << "] has ring size " << se.outputs.size() << ", expected: " << ring_size);
#ifndef NDEBUG
{
crypto::point_t source_amount_commitment = crypto::c_scalar_1div8 * se.amount * crypto::c_point_H + crypto::c_scalar_1div8 * se.real_out_amount_blinding_mask * crypto::c_point_G;
@ -1368,6 +1361,7 @@ namespace currency
{
// either normal tx or the last signature of consolidated tx -- in both cases we need to calculate non-random blinding mask for pseudo output commitment
blinding_mask = blinding_masks_sum + local_blinding_masks_sum;
// @#@ TODO additional check for the last iteration ?
}
else
{
@ -1376,7 +1370,7 @@ namespace currency
}
crypto::point_t pseudo_out_amount_commitment = se.amount * crypto::c_point_H + blinding_mask * crypto::c_point_G;
zsip.pseudo_out_amount_commitment = (crypto::c_scalar_1div8 * pseudo_out_amount_commitment).to_public_key();
sig.pseudo_out_amount_commitment = (crypto::c_scalar_1div8 * pseudo_out_amount_commitment).to_public_key();
// = two-layers ring signature data outline =
// (j in [0, ring_size-1])
@ -1393,17 +1387,17 @@ namespace currency
// se.real_out_amount_blinding_mask - blinding_mask;
std::vector<crypto::CLSAG_GG_input_ref_t> ring;
for(size_t j = 0; j < ring_size; ++j)
for(size_t j = 0; j < se.outputs.size(); ++j)
ring.emplace_back(se.outputs[j].stealth_address, se.outputs[j].amount_commitment);
bool r = crypto::generate_CLSAG_GG(tx_prefix_hash, ring, pseudo_out_amount_commitment, in.k_image, in_contexts[i].in_ephemeral.sec, se.real_out_amount_blinding_mask - blinding_mask, se.real_output, clsag_gg);
CHECK_AND_ASSERT_MES(r, false, "generate_CLSAG_GG failed for item " << i);
bool r = crypto::generate_CLSAG_GG(tx_prefix_hash, ring, pseudo_out_amount_commitment, in.k_image, in_contexts[i].in_ephemeral.sec, se.real_out_amount_blinding_mask - blinding_mask, se.real_output, sig.clsags_gg);
CHECK_AND_ASSERT_MES(r, false, "generate_CLSAG_GG failed for input #" << input_index << " (" << i << ")");
}
return true;
}
//--------------------------------------------------------------------------------
bool generate_NLSAG_sig(const std::vector<const tx_source_entry*>& sources, size_t input_starter_index, transaction& tx, const crypto::hash& tx_prefix_hash,
bool generate_NLSAG_sigs(const std::vector<const tx_source_entry*>& sources, size_t input_starter_index, transaction& tx, const crypto::hash& tx_prefix_hash,
const account_keys& sender_account_keys, const std::vector<input_generation_context_data>& in_contexts, const keypair& txkey, std::stringstream& ss_ring_s)
{
bool watch_only_mode = sender_account_keys.spend_secret_key == null_skey;
@ -1572,7 +1566,7 @@ namespace currency
std::vector<input_generation_context_data> in_contexts;
//we'll aggregate Zarcanum outs into one txin_zarcanum_inputs
txin_zarcanum_inputs ins_zc = AUTO_VAL_INIT(ins_zc);
//txin_zarcanum_inputs ins_zc = AUTO_VAL_INIT(ins_zc);
size_t input_starter_index = tx.vin.size();
uint64_t summary_inputs_money = 0;
@ -1664,10 +1658,10 @@ namespace currency
//potentially this approach might help to support htlc and multisig without making to complicated code
if (src_entr.is_zarcanum())
{
zarcanum_input zc_in = AUTO_VAL_INIT(zc_in);
txin_zc_input zc_in = AUTO_VAL_INIT(zc_in);
zc_in.k_image = img;
zc_in.key_offsets = std::move(key_offsets);
ins_zc.elements.push_back(zc_in);
tx.vin.push_back(zc_in);
zc_sources.push_back(&src_entr);
}
else
@ -1682,10 +1676,10 @@ namespace currency
}
}
if (ins_zc.elements.size())
/*if (ins_zc.elements.size())
{
tx.vin.push_back(ins_zc);
}
}*/
// "Shuffle" outs
std::vector<tx_destination_entry> shuffled_dsts(destinations);
@ -1779,17 +1773,17 @@ namespace currency
std::stringstream ss_ring_s;
if (NLSAG_sources.size())
{
bool r = generate_NLSAG_sig(NLSAG_sources, input_starter_index, tx, tx_prefix_hash, sender_account_keys, in_contexts, txkey, ss_ring_s);
CHECK_AND_ASSERT_MES(r, false, "Failed to generate_NLSAG_sig()");
bool r = generate_NLSAG_sigs(NLSAG_sources, input_starter_index, tx, tx_prefix_hash, sender_account_keys, in_contexts, txkey, ss_ring_s);
CHECK_AND_ASSERT_MES(r, false, "generate_NLSAG_sigs failed");
}
if (zc_sources.size())
{
// blinding_masks_sum is supposed to be sum(mask of all tx output) - sum(masks of all pseudo out commitments)
generate_ZC_sig(tx_prefix_hash, zc_sources, sender_account_keys, in_contexts, blinding_masks_sum, flags, tx);
bool r = generate_ZC_sigs(tx_prefix_hash, zc_sources, input_starter_index, sender_account_keys, in_contexts, blinding_masks_sum, flags, tx);
CHECK_AND_ASSERT_MES(r, false, "generate_ZC_sigs failed");
}
LOG_PRINT2("construct_tx.log", "transaction_created: " << get_transaction_hash(tx) << ENDL << obj_to_json_str(tx) << ENDL << ss_ring_s.str(), LOG_LEVEL_3);
return true;

View file

@ -414,8 +414,8 @@ namespace currency
return boost::get<txin_multisig>(in).etc_details;
else if (in.type() == typeid(txin_htlc))
return boost::get<txin_htlc>(in).etc_details;
else if (in.type() == typeid(txin_zarcanum_inputs))
return boost::get<txin_zarcanum_inputs>(in).etc_details;
else if (in.type() == typeid(txin_zc_input))
return boost::get<txin_zc_input>(in).etc_details;
else
return stub;
}
@ -714,7 +714,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 txin_zarcanum_inputs& txin) const { throw std::runtime_error("Not implemented yet"); }
size_t operator()(const txin_zc_input& txin) const { throw std::runtime_error("Not implemented yet"); }
};
return boost::apply_visitor(txin_signature_size_visitor(), tx_in);
@ -730,8 +730,8 @@ namespace currency
return &boost::get<txin_multisig>(in).etc_details;
if (in.type() == typeid(txin_htlc))
return &boost::get<txin_htlc>(in).etc_details;
if (in.type() == typeid(txin_zarcanum_inputs))
return &boost::get<txin_zarcanum_inputs>(in).etc_details;
if (in.type() == typeid(txin_zc_input))
return &boost::get<txin_zc_input>(in).etc_details;
return nullptr;
}
//---------------------------------------------------------------
@ -739,7 +739,7 @@ namespace currency
{
template<class t_input>
uint64_t operator()(const t_input& i) const { return i.amount; }
uint64_t operator()(const txin_zarcanum_inputs&) const { return 0; }
uint64_t operator()(const txin_zc_input&) const { return 0; }
uint64_t operator()(const txin_gen& i) const { return 0; }
};
inline uint64_t get_amount_from_variant(const txin_v& v)

View file

@ -438,13 +438,10 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
{
process_input_t(intk, ptc, tx);
}
VARIANT_CASE_CONST(currency::txin_zarcanum_inputs, tinz)
VARIANT_CASE_CONST(currency::txin_zc_input, in_zc)
{
for (const auto& e : tinz.elements)
{
process_input_t(e, ptc, tx);
ptc.sub_i++;
}
process_input_t(in_zc, ptc, tx);
//ptc.sub_i++;
}
VARIANT_CASE_CONST(currency::txin_multisig, inms)
{
@ -1880,9 +1877,9 @@ uint64_t wallet2::get_directly_spent_transfer_index_by_input_in_tracking_wallet(
return get_directly_spent_transfer_index_by_input_in_tracking_wallet(intk.amount, intk.key_offsets);
}
//----------------------------------------------------------------------------------------------------
uint64_t wallet2::get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::zarcanum_input& inzk)
uint64_t wallet2::get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_zc_input& inzc)
{
return get_directly_spent_transfer_index_by_input_in_tracking_wallet(0, inzk.key_offsets);
return get_directly_spent_transfer_index_by_input_in_tracking_wallet(0, inzc.key_offsets);
}
//----------------------------------------------------------------------------------------------------
uint64_t wallet2::get_directly_spent_transfer_index_by_input_in_tracking_wallet(uint64_t amount, const std::vector<currency::txout_ref_v> & key_offsets)
@ -5219,17 +5216,14 @@ bool wallet2::read_money_transfer2_details_from_tx(const transaction& tx, const
wtd.spn.push_back(in_to_key.amount);
}
}
else if (i.type() == typeid(currency::txin_zarcanum_inputs))
else if (i.type() == typeid(currency::txin_zc_input))
{
const currency::txin_zarcanum_inputs& in_to_zc = boost::get<currency::txin_zarcanum_inputs>(i);
for (auto& e : in_to_zc.elements)
{
auto it = m_key_images.find(e.k_image);
//should we panic if image not found?
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it != m_key_images.end(), "[read_money_transfer2_details_from_tx]Unknown key image in tx: " << get_transaction_hash(tx));
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it->second < m_transfers.size(), "[read_money_transfer2_details_from_tx]Index out of range for key image in tx: " << get_transaction_hash(tx));
wtd.spn.push_back(m_transfers[it->second].amount());
}
const currency::txin_zc_input& in_zc = boost::get<currency::txin_zc_input>(i);
auto it = m_key_images.find(in_zc.k_image);
//should we panic if image not found?
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it != m_key_images.end(), "[read_money_transfer2_details_from_tx]Unknown key image in tx: " << get_transaction_hash(tx));
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it->second < m_transfers.size(), "[read_money_transfer2_details_from_tx]Index out of range for key image in tx: " << get_transaction_hash(tx));
wtd.spn.push_back(m_transfers[it->second].amount());
}
}
return true;

View file

@ -1038,7 +1038,7 @@ private:
uint64_t get_wallet_minimum_height();
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(uint64_t amount, const std::vector<currency::txout_ref_v> & key_offsets);
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_to_key& intk);
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::zarcanum_input& inzk);
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_zc_input& inzc);
bool is_in_hardfork_zone(uint64_t hardfork_index);
uint8_t out_get_mixin_attr(const currency::tx_out_v& out_t);
const crypto::public_key& out_get_pub_key(const currency::tx_out_v& out_t, std::list<currency::htlc_info>& htlc_info_list);