aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/api/wallet.cpp2
-rw-r--r--src/wallet/api/wallet_manager.cpp5
-rw-r--r--src/wallet/api/wallet_manager.h2
-rw-r--r--src/wallet/node_rpc_proxy.cpp7
-rw-r--r--src/wallet/wallet2.cpp73
-rw-r--r--src/wallet/wallet2.h4
-rw-r--r--src/wallet/wallet_rpc_helpers.h1
7 files changed, 47 insertions, 47 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index cb6ced374..b058619a3 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -450,7 +450,7 @@ WalletImpl::~WalletImpl()
LOG_PRINT_L1(__FUNCTION__);
m_wallet->callback(NULL);
// Pause refresh thread - prevents refresh from starting again
- pauseRefresh();
+ WalletImpl::pauseRefresh(); // Call the method directly (not polymorphically) to protect against UB in destructor.
// Close wallet - stores cache and stops ongoing refresh operation
close(false); // do not store wallet as part of the closing activities
// Stop refresh thread
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
index 417a27db5..f5d5e2168 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
@@ -49,6 +49,11 @@ namespace epee {
namespace Monero {
+WalletManagerImpl::WalletManagerImpl()
+{
+ tools::set_strict_default_file_permissions(true);
+}
+
Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::string &password,
const std::string &language, NetworkType nettype, uint64_t kdf_rounds)
{
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
index cf3056a17..1e8cff877 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -95,7 +95,7 @@ public:
bool setProxy(const std::string &address) override;
private:
- WalletManagerImpl() {}
+ WalletManagerImpl();
friend struct WalletManagerFactory;
net::http::client m_http_client;
std::string m_errorString;
diff --git a/src/wallet/node_rpc_proxy.cpp b/src/wallet/node_rpc_proxy.cpp
index a576c267c..148f957eb 100644
--- a/src/wallet/node_rpc_proxy.cpp
+++ b/src/wallet/node_rpc_proxy.cpp
@@ -306,7 +306,12 @@ boost::optional<std::string> NodeRPCProxy::get_rpc_payment_info(bool mining, boo
m_rpc_payment_seed_height = resp_t.seed_height;
m_rpc_payment_cookie = resp_t.cookie;
- if (!epee::string_tools::parse_hexstr_to_binbuff(resp_t.hashing_blob, m_rpc_payment_blob) || m_rpc_payment_blob.size() < 43)
+ if (m_rpc_payment_diff == 0)
+ {
+ // If no payment required daemon doesn't give us back a hashing blob
+ m_rpc_payment_blob.clear();
+ }
+ else if (!epee::string_tools::parse_hexstr_to_binbuff(resp_t.hashing_blob, m_rpc_payment_blob) || m_rpc_payment_blob.size() < 43)
{
MERROR("Invalid hashing blob: " << resp_t.hashing_blob);
return std::string("Invalid hashing blob");
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 19d3c1a7f..e95e53e0c 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -149,7 +149,7 @@ using namespace cryptonote;
#define IGNORE_LONG_PAYMENT_ID_FROM_BLOCK_VERSION 12
#define DEFAULT_UNLOCK_TIME (CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE * DIFFICULTY_TARGET_V2)
-#define RECENT_SPEND_WINDOW (50 * DIFFICULTY_TARGET_V2)
+#define RECENT_SPEND_WINDOW (15 * DIFFICULTY_TARGET_V2)
static const std::string MULTISIG_SIGNATURE_MAGIC = "SigMultisigPkV1";
@@ -280,7 +280,6 @@ void do_prepare_file_names(const std::string& file_path, std::string& keys_file,
{
keys_file = file_path;
wallet_file = file_path;
- boost::system::error_code e;
if(string_tools::get_extension(keys_file) == "keys")
{//provided keys file name
wallet_file = string_tools::cut_off_extension(wallet_file);
@@ -990,13 +989,7 @@ gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets, double shap
end = rct_offsets.data() + rct_offsets.size() - CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE;
num_rct_outputs = *(end - 1);
THROW_WALLET_EXCEPTION_IF(num_rct_outputs == 0, error::wallet_internal_error, "No rct outputs");
- THROW_WALLET_EXCEPTION_IF(outputs_to_consider == 0, error::wallet_internal_error, "No rct outputs to consider");
- average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / outputs_to_consider; // this assumes constant target over the whole rct range
- if (average_output_time == 0) {
- // TODO: apply this to all cases; do so alongside a hard fork, where all clients will update at the same time, preventing anonymity puddle formation
- average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / static_cast<double>(outputs_to_consider);
- }
- THROW_WALLET_EXCEPTION_IF(average_output_time == 0, error::wallet_internal_error, "Average seconds per output cannot be 0.");
+ average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / static_cast<double>(outputs_to_consider); // this assumes constant target over the whole rct range
};
gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets): gamma_picker(rct_offsets, GAMMA_SHAPE, GAMMA_SCALE) {}
@@ -1201,8 +1194,6 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
m_ring_history_saved(false),
m_ringdb(),
m_last_block_reward(0),
- m_encrypt_keys_after_refresh(boost::none),
- m_decrypt_keys_lockers(0),
m_unattended(unattended),
m_devices_registered(false),
m_device_last_key_image_sync(0),
@@ -1854,8 +1845,7 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
boost::optional<epee::wipeable_string> pwd = m_callback->on_get_password(pool ? "output found in pool" : "output received");
THROW_WALLET_EXCEPTION_IF(!pwd, error::password_needed, tr("Password is needed to compute key image for incoming monero"));
THROW_WALLET_EXCEPTION_IF(!verify_password(*pwd), error::password_needed, tr("Invalid password: password is needed to compute key image for incoming monero"));
- decrypt_keys(*pwd);
- m_encrypt_keys_after_refresh = *pwd;
+ m_encrypt_keys_after_refresh.reset(new wallet_keys_unlocker(*this, m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only, *pwd));
}
}
@@ -2987,11 +2977,7 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction,
MTRACE("update_pool_state start");
auto keys_reencryptor = epee::misc_utils::create_scope_leave_handler([&, this]() {
- if (m_encrypt_keys_after_refresh)
- {
- encrypt_keys(*m_encrypt_keys_after_refresh);
- m_encrypt_keys_after_refresh = boost::none;
- }
+ m_encrypt_keys_after_refresh.reset();
});
// get the pool state
@@ -3422,11 +3408,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
start_height = 0;
auto keys_reencryptor = epee::misc_utils::create_scope_leave_handler([&, this]() {
- if (m_encrypt_keys_after_refresh)
- {
- encrypt_keys(*m_encrypt_keys_after_refresh);
- m_encrypt_keys_after_refresh = boost::none;
- }
+ m_encrypt_keys_after_refresh.reset();
});
auto scope_exit_handler_hwdev = epee::misc_utils::create_scope_leave_handler([&](){hwdev.computing_key_images(false);});
@@ -4433,7 +4415,26 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
m_account.set_device(hwdev);
account_public_address device_account_public_address;
- THROW_WALLET_EXCEPTION_IF(!hwdev.get_public_address(device_account_public_address), error::wallet_internal_error, "Cannot get a device address");
+ bool fetch_device_address = true;
+
+ ::hw::device_cold* dev_cold = nullptr;
+ if (m_key_device_type == hw::device::device_type::TREZOR && (dev_cold = dynamic_cast<::hw::device_cold*>(&hwdev)) != nullptr) {
+ THROW_WALLET_EXCEPTION_IF(!dev_cold->get_public_address_with_no_passphrase(device_account_public_address), error::wallet_internal_error, "Cannot get a device address");
+ if (device_account_public_address == m_account.get_keys().m_account_address) {
+ LOG_PRINT_L0("Wallet opened with an empty passphrase");
+ fetch_device_address = false;
+ dev_cold->set_use_empty_passphrase(true);
+ } else {
+ fetch_device_address = true;
+ LOG_PRINT_L0("Wallet opening with an empty passphrase failed. Retry again: " << fetch_device_address);
+ dev_cold->reset_session();
+ }
+ }
+
+ if (fetch_device_address) {
+ THROW_WALLET_EXCEPTION_IF(!hwdev.get_public_address(device_account_public_address), error::wallet_internal_error, "Cannot get a device address");
+ }
+
THROW_WALLET_EXCEPTION_IF(device_account_public_address != m_account.get_keys().m_account_address, error::wallet_internal_error, "Device wallet does not match wallet address. If the device uses the passphrase feature, please check whether the passphrase was entered correctly (it may have been misspelled - different passphrases generate different wallets, passphrase is case-sensitive). "
"Device address: " + cryptonote::get_account_address_as_str(m_nettype, false, device_account_public_address) +
", wallet address: " + m_account.get_public_address_str(m_nettype));
@@ -4547,18 +4548,12 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip
void wallet2::encrypt_keys(const crypto::chacha_key &key)
{
- boost::lock_guard<boost::mutex> lock(m_decrypt_keys_lock);
- if (--m_decrypt_keys_lockers) // another lock left ?
- return;
m_account.encrypt_keys(key);
m_account.decrypt_viewkey(key);
}
void wallet2::decrypt_keys(const crypto::chacha_key &key)
{
- boost::lock_guard<boost::mutex> lock(m_decrypt_keys_lock);
- if (m_decrypt_keys_lockers++) // already unlocked ?
- return;
m_account.encrypt_viewkey(key);
m_account.decrypt_keys(key);
}
@@ -5421,13 +5416,14 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
wallet_keys_unlocker unlocker(*this, m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only, password);
//keys loaded ok!
- //try to load wallet file. but even if we failed, it is not big problem
- if (use_fs && (!boost::filesystem::exists(m_wallet_file, e) || e))
+ //try to load wallet cache. but even if we failed, it is not big problem
+ bool cache_missing = use_fs ? (!boost::filesystem::exists(m_wallet_file, e) || e) : cache_buf.empty();
+ if (cache_missing)
{
- LOG_PRINT_L0("file not found: " << m_wallet_file << ", starting with empty blockchain");
+ LOG_PRINT_L0("wallet cache missing: " << m_wallet_file << ", starting with empty blockchain");
m_account_public_address = m_account.get_keys().m_account_address;
}
- else if (use_fs || !cache_buf.empty())
+ else
{
wallet2::cache_file_data cache_file_data;
std::string cache_file_buf;
@@ -6784,7 +6780,6 @@ bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wal
bool wallet2::parse_tx_from_str(const std::string &signed_tx_st, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set &)> accept_func)
{
std::string s = signed_tx_st;
- boost::system::error_code errcode;
signed_tx_set signed_txs;
const size_t magiclen = strlen(SIGNED_TX_PREFIX) - 1;
@@ -13434,12 +13429,8 @@ std::string wallet2::make_uri(const std::string &address, const std::string &pay
if (!payment_id.empty())
{
- crypto::hash pid32;
- if (!wallet2::parse_long_payment_id(payment_id, pid32))
- {
- error = "Invalid payment id";
- return std::string();
- }
+ error = "Standalone payment id deprecated, use integrated address instead";
+ return std::string();
}
std::string uri = "monero:" + address;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 62cd7fb80..d64832b13 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1766,9 +1766,7 @@ private:
crypto::secret_key m_original_view_secret_key;
crypto::chacha_key m_cache_key;
- boost::optional<epee::wipeable_string> m_encrypt_keys_after_refresh;
- boost::mutex m_decrypt_keys_lock;
- unsigned int m_decrypt_keys_lockers;
+ std::shared_ptr<wallet_keys_unlocker> m_encrypt_keys_after_refresh;
bool m_unattended;
bool m_devices_registered;
diff --git a/src/wallet/wallet_rpc_helpers.h b/src/wallet/wallet_rpc_helpers.h
index 35714db03..6f50b6727 100644
--- a/src/wallet/wallet_rpc_helpers.h
+++ b/src/wallet/wallet_rpc_helpers.h
@@ -28,6 +28,7 @@
#pragma once
+#include <limits>
#include <type_traits>
namespace