1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
From 45a4148e08f61fe6d85b7245e7ee445b8db97273 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Sat, 11 May 2024 16:25:10 +0200
Subject: [PATCH 03/16] store crash fix
Monero wallet crashes (sometimes) when it is syncing,
while the proper solution (that can be seen in feather)
is to not store wallet while it is being synced, this is not
acceptable for mobile wallets where OS can just come
and kill the wallet because it felt like it.
This patch depends on the background-sync patch, but
to use it as a standalone fix grabbing the definition for the
LOCK_REFRESH macro should be enough.
tobtoht suggested:
_say you want to store every 15 minutes during background sync. you stop the refresh every 15 minutes. then do something like this in the callback:_
```
// Make sure this doesn't run in the refresh thread
onRefreshed() {
if (hasItBeen15MinutesSinceWeStored()) {
store();
}
if (shouldWeContinueRefreshing()) {
startRefresh();
}
}
```
which works for crashes after the wallet is initially synced
but doesn't solve the issue for wallet that are syncing (it
would just wait for it to finish before actually storing).
Also imo store() functin should store the wallet, no matter
the current state.
---
external/randomwow | 2 +-
src/wallet/api/wallet.cpp | 23 +++++++++++------------
src/wallet/api/wallet.h | 1 -
src/wallet/wallet2.cpp | 12 +++++++++++-
src/wallet/wallet2.h | 3 +++
5 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/external/randomwow b/external/randomwow
index 6f30d4b92..27b099b6d 160000
--- a/external/randomwow
+++ b/external/randomwow
@@ -1 +1 @@
-Subproject commit 6f30d4b924fecb231e5b683915cc75d18b3b5866
+Subproject commit 27b099b6dd6fef6e17f58c6dfe00009e9c5df587
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index af420569c..d53372fc9 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -55,8 +55,8 @@ using namespace cryptonote;
#define MONERO_DEFAULT_LOG_CATEGORY "WalletAPI"
#define LOCK_REFRESH() \
- bool refresh_enabled = m_refreshEnabled; \
- m_refreshEnabled = false; \
+ bool refresh_enabled = m_wallet->get_refresh_enabled(); \
+ m_wallet->set_refresh_enabled(false); \
m_wallet->stop(); \
m_refreshCV.notify_one(); \
boost::mutex::scoped_lock lock(m_refreshMutex); \
@@ -466,7 +466,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
m_wallet2Callback.reset(new Wallet2CallbackImpl(this));
m_wallet->callback(m_wallet2Callback.get());
m_refreshThreadDone = false;
- m_refreshEnabled = false;
+ m_wallet->set_refresh_enabled(false);
m_addressBook.reset(new AddressBookImpl(this));
m_subaddress.reset(new SubaddressImpl(this));
m_subaddressAccount.reset(new SubaddressAccountImpl(this));
@@ -962,6 +962,7 @@ void WalletImpl::stop()
bool WalletImpl::store(const std::string &path)
{
clearStatus();
+ LOCK_REFRESH();
try {
if (path.empty()) {
m_wallet->store();
@@ -2449,10 +2450,10 @@ void WalletImpl::refreshThreadFunc()
}
LOG_PRINT_L3(__FUNCTION__ << ": refresh lock acquired...");
- LOG_PRINT_L3(__FUNCTION__ << ": m_refreshEnabled: " << m_refreshEnabled);
+ LOG_PRINT_L3(__FUNCTION__ << ": m_refreshEnabled: " << m_wallet->get_refresh_enabled());
LOG_PRINT_L3(__FUNCTION__ << ": m_status: " << status());
LOG_PRINT_L3(__FUNCTION__ << ": m_refreshShouldRescan: " << m_refreshShouldRescan);
- if (m_refreshEnabled) {
+ if (m_wallet->get_refresh_enabled()) {
LOG_PRINT_L3(__FUNCTION__ << ": refreshing...");
doRefresh();
}
@@ -2486,7 +2487,7 @@ void WalletImpl::doRefresh()
} catch (const std::exception &e) {
setStatusError(e.what());
break;
- }while(!rescan && (rescan=m_refreshShouldRescan.exchange(false))); // repeat if not rescanned and rescan was requested
+ }while(m_wallet->get_refresh_enabled() && !rescan && (rescan=m_refreshShouldRescan.exchange(false))); // repeat if not rescanned and rescan was requested
if (m_wallet2Callback->getListener()) {
m_wallet2Callback->getListener()->refreshed();
@@ -2496,9 +2497,9 @@ void WalletImpl::doRefresh()
void WalletImpl::startRefresh()
{
- if (!m_refreshEnabled) {
+ if (!m_wallet->get_refresh_enabled()) {
LOG_PRINT_L2(__FUNCTION__ << ": refresh started/resumed...");
- m_refreshEnabled = true;
+ m_wallet->set_refresh_enabled(true);
m_refreshCV.notify_one();
}
}
@@ -2508,7 +2509,7 @@ void WalletImpl::startRefresh()
void WalletImpl::stopRefresh()
{
if (!m_refreshThreadDone) {
- m_refreshEnabled = false;
+ m_wallet->set_refresh_enabled(false);
m_refreshThreadDone = true;
m_refreshCV.notify_one();
m_refreshThread.join();
@@ -2519,9 +2520,7 @@ void WalletImpl::pauseRefresh()
{
LOG_PRINT_L2(__FUNCTION__ << ": refresh paused...");
// TODO synchronize access
- if (!m_refreshThreadDone) {
- m_refreshEnabled = false;
- }
+ m_wallet->set_refresh_enabled(false);
}
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 1f199a72c..ac7ce2f6a 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -273,7 +273,6 @@ private:
std::unique_ptr<SubaddressAccountImpl> m_subaddressAccount;
// multi-threaded refresh stuff
- std::atomic<bool> m_refreshEnabled;
std::atomic<bool> m_refreshThreadDone;
std::atomic<int> m_refreshIntervalMillis;
std::atomic<bool> m_refreshShouldRescan;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index f111ad0d5..8d8ba33c5 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -1195,6 +1195,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
m_upper_transaction_weight_limit(0),
m_run(true),
m_callback(0),
+ m_refreshEnabled(false),
m_trusted_daemon(false),
m_nettype(nettype),
m_multisig_rounds_passed(0),
@@ -1415,6 +1416,14 @@ bool wallet2::set_daemon(std::string daemon_address, boost::optional<epee::net_u
return ret;
}
//----------------------------------------------------------------------------------------------------
+bool wallet2::get_refresh_enabled() {
+ return m_refreshEnabled;
+}
+//----------------------------------------------------------------------------------------------------
+void wallet2::set_refresh_enabled(bool val) {
+ m_refreshEnabled = val;
+}
+//----------------------------------------------------------------------------------------------------
bool wallet2::set_proxy(const std::string &address)
{
return m_http_client->set_proxy(address);
@@ -4151,8 +4160,9 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
// infer when we get an incoming output
bool first = true, last = false;
- while(m_run.load(std::memory_order_relaxed) && blocks_fetched < max_blocks)
+ while(m_run.load(std::memory_order_relaxed) && blocks_fetched < max_blocks && m_refreshEnabled)
{
+ LOG_ERROR("SYNCING");
uint64_t next_blocks_start_height;
std::vector<cryptonote::block_complete_entry> next_blocks;
std::vector<parsed_block> next_parsed_blocks;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 8ffad5675..a1d939a5a 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1078,6 +1078,8 @@ private:
epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_autodetect,
const std::string &proxy = "");
bool set_proxy(const std::string &address);
+ bool get_refresh_enabled();
+ void set_refresh_enabled(bool val);
void stop() { m_run.store(false, std::memory_order_relaxed); m_message_store.stop(); }
@@ -1996,6 +1998,7 @@ private:
boost::recursive_mutex m_daemon_rpc_mutex;
+ bool m_refreshEnabled;
bool m_trusted_daemon;
i_wallet2_callback* m_callback;
hw::device::device_type m_key_device_type;
--
2.51.0
|