carrot_impl: fix 2-out selfsend sweep carving
This commit is contained in:
@@ -372,8 +372,6 @@ TEST(wallet_tx_builder, make_carrot_transaction_proposals_wallet2_sweep_4)
|
||||
ASSERT_LE(tx_proposal.key_images_sorted.size(), FCMP_PLUS_PLUS_MAX_INPUTS);
|
||||
ASSERT_EQ(1, tx_proposal.normal_payment_proposals.size());
|
||||
ASSERT_EQ(1, tx_proposal.selfsend_payment_proposals.size());
|
||||
ASSERT_EQ(1, tx_proposal.normal_payment_proposals.size());
|
||||
ASSERT_EQ(1, tx_proposal.selfsend_payment_proposals.size());
|
||||
ASSERT_EQ(0, tx_proposal.selfsend_payment_proposals.at(0).proposal.amount);
|
||||
EXPECT_EQ(0, tx_proposal.extra.size());
|
||||
|
||||
@@ -396,6 +394,89 @@ TEST(wallet_tx_builder, make_carrot_transaction_proposals_wallet2_sweep_4)
|
||||
EXPECT_EQ(n_dests, n_actual_dests);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(wallet_tx_builder, make_carrot_transaction_proposals_wallet2_sweep_5)
|
||||
{
|
||||
// output-limited sweep to self
|
||||
|
||||
cryptonote::account_base alice;
|
||||
alice.generate();
|
||||
|
||||
// generate transfers list
|
||||
static constexpr size_t n_transfers = 71;
|
||||
tools::wallet2::transfer_container transfers;
|
||||
transfers.reserve(n_transfers);
|
||||
for (size_t i = 0; i < n_transfers; ++i)
|
||||
transfers.push_back(gen_transfer_details());
|
||||
|
||||
// generate random indices into transfer list
|
||||
static constexpr size_t n_selected_transfers = FCMP_PLUS_PLUS_MAX_INPUTS * 8;
|
||||
static_assert(n_selected_transfers < n_transfers);
|
||||
std::set<size_t> selected_transfer_indices;
|
||||
while (selected_transfer_indices.size() < n_selected_transfers)
|
||||
selected_transfer_indices.insert(crypto::rand_idx(n_transfers));
|
||||
|
||||
// generate map of amounts by key image, key image vector, and height of chain
|
||||
std::vector<crypto::key_image> selected_key_images;
|
||||
std::unordered_map<crypto::key_image, rct::xmr_amount> amounts_by_ki;
|
||||
uint64_t top_block_index = 0;
|
||||
for (const size_t selected_transfer_index : selected_transfer_indices)
|
||||
{
|
||||
const tools::wallet2::transfer_details &td = transfers.at(selected_transfer_index);
|
||||
selected_key_images.push_back(td.m_key_image);
|
||||
amounts_by_ki.emplace(td.m_key_image, td.amount());
|
||||
top_block_index = std::max(top_block_index, td.m_block_height);
|
||||
}
|
||||
top_block_index += CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE;
|
||||
|
||||
ASSERT_EQ(n_selected_transfers, selected_key_images.size());
|
||||
ASSERT_EQ(n_selected_transfers, amounts_by_ki.size());
|
||||
|
||||
const size_t n_dests = 8;
|
||||
|
||||
// make tx proposals
|
||||
const std::vector<carrot::CarrotTransactionProposalV1> tx_proposals = tools::wallet::make_carrot_transaction_proposals_wallet2_sweep(
|
||||
transfers,
|
||||
/*subaddress_map=*/{{alice.get_keys().m_account_address.m_spend_public_key, {}}},
|
||||
selected_key_images,
|
||||
alice.get_keys().m_account_address,
|
||||
/*is_subaddress=*/false,
|
||||
/*n_dests=*/n_dests,
|
||||
/*fee_per_weight=*/1,
|
||||
/*extra=*/{},
|
||||
top_block_index,
|
||||
alice.get_keys());
|
||||
ASSERT_EQ(8, tx_proposals.size());
|
||||
|
||||
std::set<crypto::key_image> actual_seen_kis;
|
||||
size_t n_actual_inputs = 0;
|
||||
size_t n_actual_dests = 0;
|
||||
for (const carrot::CarrotTransactionProposalV1 &tx_proposal : tx_proposals)
|
||||
{
|
||||
ASSERT_LE(tx_proposal.key_images_sorted.size(), FCMP_PLUS_PLUS_MAX_INPUTS);
|
||||
ASSERT_EQ(1, tx_proposal.normal_payment_proposals.size());
|
||||
ASSERT_EQ(1, tx_proposal.selfsend_payment_proposals.size());
|
||||
ASSERT_EQ(0, tx_proposal.normal_payment_proposals.at(0).amount);
|
||||
EXPECT_EQ(0, tx_proposal.extra.size());
|
||||
|
||||
rct::xmr_amount tx_inputs_amount = 0;
|
||||
for (const crypto::key_image &ki : tx_proposal.key_images_sorted)
|
||||
{
|
||||
ASSERT_TRUE(amounts_by_ki.count(ki));
|
||||
ASSERT_FALSE(actual_seen_kis.count(ki));
|
||||
actual_seen_kis.insert(ki);
|
||||
tx_inputs_amount += amounts_by_ki.at(ki);
|
||||
}
|
||||
const rct::xmr_amount tx_outputs_amount = tx_proposal.fee + tx_proposal.selfsend_payment_proposals.at(0).proposal.amount;
|
||||
ASSERT_EQ(tx_inputs_amount, tx_outputs_amount);
|
||||
|
||||
n_actual_inputs += tx_proposal.key_images_sorted.size();
|
||||
n_actual_dests += tx_proposal.selfsend_payment_proposals.size();
|
||||
}
|
||||
|
||||
EXPECT_EQ(n_selected_transfers, n_actual_inputs);
|
||||
EXPECT_EQ(n_dests, n_actual_dests);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
TEST(wallet_tx_builder, wallet2_scan_propose_sign_prove_member_and_scan_1)
|
||||
{
|
||||
// 1. create fake blockchain
|
||||
|
||||
Reference in New Issue
Block a user