N-out-TX support working for simple cases - needs edge case testing still

This commit is contained in:
Some Random Crypto Guy
2024-10-08 12:03:20 +01:00
parent d1eed6e9ff
commit 8b2b039036

View File

@@ -11298,8 +11298,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
// gather all dust and non-dust outputs of specified subaddress (if any) and below specified threshold (if any)
bool fund_found = false;
for (size_t i = 0; i < m_transfers.size(); ++i)
for (size_t idx = 0; idx < m_transfers_indices[asset_type].size(); idx++)
{
size_t i = m_transfers_indices[asset_type][idx];
const transfer_details& td = m_transfers[i];
if (m_ignore_fractional_outputs && td.amount() < fractional_threshold)
{
@@ -11392,21 +11393,23 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_return(std::vector
crypto::public_key P_change = crypto::null_pkey;
size_t change_index;
uint32_t hf_version = get_current_hard_fork();
if (hf_version >= HF_VERSION_ENABLE_N_OUTS) {
if (hf_version >= HF_VERSION_ENABLE_N_OUTS && td_origin.m_tx.version >= TRANSACTION_VERSION_N_OUTS) {
// Calculate z_i (the shared secret between sender and ourselves for the original TX)
crypto::public_key txkey_pub = null_pkey;
crypto::public_key txkey_pub = null_pkey; // R
const std::vector<crypto::public_key> in_additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(td_origin.m_tx);
if (td_origin.m_tx.vout.size()>2) {
THROW_WALLET_EXCEPTION_IF(td_origin.m_internal_output_index >= in_additional_tx_pub_keys.size(),
if (in_additional_tx_pub_keys.size() != 0) {
THROW_WALLET_EXCEPTION_IF(in_additional_tx_pub_keys.size() != td_origin.m_tx.vout.size(),
error::wallet_internal_error,
"at create_transactions_return(): incorrect number of additional TX pubkeys in origin for return_payment");
tr("at create_transactions_return(): incorrect number of additional TX pubkeys in origin TX for return_payment"));
txkey_pub = in_additional_tx_pub_keys[td_origin.m_internal_output_index];
} else {
txkey_pub = get_tx_pub_key_from_extra(td_origin.m_tx);
}
crypto::key_derivation derivation;
THROW_WALLET_EXCEPTION_IF(!generate_key_derivation(txkey_pub, m_account.get_keys().m_view_secret_key, derivation), error::wallet_internal_error, "at create_transactions_return(): failed to generate_key_derivation");
crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);
THROW_WALLET_EXCEPTION_IF(!generate_key_derivation(txkey_pub, m_account.get_keys().m_view_secret_key, derivation),
error::wallet_internal_error,
tr("at create_transactions_return(): failed to generate_key_derivation"));
crypto::secret_key z_i;
derivation_to_scalar(derivation, td_origin.m_internal_output_index, z_i);
@@ -11428,7 +11431,6 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_return(std::vector
std::strncpy(buf.domain_separator, "CHG_IDX", 8);
crypto::secret_key eci_out;
keccak((uint8_t *)&buf, sizeof(buf), (uint8_t*)&eci_out, sizeof(eci_out));
assert(false);
change_index = eci_data ^ eci_out.data[0];
return_address = td_origin.m_tx.return_address_list[td_origin.m_internal_output_index];
@@ -11450,16 +11452,18 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_return(std::vector
return_address = td_origin.m_tx.return_address;
}
THROW_WALLET_EXCEPTION_IF(!cryptonote::get_output_public_key(td_origin.m_tx.vout[change_index], P_change), error::wallet_internal_error, "Failed to identify change output");
THROW_WALLET_EXCEPTION_IF(!cryptonote::get_output_public_key(td_origin.m_tx.vout[change_index], P_change),
error::wallet_internal_error,
tr("Failed to identify change output"));
// Calculate yF
rct::key key_y = (rct::key&)(y);
rct::key key_F = (rct::key&)(td_origin.m_tx.return_address);
rct::key key_F = (rct::key&)(return_address);
rct::key key_yF = rct::scalarmultKey(key_F, key_y);
// Sanity check that we aren't attempting to return our own TX output to ourselves
rct::key key_yF_check = rct::scalarmultKey(rct::sk2rct(m_account.get_keys().m_view_secret_key), rct::pk2rct(P_change));
THROW_WALLET_EXCEPTION_IF(key_yF_check == key_yF, error::wallet_internal_error, "Attempting to return a payment to ourself");
THROW_WALLET_EXCEPTION_IF(key_yF_check == key_yF, error::wallet_internal_error, tr("Attempting to return a payment to ourself"));
// Build the subaddress to send the return to
cryptonote::account_public_address address;