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.cpp48
1 files changed, 32 insertions, 16 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 3e2ccd1ff..063c493ce 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -301,7 +301,7 @@ struct options {
const command_line::arg_descriptor<std::string> tx_notify = { "tx-notify" , "Run a program for each new incoming transaction, '%s' will be replaced by the transaction hash" , "" };
const command_line::arg_descriptor<bool> no_dns = {"no-dns", tools::wallet2::tr("Do not use DNS"), false};
const command_line::arg_descriptor<bool> offline = {"offline", tools::wallet2::tr("Do not connect to a daemon, nor use DNS"), false};
- const command_line::arg_descriptor<std::string> extra_entropy = {"extra-entropy", tools::wallet2::tr("File containing extra entropy to initialize the PRNG (any data, aim for 256 bits of entropy to be useful, wihch typically means more than 256 bits of data)")};
+ const command_line::arg_descriptor<std::string> extra_entropy = {"extra-entropy", tools::wallet2::tr("File containing extra entropy to initialize the PRNG (any data, aim for 256 bits of entropy to be useful, which typically means more than 256 bits of data)")};
};
void do_prepare_file_names(const std::string& file_path, std::string& keys_file, std::string& wallet_file, std::string &mms_file)
@@ -5969,7 +5969,7 @@ uint64_t wallet2::balance(uint32_t index_major, bool strict) const
return amount;
}
//----------------------------------------------------------------------------------------------------
-uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t *blocks_to_unlock, uint64_t *time_to_unlock) const
+uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t *blocks_to_unlock, uint64_t *time_to_unlock)
{
uint64_t amount = 0;
if (blocks_to_unlock)
@@ -6021,7 +6021,7 @@ std::map<uint32_t, uint64_t> wallet2::balance_per_subaddress(uint32_t index_majo
return amount_per_subaddr;
}
//----------------------------------------------------------------------------------------------------
-std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> wallet2::unlocked_balance_per_subaddress(uint32_t index_major, bool strict) const
+std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> wallet2::unlocked_balance_per_subaddress(uint32_t index_major, bool strict)
{
std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> amount_per_subaddr;
const uint64_t blockchain_height = get_blockchain_current_height();
@@ -6069,7 +6069,7 @@ uint64_t wallet2::balance_all(bool strict) const
return r;
}
//----------------------------------------------------------------------------------------------------
-uint64_t wallet2::unlocked_balance_all(bool strict, uint64_t *blocks_to_unlock, uint64_t *time_to_unlock) const
+uint64_t wallet2::unlocked_balance_all(bool strict, uint64_t *blocks_to_unlock, uint64_t *time_to_unlock)
{
uint64_t r = 0;
if (blocks_to_unlock)
@@ -6234,12 +6234,12 @@ void wallet2::rescan_blockchain(bool hard, bool refresh, bool keep_key_images)
finish_rescan_bc_keep_key_images(transfers_cnt, transfers_hash);
}
//----------------------------------------------------------------------------------------------------
-bool wallet2::is_transfer_unlocked(const transfer_details& td) const
+bool wallet2::is_transfer_unlocked(const transfer_details& td)
{
return is_transfer_unlocked(td.m_tx.unlock_time, td.m_block_height);
}
//----------------------------------------------------------------------------------------------------
-bool wallet2::is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height) const
+bool wallet2::is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height)
{
if(!is_tx_spendtime_unlocked(unlock_time, block_height))
return false;
@@ -6250,7 +6250,7 @@ bool wallet2::is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height)
return true;
}
//----------------------------------------------------------------------------------------------------
-bool wallet2::is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height) const
+bool wallet2::is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height)
{
if(unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER)
{
@@ -6262,12 +6262,14 @@ bool wallet2::is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_heig
}else
{
//interpret as time
- uint64_t current_time = static_cast<uint64_t>(time(NULL));
+ uint64_t adjusted_time;
+ try { adjusted_time = get_daemon_adjusted_time(); }
+ catch(...) { adjusted_time = time(NULL); } // use local time if no daemon to report blockchain time
// XXX: this needs to be fast, so we'd need to get the starting heights
// from the daemon to be correct once voting kicks in
uint64_t v2height = m_nettype == TESTNET ? 624634 : m_nettype == STAGENET ? 32000 : 1009827;
uint64_t leeway = block_height < v2height ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2;
- if(current_time + leeway >= unlock_time)
+ if(adjusted_time + leeway >= unlock_time)
return true;
else
return false;
@@ -8052,13 +8054,16 @@ std::pair<std::set<uint64_t>, size_t> outs_unique(const std::vector<std::vector<
return std::make_pair(std::move(unique), total);
}
-void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, const std::vector<size_t> &selected_transfers, size_t fake_outputs_count)
+void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, const std::vector<size_t> &selected_transfers, size_t fake_outputs_count, bool rct)
{
std::vector<uint64_t> rct_offsets;
for (size_t attempts = 3; attempts > 0; --attempts)
{
get_outs(outs, selected_transfers, fake_outputs_count, rct_offsets);
+ if (!rct)
+ return;
+
const auto unique = outs_unique(outs);
if (tx_sanity_check(unique.first, unique.second, rct_offsets.empty() ? 0 : rct_offsets.back()))
{
@@ -8696,7 +8701,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
THROW_WALLET_EXCEPTION_IF(subaddr_account != m_transfers[*i].m_subaddr_index.major, error::wallet_internal_error, "the tx uses funds from multiple accounts");
if (outs.empty())
- get_outs(outs, selected_transfers, fake_outputs_count); // may throw
+ get_outs(outs, selected_transfers, fake_outputs_count, false); // may throw
//prepare inputs
LOG_PRINT_L2("preparing outputs");
@@ -8897,10 +8902,12 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
MDEBUG("We will create " << n_multisig_txes << " txes");
}
+ bool all_rct = true;
uint64_t found_money = 0;
for(size_t idx: selected_transfers)
{
found_money += m_transfers[idx].amount();
+ all_rct &= m_transfers[idx].is_rct();
}
LOG_PRINT_L2("wanted " << print_money(needed_money) << ", found " << print_money(found_money) << ", fee " << print_money(fee));
@@ -8911,7 +8918,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
THROW_WALLET_EXCEPTION_IF(subaddr_account != m_transfers[*i].m_subaddr_index.major, error::wallet_internal_error, "the tx uses funds from multiple accounts");
if (outs.empty())
- get_outs(outs, selected_transfers, fake_outputs_count); // may throw
+ get_outs(outs, selected_transfers, fake_outputs_count, all_rct); // may throw
//prepare inputs
LOG_PRINT_L2("preparing outputs");
@@ -9104,7 +9111,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
LOG_PRINT_L2("transfer_selected_rct done");
}
-std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices) const
+std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices)
{
std::vector<size_t> picks;
float current_output_relatdness = 1.0f;
@@ -10352,7 +10359,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
const size_t tx_weight_per_ring = tx_weight_two_rings - tx_weight_one_ring;
const uint64_t fractional_threshold = (fee_multiplier * base_fee * tx_weight_per_ring) / (use_per_byte_fee ? 1 : 1024);
- THROW_WALLET_EXCEPTION_IF(unlocked_balance(subaddr_account, false) == 0, error::wallet_internal_error, "No unlocked balance in the entire wallet");
+ THROW_WALLET_EXCEPTION_IF(unlocked_balance(subaddr_account, false) == 0, error::wallet_internal_error, "No unlocked balance in the specified account");
std::map<uint32_t, std::pair<std::vector<size_t>, std::vector<size_t>>> unused_transfer_dust_indices_per_subaddr;
@@ -10682,7 +10689,7 @@ void wallet2::cold_sign_tx(const std::vector<pending_tx>& ptx_vector, signed_tx_
hw::wallet_shim wallet_shim;
setup_shim(&wallet_shim, this);
aux_data.tx_recipients = dsts_info;
- aux_data.bp_version = use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1;
+ aux_data.bp_version = (use_fork_rules(HF_VERSION_CLSAG, -10) ? 3 : use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1);
aux_data.hard_fork = get_current_hard_fork();
dev_cold->tx_sign(&wallet_shim, txs, exported_txs, aux_data);
tx_device_aux = aux_data.tx_device_aux;
@@ -10775,7 +10782,7 @@ uint64_t wallet2::get_upper_transaction_weight_limit()
return full_reward_zone - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
}
//----------------------------------------------------------------------------------------------------
-std::vector<size_t> wallet2::select_available_outputs(const std::function<bool(const transfer_details &td)> &f) const
+std::vector<size_t> wallet2::select_available_outputs(const std::function<bool(const transfer_details &td)> &f)
{
std::vector<size_t> outputs;
size_t n = 0;
@@ -12080,6 +12087,15 @@ uint64_t wallet2::get_daemon_blockchain_height(string &err)
return height;
}
+uint64_t wallet2::get_daemon_adjusted_time()
+{
+ uint64_t adjusted_time;
+
+ boost::optional<std::string> result = m_node_rpc_proxy.get_adjusted_time(adjusted_time);
+ THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Invalid adjusted time from daemon");
+ return adjusted_time;
+}
+
uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
{
err = "";