From 8b2b039036620327c7b6d6cbc3cba3cae3d47401 Mon Sep 17 00:00:00 2001 From: Some Random Crypto Guy Date: Tue, 8 Oct 2024 12:03:20 +0100 Subject: [PATCH] N-out-TX support working for simple cases - needs edge case testing still --- src/wallet/wallet2.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 803aa79..8b03f83 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -11298,8 +11298,9 @@ std::vector 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::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 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::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::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;