From 5a497bf05aebe2488c91a51fb8a041083d24c3e0 Mon Sep 17 00:00:00 2001 From: cyan Date: Wed, 2 Sep 2026 18:17:28 +0800 Subject: [PATCH] Monero: keep the sync progress redrawing during wallet2's warm-up (#3575) * Monero: keep the sync progress redrawing during wallet2's warm-up * fix: double call in getNodeHeight() fix: error handling in _refreshNodeHeight --------- Co-authored-by: Vikrant Sharma --- cw_monero/lib/api/wallet.dart | 64 +++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart index 787933217..7e094235a 100644 --- a/cw_monero/lib/api/wallet.dart +++ b/cw_monero/lib/api/wallet.dart @@ -165,23 +165,44 @@ int getCurrentHeight() => currentWallet?.blockChainHeight() ?? 0; int cachedNodeHeight = 0; bool isHeightRefreshing = false; + +Future? _nodeHeightInFlight; + +Future _refreshNodeHeight() { + final inFlight = _nodeHeightInFlight; + if (inFlight != null) return inFlight; + + try { + final wallet = currentWallet; + if (wallet == null) return Future.value(cachedNodeHeight); + + final wptrAddress = wallet.ffiAddress(); + isHeightRefreshing = true; + final f = Isolate.run(() async { + return monero.Wallet_daemonBlockChainHeight(Pointer.fromAddress(wptrAddress)); + }).then((h) { + cachedNodeHeight = h; + return h; + }).catchError((_) => cachedNodeHeight).whenComplete(() { + isHeightRefreshing = false; + _nodeHeightInFlight = null; + }); + _nodeHeightInFlight = f; + return f; + } catch (e) { + printV("error refreshing node height: $e"); + isHeightRefreshing = false; + _nodeHeightInFlight = null; + return Future.value(cachedNodeHeight); + } +} + int getNodeHeightSync() { if (isHeightRefreshing == false) { if (cachedNodeHeight != 0 && getWlptr()?.height() == 1) { return cachedNodeHeight; } - (() async { - try { - isHeightRefreshing = true; - final wptrAddress = currentWallet!.ffiAddress(); - cachedNodeHeight = await Isolate.run(() async { - return monero.Wallet_daemonBlockChainHeight(Pointer.fromAddress(wptrAddress)); - }); - } catch (_) { - } finally { - isHeightRefreshing = false; - } - })(); + unawaited(_refreshNodeHeight()); } return cachedNodeHeight; } @@ -319,6 +340,9 @@ class SyncListener { int _cachedBlockchainHeight; int _lastKnownBlockHeight; int _initialSyncHeight; + int _lastKnownNodeHeight = 0; + int _ticksSinceEmit = 0; + static const int _heartbeatTicks = 5; Future getNodeHeightOrUpdate(int baseHeight) async { if (_cachedBlockchainHeight < baseHeight || _cachedBlockchainHeight == 0) { @@ -331,6 +355,8 @@ class SyncListener { void _start() { _cachedBlockchainHeight = 0; _lastKnownBlockHeight = 0; + _lastKnownNodeHeight = 0; + _ticksSinceEmit = 0; _initialSyncHeight = 0; _updateSyncInfoTimer ??= Timer.periodic(Duration(milliseconds: 1200), (_) async { if (isNewTransactionExist()) { @@ -355,11 +381,17 @@ class SyncListener { } final bchHeight = max(nodeHeight, syncHeight); // printV("syncHeight: $syncHeight, _lastKnownBlockHeight: $_lastKnownBlockHeight, bchHeight: $bchHeight"); - if (_lastKnownBlockHeight == syncHeight) { + + _ticksSinceEmit++; + final nothingChanged = _lastKnownBlockHeight == syncHeight && + _lastKnownNodeHeight == nodeHeight; + if (nothingChanged && _ticksSinceEmit < _heartbeatTicks) { return; } + _ticksSinceEmit = 0; _lastKnownBlockHeight = syncHeight; + _lastKnownNodeHeight = nodeHeight; final track = bchHeight - _initialSyncHeight; final diff = track - (bchHeight - syncHeight); final ptc = diff <= 0 ? 0.0 : diff / track; @@ -410,7 +442,11 @@ void startRefresh() => startRefreshSync(); Future store() async => _storeSync(0); -Future getNodeHeight() async => getNodeHeightSync(); +Future getNodeHeight() async { + final cached = getNodeHeightSync(); + if (cached != 0) return cached; + return _refreshNodeHeight(); +} void rescanBlockchainAsync() => currentWallet!.rescanBlockchainAsync();