wallet2: speed up transactions using remote nodes
Asking for a full histogram from a remote node (since it's untrusted) is pretty slow, and spams the remote node, so we replace it by only adding a second input if we have rct ones, which are for all intents and purposes always mixable.
This commit is contained in:
parent
73e8510717
commit
c1e9ccc794
2 changed files with 42 additions and 4 deletions
|
@ -4120,7 +4120,7 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money) co
|
||||||
return picks;
|
return picks;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool should_pick_a_second_output(bool use_rct, size_t n_transfers, const std::vector<size_t> &unused_transfers_indices, const std::vector<size_t> &unused_dust_indices)
|
bool wallet2::should_pick_a_second_output(bool use_rct, size_t n_transfers, const std::vector<size_t> &unused_transfers_indices, const std::vector<size_t> &unused_dust_indices) const
|
||||||
{
|
{
|
||||||
if (!use_rct)
|
if (!use_rct)
|
||||||
return false;
|
return false;
|
||||||
|
@ -4128,9 +4128,43 @@ static bool should_pick_a_second_output(bool use_rct, size_t n_transfers, const
|
||||||
return false;
|
return false;
|
||||||
if (unused_dust_indices.empty() && unused_transfers_indices.empty())
|
if (unused_dust_indices.empty() && unused_transfers_indices.empty())
|
||||||
return false;
|
return false;
|
||||||
|
// we want at least one free rct output to avoid a corner case where
|
||||||
|
// we'd choose a non rct output which doesn't have enough "siblings"
|
||||||
|
// value-wise on the chain, and thus can't be mixed
|
||||||
|
bool found = false;
|
||||||
|
for (auto i: unused_dust_indices)
|
||||||
|
{
|
||||||
|
if (m_transfers[i].is_rct())
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) for (auto i: unused_transfers_indices)
|
||||||
|
{
|
||||||
|
if (m_transfers[i].is_rct())
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<size_t> wallet2::get_only_rct(const std::vector<size_t> &unused_dust_indices, const std::vector<size_t> &unused_transfers_indices) const
|
||||||
|
{
|
||||||
|
std::vector<size_t> indices;
|
||||||
|
for (size_t n: unused_dust_indices)
|
||||||
|
if (m_transfers[n].is_rct())
|
||||||
|
indices.push_back(n);
|
||||||
|
for (size_t n: unused_transfers_indices)
|
||||||
|
if (m_transfers[n].is_rct())
|
||||||
|
indices.push_back(n);
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
// Another implementation of transaction creation that is hopefully better
|
// Another implementation of transaction creation that is hopefully better
|
||||||
// While there is anything left to pay, it goes through random outputs and tries
|
// While there is anything left to pay, it goes through random outputs and tries
|
||||||
// to fill the next destination/amount. If it fully fills it, it will use the
|
// to fill the next destination/amount. If it fully fills it, it will use the
|
||||||
|
@ -4195,8 +4229,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||||
THROW_WALLET_EXCEPTION_IF(needed_money == 0, error::zero_destination);
|
THROW_WALLET_EXCEPTION_IF(needed_money == 0, error::zero_destination);
|
||||||
|
|
||||||
// gather all our dust and non dust outputs
|
// gather all our dust and non dust outputs
|
||||||
const std::vector<size_t> unused_indices = select_available_outputs_from_histogram(fake_outs_count + 1, true, true, true, trusted_daemon);
|
for (size_t i = 0; i < m_transfers.size(); ++i)
|
||||||
for (size_t i: unused_indices)
|
|
||||||
{
|
{
|
||||||
const transfer_details& td = m_transfers[i];
|
const transfer_details& td = m_transfers[i];
|
||||||
if (!td.m_spent && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td))
|
if (!td.m_spent && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td))
|
||||||
|
@ -4279,7 +4312,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||||
size_t idx;
|
size_t idx;
|
||||||
if ((dsts.empty() || dsts[0].amount == 0) && !adding_fee) {
|
if ((dsts.empty() || dsts[0].amount == 0) && !adding_fee) {
|
||||||
// the "make rct txes 2/2" case - we pick a small value output to "clean up" the wallet too
|
// the "make rct txes 2/2" case - we pick a small value output to "clean up" the wallet too
|
||||||
idx = pop_best_value(unused_dust_indices.empty() ? unused_transfers_indices : unused_dust_indices, tx.selected_transfers, true);
|
std::vector<size_t> indices = get_only_rct(unused_dust_indices, unused_transfers_indices);
|
||||||
|
idx = pop_best_value(indices, tx.selected_transfers, true);
|
||||||
|
|
||||||
// since we're trying to add a second output which is not strictly needed,
|
// since we're trying to add a second output which is not strictly needed,
|
||||||
// we only add it if it's unrelated enough to the first one
|
// we only add it if it's unrelated enough to the first one
|
||||||
|
@ -4289,6 +4323,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||||
LOG_PRINT_L2("Second outout was not strictly needed, and relatedness " << relatedness << ", not adding");
|
LOG_PRINT_L2("Second outout was not strictly needed, and relatedness " << relatedness << ", not adding");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
pop_if_present(unused_transfers_indices, idx);
|
||||||
|
pop_if_present(unused_dust_indices, idx);
|
||||||
} else if (!prefered_inputs.empty()) {
|
} else if (!prefered_inputs.empty()) {
|
||||||
idx = pop_back(prefered_inputs);
|
idx = pop_back(prefered_inputs);
|
||||||
pop_if_present(unused_transfers_indices, idx);
|
pop_if_present(unused_transfers_indices, idx);
|
||||||
|
|
|
@ -633,6 +633,8 @@ namespace tools
|
||||||
void get_outs(std::vector<std::vector<get_outs_entry>> &outs, const std::list<size_t> &selected_transfers, size_t fake_outputs_count);
|
void get_outs(std::vector<std::vector<get_outs_entry>> &outs, const std::list<size_t> &selected_transfers, size_t fake_outputs_count);
|
||||||
bool wallet_generate_key_image_helper(const cryptonote::account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, cryptonote::keypair& in_ephemeral, crypto::key_image& ki);
|
bool wallet_generate_key_image_helper(const cryptonote::account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, cryptonote::keypair& in_ephemeral, crypto::key_image& ki);
|
||||||
crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const;
|
crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const;
|
||||||
|
bool should_pick_a_second_output(bool use_rct, size_t n_transfers, const std::vector<size_t> &unused_transfers_indices, const std::vector<size_t> &unused_dust_indices) const;
|
||||||
|
std::vector<size_t> get_only_rct(const std::vector<size_t> &unused_dust_indices, const std::vector<size_t> &unused_transfers_indices) const;
|
||||||
|
|
||||||
cryptonote::account_base m_account;
|
cryptonote::account_base m_account;
|
||||||
boost::optional<epee::net_utils::http::login> m_daemon_login;
|
boost::optional<epee::net_utils::http::login> m_daemon_login;
|
||||||
|
|
Loading…
Reference in a new issue