integrate bulletproofs into monero
This commit is contained in:
+25
-12
@@ -456,7 +456,7 @@ void drop_from_short_history(std::list<crypto::hash> &short_chain_history, size_
|
||||
}
|
||||
}
|
||||
|
||||
size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs, size_t extra_size)
|
||||
size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof)
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
@@ -480,7 +480,10 @@ size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs, size_t extra
|
||||
size += 1;
|
||||
|
||||
// rangeSigs
|
||||
size += (2*64*32+32+64*32) * n_outputs;
|
||||
if (bulletproof)
|
||||
size += ((2*6 + 4 + 5)*32 + 3) * n_outputs;
|
||||
else
|
||||
size += (2*64*32+32+64*32) * n_outputs;
|
||||
|
||||
// MGs
|
||||
size += n_inputs * (64 * (mixin+1) + 32);
|
||||
@@ -501,14 +504,22 @@ size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs, size_t extra
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t estimate_tx_size(bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size)
|
||||
size_t estimate_tx_size(bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof)
|
||||
{
|
||||
if (use_rct)
|
||||
return estimate_rct_tx_size(n_inputs, mixin, n_outputs + 1, extra_size);
|
||||
return estimate_rct_tx_size(n_inputs, mixin, n_outputs + 1, extra_size, bulletproof);
|
||||
else
|
||||
return n_inputs * (mixin+1) * APPROXIMATE_INPUT_BYTES + extra_size;
|
||||
}
|
||||
|
||||
uint8_t get_bulletproof_fork(bool testnet)
|
||||
{
|
||||
if (testnet)
|
||||
return 7;
|
||||
else
|
||||
return 255; // TODO
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
namespace tools
|
||||
@@ -4066,7 +4077,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
|
||||
pending_tx ptx;
|
||||
|
||||
// loop until fee is met without increasing tx size to next KB boundary.
|
||||
const size_t estimated_tx_size = estimate_tx_size(false, unused_transfers_indices.size(), fake_outs_count, dst_vector.size(), extra.size());
|
||||
const size_t estimated_tx_size = estimate_tx_size(false, unused_transfers_indices.size(), fake_outs_count, dst_vector.size(), extra.size(), false);
|
||||
uint64_t needed_fee = calculate_fee(fee_per_kb, estimated_tx_size, fee_multiplier);
|
||||
do
|
||||
{
|
||||
@@ -5432,6 +5443,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
uint64_t needed_fee, available_for_fee = 0;
|
||||
uint64_t upper_transaction_size_limit = get_upper_transaction_size_limit();
|
||||
const bool use_rct = use_fork_rules(4, 0);
|
||||
const bool bulletproof = use_fork_rules(get_bulletproof_fork(m_testnet), 0);
|
||||
|
||||
const uint64_t fee_per_kb = get_per_kb_fee();
|
||||
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
|
||||
@@ -5567,7 +5579,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
{
|
||||
// this is used to build a tx that's 1 or 2 inputs, and 2 outputs, which
|
||||
// will get us a known fee.
|
||||
uint64_t estimated_fee = calculate_fee(fee_per_kb, estimate_rct_tx_size(2, fake_outs_count, 2, extra.size()), fee_multiplier);
|
||||
uint64_t estimated_fee = calculate_fee(fee_per_kb, estimate_rct_tx_size(2, fake_outs_count, 2, extra.size(), bulletproof), fee_multiplier);
|
||||
preferred_inputs = pick_preferred_rct_inputs(needed_money + estimated_fee, subaddr_account, subaddr_indices);
|
||||
if (!preferred_inputs.empty())
|
||||
{
|
||||
@@ -5670,7 +5682,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!dsts.empty() && dsts[0].amount <= available_amount && estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size(), extra.size()) < TX_SIZE_TARGET(upper_transaction_size_limit))
|
||||
while (!dsts.empty() && dsts[0].amount <= available_amount && estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size(), extra.size(), bulletproof) < TX_SIZE_TARGET(upper_transaction_size_limit))
|
||||
{
|
||||
// we can fully pay that destination
|
||||
LOG_PRINT_L2("We can fully pay " << get_account_address_as_str(m_testnet, dsts[0].is_subaddress, dsts[0].addr) <<
|
||||
@@ -5682,7 +5694,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
++original_output_index;
|
||||
}
|
||||
|
||||
if (available_amount > 0 && !dsts.empty() && estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size(), extra.size()) < TX_SIZE_TARGET(upper_transaction_size_limit)) {
|
||||
if (available_amount > 0 && !dsts.empty() && estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size(), extra.size(), bulletproof) < TX_SIZE_TARGET(upper_transaction_size_limit)) {
|
||||
// we can partially fill that destination
|
||||
LOG_PRINT_L2("We can partially pay " << get_account_address_as_str(m_testnet, dsts[0].is_subaddress, dsts[0].addr) <<
|
||||
" for " << print_money(available_amount) << "/" << print_money(dsts[0].amount));
|
||||
@@ -5706,7 +5718,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t estimated_rct_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size(), extra.size());
|
||||
const size_t estimated_rct_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size(), extra.size(), bulletproof);
|
||||
try_tx = dsts.empty() || (estimated_rct_tx_size >= TX_SIZE_TARGET(upper_transaction_size_limit));
|
||||
}
|
||||
}
|
||||
@@ -5715,7 +5727,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
cryptonote::transaction test_tx;
|
||||
pending_tx test_ptx;
|
||||
|
||||
const size_t estimated_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size(), extra.size());
|
||||
const size_t estimated_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size(), extra.size(), bulletproof);
|
||||
needed_fee = calculate_fee(fee_per_kb, estimated_tx_size, fee_multiplier);
|
||||
|
||||
LOG_PRINT_L2("Trying to create a tx now, with " << tx.dsts.size() << " outputs and " <<
|
||||
@@ -5917,6 +5929,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
||||
std::vector<std::vector<get_outs_entry>> outs;
|
||||
|
||||
const bool use_rct = fake_outs_count > 0 && use_fork_rules(4, 0);
|
||||
const bool bulletproof = use_fork_rules(get_bulletproof_fork(m_testnet), 0);
|
||||
const uint64_t fee_per_kb = get_per_kb_fee();
|
||||
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
|
||||
|
||||
@@ -5955,14 +5968,14 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
||||
// here, check if we need to sent tx and start a new one
|
||||
LOG_PRINT_L2("Considering whether to create a tx now, " << tx.selected_transfers.size() << " inputs, tx limit "
|
||||
<< upper_transaction_size_limit);
|
||||
const size_t estimated_rct_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size() + 1, extra.size());
|
||||
const size_t estimated_rct_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size() + 1, extra.size(), bulletproof);
|
||||
bool try_tx = (unused_dust_indices.empty() && unused_transfers_indices.empty()) || ( estimated_rct_tx_size >= TX_SIZE_TARGET(upper_transaction_size_limit));
|
||||
|
||||
if (try_tx) {
|
||||
cryptonote::transaction test_tx;
|
||||
pending_tx test_ptx;
|
||||
|
||||
const size_t estimated_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size(), extra.size());
|
||||
const size_t estimated_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size(), extra.size(), bulletproof);
|
||||
needed_fee = calculate_fee(fee_per_kb, estimated_tx_size, fee_multiplier);
|
||||
|
||||
tx.dsts.push_back(tx_destination_entry(1, address, is_subaddress));
|
||||
|
||||
Reference in New Issue
Block a user