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,
|
void get_output_enote_proposals(std::vector<CarrotPaymentProposalV1> &&normal_payment_proposals,
|
||||||
std::vector<CarrotPaymentProposalSelfSendV1> &&selfsend_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,
|
const crypto::key_image &tx_first_key_image,
|
||||||
std::vector<RCTOutputEnoteProposal> &output_enote_proposals_out,
|
std::vector<RCTOutputEnoteProposal> &output_enote_proposals_out,
|
||||||
encrypted_payment_id_t &encrypted_payment_id_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;
|
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;
|
const bool ambiguous_pid_destination = num_integrated == 0 && normal_payment_proposals.size() > 1;
|
||||||
if (ambiguous_pid_destination)
|
if (ambiguous_pid_destination)
|
||||||
encrypted_payment_id_out = gen_payment_id();
|
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)
|
for (const CarrotPaymentProposalSelfSendV1 &selfsend_payment_proposal : selfsend_payment_proposals)
|
||||||
{
|
{
|
||||||
get_output_proposal_internal_v1(selfsend_payment_proposal,
|
if (s_view_balance_dev != nullptr)
|
||||||
s_view_balance_dev,
|
{
|
||||||
tx_first_key_image,
|
get_output_proposal_internal_v1(selfsend_payment_proposal,
|
||||||
tools::add_element(output_enote_proposals_out));
|
*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
|
// 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::public_key &change_address_spend_pubkey,
|
||||||
const crypto::x25519_pubkey &other_enote_ephemeral_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,
|
void get_output_enote_proposals(std::vector<CarrotPaymentProposalV1> &&normal_payment_proposals,
|
||||||
std::vector<CarrotPaymentProposalSelfSendV1> &&selfsend_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,
|
const crypto::key_image &tx_first_key_image,
|
||||||
std::vector<RCTOutputEnoteProposal> &output_enote_proposals_out,
|
std::vector<RCTOutputEnoteProposal> &output_enote_proposals_out,
|
||||||
encrypted_payment_id_t &encrypted_payment_id_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,
|
void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &proposal,
|
||||||
const view_incoming_key_device &k_view_dev,
|
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,
|
const crypto::key_image &tx_first_key_image,
|
||||||
RCTOutputEnoteProposal &output_enote_out)
|
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,
|
k_view_dev.make_janus_anchor_special(proposal.enote_ephemeral_pubkey,
|
||||||
input_context,
|
input_context,
|
||||||
output_enote_out.enote.onetime_address,
|
output_enote_out.enote.onetime_address,
|
||||||
primary_address_spend_pubkey,
|
account_spend_pubkey,
|
||||||
janus_anchor_special);
|
janus_anchor_special);
|
||||||
|
|
||||||
// 6. encrypt special anchor: anchor_enc = anchor XOR m_anchor
|
// 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)
|
* brief: get_output_proposal_v1 - convert the carrot proposal to an output proposal (external selfsend)
|
||||||
* param: proposal -
|
* param: proposal -
|
||||||
* param: k_view_dev -
|
* param: k_view_dev -
|
||||||
* param: primary_address_spend_pubkey -
|
* param: account_spend_pubkey -
|
||||||
* param: tx_first_key_image -
|
* param: tx_first_key_image -
|
||||||
* outparam: output_enote_out -
|
* outparam: output_enote_out -
|
||||||
*/
|
*/
|
||||||
void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &proposal,
|
void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &proposal,
|
||||||
const view_incoming_key_device &k_view_dev,
|
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,
|
const crypto::key_image &tx_first_key_image,
|
||||||
RCTOutputEnoteProposal &output_enote_out);
|
RCTOutputEnoteProposal &output_enote_out);
|
||||||
/**
|
/**
|
||||||
* brief: get_output_proposal_internal_v1 - convert the carrot proposal to an output proposal (internal)
|
* brief: get_output_proposal_internal_v1 - convert the carrot proposal to an output proposal (internal)
|
||||||
* param: proposal -
|
* param: proposal -
|
||||||
* param: s_view_balance_dev -
|
* param: s_view_balance_dev -
|
||||||
* param: primary_address_spend_pubkey -
|
* param: account_spend_pubkey -
|
||||||
* param: tx_first_key_image -
|
* param: tx_first_key_image -
|
||||||
* outparam: output_enote_out -
|
* outparam: output_enote_out -
|
||||||
* outparam: partial_memo_out -
|
* outparam: partial_memo_out -
|
||||||
|
@ -893,10 +893,11 @@ TEST(carrot_core, main_address_coinbase_scan_completeness)
|
|||||||
enote.onetime_address));
|
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_subaddress,
|
||||||
const bool bob_integrated,
|
const bool bob_integrated,
|
||||||
const CarrotEnoteType alice_selfsend_type)
|
const CarrotEnoteType alice_selfsend_type,
|
||||||
|
const bool alice_internal_selfsends)
|
||||||
{
|
{
|
||||||
// generate alice keys and address
|
// generate alice keys and address
|
||||||
const mock_carrot_keys alice = mock_carrot_keys::generate();
|
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;
|
encrypted_payment_id_t encrypted_payment_id;
|
||||||
get_output_enote_proposals({bob_payment_proposal},
|
get_output_enote_proposals({bob_payment_proposal},
|
||||||
{alice_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,
|
tx_first_key_image,
|
||||||
enote_proposals,
|
enote_proposals,
|
||||||
encrypted_payment_id);
|
encrypted_payment_id);
|
||||||
|
|
||||||
ASSERT_EQ(2, enote_proposals.size()); // 2-out tx
|
ASSERT_EQ(2, enote_proposals.size()); // 2-out tx
|
||||||
|
|
||||||
// collect enotes
|
// 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)
|
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_output_enote_proposals_completeness(false, false, false, CarrotEnoteType::PAYMENT, true);
|
||||||
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::CHANGE, true);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_main2sub_completeness)
|
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_output_enote_proposals_completeness(false, true, false, CarrotEnoteType::PAYMENT, true);
|
||||||
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::CHANGE, true);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_main2integ_completeness)
|
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_output_enote_proposals_completeness(false, false, true, CarrotEnoteType::PAYMENT, true);
|
||||||
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::CHANGE, true);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_sub2main_completeness)
|
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_output_enote_proposals_completeness(true, false, false, CarrotEnoteType::PAYMENT, true);
|
||||||
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::CHANGE, true);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_sub2sub_completeness)
|
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_output_enote_proposals_completeness(true, true, false, CarrotEnoteType::PAYMENT, true);
|
||||||
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::CHANGE, true);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
TEST(carrot_core, get_enote_output_proposals_internal_ss_sub2integ_completeness)
|
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_output_enote_proposals_completeness(true, false, true, CarrotEnoteType::PAYMENT, true);
|
||||||
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::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