aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r--src/wallet/wallet2.cpp81
1 files changed, 54 insertions, 27 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 96b77a7a6..5e764579c 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -140,6 +140,8 @@ namespace
struct options {
const command_line::arg_descriptor<std::string> daemon_address = {"daemon-address", tools::wallet2::tr("Use daemon instance at <host>:<port>"), ""};
const command_line::arg_descriptor<std::string> daemon_host = {"daemon-host", tools::wallet2::tr("Use daemon instance at host <arg> instead of localhost"), ""};
+ const command_line::arg_descriptor<bool> trusted_daemon = {"trusted-daemon", tools::wallet2::tr("Enable commands which rely on a trusted daemon"), false};
+ const command_line::arg_descriptor<bool> untrusted_daemon = {"untrusted-daemon", tools::wallet2::tr("Disable commands which rely on a trusted daemon"), false};
const command_line::arg_descriptor<std::string> password = {"password", tools::wallet2::tr("Wallet password (escape/quote as needed)"), "", true};
const command_line::arg_descriptor<std::string> password_file = {"password-file", tools::wallet2::tr("Wallet password file"), "", true};
const command_line::arg_descriptor<int> daemon_port = {"daemon-port", tools::wallet2::tr("Use daemon instance at port <arg> instead of 18081"), 0};
@@ -236,8 +238,29 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
if (daemon_address.empty())
daemon_address = std::string("http://") + daemon_host + ":" + std::to_string(daemon_port);
+ boost::optional<bool> trusted_daemon;
+ if (!command_line::is_arg_defaulted(vm, opts.trusted_daemon) || !command_line::is_arg_defaulted(vm, opts.untrusted_daemon))
+ trusted_daemon = command_line::get_arg(vm, opts.trusted_daemon) && !command_line::get_arg(vm, opts.untrusted_daemon);
+ THROW_WALLET_EXCEPTION_IF(!command_line::is_arg_defaulted(vm, opts.trusted_daemon) && !command_line::is_arg_defaulted(vm, opts.untrusted_daemon),
+ tools::error::wallet_internal_error, tools::wallet2::tr("--trusted-daemon and --untrusted-daemon are both seen, assuming untrusted"));
+
+ // set --trusted-daemon if local and not overridden
+ if (!trusted_daemon)
+ {
+ try
+ {
+ trusted_daemon = false;
+ if (tools::is_local_address(daemon_address))
+ {
+ MINFO(tr("Daemon is local, assuming trusted"));
+ trusted_daemon = true;
+ }
+ }
+ catch (const std::exception &e) { }
+ }
+
std::unique_ptr<tools::wallet2> wallet(new tools::wallet2(nettype, kdf_rounds));
- wallet->init(rpc, std::move(daemon_address), std::move(login));
+ wallet->init(rpc, std::move(daemon_address), std::move(login), 0, false, *trusted_daemon);
boost::filesystem::path ringdb_path = command_line::get_arg(vm, opts.shared_ringdb_dir);
wallet->set_ring_database(ringdb_path.string());
return wallet;
@@ -680,6 +703,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds):
m_multisig_rescan_k(NULL),
m_run(true),
m_callback(0),
+ m_trusted_daemon(false),
m_nettype(nettype),
m_always_confirm_transfers(true),
m_print_ring_members(false),
@@ -745,6 +769,8 @@ void wallet2::init_options(boost::program_options::options_description& desc_par
const options opts{};
command_line::add_arg(desc_params, opts.daemon_address);
command_line::add_arg(desc_params, opts.daemon_host);
+ command_line::add_arg(desc_params, opts.trusted_daemon);
+ command_line::add_arg(desc_params, opts.untrusted_daemon);
command_line::add_arg(desc_params, opts.password);
command_line::add_arg(desc_params, opts.password_file);
command_line::add_arg(desc_params, opts.daemon_port);
@@ -796,7 +822,7 @@ std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::varia
}
//----------------------------------------------------------------------------------------------------
-bool wallet2::init(bool rpc, std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, uint64_t upper_transaction_size_limit, bool ssl)
+bool wallet2::init(bool rpc, std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, uint64_t upper_transaction_size_limit, bool ssl, bool trusted_daemon)
{
m_rpc = rpc;
m_checkpoints.init_default_checkpoints(m_nettype);
@@ -806,6 +832,7 @@ bool wallet2::init(bool rpc, std::string daemon_address, boost::optional<epee::n
m_upper_transaction_size_limit = upper_transaction_size_limit;
m_daemon_address = std::move(daemon_address);
m_daemon_login = std::move(daemon_login);
+ m_trusted_daemon = trusted_daemon;
// When switching from light wallet to full wallet, we need to reset the height we got from lw node.
return m_http_client.set_server(get_daemon_address(), get_daemon_login(), ssl);
}
@@ -4901,7 +4928,7 @@ size_t wallet2::pop_best_value(std::vector<size_t> &unused_indices, const std::v
// returns:
// direct return: amount of money found
// modified reference: selected_transfers, a list of iterators/indices of input sources
-uint64_t wallet2::select_transfers(uint64_t needed_money, std::vector<size_t> unused_transfers_indices, std::vector<size_t>& selected_transfers, bool trusted_daemon) const
+uint64_t wallet2::select_transfers(uint64_t needed_money, std::vector<size_t> unused_transfers_indices, std::vector<size_t>& selected_transfers) const
{
uint64_t found_money = 0;
selected_transfers.reserve(unused_transfers_indices.size());
@@ -4945,17 +4972,17 @@ void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t amo
//----------------------------------------------------------------------------------------------------
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, bool trusted_daemon)
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_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);
+ 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);
}
//----------------------------------------------------------------------------------------------------
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, bool trusted_daemon)
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra)
{
cryptonote::transaction tx;
pending_tx ptx;
- transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, tx, ptx, trusted_daemon);
+ transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, tx, ptx);
}
namespace {
@@ -5941,9 +5968,9 @@ uint32_t wallet2::adjust_priority(uint32_t priority)
//
// this function will make multiple calls to wallet2::transfer if multiple
// 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, uint32_t priority, const std::vector<uint8_t>& extra, bool trusted_daemon)
+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, uint32_t priority, const std::vector<uint8_t>& extra)
{
- const std::vector<size_t> unused_transfers_indices = select_available_outputs_from_histogram(fake_outs_count + 1, true, true, true, trusted_daemon);
+ const std::vector<size_t> unused_transfers_indices = select_available_outputs_from_histogram(fake_outs_count + 1, true, true, true);
const uint64_t fee_per_kb = get_per_kb_fee();
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
@@ -5977,7 +6004,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
uint64_t needed_fee = calculate_fee(fee_per_kb, estimated_tx_size, fee_multiplier);
do
{
- transfer(dst_vector, fake_outs_count, unused_transfers_indices, unlock_time, needed_fee, extra, tx, ptx, trusted_daemon);
+ transfer(dst_vector, fake_outs_count, unused_transfers_indices, unlock_time, needed_fee, extra, tx, ptx);
auto txBlob = t_serializable_object_to_blob(ptx.tx);
needed_fee = calculate_fee(fee_per_kb, txBlob, fee_multiplier);
} while (ptx.fee < needed_fee);
@@ -7951,7 +7978,7 @@ bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image,
// This system allows for sending (almost) the entire balance, since it does
// not generate spurious change in all txes, thus decreasing the instantaneous
// 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, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, bool trusted_daemon)
+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, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
{
//ensure device is let in NONE mode in any case
hw::device &hwdev = m_account.get_device();
@@ -8476,7 +8503,7 @@ skip_tx:
return ptx_vector;
}
-std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, bool trusted_daemon)
+std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
{
std::vector<size_t> unused_transfers_indices;
std::vector<size_t> unused_dust_indices;
@@ -8527,10 +8554,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
}
}
- return create_transactions_from(address, is_subaddress, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra, trusted_daemon);
+ return create_transactions_from(address, is_subaddress, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra);
}
-std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, bool trusted_daemon)
+std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra)
{
std::vector<size_t> unused_transfers_indices;
std::vector<size_t> unused_dust_indices;
@@ -8548,10 +8575,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypt
break;
}
}
- return create_transactions_from(address, is_subaddress, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra, trusted_daemon);
+ return create_transactions_from(address, is_subaddress, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra);
}
-std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, bool trusted_daemon)
+std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra)
{
//ensure device is let in NONE mode in any case
hw::device &hwdev = m_account.get_device();
@@ -8785,12 +8812,12 @@ std::vector<uint64_t> wallet2::get_unspent_amounts_vector() const
return vector;
}
//----------------------------------------------------------------------------------------------------
-std::vector<size_t> wallet2::select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct, bool trusted_daemon)
+std::vector<size_t> wallet2::select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct)
{
cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request req_t = AUTO_VAL_INIT(req_t);
cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response resp_t = AUTO_VAL_INIT(resp_t);
m_daemon_rpc_mutex.lock();
- if (trusted_daemon)
+ if (is_trusted_daemon())
req_t.amounts = get_unspent_amounts_vector();
req_t.min_count = count;
req_t.max_count = 0;
@@ -8851,21 +8878,21 @@ const wallet2::transfer_details &wallet2::get_transfer_details(size_t idx) const
return m_transfers[idx];
}
//----------------------------------------------------------------------------------------------------
-std::vector<size_t> wallet2::select_available_unmixable_outputs(bool trusted_daemon)
+std::vector<size_t> wallet2::select_available_unmixable_outputs()
{
// request all outputs with less than 3 instances
const size_t min_mixin = use_fork_rules(7, 10) ? 6 : use_fork_rules(6, 10) ? 4 : 2; // v6 increases min mixin from 2 to 4, v7 to 6
- return select_available_outputs_from_histogram(min_mixin + 1, false, true, false, trusted_daemon);
+ return select_available_outputs_from_histogram(min_mixin + 1, false, true, false);
}
//----------------------------------------------------------------------------------------------------
-std::vector<size_t> wallet2::select_available_mixable_outputs(bool trusted_daemon)
+std::vector<size_t> wallet2::select_available_mixable_outputs()
{
// request all outputs with at least 3 instances, so we can use mixin 2 with
const size_t min_mixin = use_fork_rules(7, 10) ? 6 : use_fork_rules(6, 10) ? 4 : 2; // v6 increases min mixin from 2 to 4, v7 to 6
- return select_available_outputs_from_histogram(min_mixin + 1, true, true, true, trusted_daemon);
+ return select_available_outputs_from_histogram(min_mixin + 1, true, true, true);
}
//----------------------------------------------------------------------------------------------------
-std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bool trusted_daemon)
+std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions()
{
// From hard fork 1, we don't consider small amounts to be dust anymore
const bool hf1_rules = use_fork_rules(2, 10); // first hard fork has version 2
@@ -8874,7 +8901,7 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
const uint64_t fee_per_kb = get_per_kb_fee();
// may throw
- std::vector<size_t> unmixable_outputs = select_available_unmixable_outputs(trusted_daemon);
+ std::vector<size_t> unmixable_outputs = select_available_unmixable_outputs();
size_t num_dust_outputs = unmixable_outputs.size();
if (num_dust_outputs == 0)
@@ -8892,13 +8919,13 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
unmixable_transfer_outputs.push_back(n);
}
- return create_transactions_from(m_account_public_address, false, unmixable_transfer_outputs, unmixable_dust_outputs, 0 /*fake_outs_count */, 0 /* unlock_time */, 1 /*priority */, std::vector<uint8_t>(), trusted_daemon);
+ return create_transactions_from(m_account_public_address, false, unmixable_transfer_outputs, unmixable_dust_outputs, 0 /*fake_outs_count */, 0 /* unlock_time */, 1 /*priority */, std::vector<uint8_t>());
}
//----------------------------------------------------------------------------------------------------
-void wallet2::discard_unmixable_outputs(bool trusted_daemon)
+void wallet2::discard_unmixable_outputs()
{
// may throw
- std::vector<size_t> unmixable_outputs = select_available_unmixable_outputs(trusted_daemon);
+ std::vector<size_t> unmixable_outputs = select_available_unmixable_outputs();
for (size_t idx : unmixable_outputs)
{
m_transfers[idx].m_spent = true;