1
0
Fork 0
forked from lthn/blockchain

first draft of wallet atomics workflow is done(no tests created yet)

This commit is contained in:
cryptozoidberg 2021-02-02 22:14:34 +01:00
parent a31670f225
commit ae24efa5e3
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
2 changed files with 84 additions and 22 deletions

View file

@ -1171,8 +1171,56 @@ namespace currency
for (const tx_source_entry& src_entr : sources)
{
in_contexts.push_back(input_generation_context_data());
if (!src_entr.is_multisig())
if(src_entr.is_multisig())
{//multisig input
txin_multisig input_multisig = AUTO_VAL_INIT(input_multisig);
summary_inputs_money += input_multisig.amount = src_entr.amount;
input_multisig.multisig_out_id = src_entr.multisig_id;
input_multisig.sigs_count = src_entr.ms_sigs_count;
tx.vin.push_back(input_multisig);
}
else if (src_entr.htlc_origin.size())
{
//htlc redeem
keypair& in_ephemeral = in_contexts.back().in_ephemeral;
//txin_to_key
if(src_entr.outputs.size() != 1)
{
LOG_ERROR("htlc in: wrong output src_entr.outputs.size() = " << src_entr.outputs.size());
return false;
}
summary_inputs_money += src_entr.amount;
//key_derivation recv_derivation;
crypto::key_image img;
if (!generate_key_image_helper(sender_account_keys, src_entr.real_out_tx_key, src_entr.real_output_in_tx_index, in_ephemeral, img))
return false;
//check that derivated key is equal with real output key
if (!(in_ephemeral.pub == src_entr.outputs[src_entr.real_output].second))
{
LOG_ERROR("derived public key missmatch with output public key! " << ENDL << "derived_key:"
<< string_tools::pod_to_hex(in_ephemeral.pub) << ENDL << "real output_public_key:"
<< string_tools::pod_to_hex(src_entr.outputs[src_entr.real_output].second));
return false;
}
//put key image into tx input
txin_htlc input_to_key;
input_to_key.amount = src_entr.amount;
input_to_key.k_image = img;
input_to_key.hltc_origin = src_entr.htlc_origin;
//fill outputs array and use relative offsets
BOOST_FOREACH(const tx_source_entry::output_entry& out_entry, src_entr.outputs)
input_to_key.key_offsets.push_back(out_entry.first);
input_to_key.key_offsets = absolute_output_offsets_to_relative(input_to_key.key_offsets);
tx.vin.push_back(input_to_key);
}
else
{
//regular to key out
keypair& in_ephemeral = in_contexts.back().in_ephemeral;
//txin_to_key
if (src_entr.real_output >= src_entr.outputs.size())
@ -1197,7 +1245,26 @@ namespace currency
}
//put key image into tx input
txin_to_key input_to_key;
txin_v in_v;
txin_to_key* ptokey = nullptr;
if (src_entr.htlc_origin.size())
{
//add txin_htlc
txin_htlc in_htlc = AUTO_VAL_INIT(inp_htlc);
in_htlc.hltc_origin = src_entr.htlc_origin;
in_v = in_htlc;
txin_htlc& in_v_ref = boost::get<txin_htlc>(in_v);
ptokey = static_cast<txin_to_key*>(&in_v_ref);
}
else
{
in_v = txin_to_key();
txin_to_key& in_v_ref = boost::get<txin_to_key>(in_v);
ptokey = &in_v_ref;
}
txin_to_key& input_to_key = *ptokey;
input_to_key.amount = src_entr.amount;
input_to_key.k_image = img;
@ -1206,16 +1273,9 @@ namespace currency
input_to_key.key_offsets.push_back(out_entry.first);
input_to_key.key_offsets = absolute_output_offsets_to_relative(input_to_key.key_offsets);
tx.vin.push_back(input_to_key);
}
else
{//multisig input
txin_multisig input_multisig = AUTO_VAL_INIT(input_multisig);
summary_inputs_money += input_multisig.amount = src_entr.amount;
input_multisig.multisig_out_id = src_entr.multisig_id;
input_multisig.sigs_count = src_entr.ms_sigs_count;
tx.vin.push_back(input_multisig);
tx.vin.push_back(in_v);
}
}
// "Shuffle" outs
@ -1302,9 +1362,14 @@ namespace currency
tx.signatures.push_back(std::vector<crypto::signature>());
std::vector<crypto::signature>& sigs = tx.signatures.back();
if (!src_entr.is_multisig())
if(src_entr.is_multisig())
{
// txin_to_key
// txin_multisig -- don't sign anything here (see also sign_multisig_input_in_tx())
sigs.resize(src_entr.ms_keys_count, null_sig); // just reserve keys.size() null signatures (NOTE: not minimum_sigs!)
}
else
{
// regular txin_to_key or htlc
ss_ring_s << "input #" << input_index << ", pub_keys:" << ENDL;
std::vector<const crypto::public_key*> keys_ptrs;
BOOST_FOREACH(const tx_source_entry::output_entry& o, src_entr.outputs)
@ -1321,11 +1386,6 @@ namespace currency
std::for_each(sigs.begin(), sigs.end(), [&ss_ring_s](const crypto::signature& s) { ss_ring_s << s << ENDL; });
ss_ring_s << "prefix_hash: " << tx_prefix_hash << ENDL << "in_ephemeral_key: " << in_contexts[in_context_index].in_ephemeral.sec << ENDL << "real_output: " << src_entr.real_output << ENDL;
}
else
{
// txin_multisig -- don't sign anything here (see also sign_multisig_input_in_tx())
sigs.resize(src_entr.ms_keys_count, null_sig); // just reserve keys.size() null signatures (NOTE: not minimum_sigs!)
}
if (src_entr.separately_signed_tx_complete)
{
// if separately signed tx is complete, put one more signature to the last bunch using tx secret key, which confirms that transaction has been generated by authorized subject

View file

@ -4301,13 +4301,15 @@ bool wallet2::prepare_tx_sources_htlc(crypto::hash htlc_tx_id, const std::string
sources.push_back(AUTO_VAL_INIT(currency::tx_source_entry()));
currency::tx_source_entry& src = sources.back();
currency::tx_output_entry real_oe = AUTO_VAL_INIT(real_oe);
real_oe.first = td.m_global_output_index; // TODO: use ref_by_id when necessary
real_oe.second = htlc_out.pkey_redeem;
src.outputs.push_back(real_oe); //m_global_output_index should be prefetched
src.amount = found_money = td.amount();
src.real_output_in_tx_index = td.m_internal_output_index;
src.real_output = 0;//no mixins supposed to be in htlc
src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_ptx_wallet_info->m_tx);
src.htlc_origin = origin;
//src.multisig_id = multisig_id;
//src.ms_sigs_count = ms_out.minimum_sigs;
//src.ms_keys_count = ms_out.keys.size();
return true;
}
@ -4880,7 +4882,7 @@ void wallet2::prepare_transaction(const construct_tx_param& ctp, finalize_tx_par
else if (ctp.htlc_tx_id != currency::null_hash)
{
//htlc
bool prepare_tx_sources_htlc(htlc_tx_id, ctp.htlc_origin, sources, found_money);
prepare_tx_sources_htlc(htlc_tx_id, ctp.htlc_origin, sources, found_money);
}
else if (ctp.multisig_id != currency::null_hash)
{