aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/epee/include/file_io_utils.h25
-rw-r--r--contrib/epee/include/string_tools.h35
-rw-r--r--src/common/util.cpp98
-rw-r--r--src/common/util.h14
-rw-r--r--src/cryptonote_core/blockchain.cpp2
-rw-r--r--src/wallet/api/address_book.h14
-rw-r--r--src/wallet/api/pending_transaction.h26
-rw-r--r--src/wallet/api/subaddress.h8
-rw-r--r--src/wallet/api/transaction_info.h30
-rw-r--r--src/wallet/api/unsigned_transaction.h23
-rw-r--r--src/wallet/api/wallet.cpp3
-rw-r--r--src/wallet/api/wallet.h184
-rw-r--r--src/wallet/api/wallet_manager.h44
-rw-r--r--src/wallet/wallet2.cpp8
-rw-r--r--src/wallet/wallet2.h1
-rw-r--r--src/wallet/wallet_rpc_server_commands_defs.h6
16 files changed, 324 insertions, 197 deletions
diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h
index 4434f7383..25f8c648b 100644
--- a/contrib/epee/include/file_io_utils.h
+++ b/contrib/epee/include/file_io_utils.h
@@ -33,6 +33,7 @@
#include <boost/filesystem/operations.hpp>
#ifdef WIN32
#include <windows.h>
+#include "string_tools.h"
#endif
// On Windows there is a problem with non-ASCII characters in path and file names
@@ -72,11 +73,9 @@ namespace file_io_utils
bool save_string_to_file(const std::string& path_to_file, const std::string& str)
{
#ifdef WIN32
- WCHAR wide_path[1000];
- int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000);
- if (chars == 0)
- return false;
- HANDLE file_handle = CreateFileW(wide_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ std::wstring wide_path;
+ try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
+ HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
DWORD bytes_written;
@@ -131,11 +130,9 @@ namespace file_io_utils
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000)
{
#ifdef WIN32
- WCHAR wide_path[1000];
- int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000);
- if (chars == 0)
- return false;
- HANDLE file_handle = CreateFileW(wide_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ std::wstring wide_path;
+ try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
+ HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
DWORD file_size = GetFileSize(file_handle, NULL);
@@ -202,11 +199,9 @@ namespace file_io_utils
bool get_file_size(const std::string& path_to_file, uint64_t &size)
{
#ifdef WIN32
- WCHAR wide_path[1000];
- int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000);
- if (chars == 0)
- return false;
- HANDLE file_handle = CreateFileW(wide_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ std::wstring wide_path;
+ try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
+ HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
LARGE_INTEGER file_size;
diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h
index 63705e401..8d8603076 100644
--- a/contrib/epee/include/string_tools.h
+++ b/contrib/epee/include/string_tools.h
@@ -381,6 +381,41 @@ POP_WARNINGS
res = str.substr(0, pos);
return res;
}
+ //----------------------------------------------------------------------------
+#ifdef _WIN32
+ inline std::wstring utf8_to_utf16(const std::string& str)
+ {
+ if (str.empty())
+ return {};
+ int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
+ if (wstr_size == 0)
+ {
+ throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
+ }
+ std::wstring wstr(wstr_size, wchar_t{});
+ if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
+ {
+ throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
+ }
+ return wstr;
+ }
+ inline std::string utf16_to_utf8(const std::wstring& wstr)
+ {
+ if (wstr.empty())
+ return {};
+ int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
+ if (str_size == 0)
+ {
+ throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
+ }
+ std::string str(str_size, char{});
+ if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
+ {
+ throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
+ }
+ return str;
+ }
+#endif
}
}
#endif //_STRING_TOOLS_H_
diff --git a/src/common/util.cpp b/src/common/util.cpp
index 329352e94..7d9d7b408 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -195,6 +195,73 @@ namespace tools
catch (...) {}
}
+ file_locker::file_locker(const std::string &filename)
+ {
+#ifdef WIN32
+ m_fd = INVALID_HANDLE_VALUE;
+ std::wstring filename_wide;
+ try
+ {
+ filename_wide = string_tools::utf8_to_utf16(filename);
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("Failed to convert path \"" << filename << "\" to UTF-16: " << e.what());
+ return;
+ }
+ m_fd = CreateFileW(filename_wide.c_str(), GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (m_fd != INVALID_HANDLE_VALUE)
+ {
+ OVERLAPPED ov;
+ memset(&ov, 0, sizeof(ov));
+ if (!LockFileEx(m_fd, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &ov))
+ {
+ MERROR("Failed to lock " << filename << ": " << std::error_code(GetLastError(), std::system_category()));
+ CloseHandle(m_fd);
+ m_fd = INVALID_HANDLE_VALUE;
+ }
+ }
+ else
+ {
+ MERROR("Failed to open " << filename << ": " << std::error_code(GetLastError(), std::system_category()));
+ }
+#else
+ m_fd = open(filename.c_str(), O_RDONLY | O_CREAT, 0666);
+ if (m_fd != -1)
+ {
+ if (flock(m_fd, LOCK_EX | LOCK_NB) == -1)
+ {
+ MERROR("Failed to lock " << filename << ": " << std::strerror(errno));
+ close(m_fd);
+ m_fd = -1;
+ }
+ }
+ else
+ {
+ MERROR("Failed to open " << filename << ": " << std::strerror(errno));
+ }
+#endif
+ }
+ file_locker::~file_locker()
+ {
+ if (locked())
+ {
+#ifdef WIN32
+ CloseHandle(m_fd);
+#else
+ close(m_fd);
+#endif
+ }
+ }
+ bool file_locker::locked() const
+ {
+#ifdef WIN32
+ return m_fd != INVALID_HANDLE_VALUE;
+#else
+ return m_fd != -1;
+#endif
+ }
+
#ifdef WIN32
std::string get_windows_version_display_string()
{
@@ -451,10 +518,15 @@ std::string get_nix_version_display_string()
if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate))
{
- int size_needed = WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), NULL, 0, NULL, NULL);
- std::string folder_name(size_needed, 0);
- WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), &folder_name[0], size_needed, NULL, NULL);
- return folder_name;
+ try
+ {
+ return string_tools::utf16_to_utf8(psz_path);
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("utf16_to_utf8 failed: " << e.what());
+ return "";
+ }
}
LOG_ERROR("SHGetSpecialFolderPathW() failed, could not obtain requested path.");
@@ -515,18 +587,20 @@ std::string get_nix_version_display_string()
int code;
#if defined(WIN32)
// Maximizing chances for success
- WCHAR wide_replacement_name[1000];
- MultiByteToWideChar(CP_UTF8, 0, replacement_name.c_str(), replacement_name.size() + 1, wide_replacement_name, 1000);
- WCHAR wide_replaced_name[1000];
- MultiByteToWideChar(CP_UTF8, 0, replaced_name.c_str(), replaced_name.size() + 1, wide_replaced_name, 1000);
-
- DWORD attributes = ::GetFileAttributesW(wide_replaced_name);
+ std::wstring wide_replacement_name;
+ try { wide_replacement_name = string_tools::utf8_to_utf16(replacement_name); }
+ catch (...) { return std::error_code(GetLastError(), std::system_category()); }
+ std::wstring wide_replaced_name;
+ try { wide_replaced_name = string_tools::utf8_to_utf16(replaced_name); }
+ catch (...) { return std::error_code(GetLastError(), std::system_category()); }
+
+ DWORD attributes = ::GetFileAttributesW(wide_replaced_name.c_str());
if (INVALID_FILE_ATTRIBUTES != attributes)
{
- ::SetFileAttributesW(wide_replaced_name, attributes & (~FILE_ATTRIBUTE_READONLY));
+ ::SetFileAttributesW(wide_replaced_name.c_str(), attributes & (~FILE_ATTRIBUTE_READONLY));
}
- bool ok = 0 != ::MoveFileExW(wide_replacement_name, wide_replaced_name, MOVEFILE_REPLACE_EXISTING);
+ bool ok = 0 != ::MoveFileExW(wide_replacement_name.c_str(), wide_replaced_name.c_str(), MOVEFILE_REPLACE_EXISTING);
code = ok ? 0 : static_cast<int>(::GetLastError());
#else
bool ok = 0 == std::rename(replacement_name.c_str(), replaced_name.c_str());
diff --git a/src/common/util.h b/src/common/util.h
index dc426830b..a57a85fee 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -91,6 +91,20 @@ namespace tools
const std::string& filename() const noexcept { return m_filename; }
};
+ class file_locker
+ {
+ public:
+ file_locker(const std::string &filename);
+ ~file_locker();
+ bool locked() const;
+ private:
+#ifdef WIN32
+ HANDLE m_fd;
+#else
+ int m_fd;
+#endif
+ };
+
/*! \brief Returns the default data directory.
*
* \details Windows < Vista: C:\\Documents and Settings\\Username\\Application Data\\CRYPTONOTE_NAME
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index fb88a13cb..73ce98366 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -2745,7 +2745,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool::waiter waiter;
- const auto waiter_guard = epee::misc_utils::create_scope_leave_handler([&]() { waiter.wait(); });
+ const auto waiter_guard = epee::misc_utils::create_scope_leave_handler([&]() { waiter.wait(&tpool); });
int threads = tpool.get_max_concurrency();
for (const auto& txin : tx.vin)
diff --git a/src/wallet/api/address_book.h b/src/wallet/api/address_book.h
index 7d9200550..f4ca68efd 100644
--- a/src/wallet/api/address_book.h
+++ b/src/wallet/api/address_book.h
@@ -42,16 +42,16 @@ public:
~AddressBookImpl();
// Fetches addresses from Wallet2
- void refresh();
- std::vector<AddressBookRow*> getAll() const;
- bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description);
- bool deleteRow(std::size_t rowId);
+ void refresh() override;
+ std::vector<AddressBookRow*> getAll() const override;
+ bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) override;
+ bool deleteRow(std::size_t rowId) override;
// Error codes. See AddressBook:ErrorCode enum in wallet2_api.h
- std::string errorString() const {return m_errorString;}
- int errorCode() const {return m_errorCode;}
+ std::string errorString() const override {return m_errorString;}
+ int errorCode() const override {return m_errorCode;}
- int lookupPaymentID(const std::string &payment_id) const;
+ int lookupPaymentID(const std::string &payment_id) const override;
private:
void clearRows();
diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h
index 4f963c134..50b9f07ef 100644
--- a/src/wallet/api/pending_transaction.h
+++ b/src/wallet/api/pending_transaction.h
@@ -43,21 +43,21 @@ class PendingTransactionImpl : public PendingTransaction
public:
PendingTransactionImpl(WalletImpl &wallet);
~PendingTransactionImpl();
- int status() const;
- std::string errorString() const;
- bool commit(const std::string &filename = "", bool overwrite = false);
- uint64_t amount() const;
- uint64_t dust() const;
- uint64_t fee() const;
- std::vector<std::string> txid() const;
- uint64_t txCount() const;
- std::vector<uint32_t> subaddrAccount() const;
- std::vector<std::set<uint32_t>> subaddrIndices() const;
+ int status() const override;
+ std::string errorString() const override;
+ bool commit(const std::string &filename = "", bool overwrite = false) override;
+ uint64_t amount() const override;
+ uint64_t dust() const override;
+ uint64_t fee() const override;
+ std::vector<std::string> txid() const override;
+ uint64_t txCount() const override;
+ std::vector<uint32_t> subaddrAccount() const override;
+ std::vector<std::set<uint32_t>> subaddrIndices() const override;
// TODO: continue with interface;
- std::string multisigSignData();
- void signMultisigTx();
- std::vector<std::string> signersKeys() const;
+ std::string multisigSignData() override;
+ void signMultisigTx() override;
+ std::vector<std::string> signersKeys() const override;
private:
friend class WalletImpl;
diff --git a/src/wallet/api/subaddress.h b/src/wallet/api/subaddress.h
index 3f9e37ac8..f3db7d97b 100644
--- a/src/wallet/api/subaddress.h
+++ b/src/wallet/api/subaddress.h
@@ -40,10 +40,10 @@ public:
~SubaddressImpl();
// Fetches addresses from Wallet2
- void refresh(uint32_t accountIndex);
- std::vector<SubaddressRow*> getAll() const;
- void addRow(uint32_t accountIndex, const std::string &label);
- void setLabel(uint32_t accountIndex, uint32_t addressIndex, const std::string &label);
+ void refresh(uint32_t accountIndex) override;
+ std::vector<SubaddressRow*> getAll() const override;
+ void addRow(uint32_t accountIndex, const std::string &label) override;
+ void setLabel(uint32_t accountIndex, uint32_t addressIndex, const std::string &label) override;
private:
void clearRows();
diff --git a/src/wallet/api/transaction_info.h b/src/wallet/api/transaction_info.h
index 5df9a44ef..37e0445d9 100644
--- a/src/wallet/api/transaction_info.h
+++ b/src/wallet/api/transaction_info.h
@@ -42,24 +42,24 @@ public:
TransactionInfoImpl();
~TransactionInfoImpl();
//! in/out
- virtual int direction() const;
+ virtual int direction() const override;
//! true if hold
- virtual bool isPending() const;
- virtual bool isFailed() const;
- virtual uint64_t amount() const;
+ virtual bool isPending() const override;
+ virtual bool isFailed() const override;
+ virtual uint64_t amount() const override;
//! always 0 for incoming txes
- virtual uint64_t fee() const;
- virtual uint64_t blockHeight() const;
- virtual std::set<uint32_t> subaddrIndex() const;
- virtual uint32_t subaddrAccount() const;
- virtual std::string label() const;
+ virtual uint64_t fee() const override;
+ virtual uint64_t blockHeight() const override;
+ virtual std::set<uint32_t> subaddrIndex() const override;
+ virtual uint32_t subaddrAccount() const override;
+ virtual std::string label() const override;
- virtual std::string hash() const;
- virtual std::time_t timestamp() const;
- virtual std::string paymentId() const;
- virtual const std::vector<Transfer> &transfers() const;
- virtual uint64_t confirmations() const;
- virtual uint64_t unlockTime() const;
+ virtual std::string hash() const override;
+ virtual std::time_t timestamp() const override;
+ virtual std::string paymentId() const override;
+ virtual const std::vector<Transfer> &transfers() const override;
+ virtual uint64_t confirmations() const override;
+ virtual uint64_t unlockTime() const override;
private:
int m_direction;
diff --git a/src/wallet/api/unsigned_transaction.h b/src/wallet/api/unsigned_transaction.h
index a35630535..8a3330014 100644
--- a/src/wallet/api/unsigned_transaction.h
+++ b/src/wallet/api/unsigned_transaction.h
@@ -43,19 +43,18 @@ class UnsignedTransactionImpl : public UnsignedTransaction
public:
UnsignedTransactionImpl(WalletImpl &wallet);
~UnsignedTransactionImpl();
- int status() const;
- std::string errorString() const;
- std::vector<uint64_t> amount() const;
- std::vector<uint64_t> dust() const;
- std::vector<uint64_t> fee() const;
- std::vector<uint64_t> mixin() const;
- std::vector<std::string> paymentId() const;
- std::vector<std::string> recipientAddress() const;
- uint64_t txCount() const;
+ int status() const override;
+ std::string errorString() const override;
+ std::vector<uint64_t> amount() const override;
+ std::vector<uint64_t> fee() const override;
+ std::vector<uint64_t> mixin() const override;
+ std::vector<std::string> paymentId() const override;
+ std::vector<std::string> recipientAddress() const override;
+ uint64_t txCount() const override;
// sign txs and save to file
- bool sign(const std::string &signedFileName);
- std::string confirmationMessage() const {return m_confirmationMessage;}
- uint64_t minMixinCount() const;
+ bool sign(const std::string &signedFileName) override;
+ std::string confirmationMessage() const override {return m_confirmationMessage;}
+ uint64_t minMixinCount() const override;
private:
// Callback function to check all loaded tx's and generate confirmationMessage
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index c7dbd29e4..3f6bfec9e 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -721,6 +721,7 @@ bool WalletImpl::close(bool store)
LOG_PRINT_L1("Calling wallet::stop...");
m_wallet->stop();
LOG_PRINT_L1("wallet::stop done");
+ m_wallet->deinit();
result = true;
clearStatus();
} catch (const std::exception &e) {
@@ -1965,7 +1966,7 @@ void WalletImpl::doRefresh()
// Syncing daemon and refreshing wallet simultaneously is very resource intensive.
// Disable refresh if wallet is disconnected or daemon isn't synced.
if (m_wallet->light_wallet() || daemonSynced()) {
- m_wallet->refresh();
+ m_wallet->refresh(trustedDaemon());
if (!m_synchronized) {
m_synchronized = true;
}
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 08232cafd..eefb2fe94 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -57,7 +57,7 @@ public:
bool create(const std::string &path, const std::string &password,
const std::string &language);
bool createWatchOnly(const std::string &path, const std::string &password,
- const std::string &language) const;
+ const std::string &language) const override;
bool open(const std::string &path, const std::string &password);
bool recover(const std::string &path,const std::string &password,
const std::string &seed);
@@ -80,58 +80,58 @@ public:
const std::string &password,
const std::string &device_name);
bool close(bool store = true);
- std::string seed() const;
- std::string getSeedLanguage() const;
- void setSeedLanguage(const std::string &arg);
+ std::string seed() const override;
+ std::string getSeedLanguage() const override;
+ void setSeedLanguage(const std::string &arg) override;
// void setListener(Listener *) {}
- int status() const;
- std::string errorString() const;
+ int status() const override;
+ std::string errorString() const override;
void statusWithErrorString(int& status, std::string& errorString) const override;
- bool setPassword(const std::string &password);
- std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const;
- std::string integratedAddress(const std::string &payment_id) const;
- std::string secretViewKey() const;
- std::string publicViewKey() const;
- std::string secretSpendKey() const;
- std::string publicSpendKey() const;
- std::string publicMultisigSignerKey() const;
- std::string path() const;
- bool store(const std::string &path);
- std::string filename() const;
- std::string keysFilename() const;
- bool init(const std::string &daemon_address, uint64_t upper_transaction_size_limit = 0, const std::string &daemon_username = "", const std::string &daemon_password = "", bool use_ssl = false, bool lightWallet = false);
- bool connectToDaemon();
- ConnectionStatus connected() const;
- void setTrustedDaemon(bool arg);
- bool trustedDaemon() const;
- uint64_t balance(uint32_t accountIndex = 0) const;
- uint64_t unlockedBalance(uint32_t accountIndex = 0) const;
- uint64_t blockChainHeight() const;
- uint64_t approximateBlockChainHeight() const;
- uint64_t daemonBlockChainHeight() const;
- uint64_t daemonBlockChainTargetHeight() const;
- bool synchronized() const;
- bool refresh();
- void refreshAsync();
- void setAutoRefreshInterval(int millis);
- int autoRefreshInterval() const;
- void setRefreshFromBlockHeight(uint64_t refresh_from_block_height);
- uint64_t getRefreshFromBlockHeight() const { return m_wallet->get_refresh_from_block_height(); };
- void setRecoveringFromSeed(bool recoveringFromSeed);
+ bool setPassword(const std::string &password) override;
+ std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const override;
+ std::string integratedAddress(const std::string &payment_id) const override;
+ std::string secretViewKey() const override;
+ std::string publicViewKey() const override;
+ std::string secretSpendKey() const override;
+ std::string publicSpendKey() const override;
+ std::string publicMultisigSignerKey() const override;
+ std::string path() const override;
+ bool store(const std::string &path) override;
+ std::string filename() const override;
+ std::string keysFilename() const override;
+ bool init(const std::string &daemon_address, uint64_t upper_transaction_size_limit = 0, const std::string &daemon_username = "", const std::string &daemon_password = "", bool use_ssl = false, bool lightWallet = false) override;
+ bool connectToDaemon() override;
+ ConnectionStatus connected() const override;
+ void setTrustedDaemon(bool arg) override;
+ bool trustedDaemon() const override;
+ uint64_t balance(uint32_t accountIndex = 0) const override;
+ uint64_t unlockedBalance(uint32_t accountIndex = 0) const override;
+ uint64_t blockChainHeight() const override;
+ uint64_t approximateBlockChainHeight() const override;
+ uint64_t daemonBlockChainHeight() const override;
+ uint64_t daemonBlockChainTargetHeight() const override;
+ bool synchronized() const override;
+ bool refresh() override;
+ void refreshAsync() override;
+ void setAutoRefreshInterval(int millis) override;
+ int autoRefreshInterval() const override;
+ void setRefreshFromBlockHeight(uint64_t refresh_from_block_height) override;
+ uint64_t getRefreshFromBlockHeight() const override { return m_wallet->get_refresh_from_block_height(); };
+ void setRecoveringFromSeed(bool recoveringFromSeed) override;
void setRecoveringFromDevice(bool recoveringFromDevice) override;
void setSubaddressLookahead(uint32_t major, uint32_t minor) override;
- bool watchOnly() const;
- bool rescanSpent();
- NetworkType nettype() const {return static_cast<NetworkType>(m_wallet->nettype());}
- void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const;
- bool useForkRules(uint8_t version, int64_t early_blocks) const;
-
- void addSubaddressAccount(const std::string& label);
- size_t numSubaddressAccounts() const;
- size_t numSubaddresses(uint32_t accountIndex) const;
- void addSubaddress(uint32_t accountIndex, const std::string& label);
- std::string getSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex) const;
- void setSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex, const std::string &label);
+ bool watchOnly() const override;
+ bool rescanSpent() override;
+ NetworkType nettype() const override {return static_cast<NetworkType>(m_wallet->nettype());}
+ void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const override;
+ bool useForkRules(uint8_t version, int64_t early_blocks) const override;
+
+ void addSubaddressAccount(const std::string& label) override;
+ size_t numSubaddressAccounts() const override;
+ size_t numSubaddresses(uint32_t accountIndex) const override;
+ void addSubaddress(uint32_t accountIndex, const std::string& label) override;
+ std::string getSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex) const override;
+ void setSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex, const std::string &label) override;
MultisigState multisig() const override;
std::string getMultisigInfo() const override;
@@ -145,49 +145,49 @@ public:
optional<uint64_t> amount, uint32_t mixin_count,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
- std::set<uint32_t> subaddr_indices = {});
- virtual PendingTransaction * createSweepUnmixableTransaction();
- bool submitTransaction(const std::string &fileName);
- virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename);
- bool exportKeyImages(const std::string &filename);
- bool importKeyImages(const std::string &filename);
-
- virtual void disposeTransaction(PendingTransaction * t);
- virtual TransactionHistory * history();
- virtual AddressBook * addressBook();
- virtual Subaddress * subaddress();
- virtual SubaddressAccount * subaddressAccount();
- virtual void setListener(WalletListener * l);
- virtual uint32_t defaultMixin() const;
- virtual void setDefaultMixin(uint32_t arg);
- virtual bool setUserNote(const std::string &txid, const std::string &note);
- virtual std::string getUserNote(const std::string &txid) const;
- virtual std::string getTxKey(const std::string &txid) const;
- virtual bool checkTxKey(const std::string &txid, std::string tx_key, const std::string &address, uint64_t &received, bool &in_pool, uint64_t &confirmations);
- virtual std::string getTxProof(const std::string &txid, const std::string &address, const std::string &message) const;
- virtual bool checkTxProof(const std::string &txid, const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations);
- virtual std::string getSpendProof(const std::string &txid, const std::string &message) const;
- virtual bool checkSpendProof(const std::string &txid, const std::string &message, const std::string &signature, bool &good) const;
- virtual std::string getReserveProof(bool all, uint32_t account_index, uint64_t amount, const std::string &message) const;
- virtual bool checkReserveProof(const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &total, uint64_t &spent) const;
- virtual std::string signMessage(const std::string &message);
- virtual bool verifySignedMessage(const std::string &message, const std::string &address, const std::string &signature) const;
- virtual std::string signMultisigParticipant(const std::string &message) const;
- virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const;
- virtual void startRefresh();
- virtual void pauseRefresh();
- virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error);
- virtual std::string getDefaultDataDir() const;
- virtual bool lightWalletLogin(bool &isNewWallet) const;
- virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status);
- virtual bool blackballOutputs(const std::vector<std::string> &pubkeys, bool add);
- virtual bool unblackballOutput(const std::string &pubkey);
- virtual bool getRing(const std::string &key_image, std::vector<uint64_t> &ring) const;
- virtual bool getRings(const std::string &txid, std::vector<std::pair<std::string, std::vector<uint64_t>>> &rings) const;
- virtual bool setRing(const std::string &key_image, const std::vector<uint64_t> &ring, bool relative);
- virtual void segregatePreForkOutputs(bool segregate);
- virtual void segregationHeight(uint64_t height);
- virtual void keyReuseMitigation2(bool mitigation);
+ std::set<uint32_t> subaddr_indices = {}) override;
+ virtual PendingTransaction * createSweepUnmixableTransaction() override;
+ bool submitTransaction(const std::string &fileName) override;
+ virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
+ bool exportKeyImages(const std::string &filename) override;
+ bool importKeyImages(const std::string &filename) override;
+
+ virtual void disposeTransaction(PendingTransaction * t) override;
+ virtual TransactionHistory * history() override;
+ virtual AddressBook * addressBook() override;
+ virtual Subaddress * subaddress() override;
+ virtual SubaddressAccount * subaddressAccount() override;
+ virtual void setListener(WalletListener * l) override;
+ virtual uint32_t defaultMixin() const override;
+ virtual void setDefaultMixin(uint32_t arg) override;
+ virtual bool setUserNote(const std::string &txid, const std::string &note) override;
+ virtual std::string getUserNote(const std::string &txid) const override;
+ virtual std::string getTxKey(const std::string &txid) const override;
+ virtual bool checkTxKey(const std::string &txid, std::string tx_key, const std::string &address, uint64_t &received, bool &in_pool, uint64_t &confirmations) override;
+ virtual std::string getTxProof(const std::string &txid, const std::string &address, const std::string &message) const override;
+ virtual bool checkTxProof(const std::string &txid, const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations) override;
+ virtual std::string getSpendProof(const std::string &txid, const std::string &message) const override;
+ virtual bool checkSpendProof(const std::string &txid, const std::string &message, const std::string &signature, bool &good) const override;
+ virtual std::string getReserveProof(bool all, uint32_t account_index, uint64_t amount, const std::string &message) const override;
+ virtual bool checkReserveProof(const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &total, uint64_t &spent) const override;
+ virtual std::string signMessage(const std::string &message) override;
+ virtual bool verifySignedMessage(const std::string &message, const std::string &address, const std::string &signature) const override;
+ virtual std::string signMultisigParticipant(const std::string &message) const override;
+ virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const override;
+ virtual void startRefresh() override;
+ virtual void pauseRefresh() override;
+ virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error) override;
+ virtual std::string getDefaultDataDir() const override;
+ virtual bool lightWalletLogin(bool &isNewWallet) const override;
+ virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) override;
+ virtual bool blackballOutputs(const std::vector<std::string> &pubkeys, bool add) override;
+ virtual bool unblackballOutput(const std::string &pubkey) override;
+ virtual bool getRing(const std::string &key_image, std::vector<uint64_t> &ring) const override;
+ virtual bool getRings(const std::string &txid, std::vector<std::pair<std::string, std::vector<uint64_t>>> &rings) const override;
+ virtual bool setRing(const std::string &key_image, const std::vector<uint64_t> &ring, bool relative) override;
+ virtual void segregatePreForkOutputs(bool segregate) override;
+ virtual void segregationHeight(uint64_t height) override;
+ virtual void keyReuseMitigation2(bool mitigation) override;
private:
void clearStatus() const;
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
index 19aad9ee3..656a7142c 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -39,13 +39,13 @@ class WalletManagerImpl : public WalletManager
{
public:
Wallet * createWallet(const std::string &path, const std::string &password,
- const std::string &language, NetworkType nettype);
- Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype);
+ const std::string &language, NetworkType nettype) override;
+ Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype) override;
virtual Wallet * recoveryWallet(const std::string &path,
const std::string &password,
const std::string &mnemonic,
NetworkType nettype,
- uint64_t restoreHeight);
+ uint64_t restoreHeight) override;
virtual Wallet * createWalletFromKeys(const std::string &path,
const std::string &password,
const std::string &language,
@@ -53,9 +53,9 @@ public:
uint64_t restoreHeight,
const std::string &addressString,
const std::string &viewKeyString,
- const std::string &spendKeyString = "");
+ const std::string &spendKeyString = "") override;
// next two methods are deprecated - use the above version which allow setting of a password
- virtual Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight);
+ virtual Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight) override;
// deprecated: use createWalletFromKeys(..., password, ...) instead
virtual Wallet * createWalletFromKeys(const std::string &path,
const std::string &language,
@@ -63,29 +63,29 @@ public:
uint64_t restoreHeight,
const std::string &addressString,
const std::string &viewKeyString,
- const std::string &spendKeyString = "");
+ const std::string &spendKeyString = "") override;
virtual Wallet * createWalletFromDevice(const std::string &path,
const std::string &password,
NetworkType nettype,
const std::string &deviceName,
uint64_t restoreHeight = 0,
const std::string &subaddressLookahead = "") override;
- virtual bool closeWallet(Wallet *wallet, bool store = true);
- bool walletExists(const std::string &path);
- bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key) const;
- std::vector<std::string> findWallets(const std::string &path);
- std::string errorString() const;
- void setDaemonAddress(const std::string &address);
- bool connected(uint32_t *version = NULL);
- uint64_t blockchainHeight();
- uint64_t blockchainTargetHeight();
- uint64_t networkDifficulty();
- double miningHashRate();
- uint64_t blockTarget();
- bool isMining();
- bool startMining(const std::string &address, uint32_t threads = 1, bool background_mining = false, bool ignore_battery = true);
- bool stopMining();
- std::string resolveOpenAlias(const std::string &address, bool &dnssec_valid) const;
+ 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) const override;
+ std::vector<std::string> findWallets(const std::string &path) override;
+ std::string errorString() const override;
+ void setDaemonAddress(const std::string &address) override;
+ bool connected(uint32_t *version = NULL) override;
+ uint64_t blockchainHeight() override;
+ uint64_t blockchainTargetHeight() override;
+ uint64_t networkDifficulty() override;
+ double miningHashRate() override;
+ uint64_t blockTarget() override;
+ bool isMining() override;
+ bool startMining(const std::string &address, uint32_t threads = 1, bool background_mining = false, bool ignore_battery = true) override;
+ bool stopMining() override;
+ std::string resolveOpenAlias(const std::string &address, bool &dnssec_valid) const override;
private:
WalletManagerImpl() {}
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index e5e331797..1a1537e62 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -2636,6 +2636,7 @@ void wallet2::detach_blockchain(uint64_t height)
bool wallet2::deinit()
{
m_is_initialized=false;
+ m_keys_file_locker.reset();
return true;
}
//----------------------------------------------------------------------------------------------------
@@ -2802,10 +2803,12 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
crypto::chacha20(account_data.data(), account_data.size(), key, keys_file_data.iv, &cipher[0]);
keys_file_data.account_data = cipher;
+ m_keys_file_locker.reset();
std::string buf;
r = ::serialization::dump_binary(keys_file_data, buf);
r = r && epee::file_io_utils::save_string_to_file(keys_file_name, buf); //and never touch wallet_keys_file again, only read
CHECK_AND_ASSERT_MES(r, false, "failed to generate wallet keys file " << keys_file_name);
+ m_keys_file_locker.reset(new tools::file_locker(m_keys_file));
return true;
}
@@ -3935,12 +3938,17 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
boost::system::error_code e;
bool exists = boost::filesystem::exists(m_keys_file, e);
THROW_WALLET_EXCEPTION_IF(e || !exists, error::file_not_found, m_keys_file);
+ m_keys_file_locker.reset(new tools::file_locker(m_keys_file));
+ THROW_WALLET_EXCEPTION_IF(!m_keys_file_locker->locked(), error::wallet_internal_error, "internal error: \"" + m_keys_file + "\" is opened by another wallet program");
+ // this temporary unlocking is necessary for Windows (otherwise the file couldn't be loaded).
+ m_keys_file_locker.reset();
if (!load_keys(m_keys_file, password))
{
THROW_WALLET_EXCEPTION_IF(true, error::file_read_error, m_keys_file);
}
LOG_PRINT_L0("Loaded wallet keys file, with public address: " << m_account.get_public_address_str(m_nettype));
+ m_keys_file_locker.reset(new tools::file_locker(m_keys_file));
//keys loaded ok!
//try to load wallet file. but even if we failed, it is not big problem
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 705933979..d33d8258b 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1308,6 +1308,7 @@ namespace tools
boost::optional<crypto::chacha_key> m_ringdb_key;
uint64_t m_last_block_reward;
+ std::unique_ptr<tools::file_locker> m_keys_file_locker;
};
}
BOOST_CLASS_VERSION(tools::wallet2, 25)
diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h
index aa61640a3..1bd572add 100644
--- a/src/wallet/wallet_rpc_server_commands_defs.h
+++ b/src/wallet/wallet_rpc_server_commands_defs.h
@@ -1195,7 +1195,7 @@ namespace wallet_rpc
std::string address;
bool double_spend_seen;
uint64_t confirmations;
- uint64_t suggested_confirmation_threshold;
+ uint64_t suggested_confirmations_threshold;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(txid);
@@ -1211,8 +1211,8 @@ namespace wallet_rpc
KV_SERIALIZE(subaddr_index);
KV_SERIALIZE(address);
KV_SERIALIZE(double_spend_seen)
- KV_SERIALIZE_OPT(confirmations, 0)
- KV_SERIALIZE_OPT(suggested_confirmation_threshold, 0)
+ KV_SERIALIZE_OPT(confirmations, (uint64_t)0)
+ KV_SERIALIZE_OPT(suggested_confirmations_threshold, (uint64_t)0)
END_KV_SERIALIZE_MAP()
};