mirror of
https://github.com/monero-project/monero.git
synced 2024-12-14 20:36:31 +02:00
Merge pull request #783
48d0747
wallet: better output selection for transfer/transfer_new (moneromooo-monero)
This commit is contained in:
commit
6bfb8799c3
@ -2133,9 +2133,9 @@ bool simple_wallet::transfer_main(bool new_algorithm, const std::vector<std::str
|
|||||||
// figure out what tx will be necessary
|
// figure out what tx will be necessary
|
||||||
std::vector<tools::wallet2::pending_tx> ptx_vector;
|
std::vector<tools::wallet2::pending_tx> ptx_vector;
|
||||||
if (new_algorithm)
|
if (new_algorithm)
|
||||||
ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra);
|
ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon);
|
||||||
else
|
else
|
||||||
ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra);
|
ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon);
|
||||||
|
|
||||||
// if more than one tx necessary, prompt user to confirm
|
// if more than one tx necessary, prompt user to confirm
|
||||||
if (m_wallet->always_confirm_transfers() || ptx_vector.size() > 1)
|
if (m_wallet->always_confirm_transfers() || ptx_vector.size() > 1)
|
||||||
|
@ -1749,47 +1749,12 @@ namespace
|
|||||||
// returns:
|
// returns:
|
||||||
// direct return: amount of money found
|
// direct return: amount of money found
|
||||||
// modified reference: selected_transfers, a list of iterators/indices of input sources
|
// modified reference: selected_transfers, a list of iterators/indices of input sources
|
||||||
uint64_t wallet2::select_transfers(uint64_t needed_money, bool add_dust, uint64_t dust, bool hf2_rules, std::list<transfer_container::iterator>& selected_transfers)
|
uint64_t wallet2::select_transfers(uint64_t needed_money, std::vector<size_t> unused_transfers_indices, std::list<transfer_container::iterator>& selected_transfers, bool trusted_daemon)
|
||||||
{
|
{
|
||||||
std::vector<size_t> unused_transfers_indices;
|
|
||||||
std::vector<size_t> unused_dust_indices;
|
|
||||||
|
|
||||||
// aggregate sources available for transfers
|
|
||||||
// if dust needed, take dust from only one source (so require source has at least dust amount)
|
|
||||||
for (size_t i = 0; i < m_transfers.size(); ++i)
|
|
||||||
{
|
|
||||||
const transfer_details& td = m_transfers[i];
|
|
||||||
if (!td.m_spent && is_transfer_unlocked(td))
|
|
||||||
{
|
|
||||||
if (dust < td.amount() && is_valid_decomposed_amount(td.amount()))
|
|
||||||
unused_transfers_indices.push_back(i);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// for hf2 rules, we disregard dust, which will be spendable only
|
|
||||||
// via sweep_dust. If we're asked to add dust, though, we still
|
|
||||||
// consider them, as this will be a mixin 0 tx (and thus we may
|
|
||||||
// end up with a tx with one mixable output and N dusty ones).
|
|
||||||
// This should be made better at some point...
|
|
||||||
if (!hf2_rules || add_dust)
|
|
||||||
unused_dust_indices.push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool select_one_dust = add_dust && !unused_dust_indices.empty();
|
|
||||||
uint64_t found_money = 0;
|
uint64_t found_money = 0;
|
||||||
while (found_money < needed_money && (!unused_transfers_indices.empty() || !unused_dust_indices.empty()))
|
while (found_money < needed_money && !unused_transfers_indices.empty())
|
||||||
{
|
{
|
||||||
size_t idx;
|
size_t idx = pop_random_value(unused_transfers_indices);
|
||||||
if (select_one_dust)
|
|
||||||
{
|
|
||||||
idx = pop_random_value(unused_dust_indices);
|
|
||||||
select_one_dust = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
idx = !unused_transfers_indices.empty() ? pop_random_value(unused_transfers_indices) : pop_random_value(unused_dust_indices);
|
|
||||||
}
|
|
||||||
|
|
||||||
transfer_container::iterator it = m_transfers.begin() + idx;
|
transfer_container::iterator it = m_transfers.begin() + idx;
|
||||||
selected_transfers.push_back(it);
|
selected_transfers.push_back(it);
|
||||||
@ -1811,18 +1776,18 @@ void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, const std::v
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count,
|
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outs_count, const std::vector<size_t> &unused_transfers_indices,
|
||||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx& ptx)
|
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx& ptx, bool trusted_daemon)
|
||||||
{
|
{
|
||||||
transfer(dsts, fake_outputs_count, unlock_time, fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), tx, ptx);
|
transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), tx, ptx, trusted_daemon);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count,
|
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outs_count, const std::vector<size_t> &unused_transfers_indices,
|
||||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra)
|
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, bool trusted_daemon)
|
||||||
{
|
{
|
||||||
cryptonote::transaction tx;
|
cryptonote::transaction tx;
|
||||||
pending_tx ptx;
|
pending_tx ptx;
|
||||||
transfer(dsts, fake_outputs_count, unlock_time, fee, extra, tx, ptx);
|
transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, tx, ptx, trusted_daemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -2020,8 +1985,9 @@ void wallet2::commit_tx(std::vector<pending_tx>& ptx_vector)
|
|||||||
//
|
//
|
||||||
// this function will make multiple calls to wallet2::transfer if multiple
|
// this function will make multiple calls to wallet2::transfer if multiple
|
||||||
// transactions will be required
|
// transactions will be required
|
||||||
std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee_UNUSED, const std::vector<uint8_t> extra)
|
std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee_UNUSED, const std::vector<uint8_t> extra, bool trusted_daemon)
|
||||||
{
|
{
|
||||||
|
const std::vector<size_t> unused_transfers_indices = select_available_outputs_from_histogram(fake_outs_count + 1, true, trusted_daemon);
|
||||||
|
|
||||||
// failsafe split attempt counter
|
// failsafe split attempt counter
|
||||||
size_t attempt_count = 0;
|
size_t attempt_count = 0;
|
||||||
@ -2051,7 +2017,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
|
|||||||
uint64_t needed_fee = 0;
|
uint64_t needed_fee = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
transfer(dst_vector, fake_outs_count, unlock_time, needed_fee, extra, tx, ptx);
|
transfer(dst_vector, fake_outs_count, unused_transfers_indices, unlock_time, needed_fee, extra, tx, ptx, trusted_daemon);
|
||||||
auto txBlob = t_serializable_object_to_blob(ptx.tx);
|
auto txBlob = t_serializable_object_to_blob(ptx.tx);
|
||||||
needed_fee = calculate_fee(txBlob);
|
needed_fee = calculate_fee(txBlob);
|
||||||
} while (ptx.fee < needed_fee);
|
} while (ptx.fee < needed_fee);
|
||||||
@ -2284,7 +2250,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
|
|||||||
// This system allows for sending (almost) the entire balance, since it does
|
// This system allows for sending (almost) the entire balance, since it does
|
||||||
// not generate spurious change in all txes, thus decreasing the instantaneous
|
// not generate spurious change in all txes, thus decreasing the instantaneous
|
||||||
// usable balance.
|
// usable balance.
|
||||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee_UNUSED, const std::vector<uint8_t> extra)
|
std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee_UNUSED, const std::vector<uint8_t> extra, bool trusted_daemon)
|
||||||
{
|
{
|
||||||
std::vector<size_t> unused_transfers_indices;
|
std::vector<size_t> unused_transfers_indices;
|
||||||
std::vector<size_t> unused_dust_indices;
|
std::vector<size_t> unused_dust_indices;
|
||||||
@ -2704,9 +2670,8 @@ std::vector<uint64_t> wallet2::get_unspent_amounts_vector()
|
|||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
std::vector<size_t> wallet2::select_available_unmixable_outputs(bool trusted_daemon)
|
std::vector<size_t> wallet2::select_available_outputs_from_histogram(uint64_t count, bool atleast, bool trusted_daemon)
|
||||||
{
|
{
|
||||||
// request all outputs with at least 3 instances, so we can use mixin 2 with
|
|
||||||
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request> req_t = AUTO_VAL_INIT(req_t);
|
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request> req_t = AUTO_VAL_INIT(req_t);
|
||||||
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response, std::string> resp_t = AUTO_VAL_INIT(resp_t);
|
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response, std::string> resp_t = AUTO_VAL_INIT(resp_t);
|
||||||
m_daemon_rpc_mutex.lock();
|
m_daemon_rpc_mutex.lock();
|
||||||
@ -2715,7 +2680,7 @@ std::vector<size_t> wallet2::select_available_unmixable_outputs(bool trusted_dae
|
|||||||
req_t.method = "get_output_histogram";
|
req_t.method = "get_output_histogram";
|
||||||
if (trusted_daemon)
|
if (trusted_daemon)
|
||||||
req_t.params.amounts = get_unspent_amounts_vector();
|
req_t.params.amounts = get_unspent_amounts_vector();
|
||||||
req_t.params.min_count = 3;
|
req_t.params.min_count = count;
|
||||||
req_t.params.max_count = 0;
|
req_t.params.max_count = 0;
|
||||||
bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
|
bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
|
||||||
m_daemon_rpc_mutex.unlock();
|
m_daemon_rpc_mutex.unlock();
|
||||||
@ -2729,14 +2694,32 @@ std::vector<size_t> wallet2::select_available_unmixable_outputs(bool trusted_dae
|
|||||||
mixable.insert(i.amount);
|
mixable.insert(i.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return select_available_outputs([mixable](const transfer_details &td) {
|
return select_available_outputs([mixable, atleast](const transfer_details &td) {
|
||||||
const uint64_t amount = td.amount();
|
const uint64_t amount = td.amount();
|
||||||
|
if (atleast) {
|
||||||
|
if (mixable.find(amount) != mixable.end())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
if (mixable.find(amount) == mixable.end())
|
if (mixable.find(amount) == mixable.end())
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
std::vector<size_t> wallet2::select_available_unmixable_outputs(bool trusted_daemon)
|
||||||
|
{
|
||||||
|
// request all outputs with less than 3 instances
|
||||||
|
return select_available_outputs_from_histogram(3, false, trusted_daemon);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
std::vector<size_t> wallet2::select_available_mixable_outputs(bool trusted_daemon)
|
||||||
|
{
|
||||||
|
// request all outputs with at least 3 instances, so we can use mixin 2 with
|
||||||
|
return select_available_outputs_from_histogram(3, true, trusted_daemon);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bool trusted_daemon)
|
std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bool trusted_daemon)
|
||||||
{
|
{
|
||||||
// From hard fork 1, we don't consider small amounts to be dust anymore
|
// From hard fork 1, we don't consider small amounts to be dust anymore
|
||||||
|
@ -274,11 +274,11 @@ namespace tools
|
|||||||
uint64_t unlocked_balance() const;
|
uint64_t unlocked_balance() const;
|
||||||
uint64_t unlocked_dust_balance(const tx_dust_policy &dust_policy) const;
|
uint64_t unlocked_dust_balance(const tx_dust_policy &dust_policy) const;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy);
|
void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, bool trusted_daemon);
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx& ptx);
|
void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx& ptx, bool trusted_daemon);
|
||||||
void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra);
|
void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, bool trusted_daemon);
|
||||||
void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx& ptx);
|
void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx& ptx, bool trusted_daemon);
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void transfer_from(const std::vector<size_t> &outs, size_t num_outputs, uint64_t unlock_time, uint64_t needed_fee, T destination_split_strategy, const tx_dust_policy& dust_policy, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx);
|
void transfer_from(const std::vector<size_t> &outs, size_t num_outputs, uint64_t unlock_time, uint64_t needed_fee, T destination_split_strategy, const tx_dust_policy& dust_policy, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx);
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -287,8 +287,8 @@ namespace tools
|
|||||||
|
|
||||||
void commit_tx(pending_tx& ptx_vector);
|
void commit_tx(pending_tx& ptx_vector);
|
||||||
void commit_tx(std::vector<pending_tx>& ptx_vector);
|
void commit_tx(std::vector<pending_tx>& ptx_vector);
|
||||||
std::vector<pending_tx> create_transactions(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee, const std::vector<uint8_t> extra);
|
std::vector<pending_tx> create_transactions(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee, const std::vector<uint8_t> extra, bool trusted_daemon);
|
||||||
std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee_UNUSED, const std::vector<uint8_t> extra);
|
std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee_UNUSED, const std::vector<uint8_t> extra, bool trusted_daemon);
|
||||||
std::vector<pending_tx> create_unmixable_sweep_transactions(bool trusted_daemon);
|
std::vector<pending_tx> create_unmixable_sweep_transactions(bool trusted_daemon);
|
||||||
bool check_connection();
|
bool check_connection();
|
||||||
void get_transfers(wallet2::transfer_container& incoming_transfers) const;
|
void get_transfers(wallet2::transfer_container& incoming_transfers) const;
|
||||||
@ -389,7 +389,7 @@ namespace tools
|
|||||||
void pull_blocks(uint64_t start_height, uint64_t& blocks_start_height, const std::list<crypto::hash> &short_chain_history, std::list<cryptonote::block_complete_entry> &blocks);
|
void pull_blocks(uint64_t start_height, uint64_t& blocks_start_height, const std::list<crypto::hash> &short_chain_history, std::list<cryptonote::block_complete_entry> &blocks);
|
||||||
void pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, const std::list<cryptonote::block_complete_entry> &prev_blocks, std::list<cryptonote::block_complete_entry> &blocks, bool &error);
|
void pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, const std::list<cryptonote::block_complete_entry> &prev_blocks, std::list<cryptonote::block_complete_entry> &blocks, bool &error);
|
||||||
void process_blocks(uint64_t start_height, const std::list<cryptonote::block_complete_entry> &blocks, uint64_t& blocks_added);
|
void process_blocks(uint64_t start_height, const std::list<cryptonote::block_complete_entry> &blocks, uint64_t& blocks_added);
|
||||||
uint64_t select_transfers(uint64_t needed_money, bool add_dust, uint64_t dust, bool hf2_rules, std::list<transfer_container::iterator>& selected_transfers);
|
uint64_t select_transfers(uint64_t needed_money, std::vector<size_t> unused_transfers_indices, std::list<transfer_container::iterator>& selected_transfers, bool trusted_daemon);
|
||||||
bool prepare_file_names(const std::string& file_path);
|
bool prepare_file_names(const std::string& file_path);
|
||||||
void process_unconfirmed(const cryptonote::transaction& tx, uint64_t height);
|
void process_unconfirmed(const cryptonote::transaction& tx, uint64_t height);
|
||||||
void process_outgoing(const cryptonote::transaction& tx, uint64_t height, uint64_t spent, uint64_t received);
|
void process_outgoing(const cryptonote::transaction& tx, uint64_t height, uint64_t spent, uint64_t received);
|
||||||
@ -403,8 +403,10 @@ namespace tools
|
|||||||
uint64_t get_upper_tranaction_size_limit();
|
uint64_t get_upper_tranaction_size_limit();
|
||||||
void check_pending_txes();
|
void check_pending_txes();
|
||||||
std::vector<uint64_t> get_unspent_amounts_vector();
|
std::vector<uint64_t> get_unspent_amounts_vector();
|
||||||
|
std::vector<size_t> select_available_outputs_from_histogram(uint64_t count, bool atleast, bool trusted_daemon);
|
||||||
std::vector<size_t> select_available_outputs(const std::function<bool(const transfer_details &td)> &f);
|
std::vector<size_t> select_available_outputs(const std::function<bool(const transfer_details &td)> &f);
|
||||||
std::vector<size_t> select_available_unmixable_outputs(bool trusted_daemon);
|
std::vector<size_t> select_available_unmixable_outputs(bool trusted_daemon);
|
||||||
|
std::vector<size_t> select_available_mixable_outputs(bool trusted_daemon);
|
||||||
|
|
||||||
cryptonote::account_base m_account;
|
cryptonote::account_base m_account;
|
||||||
std::string m_daemon_address;
|
std::string m_daemon_address;
|
||||||
@ -562,17 +564,17 @@ namespace tools
|
|||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count,
|
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outs_count, const std::vector<size_t> &unused_transfers_indices,
|
||||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy)
|
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, bool trusted_daemon)
|
||||||
{
|
{
|
||||||
pending_tx ptx;
|
pending_tx ptx;
|
||||||
cryptonote::transaction tx;
|
cryptonote::transaction tx;
|
||||||
transfer(dsts, fake_outputs_count, unlock_time, fee, extra, destination_split_strategy, dust_policy, tx, ptx);
|
transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, destination_split_strategy, dust_policy, tx, ptx, trusted_daemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count,
|
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices,
|
||||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx)
|
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx, bool trusted_daemon)
|
||||||
{
|
{
|
||||||
using namespace cryptonote;
|
using namespace cryptonote;
|
||||||
// throw if attempting a transaction with no destinations
|
// throw if attempting a transaction with no destinations
|
||||||
@ -593,9 +595,7 @@ namespace tools
|
|||||||
// randomly select inputs for transaction
|
// randomly select inputs for transaction
|
||||||
// throw if requested send amount is greater than amount available to send
|
// throw if requested send amount is greater than amount available to send
|
||||||
std::list<transfer_container::iterator> selected_transfers;
|
std::list<transfer_container::iterator> selected_transfers;
|
||||||
bool hf2_rules = use_fork_rules(2); // first fork has version 2
|
uint64_t found_money = select_transfers(needed_money, unused_transfers_indices, selected_transfers, trusted_daemon);
|
||||||
const bool add_dust = (0 == fake_outputs_count) && hf2_rules;
|
|
||||||
uint64_t found_money = select_transfers(needed_money, add_dust, dust_policy.dust_threshold, hf2_rules, selected_transfers);
|
|
||||||
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_money, found_money, needed_money - fee, fee);
|
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_money, found_money, needed_money - fee, fee);
|
||||||
|
|
||||||
typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry;
|
typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry;
|
||||||
|
@ -232,7 +232,7 @@ namespace tools
|
|||||||
LOG_PRINT_L1("Requested mixin " << req.mixin << " too low for hard fork 2, using 2");
|
LOG_PRINT_L1("Requested mixin " << req.mixin << " too low for hard fork 2, using 2");
|
||||||
mixin = 2;
|
mixin = 2;
|
||||||
}
|
}
|
||||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet.create_transactions(dsts, mixin, req.unlock_time, req.fee, extra);
|
std::vector<wallet2::pending_tx> ptx_vector = m_wallet.create_transactions(dsts, mixin, req.unlock_time, req.fee, extra, req.trusted_daemon);
|
||||||
|
|
||||||
// reject proposed transactions if there are more than one. see on_transfer_split below.
|
// reject proposed transactions if there are more than one. see on_transfer_split below.
|
||||||
if (ptx_vector.size() != 1)
|
if (ptx_vector.size() != 1)
|
||||||
@ -299,9 +299,9 @@ namespace tools
|
|||||||
}
|
}
|
||||||
std::vector<wallet2::pending_tx> ptx_vector;
|
std::vector<wallet2::pending_tx> ptx_vector;
|
||||||
if (req.new_algorithm)
|
if (req.new_algorithm)
|
||||||
ptx_vector = m_wallet.create_transactions_2(dsts, mixin, req.unlock_time, req.fee, extra);
|
ptx_vector = m_wallet.create_transactions_2(dsts, mixin, req.unlock_time, req.fee, extra, req.trusted_daemon);
|
||||||
else
|
else
|
||||||
ptx_vector = m_wallet.create_transactions(dsts, mixin, req.unlock_time, req.fee, extra);
|
ptx_vector = m_wallet.create_transactions(dsts, mixin, req.unlock_time, req.fee, extra, req.trusted_daemon);
|
||||||
|
|
||||||
m_wallet.commit_tx(ptx_vector);
|
m_wallet.commit_tx(ptx_vector);
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@ namespace wallet_rpc
|
|||||||
uint64_t unlock_time;
|
uint64_t unlock_time;
|
||||||
std::string payment_id;
|
std::string payment_id;
|
||||||
bool get_tx_key;
|
bool get_tx_key;
|
||||||
|
bool trusted_daemon;
|
||||||
|
|
||||||
BEGIN_KV_SERIALIZE_MAP()
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
KV_SERIALIZE(destinations)
|
KV_SERIALIZE(destinations)
|
||||||
@ -123,6 +124,7 @@ namespace wallet_rpc
|
|||||||
KV_SERIALIZE(unlock_time)
|
KV_SERIALIZE(unlock_time)
|
||||||
KV_SERIALIZE(payment_id)
|
KV_SERIALIZE(payment_id)
|
||||||
KV_SERIALIZE(get_tx_key)
|
KV_SERIALIZE(get_tx_key)
|
||||||
|
KV_SERIALIZE(trusted_daemon)
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -149,6 +151,7 @@ namespace wallet_rpc
|
|||||||
std::string payment_id;
|
std::string payment_id;
|
||||||
bool new_algorithm;
|
bool new_algorithm;
|
||||||
bool get_tx_keys;
|
bool get_tx_keys;
|
||||||
|
bool trusted_daemon;
|
||||||
|
|
||||||
BEGIN_KV_SERIALIZE_MAP()
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
KV_SERIALIZE(destinations)
|
KV_SERIALIZE(destinations)
|
||||||
@ -158,6 +161,7 @@ namespace wallet_rpc
|
|||||||
KV_SERIALIZE(payment_id)
|
KV_SERIALIZE(payment_id)
|
||||||
KV_SERIALIZE(new_algorithm)
|
KV_SERIALIZE(new_algorithm)
|
||||||
KV_SERIALIZE(get_tx_keys)
|
KV_SERIALIZE(get_tx_keys)
|
||||||
|
KV_SERIALIZE(trusted_daemon)
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ bool do_send_money(tools::wallet2& w1, tools::wallet2& w2, size_t mix_in_factor,
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
tools::wallet2::pending_tx ptx;
|
tools::wallet2::pending_tx ptx;
|
||||||
w1.transfer(dsts, mix_in_factor, 0, TEST_FEE, std::vector<uint8_t>(), tools::detail::null_split_strategy, tools::tx_dust_policy(TEST_DUST_THRESHOLD), tx, ptx);
|
w1.transfer(dsts, mix_in_factor, 0, TEST_FEE, std::vector<uint8_t>(), tools::detail::null_split_strategy, tools::tx_dust_policy(TEST_DUST_THRESHOLD), tx, ptx, true);
|
||||||
w1.commit_tx(ptx);
|
w1.commit_tx(ptx);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user