From fb3c8168179ce77b845b1ea0e2615307867c8159 Mon Sep 17 00:00:00 2001 From: Rafael Saes Date: Fri, 24 May 2024 10:13:02 -0300 Subject: [PATCH 1/4] fix: update tip on set scanning --- cw_bitcoin/lib/electrum_wallet.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index dac240a24..e571738b9 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -202,7 +202,7 @@ abstract class ElectrumWalletBase silentPaymentsScanningActive = active; if (active) { - final tip = await getCurrentChainTip(); + final tip = await getUpdatedChainTip(); if (tip == walletInfo.restoreHeight) { syncStatus = SyncedTipSyncStatus(tip); From da59860241b77cdf309eea1153ca726ef2d6db44 Mon Sep 17 00:00:00 2001 From: Rafael Saes Date: Fri, 24 May 2024 11:15:33 -0300 Subject: [PATCH 2/4] fix: connection switching back and forth --- cw_bitcoin/lib/electrum.dart | 10 +++++----- cw_bitcoin/lib/electrum_wallet.dart | 13 +++++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart index bcef89f43..464b56735 100644 --- a/cw_bitcoin/lib/electrum.dart +++ b/cw_bitcoin/lib/electrum.dart @@ -41,7 +41,7 @@ class ElectrumClient { bool get isConnected => _isConnected; Socket? socket; - void Function(bool)? onConnectionStatusChange; + void Function(bool?)? onConnectionStatusChange; int _id; final Map _tasks; Map get tasks => _tasks; @@ -91,7 +91,7 @@ class ElectrumClient { _setIsConnected(false); }, onDone: () { unterminatedString = ''; - _setIsConnected(false); + _setIsConnected(null); }); keepAlive(); } @@ -146,7 +146,7 @@ class ElectrumClient { await callWithTimeout(method: 'server.ping'); _setIsConnected(true); } on RequestFailedTimeoutException catch (_) { - _setIsConnected(false); + _setIsConnected(null); } } @@ -480,12 +480,12 @@ class ElectrumClient { } } - void _setIsConnected(bool isConnected) { + void _setIsConnected(bool? isConnected) { if (_isConnected != isConnected) { onConnectionStatusChange?.call(isConnected); } - _isConnected = isConnected; + _isConnected = isConnected ?? false; } void _handleResponse(Map response) { diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index e571738b9..bbe153de1 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -235,7 +235,10 @@ abstract class ElectrumWalletBase } Future getUpdatedChainTip() async { - _currentChainTip = await electrumClient.getCurrentBlockChainTip(); + final newTip = await electrumClient.getCurrentBlockChainTip(); + if (newTip != null && newTip > (_currentChainTip ?? 0)) { + _currentChainTip = newTip; + } return _currentChainTip ?? 0; } @@ -444,13 +447,15 @@ abstract class ElectrumWalletBase await electrumClient.close(); - electrumClient.onConnectionStatusChange = (bool isConnected) async { + electrumClient.onConnectionStatusChange = (bool? isConnected) async { if (syncStatus is SyncingSyncStatus) return; - if (isConnected && syncStatus is! SyncedSyncStatus) { + if (isConnected == true && syncStatus is! SyncedSyncStatus) { syncStatus = ConnectedSyncStatus(); - } else if (!isConnected) { + } else if (isConnected == false) { syncStatus = LostConnectionSyncStatus(); + } else if (!(isConnected ?? false) && syncStatus is! ConnectingSyncStatus) { + syncStatus = NotConnectedSyncStatus(); } }; From cfa4515a826674f7987db972cb9a74b9d67ec683 Mon Sep 17 00:00:00 2001 From: Rafael Saes Date: Fri, 24 May 2024 15:36:53 -0300 Subject: [PATCH 3/4] feat: check if node is electrs, and supports sp --- cw_bitcoin/lib/electrum.dart | 8 ++-- lib/bitcoin/cw_bitcoin.dart | 43 +++++++++++++++---- .../screens/dashboard/pages/balance_page.dart | 3 +- lib/src/screens/rescan/rescan_page.dart | 3 +- tool/configure.dart | 2 +- 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart index 464b56735..0c88e234e 100644 --- a/cw_bitcoin/lib/electrum.dart +++ b/cw_bitcoin/lib/electrum.dart @@ -150,7 +150,8 @@ class ElectrumClient { } } - Future> version() => call(method: 'server.version').then((dynamic result) { + Future> version() => + call(method: 'server.version', params: ["", "1.4"]).then((dynamic result) { if (result is List) { return result.map((dynamic val) => val.toString()).toList(); } @@ -287,9 +288,8 @@ class ElectrumClient { ); } - Future> getTweaks({required int height}) async => - await callWithTimeout(method: 'blockchain.tweaks.get', params: [height], timeout: 10000) - as Map; + Future getTweaks({required int height}) async => + await callWithTimeout(method: 'blockchain.tweaks.subscribe', params: [height, 1, false]); Future estimatefee({required int p}) => call(method: 'blockchain.estimatefee', params: [p]).then((dynamic result) { diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart index 75e7eb2a6..6bdba2c61 100644 --- a/lib/bitcoin/cw_bitcoin.dart +++ b/lib/bitcoin/cw_bitcoin.dart @@ -509,8 +509,7 @@ class CWBitcoin extends Bitcoin { Future setScanningActive(Object wallet, bool active) async { final bitcoinWallet = wallet as ElectrumWallet; - // TODO: always when setting to scanning active, will force switch nodes. Remove when not needed anymore - if (!getNodeIsCakeElectrs(wallet)) { + if (!(await getNodeIsElectrsSPEnabled(wallet))) { final node = Node( useSSL: false, uri: 'electrs.cakewallet.com:${(wallet.network == BitcoinNetwork.testnet ? 50002 : 50001)}', @@ -535,8 +534,7 @@ class CWBitcoin extends Bitcoin { @override Future rescan(Object wallet, {required int height, bool? doSingleScan}) async { final bitcoinWallet = wallet as ElectrumWallet; - // TODO: always when setting to scanning active, will force switch nodes. Remove when not needed anymore - if (!getNodeIsCakeElectrs(wallet)) { + if (!(await getNodeIsElectrsSPEnabled(wallet))) { final node = Node( useSSL: false, uri: 'electrs.cakewallet.com:${(wallet.network == BitcoinNetwork.testnet ? 50002 : 50001)}', @@ -547,13 +545,40 @@ class CWBitcoin extends Bitcoin { bitcoinWallet.rescan(height: height, doSingleScan: doSingleScan); } - @override - bool getNodeIsCakeElectrs(Object wallet) { + Future getNodeIsElectrs(Object wallet) async { final bitcoinWallet = wallet as ElectrumWallet; - final node = bitcoinWallet.node; - return node?.uri.host == 'electrs.cakewallet.com' && - node?.uri.port == (wallet.network == BitcoinNetwork.testnet ? 50002 : 50001); + final version = await bitcoinWallet.electrumClient.version(); + + if (version.isEmpty) { + return false; + } + + final server = version[0]; + + if (server.toLowerCase().contains('electrs')) { + return true; + } + + return false; + } + + @override + Future getNodeIsElectrsSPEnabled(Object wallet) async { + if (!(await getNodeIsElectrs(wallet))) { + return false; + } + + final bitcoinWallet = wallet as ElectrumWallet; + final tweaksResponse = await bitcoinWallet.electrumClient.getTweaks(height: 0); + + print('tweaksResponse: $tweaksResponse'); + + if (tweaksResponse != null) { + return true; + } + + return false; } @override diff --git a/lib/src/screens/dashboard/pages/balance_page.dart b/lib/src/screens/dashboard/pages/balance_page.dart index 2f6a10bb3..3ed2a603f 100644 --- a/lib/src/screens/dashboard/pages/balance_page.dart +++ b/lib/src/screens/dashboard/pages/balance_page.dart @@ -329,7 +329,8 @@ class CryptoBalanceWidget extends StatelessWidget { final isSilentPaymentsScanningActive = dashboardViewModel.silentPaymentsScanningActive; final newValue = !isSilentPaymentsScanningActive; - final needsToSwitch = bitcoin!.getNodeIsCakeElectrs(dashboardViewModel.wallet) == false; + final needsToSwitch = !isSilentPaymentsScanningActive && + await bitcoin!.getNodeIsElectrsSPEnabled(dashboardViewModel.wallet) == false; if (needsToSwitch) { return showPopUp( diff --git a/lib/src/screens/rescan/rescan_page.dart b/lib/src/screens/rescan/rescan_page.dart index b633a127e..521e314b3 100644 --- a/lib/src/screens/rescan/rescan_page.dart +++ b/lib/src/screens/rescan/rescan_page.dart @@ -55,7 +55,8 @@ class RescanPage extends BasePage { } Future _toggleSilentPaymentsScanning(BuildContext context) async { - final needsToSwitch = bitcoin!.getNodeIsCakeElectrs(_rescanViewModel.wallet) == false; + final needsToSwitch = + await bitcoin!.getNodeIsElectrsSPEnabled(_rescanViewModel.wallet) == false; if (needsToSwitch) { return showPopUp( diff --git a/tool/configure.dart b/tool/configure.dart index cf250fb54..5e4e64439 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -213,7 +213,7 @@ abstract class Bitcoin { {int? outputsCount, int? size}); int getHeightByDate({required DateTime date}); Future rescan(Object wallet, {required int height, bool? doSingleScan}); - bool getNodeIsCakeElectrs(Object wallet); + bool getNodeIsElectrsSPEnabled(Object wallet); void deleteSilentPaymentAddress(Object wallet, String address); Future updateFeeRates(Object wallet); int getMaxCustomFeeRate(Object wallet); From 76503938aed9604cb86a17b094fa33c11f8853ab Mon Sep 17 00:00:00 2001 From: Rafael Saes Date: Fri, 24 May 2024 16:29:10 -0300 Subject: [PATCH 4/4] chore: fix build --- tool/configure.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/configure.dart b/tool/configure.dart index 5e4e64439..95b85d121 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -213,7 +213,7 @@ abstract class Bitcoin { {int? outputsCount, int? size}); int getHeightByDate({required DateTime date}); Future rescan(Object wallet, {required int height, bool? doSingleScan}); - bool getNodeIsElectrsSPEnabled(Object wallet); + Future getNodeIsElectrsSPEnabled(Object wallet); void deleteSilentPaymentAddress(Object wallet, String address); Future updateFeeRates(Object wallet); int getMaxCustomFeeRate(Object wallet);