aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md10
-rw-r--r--contrib/gitian/README.md4
-rw-r--r--src/blockchain_utilities/blockchain_export.cpp6
-rw-r--r--src/blockchain_utilities/blockchain_import.cpp12
-rw-r--r--src/blockchain_utilities/bootstrap_file.cpp75
-rw-r--r--src/blockchain_utilities/bootstrap_file.h10
-rw-r--r--src/blocks/checkpoints.datbin275780 -> 276292 bytes
-rw-r--r--src/checkpoints/checkpoints.cpp1
-rw-r--r--src/cryptonote_core/blockchain.cpp20
-rw-r--r--src/version.cpp.in2
-rw-r--r--src/wallet/api/wallet.cpp5
-rw-r--r--src/wallet/api/wallet.h1
-rw-r--r--src/wallet/api/wallet2_api.h5
13 files changed, 105 insertions, 46 deletions
diff --git a/README.md b/README.md
index f1c530b20..cd9fcbc39 100644
--- a/README.md
+++ b/README.md
@@ -134,8 +134,8 @@ Dates are provided in the format YYYY-MM-DD.
| 1788000 | 2019-03-09 | v10 | v0.14.0.0 | v0.14.1.2 | New PoW based on Cryptonight-R, new block weight algorithm, slightly more efficient RingCT format
| 1788720 | 2019-03-10 | v11 | v0.14.0.0 | v0.14.1.2 | forbid old RingCT transaction format
| 1978433 | 2019-11-30* | v12 | v0.15.0.0 | v0.16.0.0 | New PoW based on RandomX, only allow >= 2 outputs, change to the block median used to calculate penalty, v1 coinbases are forbidden, rct sigs in coinbase forbidden, 10 block lock time for incoming outputs
-| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.1.0 | New CLSAG transaction format
-| 2210720 | 2020-10-18 | v14 | v0.17.0.0 | v0.17.1.0 | forbid old MLSAG transaction format
+| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.1.1 | New CLSAG transaction format
+| 2210720 | 2020-10-18 | v14 | v0.17.1.1 | v0.17.1.1 | forbid old MLSAG transaction format
| XXXXXXX | XXX-XX-XX | XXX | vX.XX.X.X | vX.XX.X.X | XXX |
X's indicate that these details have not been determined as of commit date.
@@ -295,7 +295,7 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch (
```bash
git clone https://github.com/monero-project/monero.git
cd monero
- git checkout tags/v0.17.1.0
+ git checkout tags/v0.17.1.1
```
* Build:
@@ -412,10 +412,10 @@ application.
cd monero
```
-* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.17.1.0'. If you don't care about the version and just want binaries from master, skip this step:
+* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.17.1.1'. If you don't care about the version and just want binaries from master, skip this step:
```bash
- git checkout v0.17.1.0
+ git checkout v0.17.1.1
```
* If you are on a 64-bit system, run:
diff --git a/contrib/gitian/README.md b/contrib/gitian/README.md
index 2b277f8c4..0a15f80b6 100644
--- a/contrib/gitian/README.md
+++ b/contrib/gitian/README.md
@@ -126,7 +126,7 @@ Setup for LXC:
```bash
GH_USER=fluffypony
-VERSION=v0.17.1.0
+VERSION=v0.17.1.1
./gitian-build.py --setup $GH_USER $VERSION
```
@@ -182,7 +182,7 @@ If you chose to do detached signing using `--detach-sign` above (recommended), y
```bash
GH_USER=fluffypony
-VERSION=v0.17.1.0
+VERSION=v0.17.1.1
gpg --detach-sign ${VERSION}-linux/${GH_USER}/monero-linux-*-build.assert
gpg --detach-sign ${VERSION}-win/${GH_USER}/monero-win-*-build.assert
diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp
index e55930b00..87cd7945c 100644
--- a/src/blockchain_utilities/blockchain_export.cpp
+++ b/src/blockchain_utilities/blockchain_export.cpp
@@ -47,6 +47,7 @@ int main(int argc, char* argv[])
epee::string_tools::set_module_name_and_folder(argv[0]);
uint32_t log_level = 0;
+ uint64_t block_start = 0;
uint64_t block_stop = 0;
bool blocks_dat = false;
@@ -58,6 +59,7 @@ int main(int argc, char* argv[])
po::options_description desc_cmd_sett("Command line options and settings options");
const command_line::arg_descriptor<std::string> arg_output_file = {"output-file", "Specify output file", "", true};
const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""};
+ const command_line::arg_descriptor<uint64_t> arg_block_start = {"block-start", "Start at block number", block_start};
const command_line::arg_descriptor<uint64_t> arg_block_stop = {"block-stop", "Stop at block number", block_stop};
const command_line::arg_descriptor<bool> arg_blocks_dat = {"blocksdat", "Output in blocks.dat format", blocks_dat};
@@ -67,6 +69,7 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_cmd_sett, cryptonote::arg_testnet_on);
command_line::add_arg(desc_cmd_sett, cryptonote::arg_stagenet_on);
command_line::add_arg(desc_cmd_sett, arg_log_level);
+ command_line::add_arg(desc_cmd_sett, arg_block_start);
command_line::add_arg(desc_cmd_sett, arg_block_stop);
command_line::add_arg(desc_cmd_sett, arg_blocks_dat);
@@ -97,6 +100,7 @@ int main(int argc, char* argv[])
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
else
mlog_set_log(std::string(std::to_string(log_level) + ",bcutil:INFO").c_str());
+ block_start = command_line::get_arg(vm, arg_block_start);
block_stop = command_line::get_arg(vm, arg_block_stop);
LOG_PRINT_L0("Starting...");
@@ -178,7 +182,7 @@ int main(int argc, char* argv[])
else
{
BootstrapFile bootstrap;
- r = bootstrap.store_blockchain_raw(core_storage, NULL, output_file_path, block_stop);
+ r = bootstrap.store_blockchain_raw(core_storage, NULL, output_file_path, block_start, block_stop);
}
CHECK_AND_ASSERT_MES(r, 1, "Failed to export blockchain raw data");
LOG_PRINT_L0("Blockchain raw data exported OK");
diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp
index ab2313096..60c069c3b 100644
--- a/src/blockchain_utilities/blockchain_import.cpp
+++ b/src/blockchain_utilities/blockchain_import.cpp
@@ -227,6 +227,7 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path
return false;
}
+ uint64_t block_first, block_last;
uint64_t start_height = 1, seek_height;
if (opt_resume)
start_height = core.get_blockchain_storage().get_current_blockchain_height();
@@ -235,10 +236,10 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path
BootstrapFile bootstrap;
std::streampos pos;
// BootstrapFile bootstrap(import_file_path);
- uint64_t total_source_blocks = bootstrap.count_blocks(import_file_path, pos, seek_height);
- MINFO("bootstrap file last block number: " << total_source_blocks-1 << " (zero-based height) total blocks: " << total_source_blocks);
+ uint64_t total_source_blocks = bootstrap.count_blocks(import_file_path, pos, seek_height, block_first);
+ MINFO("bootstrap file last block number: " << total_source_blocks+block_first-1 << " (zero-based height) total blocks: " << total_source_blocks);
- if (total_source_blocks-1 <= start_height)
+ if (total_source_blocks+block_first-1 <= start_height)
{
return false;
}
@@ -260,7 +261,8 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path
// 4 byte magic + (currently) 1024 byte header structures
uint8_t major_version, minor_version;
- bootstrap.seek_to_first_chunk(import_file, major_version, minor_version);
+ uint64_t dummy;
+ bootstrap.seek_to_first_chunk(import_file, major_version, minor_version, dummy, dummy);
std::string str1;
char buffer1[1024];
@@ -275,7 +277,7 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path
if (! block_stop)
{
- block_stop = total_source_blocks - 1;
+ block_stop = total_source_blocks+block_first - 1;
}
// These are what we'll try to use, and they don't have to be a determination
diff --git a/src/blockchain_utilities/bootstrap_file.cpp b/src/blockchain_utilities/bootstrap_file.cpp
index a4704626f..7050b9ab1 100644
--- a/src/blockchain_utilities/bootstrap_file.cpp
+++ b/src/blockchain_utilities/bootstrap_file.cpp
@@ -52,7 +52,7 @@ namespace
-bool BootstrapFile::open_writer(const boost::filesystem::path& file_path)
+bool BootstrapFile::open_writer(const boost::filesystem::path& file_path, uint64_t start_block, uint64_t stop_block)
{
const boost::filesystem::path dir_path = file_path.parent_path();
if (!dir_path.empty())
@@ -78,7 +78,7 @@ bool BootstrapFile::open_writer(const boost::filesystem::path& file_path)
m_raw_data_file = new std::ofstream();
bool do_initialize_file = false;
- uint64_t num_blocks = 0;
+ uint64_t num_blocks = 0, block_first = 0;
if (! boost::filesystem::exists(file_path))
{
@@ -88,10 +88,12 @@ bool BootstrapFile::open_writer(const boost::filesystem::path& file_path)
}
else
{
- num_blocks = count_blocks(file_path.string());
- MDEBUG("appending to existing file with height: " << num_blocks-1 << " total blocks: " << num_blocks);
+ std::streampos dummy_pos;
+ uint64_t dummy_height = 0;
+ num_blocks = count_blocks(file_path.string(), dummy_pos, dummy_height, block_first);
+ MDEBUG("appending to existing file with height: " << num_blocks+block_first-1 << " total blocks: " << num_blocks);
}
- m_height = num_blocks;
+ m_height = num_blocks+block_first;
if (do_initialize_file)
m_raw_data_file->open(file_path.string(), std::ios_base::binary | std::ios_base::out | std::ios::trunc);
@@ -106,13 +108,12 @@ bool BootstrapFile::open_writer(const boost::filesystem::path& file_path)
return false;
if (do_initialize_file)
- initialize_file();
+ initialize_file(start_block, stop_block);
return true;
}
-
-bool BootstrapFile::initialize_file()
+bool BootstrapFile::initialize_file(uint64_t first_block, uint64_t last_block)
{
const uint32_t file_magic = blockchain_raw_magic;
@@ -129,8 +130,8 @@ bool BootstrapFile::initialize_file()
bfi.header_size = header_size;
bootstrap::blocks_info bbi;
- bbi.block_first = 0;
- bbi.block_last = 0;
+ bbi.block_first = first_block;
+ bbi.block_last = last_block;
bbi.block_last_pos = 0;
buffer_type buffer2;
@@ -261,7 +262,7 @@ bool BootstrapFile::close()
}
-bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop)
+bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t start_block, uint64_t requested_block_stop)
{
uint64_t num_blocks_written = 0;
m_max_chunk = 0;
@@ -269,17 +270,11 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem
m_tx_pool = _tx_pool;
uint64_t progress_interval = 100;
MINFO("Storing blocks raw data...");
- if (!BootstrapFile::open_writer(output_file))
- {
- MFATAL("failed to open raw file for write");
- return false;
- }
block b;
// block_start, block_stop use 0-based height. m_height uses 1-based height. So to resume export
// from last exported block, block_start doesn't need to add 1 here, as it's already at the next
// height.
- uint64_t block_start = m_height;
uint64_t block_stop = 0;
MINFO("source blockchain height: " << m_blockchain_storage->get_current_blockchain_height()-1);
if ((requested_block_stop > 0) && (requested_block_stop < m_blockchain_storage->get_current_blockchain_height()))
@@ -292,6 +287,13 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem
block_stop = m_blockchain_storage->get_current_blockchain_height() - 1;
MINFO("Using block height of source blockchain: " << block_stop);
}
+ if (!BootstrapFile::open_writer(output_file, start_block, block_stop))
+ {
+ MFATAL("failed to open raw file for write");
+ return false;
+ }
+ uint64_t block_start = m_height ? m_height : start_block;
+ MINFO("Starting block height: " << block_start);
for (m_cur_height = block_start; m_cur_height <= block_stop; ++m_cur_height)
{
// this method's height refers to 0-based height (genesis block = height 0)
@@ -323,7 +325,8 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem
return BootstrapFile::close();
}
-uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file, uint8_t &major_version, uint8_t &minor_version)
+uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file, uint8_t &major_version, uint8_t &minor_version,
+ uint64_t &block_first, uint64_t &block_last)
{
uint32_t file_magic;
@@ -368,11 +371,35 @@ uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file, uint8_t
MINFO("bootstrap magic size: " << sizeof(file_magic));
MINFO("bootstrap header size: " << bfi.header_size);
+ uint32_t buflen_blocks_info;
+
+ import_file.read(buf1, sizeof(buflen_blocks_info));
+ str1.assign(buf1, sizeof(buflen_blocks_info));
+ if (! import_file)
+ throw std::runtime_error("Error reading expected number of bytes");
+ if (! ::serialization::parse_binary(str1, buflen_blocks_info))
+ throw std::runtime_error("Error in deserialization of buflen_blocks_info");
+ MINFO("bootstrap::blocks_info size: " << buflen_blocks_info);
+
+ if (buflen_blocks_info > sizeof(buf1))
+ throw std::runtime_error("Error: bootstrap::blocks_info size exceeds buffer size");
+ import_file.read(buf1, buflen_blocks_info);
+ if (! import_file)
+ throw std::runtime_error("Error reading expected number of bytes");
+ str1.assign(buf1, buflen_blocks_info);
+ bootstrap::blocks_info bbi;
+ if (! ::serialization::parse_binary(str1, bbi))
+ throw std::runtime_error("Error in deserialization of bootstrap::blocks_info");
+ MINFO("bootstrap first block:" << bbi.block_first);
+ MINFO("bootstrap last block:" << bbi.block_last);
+
uint64_t full_header_size = sizeof(file_magic) + bfi.header_size;
import_file.seekg(full_header_size);
major_version = bfi.major_version;
minor_version = bfi.minor_version;
+ block_first = bbi.block_first;
+ block_last = bbi.block_last;
return full_header_size;
}
@@ -436,13 +463,14 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path)
{
std::streampos dummy_pos;
uint64_t dummy_height = 0;
- return count_blocks(import_file_path, dummy_pos, dummy_height);
+ return count_blocks(import_file_path, dummy_pos, dummy_height, dummy_height);
}
// If seek_height is non-zero on entry, return a stream position <= this height when finished.
// And return the actual height corresponding to this position. Allows the caller to locate its
// starting position without having to reread the entire file again.
-uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::streampos &start_pos, uint64_t& seek_height)
+uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::streampos &start_pos,
+ uint64_t& seek_height, uint64_t &block_first)
{
boost::filesystem::path raw_file_path(import_file_path);
boost::system::error_code ec;
@@ -464,7 +492,8 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::s
uint64_t full_header_size; // 4 byte magic + length of header structures
uint8_t major_version, minor_version;
- full_header_size = seek_to_first_chunk(import_file, major_version, minor_version);
+ uint64_t block_last;
+ full_header_size = seek_to_first_chunk(import_file, major_version, minor_version, block_first, block_last);
MINFO("Scanning blockchain from bootstrap file...");
bool quit = false;
@@ -473,11 +502,11 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::s
while (! quit)
{
- if (start_height && h + progress_interval >= start_height - 1)
+ if (start_height && h + block_first + progress_interval >= start_height - 1)
{
start_height = 0;
start_pos = import_file.tellg();
- seek_height = h;
+ seek_height = h + block_first;
}
bytes_read += count_bytes(import_file, progress_interval, blocks, quit);
h += blocks;
diff --git a/src/blockchain_utilities/bootstrap_file.h b/src/blockchain_utilities/bootstrap_file.h
index 23dbb64d7..ff2875a61 100644
--- a/src/blockchain_utilities/bootstrap_file.h
+++ b/src/blockchain_utilities/bootstrap_file.h
@@ -57,12 +57,12 @@ class BootstrapFile
public:
uint64_t count_bytes(std::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit);
- uint64_t count_blocks(const std::string& dir_path, std::streampos& start_pos, uint64_t& seek_height);
+ uint64_t count_blocks(const std::string& dir_path, std::streampos& start_pos, uint64_t& seek_height, uint64_t& block_first);
uint64_t count_blocks(const std::string& dir_path);
- uint64_t seek_to_first_chunk(std::ifstream& import_file, uint8_t &major_version, uint8_t &minor_version);
+ uint64_t seek_to_first_chunk(std::ifstream& import_file, uint8_t &major_version, uint8_t &minor_version, uint64_t &block_first, uint64_t &block_last);
bool store_blockchain_raw(cryptonote::Blockchain* cs, cryptonote::tx_memory_pool* txp,
- boost::filesystem::path& output_file, uint64_t use_block_height=0);
+ boost::filesystem::path& output_file, uint64_t start_block=0, uint64_t stop_block=0);
protected:
@@ -75,8 +75,8 @@ protected:
boost::iostreams::stream<boost::iostreams::back_insert_device<buffer_type>>* m_output_stream;
// open export file for write
- bool open_writer(const boost::filesystem::path& file_path);
- bool initialize_file();
+ bool open_writer(const boost::filesystem::path& file_path, uint64_t start_block, uint64_t stop_block);
+ bool initialize_file(uint64_t start_block, uint64_t stop_block);
bool close();
void write_block(block& block);
void flush_chunk();
diff --git a/src/blocks/checkpoints.dat b/src/blocks/checkpoints.dat
index 1a39fda5d..5362e5f63 100644
--- a/src/blocks/checkpoints.dat
+++ b/src/blocks/checkpoints.dat
Binary files differ
diff --git a/src/checkpoints/checkpoints.cpp b/src/checkpoints/checkpoints.cpp
index 2d47ec922..b9accc952 100644
--- a/src/checkpoints/checkpoints.cpp
+++ b/src/checkpoints/checkpoints.cpp
@@ -239,6 +239,7 @@ namespace cryptonote
ADD_CHECKPOINT2(2182500, "0d22b5f81982eff21d094af9e821dc2007e6342069e3b1a37b15d97646353124", "0xead4a874083492");
ADD_CHECKPOINT2(2193000, "6e91b917a40309f89f75f2c8d7be5a6d1a3c425634f07f7d1867bd32d2e602ed", "0xf085140f17389d");
ADD_CHECKPOINT2(2206500, "dd3c8590f33eaa546a4ce69d02f27fd58a2f115cd32d733bd9426f8278f0cb8a", "0xf8725275799f0d");
+ ADD_CHECKPOINT2(2210500, "ed17259215ac6aabe6e8252b5b5eff613d2e69cc2111173e567109aa78301911", "0xfbcb50a9a6a433");
return true;
}
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 645123fae..b8b407dcf 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -3068,9 +3068,21 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
if (tx.version >= 2) {
if (tx.rct_signatures.type <= rct::RCTTypeBulletproof2)
{
- MERROR_VER("Ringct type " << (unsigned)tx.rct_signatures.type << " is not allowed from v" << (HF_VERSION_CLSAG + 1));
- tvc.m_invalid_output = true;
- return false;
+ // two MLSAG txes went in due to a bug with txes that went into the txpool before the fork, grandfather them in
+ static const char * grandfathered[2] = { "c5151944f0583097ba0c88cd0f43e7fabb3881278aa2f73b3b0a007c5d34e910", "6f2f117cde6fbcf8d4a6ef8974fcac744726574ac38cf25d3322c996b21edd4c" };
+ crypto::hash h0, h1;
+ epee::string_tools::hex_to_pod(grandfathered[0], h0);
+ epee::string_tools::hex_to_pod(grandfathered[1], h1);
+ if (cryptonote::get_transaction_hash(tx) == h0 || cryptonote::get_transaction_hash(tx) == h1)
+ {
+ MDEBUG("Grandfathering cryptonote::get_transaction_hash(tx) in");
+ }
+ else
+ {
+ MERROR_VER("Ringct type " << (unsigned)tx.rct_signatures.type << " is not allowed from v" << (HF_VERSION_CLSAG + 1));
+ tvc.m_invalid_output = true;
+ return false;
+ }
}
}
}
@@ -5364,7 +5376,7 @@ void Blockchain::cancel()
}
#if defined(PER_BLOCK_CHECKPOINT)
-static const char expected_block_hashes_hash[] = "49db4105aadc7c296ffbf5d56de1785361684671544489f3c5e56cb40ef92a28";
+static const char expected_block_hashes_hash[] = "be42dfed51f6b9da134d7dcfd5f4b7e1df8cae93f1b41b846a5818f0aaf09fda";
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
{
if (get_checkpoints == nullptr || !m_fast_sync)
diff --git a/src/version.cpp.in b/src/version.cpp.in
index 0c24fd45c..bd5caa039 100644
--- a/src/version.cpp.in
+++ b/src/version.cpp.in
@@ -1,5 +1,5 @@
#define DEF_MONERO_VERSION_TAG "@VERSIONTAG@"
-#define DEF_MONERO_VERSION "0.17.1.0"
+#define DEF_MONERO_VERSION "0.17.1.1"
#define DEF_MONERO_RELEASE_NAME "Oxygen Orion"
#define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG
#define DEF_MONERO_VERSION_IS_RELEASE @VERSION_IS_RELEASE@
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 152a7dcd7..9acc8484c 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -910,6 +910,11 @@ std::string WalletImpl::path() const
return m_wallet->path();
}
+void WalletImpl::stop()
+{
+ m_wallet->stop();
+}
+
bool WalletImpl::store(const std::string &path)
{
clearStatus();
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index caf1e9ed4..3bf3e759b 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -99,6 +99,7 @@ public:
std::string publicSpendKey() const override;
std::string publicMultisigSignerKey() const override;
std::string path() const override;
+ void stop() override;
bool store(const std::string &path) override;
std::string filename() const override;
std::string keysFilename() const override;
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 50df7e5dd..999823ff1 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -507,6 +507,11 @@ struct Wallet
virtual std::string publicMultisigSignerKey() const = 0;
/*!
+ * \brief stop - interrupts wallet refresh() loop once (doesn't stop background refresh thread)
+ */
+ virtual void stop() = 0;
+
+ /*!
* \brief store - stores wallet to file.
* \param path - main filename to store wallet to. additionally stores address file and keys file.
* to store to the same file - just pass empty string;