aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/api/wallet.cpp12
-rw-r--r--src/wallet/api/wallet2_api.h27
-rw-r--r--src/wallet/api/wallet_manager.cpp15
-rw-r--r--src/wallet/api/wallet_manager.h5
-rw-r--r--src/wallet/wallet2.cpp47
-rw-r--r--src/wallet/wallet2.h5
6 files changed, 87 insertions, 24 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index c1303c225..032b873d6 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -249,6 +249,13 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback
}
}
+ virtual void on_device_button_pressed()
+ {
+ if (m_listener) {
+ m_listener->onDeviceButtonPressed();
+ }
+ }
+
virtual boost::optional<epee::wipeable_string> on_device_pin_request()
{
if (m_listener) {
@@ -449,6 +456,11 @@ WalletImpl::~WalletImpl()
close(false); // do not store wallet as part of the closing activities
// Stop refresh thread
stopRefresh();
+
+ if (m_wallet2Callback->getListener()) {
+ m_wallet2Callback->getListener()->onSetWallet(nullptr);
+ }
+
LOG_PRINT_L1(__FUNCTION__ << " finished");
}
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index ee1d6ae79..0af3b1867 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -37,6 +37,7 @@
#include <set>
#include <ctime>
#include <iostream>
+#include <stdexcept>
// Public interface for libwallet library
namespace Monero {
@@ -337,6 +338,7 @@ protected:
bool m_indeterminate;
};
+struct Wallet;
struct WalletListener
{
virtual ~WalletListener() = 0;
@@ -381,7 +383,12 @@ struct WalletListener
/**
* @brief called by device if the action is required
*/
- virtual void onDeviceButtonRequest(uint64_t code) {}
+ virtual void onDeviceButtonRequest(uint64_t code) { (void)code; }
+
+ /**
+ * @brief called by device if the button was pressed
+ */
+ virtual void onDeviceButtonPressed() { }
/**
* @brief called by device when PIN is needed
@@ -401,7 +408,12 @@ struct WalletListener
/**
* @brief Signalizes device operation progress
*/
- virtual void onDeviceProgress(const DeviceProgress & event) {};
+ virtual void onDeviceProgress(const DeviceProgress & event) { (void)event; };
+
+ /**
+ * @brief If the listener is created before the wallet this enables to set created wallet object
+ */
+ virtual void onSetWallet(Wallet * wallet) { (void)wallet; };
};
@@ -440,8 +452,8 @@ struct Wallet
//! returns both error and error string atomically. suggested to use in instead of status() and errorString()
virtual void statusWithErrorString(int& status, std::string& errorString) const = 0;
virtual bool setPassword(const std::string &password) = 0;
- virtual bool setDevicePin(const std::string &password) { return false; };
- virtual bool setDevicePassphrase(const std::string &password) { return false; };
+ virtual bool setDevicePin(const std::string &pin) { (void)pin; return false; };
+ virtual bool setDevicePassphrase(const std::string &passphrase) { (void)passphrase; return false; };
virtual std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const = 0;
std::string mainAddress() const { return address(0, 0); }
virtual std::string path() const = 0;
@@ -1020,9 +1032,10 @@ struct WalletManager
* \param password Password of wallet file
* \param nettype Network type
* \param kdf_rounds Number of rounds for key derivation function
+ * \param listener Wallet listener to set to the wallet after creation
* \return Wallet instance (Wallet::status() needs to be called to check if opened successfully)
*/
- virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1) = 0;
+ virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) = 0;
Wallet * openWallet(const std::string &path, const std::string &password, bool testnet = false) // deprecated
{
return openWallet(path, password, testnet ? TESTNET : MAINNET);
@@ -1134,6 +1147,7 @@ struct WalletManager
* \param restoreHeight restore from start height (0 sets to current height)
* \param subaddressLookahead Size of subaddress lookahead (empty sets to some default low value)
* \param kdf_rounds Number of rounds for key derivation function
+ * \param listener Wallet listener to set to the wallet after creation
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
*/
virtual Wallet * createWalletFromDevice(const std::string &path,
@@ -1142,7 +1156,8 @@ struct WalletManager
const std::string &deviceName,
uint64_t restoreHeight = 0,
const std::string &subaddressLookahead = "",
- uint64_t kdf_rounds = 1) = 0;
+ uint64_t kdf_rounds = 1,
+ WalletListener * listener = nullptr) = 0;
/*!
* \brief Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed, wallet object not deleted
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
index f584e88ac..ef2ed2015 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
@@ -57,9 +57,14 @@ Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::stri
return wallet;
}
-Wallet *WalletManagerImpl::openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds)
+Wallet *WalletManagerImpl::openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds, WalletListener * listener)
{
WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds);
+ wallet->setListener(listener);
+ if (listener){
+ listener->onSetWallet(wallet);
+ }
+
wallet->open(path, password);
//Refresh addressBook
wallet->addressBook()->refresh();
@@ -122,9 +127,15 @@ Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path,
const std::string &deviceName,
uint64_t restoreHeight,
const std::string &subaddressLookahead,
- uint64_t kdf_rounds)
+ uint64_t kdf_rounds,
+ WalletListener * listener)
{
WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds);
+ wallet->setListener(listener);
+ if (listener){
+ listener->onSetWallet(wallet);
+ }
+
if(restoreHeight > 0){
wallet->setRefreshFromBlockHeight(restoreHeight);
} else {
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
index 0c83d794f..235f96e17 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -40,7 +40,7 @@ class WalletManagerImpl : public WalletManager
public:
Wallet * createWallet(const std::string &path, const std::string &password,
const std::string &language, NetworkType nettype, uint64_t kdf_rounds = 1) override;
- Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1) override;
+ Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) override;
virtual Wallet * recoveryWallet(const std::string &path,
const std::string &password,
const std::string &mnemonic,
@@ -72,7 +72,8 @@ public:
const std::string &deviceName,
uint64_t restoreHeight = 0,
const std::string &subaddressLookahead = "",
- uint64_t kdf_rounds = 1) override;
+ uint64_t kdf_rounds = 1,
+ WalletListener * listener = nullptr) override;
virtual bool closeWallet(Wallet *wallet, bool store = true) override;
bool walletExists(const std::string &path) override;
bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index dfcc61426..b288994a5 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -265,6 +265,7 @@ struct options {
const command_line::arg_descriptor<std::string> hw_device = {"hw-device", tools::wallet2::tr("HW device to use"), ""};
const command_line::arg_descriptor<std::string> hw_device_derivation_path = {"hw-device-deriv-path", tools::wallet2::tr("HW device wallet derivation path (e.g., SLIP-10)"), ""};
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};
};
void do_prepare_file_names(const std::string& file_path, std::string& keys_file, std::string& wallet_file, std::string &mms_file)
@@ -452,6 +453,9 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
wallet->device_name(device_name);
wallet->device_derivation_path(device_derivation_path);
+ if (command_line::get_arg(vm, opts.no_dns))
+ wallet->enable_dns(false);
+
try
{
if (!command_line::is_arg_defaulted(vm, opts.tx_notify))
@@ -992,6 +996,12 @@ void wallet_device_callback::on_button_request(uint64_t code)
wallet->on_device_button_request(code);
}
+void wallet_device_callback::on_button_pressed()
+{
+ if (wallet)
+ wallet->on_device_button_pressed();
+}
+
boost::optional<epee::wipeable_string> wallet_device_callback::on_pin_request()
{
if (wallet)
@@ -1072,7 +1082,8 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended):
m_encrypt_keys_after_refresh(boost::none),
m_unattended(unattended),
m_devices_registered(false),
- m_device_last_key_image_sync(0)
+ m_device_last_key_image_sync(0),
+ m_use_dns(true)
{
}
@@ -1127,6 +1138,7 @@ void wallet2::init_options(boost::program_options::options_description& desc_par
command_line::add_arg(desc_params, opts.hw_device);
command_line::add_arg(desc_params, opts.hw_device_derivation_path);
command_line::add_arg(desc_params, opts.tx_notify);
+ command_line::add_arg(desc_params, opts.no_dns);
}
std::pair<std::unique_ptr<wallet2>, tools::password_container> wallet2::make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
@@ -5773,7 +5785,7 @@ namespace
{
CHECK_AND_ASSERT_MES(!vec.empty(), T(), "Vector must be non-empty");
- size_t idx = crypto::rand<size_t>() % vec.size();
+ size_t idx = crypto::rand_idx(vec.size());
return pop_index (vec, idx);
}
@@ -5876,7 +5888,7 @@ size_t wallet2::pop_best_value_from(const transfer_container &transfers, std::ve
}
else
{
- idx = crypto::rand<size_t>() % candidates.size();
+ idx = crypto::rand_idx(candidates.size());
}
return pop_index (unused_indices, candidates[idx]);
}
@@ -7565,7 +7577,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
if (n_rct == 0)
return rct_offsets[block_offset] ? rct_offsets[block_offset] - 1 : 0;
MDEBUG("Picking 1/" << n_rct << " in " << (last_block_offset - first_block_offset + 1) << " blocks centered around " << block_offset + rct_start_height);
- return first_rct + crypto::rand<uint64_t>() % n_rct;
+ return first_rct + crypto::rand_idx(n_rct);
};
size_t num_selected_transfers = 0;
@@ -9621,14 +9633,16 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, s
change -= r.second.first;
MDEBUG("Adding " << cryptonote::print_money(change) << " expected change");
+ // for all txes that have actual change, check change is coming back to the sending wallet
for (const pending_tx &ptx: ptx_vector)
- THROW_WALLET_EXCEPTION_IF(ptx.change_dts.addr != ptx_vector[0].change_dts.addr, error::wallet_internal_error,
- "Change goes to several different addresses");
- const auto it = m_subaddresses.find(ptx_vector[0].change_dts.addr.m_spend_public_key);
- THROW_WALLET_EXCEPTION_IF(change > 0 && it == m_subaddresses.end(), error::wallet_internal_error, "Change address is not ours");
-
- required[ptx_vector[0].change_dts.addr].first += change;
- required[ptx_vector[0].change_dts.addr].second = ptx_vector[0].change_dts.is_subaddress;
+ {
+ if (ptx.change_dts.amount == 0)
+ continue;
+ THROW_WALLET_EXCEPTION_IF(m_subaddresses.find(ptx.change_dts.addr.m_spend_public_key) == m_subaddresses.end(),
+ error::wallet_internal_error, "Change address is not ours");
+ required[ptx.change_dts.addr].first += ptx.change_dts.amount;
+ required[ptx.change_dts.addr].second = ptx.change_dts.is_subaddress;
+ }
for (const auto &r: required)
{
@@ -9694,7 +9708,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
if (unused_transfer_dust_indices_per_subaddr.count(0) == 1 && unused_transfer_dust_indices_per_subaddr.size() > 1)
unused_transfer_dust_indices_per_subaddr.erase(0);
auto i = unused_transfer_dust_indices_per_subaddr.begin();
- std::advance(i, crypto::rand<size_t>() % unused_transfer_dust_indices_per_subaddr.size());
+ std::advance(i, crypto::rand_idx(unused_transfer_dust_indices_per_subaddr.size()));
unused_transfers_indices = i->second.first;
unused_dust_indices = i->second.second;
LOG_PRINT_L2("Spending from subaddress index " << i->first);
@@ -12865,8 +12879,7 @@ uint64_t wallet2::get_segregation_fork_height() const
if (m_segregation_height > 0)
return m_segregation_height;
- static const bool use_dns = true;
- if (use_dns)
+ if (m_use_dns)
{
// All four MoneroPulse domains have DNSSEC on and valid
static const std::vector<std::string> dns_urls = {
@@ -12946,6 +12959,12 @@ void wallet2::on_device_button_request(uint64_t code)
m_callback->on_device_button_request(code);
}
//----------------------------------------------------------------------------------------------------
+void wallet2::on_device_button_pressed()
+{
+ if (nullptr != m_callback)
+ m_callback->on_device_button_pressed();
+}
+//----------------------------------------------------------------------------------------------------
boost::optional<epee::wipeable_string> wallet2::on_device_pin_request()
{
if (nullptr != m_callback)
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index c8ac7d429..39380c9df 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -105,6 +105,7 @@ namespace tools
virtual void on_lw_money_spent(uint64_t height, const crypto::hash &txid, uint64_t amount) {}
// Device callbacks
virtual void on_device_button_request(uint64_t code) {}
+ virtual void on_device_button_pressed() {}
virtual boost::optional<epee::wipeable_string> on_device_pin_request() { return boost::none; }
virtual boost::optional<epee::wipeable_string> on_device_passphrase_request(bool on_device) { return boost::none; }
virtual void on_device_progress(const hw::device_progress& event) {};
@@ -118,6 +119,7 @@ namespace tools
public:
wallet_device_callback(wallet2 * wallet): wallet(wallet) {};
void on_button_request(uint64_t code=0) override;
+ void on_button_pressed() override;
boost::optional<epee::wipeable_string> on_pin_request() override;
boost::optional<epee::wipeable_string> on_passphrase_request(bool on_device) override;
void on_progress(const hw::device_progress& event) override;
@@ -1288,6 +1290,7 @@ namespace tools
void hash_m_transfer(const transfer_details & transfer, crypto::hash &hash) const;
uint64_t hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const;
void finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash);
+ void enable_dns(bool enable) { m_use_dns = enable; }
private:
/*!
@@ -1378,6 +1381,7 @@ namespace tools
wallet_device_callback * get_device_callback();
void on_device_button_request(uint64_t code);
+ void on_device_button_pressed();
boost::optional<epee::wipeable_string> on_device_pin_request();
boost::optional<epee::wipeable_string> on_device_passphrase_request(bool on_device);
void on_device_progress(const hw::device_progress& event);
@@ -1469,6 +1473,7 @@ namespace tools
std::string m_device_name;
std::string m_device_derivation_path;
uint64_t m_device_last_key_image_sync;
+ bool m_use_dns;
// Aux transaction data from device
std::unordered_map<crypto::hash, std::string> m_tx_device;