|
6 | 6 | import java.util.concurrent.CountDownLatch;
|
7 | 7 | import java.util.concurrent.TimeUnit;
|
8 | 8 |
|
9 |
| -import org.apache.commons.lang3.exception.ExceptionUtils; |
10 |
| - |
11 | 9 | import haveno.common.Timer;
|
12 | 10 | import haveno.common.UserThread;
|
13 | 11 | import haveno.core.api.XmrConnectionService;
|
|
28 | 26 | public abstract class XmrWalletBase {
|
29 | 27 |
|
30 | 28 | // constants
|
31 |
| - public static final int SYNC_PROGRESS_TIMEOUT_SECONDS = 120; |
| 29 | + public static final int SYNC_PROGRESS_TIMEOUT_SECONDS = 180; |
32 | 30 | public static final int DIRECT_SYNC_WITHIN_BLOCKS = 100;
|
33 | 31 | public static final int SAVE_WALLET_DELAY_SECONDS = 300;
|
34 | 32 | private static final String SYNC_PROGRESS_TIMEOUT_MSG = "Sync progress timeout called";
|
@@ -71,74 +69,80 @@ public void syncWithProgress() {
|
71 | 69 |
|
72 | 70 | public void syncWithProgress(boolean repeatSyncToLatestHeight) {
|
73 | 71 | synchronized (walletLock) {
|
| 72 | + try { |
| 73 | + |
| 74 | + // set initial state |
| 75 | + if (isSyncingWithProgress) log.warn("Syncing with progress while already syncing with progress. That should never happen"); |
| 76 | + isSyncingWithProgress = true; |
| 77 | + syncProgressError = null; |
| 78 | + long targetHeightAtStart = xmrConnectionService.getTargetHeight(); |
| 79 | + syncStartHeight = walletHeight.get(); |
| 80 | + updateSyncProgress(syncStartHeight, targetHeightAtStart); |
| 81 | + |
| 82 | + // test connection changing on startup before wallet synced |
| 83 | + if (testReconnectOnStartup) { |
| 84 | + UserThread.runAfter(() -> { |
| 85 | + log.warn("Testing connection change on startup before wallet synced"); |
| 86 | + if (xmrConnectionService.getConnection().getUri().equals(testReconnectMonerod1)) xmrConnectionService.setConnection(testReconnectMonerod2); |
| 87 | + else xmrConnectionService.setConnection(testReconnectMonerod1); |
| 88 | + }, 1); |
| 89 | + testReconnectOnStartup = false; // only run once |
| 90 | + } |
74 | 91 |
|
75 |
| - // set initial state |
76 |
| - if (isSyncingWithProgress) log.warn("Syncing with progress while already syncing with progress. That should never happen"); |
77 |
| - isSyncingWithProgress = true; |
78 |
| - syncProgressError = null; |
79 |
| - long targetHeightAtStart = xmrConnectionService.getTargetHeight(); |
80 |
| - syncStartHeight = walletHeight.get(); |
81 |
| - updateSyncProgress(syncStartHeight, targetHeightAtStart); |
82 |
| - |
83 |
| - // test connection changing on startup before wallet synced |
84 |
| - if (testReconnectOnStartup) { |
85 |
| - UserThread.runAfter(() -> { |
86 |
| - log.warn("Testing connection change on startup before wallet synced"); |
87 |
| - if (xmrConnectionService.getConnection().getUri().equals(testReconnectMonerod1)) xmrConnectionService.setConnection(testReconnectMonerod2); |
88 |
| - else xmrConnectionService.setConnection(testReconnectMonerod1); |
89 |
| - }, 1); |
90 |
| - testReconnectOnStartup = false; // only run once |
91 |
| - } |
| 92 | + // native wallet provides sync notifications |
| 93 | + if (wallet instanceof MoneroWalletFull) { |
| 94 | + if (testReconnectOnStartup) HavenoUtils.waitFor(1000); // delay sync to test |
| 95 | + wallet.sync(new MoneroWalletListener() { |
| 96 | + @Override |
| 97 | + public void onSyncProgress(long height, long startHeight, long endHeight, double percentDone, String message) { |
| 98 | + long appliedTargetHeight = repeatSyncToLatestHeight ? xmrConnectionService.getTargetHeight() : targetHeightAtStart; |
| 99 | + updateSyncProgress(height, appliedTargetHeight); |
| 100 | + } |
| 101 | + }); |
| 102 | + setWalletSyncedWithProgress(); |
| 103 | + return; |
| 104 | + } |
92 | 105 |
|
93 |
| - // native wallet provides sync notifications |
94 |
| - if (wallet instanceof MoneroWalletFull) { |
95 |
| - if (testReconnectOnStartup) HavenoUtils.waitFor(1000); // delay sync to test |
96 |
| - wallet.sync(new MoneroWalletListener() { |
97 |
| - @Override |
98 |
| - public void onSyncProgress(long height, long startHeight, long endHeight, double percentDone, String message) { |
99 |
| - long appliedTargetHeight = repeatSyncToLatestHeight ? xmrConnectionService.getTargetHeight() : targetHeightAtStart; |
100 |
| - updateSyncProgress(height, appliedTargetHeight); |
| 106 | + // start polling wallet for progress |
| 107 | + syncProgressLatch = new CountDownLatch(1); |
| 108 | + syncProgressLooper = new TaskLooper(() -> { |
| 109 | + long height; |
| 110 | + try { |
| 111 | + height = wallet.getHeight(); // can get read timeout while syncing |
| 112 | + } catch (Exception e) { |
| 113 | + if (wallet != null && !isShutDownStarted) { |
| 114 | + log.warn("Error getting wallet height while syncing with progress: " + e.getMessage()); |
| 115 | + } |
| 116 | + return; |
| 117 | + } |
| 118 | + long appliedTargetHeight = repeatSyncToLatestHeight ? xmrConnectionService.getTargetHeight() : targetHeightAtStart; |
| 119 | + updateSyncProgress(height, appliedTargetHeight); |
| 120 | + if (height >= appliedTargetHeight) { |
| 121 | + setWalletSyncedWithProgress(); |
| 122 | + syncProgressLatch.countDown(); |
101 | 123 | }
|
102 | 124 | });
|
103 |
| - setWalletSyncedWithProgress(); |
104 |
| - return; |
105 |
| - } |
106 |
| - |
107 |
| - // start polling wallet for progress |
108 |
| - syncProgressLatch = new CountDownLatch(1); |
109 |
| - syncProgressLooper = new TaskLooper(() -> { |
110 |
| - long height; |
111 |
| - try { |
112 |
| - height = wallet.getHeight(); // can get read timeout while syncing |
113 |
| - } catch (Exception e) { |
114 |
| - if (wallet != null && !isShutDownStarted) { |
115 |
| - log.warn("Error getting wallet height while syncing with progress: " + e.getMessage()); |
| 125 | + wallet.startSyncing(xmrConnectionService.getRefreshPeriodMs()); |
| 126 | + syncProgressLooper.start(1000); |
| 127 | + |
| 128 | + // wait for sync to complete |
| 129 | + HavenoUtils.awaitLatch(syncProgressLatch); |
| 130 | + |
| 131 | + // stop polling |
| 132 | + syncProgressLooper.stop(); |
| 133 | + syncProgressTimeout.stop(); |
| 134 | + if (wallet != null) { // can become null if interrupted by force close |
| 135 | + if (syncProgressError == null || !HavenoUtils.isUnresponsive(syncProgressError)) { // TODO: skipping stop sync if unresponsive because wallet will hang. if unresponsive, wallet is assumed to be force restarted by caller, but that should be done internally here instead of externally? |
| 136 | + wallet.stopSyncing(); |
116 | 137 | }
|
117 |
| - return; |
118 |
| - } |
119 |
| - long appliedTargetHeight = repeatSyncToLatestHeight ? xmrConnectionService.getTargetHeight() : targetHeightAtStart; |
120 |
| - updateSyncProgress(height, appliedTargetHeight); |
121 |
| - if (height >= appliedTargetHeight) { |
122 |
| - setWalletSyncedWithProgress(); |
123 |
| - syncProgressLatch.countDown(); |
124 |
| - } |
125 |
| - }); |
126 |
| - wallet.startSyncing(xmrConnectionService.getRefreshPeriodMs()); |
127 |
| - syncProgressLooper.start(1000); |
128 |
| - |
129 |
| - // wait for sync to complete |
130 |
| - HavenoUtils.awaitLatch(syncProgressLatch); |
131 |
| - |
132 |
| - // stop polling |
133 |
| - syncProgressLooper.stop(); |
134 |
| - syncProgressTimeout.stop(); |
135 |
| - isSyncingWithProgress = false; |
136 |
| - if (wallet != null) { // can become null if interrupted by force close |
137 |
| - if (syncProgressError == null || !HavenoUtils.isUnresponsive(syncProgressError)) { // TODO: skipping stop sync if unresponsive because wallet will hang. if unresponsive, wallet is assumed to be force restarted by caller, but that should be done internally here instead of externally? |
138 |
| - wallet.stopSyncing(); |
139 | 138 | }
|
| 139 | + if (syncProgressError != null) throw new RuntimeException(syncProgressError); |
| 140 | + } catch (Exception e) { |
| 141 | + throw e; |
| 142 | + } finally { |
| 143 | + isSyncingWithProgress = false; |
140 | 144 | }
|
141 |
| - if (syncProgressError != null) throw new RuntimeException(syncProgressError); |
| 145 | + |
142 | 146 | }
|
143 | 147 | }
|
144 | 148 |
|
|
0 commit comments