mirror of
https://github.com/monero-project/monero.git
synced 2024-12-04 23:51:08 +02:00
get_output_enote_proposals now supports external selfsends
This commit is contained in:
parent
8dc6a12ec7
commit
b70222c774
@ -146,7 +146,9 @@ tools::optional_variant<CarrotPaymentProposalV1, CarrotPaymentProposalSelfSendV1
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void get_output_enote_proposals(std::vector<CarrotPaymentProposalV1> &&normal_payment_proposals,
|
||||
std::vector<CarrotPaymentProposalSelfSendV1> &&selfsend_payment_proposals,
|
||||
const view_balance_secret_device &s_view_balance_dev,
|
||||
const view_balance_secret_device *s_view_balance_dev,
|
||||
const view_incoming_key_device *k_view_dev,
|
||||
const crypto::public_key &account_spend_pubkey,
|
||||
const crypto::key_image &tx_first_key_image,
|
||||
std::vector<RCTOutputEnoteProposal> &output_enote_proposals_out,
|
||||
encrypted_payment_id_t &encrypted_payment_id_out)
|
||||
@ -208,18 +210,34 @@ void get_output_enote_proposals(std::vector<CarrotPaymentProposalV1> &&normal_pa
|
||||
encrypted_payment_id_out = encrypted_payment_id;
|
||||
}
|
||||
|
||||
// in the case that the pid is ambiguous, set it to random bytes
|
||||
// in the case that the pid target is ambiguous, set it to random bytes
|
||||
const bool ambiguous_pid_destination = num_integrated == 0 && normal_payment_proposals.size() > 1;
|
||||
if (ambiguous_pid_destination)
|
||||
encrypted_payment_id_out = gen_payment_id();
|
||||
|
||||
// construct selfsend enotes
|
||||
// construct selfsend enotes, preferring internal enotes over special enotes when possible
|
||||
for (const CarrotPaymentProposalSelfSendV1 &selfsend_payment_proposal : selfsend_payment_proposals)
|
||||
{
|
||||
get_output_proposal_internal_v1(selfsend_payment_proposal,
|
||||
s_view_balance_dev,
|
||||
tx_first_key_image,
|
||||
tools::add_element(output_enote_proposals_out));
|
||||
if (s_view_balance_dev != nullptr)
|
||||
{
|
||||
get_output_proposal_internal_v1(selfsend_payment_proposal,
|
||||
*s_view_balance_dev,
|
||||
tx_first_key_image,
|
||||
tools::add_element(output_enote_proposals_out));
|
||||
}
|
||||
else if (k_view_dev != nullptr)
|
||||
{
|
||||
get_output_proposal_special_v1(selfsend_payment_proposal,
|
||||
*k_view_dev,
|
||||
account_spend_pubkey,
|
||||
tx_first_key_image,
|
||||
tools::add_element(output_enote_proposals_out));
|
||||
}
|
||||
else // neither k_v nor s_vb device passed
|
||||
{
|
||||
ASSERT_MES_AND_THROW(
|
||||
"get output enote proposals: neither a view-balance nor view-incoming device was provided");
|
||||
}
|
||||
}
|
||||
|
||||
// sort enotes by D_e and assert uniqueness properties of D_e
|
||||
|
@ -87,11 +87,25 @@ tools::optional_variant<CarrotPaymentProposalV1, CarrotPaymentProposalSelfSendV1
|
||||
const crypto::public_key &change_address_spend_pubkey,
|
||||
const crypto::x25519_pubkey &other_enote_ephemeral_pubkey);
|
||||
/**
|
||||
* brief: get_output_enote_proposals - convert payment proposals into output enote proposals
|
||||
* brief: get_output_enote_proposals - convert a *finalized* set of payment proposals into output enote proposals
|
||||
* param: normal_payment_proposals -
|
||||
* param: selfsend_payment_proposals -
|
||||
* param: s_view_balance_dev - pointer to view-balance device (OPTIONAL)
|
||||
* param: k_view_dev - pointer to view-incoming device (OPTIONAL)
|
||||
* param: account_spend_pubkey - K_s
|
||||
* param: tx_first_key_image - KI_1
|
||||
* outparam: output_enote_proposals_out -
|
||||
* outparam: encrypted_payment_id_out - pid_enc
|
||||
* throw: std::runtime_error if the payment proposals do not represent a valid tx output set, or if no devices
|
||||
*
|
||||
* If s_view_balance_dev is not NULL, then the selfsend payments are converted into *internal* enotes.
|
||||
* Otherwise, if k_view_dev is not NULL, then the selfsend payments are converted into *external* enotes.
|
||||
*/
|
||||
void get_output_enote_proposals(std::vector<CarrotPaymentProposalV1> &&normal_payment_proposals,
|
||||
std::vector<CarrotPaymentProposalSelfSendV1> &&selfsend_payment_proposals,
|
||||
const view_balance_secret_device &s_view_balance_dev,
|
||||
const view_balance_secret_device *s_view_balance_dev,
|
||||
const view_incoming_key_device *k_view_dev,
|
||||
const crypto::public_key &account_spend_pubkey,
|
||||
const crypto::key_image &tx_first_key_image,
|
||||
std::vector<RCTOutputEnoteProposal> &output_enote_proposals_out,
|
||||
encrypted_payment_id_t &encrypted_payment_id_out);
|
||||
|
@ -321,7 +321,7 @@ void get_output_proposal_normal_v1(const CarrotPaymentProposalV1 &proposal,
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &proposal,
|
||||
const view_incoming_key_device &k_view_dev,
|
||||
const crypto::public_key &primary_address_spend_pubkey,
|
||||
const crypto::public_key &account_spend_pubkey,
|
||||
const crypto::key_image &tx_first_key_image,
|
||||
RCTOutputEnoteProposal &output_enote_out)
|
||||
{
|
||||
@ -362,7 +362,7 @@ void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &propo
|
||||
k_view_dev.make_janus_anchor_special(proposal.enote_ephemeral_pubkey,
|
||||
input_context,
|
||||
output_enote_out.enote.onetime_address,
|
||||
primary_address_spend_pubkey,
|
||||
account_spend_pubkey,
|
||||
janus_anchor_special);
|
||||
|
||||
// 6. encrypt special anchor: anchor_enc = anchor XOR m_anchor
|
||||
|
@ -129,20 +129,20 @@ void get_output_proposal_normal_v1(const CarrotPaymentProposalV1 &proposal,
|
||||
* brief: get_output_proposal_v1 - convert the carrot proposal to an output proposal (external selfsend)
|
||||
* param: proposal -
|
||||
* param: k_view_dev -
|
||||
* param: primary_address_spend_pubkey -
|
||||
* param: account_spend_pubkey -
|
||||
* param: tx_first_key_image -
|
||||
* outparam: output_enote_out -
|
||||
*/
|
||||
void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &proposal,
|
||||
const view_incoming_key_device &k_view_dev,
|
||||
const crypto::public_key &primary_address_spend_pubkey,
|
||||
const crypto::public_key &account_spend_pubkey,
|
||||
const crypto::key_image &tx_first_key_image,
|
||||
RCTOutputEnoteProposal &output_enote_out);
|
||||
/**
|
||||
* brief: get_output_proposal_internal_v1 - convert the carrot proposal to an output proposal (internal)
|
||||
* param: proposal -
|
||||
* param: s_view_balance_dev -
|
||||
* param: primary_address_spend_pubkey -
|
||||
* param: account_spend_pubkey -
|
||||
* param: tx_first_key_image -
|
||||
* outparam: output_enote_out -
|
||||
* outparam: partial_memo_out -
|
||||
|
@ -893,10 +893,11 @@ TEST(carrot_core, main_address_coinbase_scan_completeness)
|
||||
enote.onetime_address));
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
static void subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(const bool alice_subaddress,
|
||||
static void subtest_2out_transfer_get_output_enote_proposals_completeness(const bool alice_subaddress,
|
||||
const bool bob_subaddress,
|
||||
const bool bob_integrated,
|
||||
const CarrotEnoteType alice_selfsend_type)
|
||||
const CarrotEnoteType alice_selfsend_type,
|
||||
const bool alice_internal_selfsends)
|
||||
{
|
||||
// generate alice keys and address
|
||||
const mock_carrot_keys alice = mock_carrot_keys::generate();
|
||||
@ -972,11 +973,13 @@ static void subtest_2out_transfer_get_enote_output_proposals_internal_ss_complet
|
||||
encrypted_payment_id_t encrypted_payment_id;
|
||||
get_output_enote_proposals({bob_payment_proposal},
|
||||
{alice_payment_proposal},
|
||||
alice.s_view_balance_dev,
|
||||
alice_internal_selfsends ? &alice.s_view_balance_dev : nullptr,
|
||||
&alice.k_view_dev,
|
||||
alice.account_spend_pubkey,
|
||||
tx_first_key_image,
|
||||
enote_proposals,
|
||||
encrypted_payment_id);
|
||||
|
||||
|
||||
ASSERT_EQ(2, enote_proposals.size()); // 2-out tx
|
||||
|
||||
// collect enotes
|
||||
@ -1061,37 +1064,73 @@ static void subtest_2out_transfer_get_enote_output_proposals_internal_ss_complet
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_main2main_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(false, false, false, CarrotEnoteType::PAYMENT);
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(false, false, false, CarrotEnoteType::CHANGE);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, false, false, CarrotEnoteType::PAYMENT, true);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, false, false, CarrotEnoteType::CHANGE, true);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_main2sub_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(false, true, false, CarrotEnoteType::PAYMENT);
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(false, true, false, CarrotEnoteType::CHANGE);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, true, false, CarrotEnoteType::PAYMENT, true);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, true, false, CarrotEnoteType::CHANGE, true);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_main2integ_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(false, false, true, CarrotEnoteType::PAYMENT);
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(false, false, true, CarrotEnoteType::CHANGE);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, false, true, CarrotEnoteType::PAYMENT, true);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, false, true, CarrotEnoteType::CHANGE, true);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_sub2main_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(true, false, false, CarrotEnoteType::PAYMENT);
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(true, false, false, CarrotEnoteType::CHANGE);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, false, false, CarrotEnoteType::PAYMENT, true);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, false, false, CarrotEnoteType::CHANGE, true);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_sub2sub_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(true, true, false, CarrotEnoteType::PAYMENT);
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(true, true, false, CarrotEnoteType::CHANGE);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, true, false, CarrotEnoteType::PAYMENT, true);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, true, false, CarrotEnoteType::CHANGE, true);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_sub2integ_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(true, false, true, CarrotEnoteType::PAYMENT);
|
||||
subtest_2out_transfer_get_enote_output_proposals_internal_ss_completeness(true, false, true, CarrotEnoteType::CHANGE);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, false, true, CarrotEnoteType::PAYMENT, true);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, false, true, CarrotEnoteType::CHANGE, true);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_external_ss_main2main_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, false, false, CarrotEnoteType::PAYMENT, false);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, false, false, CarrotEnoteType::CHANGE, false);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_external_ss_main2sub_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, true, false, CarrotEnoteType::PAYMENT, false);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, true, false, CarrotEnoteType::CHANGE, false);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_external_ss_main2integ_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, false, true, CarrotEnoteType::PAYMENT, false);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(false, false, true, CarrotEnoteType::CHANGE, false);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_external_ss_sub2main_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, false, false, CarrotEnoteType::PAYMENT, false);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, false, false, CarrotEnoteType::CHANGE, false);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_external_ss_sub2sub_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, true, false, CarrotEnoteType::PAYMENT, false);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, true, false, CarrotEnoteType::CHANGE, false);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(carrot_core, get_enote_output_proposals_external_ss_sub2integ_completeness)
|
||||
{
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, false, true, CarrotEnoteType::PAYMENT, false);
|
||||
subtest_2out_transfer_get_output_enote_proposals_completeness(true, false, true, CarrotEnoteType::CHANGE, false);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user