fix: improve scanning by date, fix single block scan

This commit is contained in:
Rafael Saes 2024-04-18 08:57:16 -03:00
parent 5b3128f751
commit ca81d44e6c
4 changed files with 37 additions and 32 deletions

View file

@ -8,8 +8,6 @@ import 'package:cw_bitcoin/script_hash.dart';
import 'package:flutter/foundation.dart';
import 'package:rxdart/rxdart.dart';
const int TWEAKS_COUNT = 20;
String jsonrpcparams(List<Object> params) {
final _params = params.map((val) => '"${val.toString()}"').join(',');
return '[$_params]';
@ -280,12 +278,12 @@ class ElectrumClient {
Future<Map<String, dynamic>> getHeader({required int height}) async =>
await call(method: 'blockchain.block.get_header', params: [height]) as Map<String, dynamic>;
BehaviorSubject<Object>? tweaksSubscribe({required int height}) {
BehaviorSubject<Object>? tweaksSubscribe({required int height, required int count}) {
_id += 1;
return subscribe<Object>(
id: 'blockchain.tweaks.subscribe:${height + TWEAKS_COUNT}',
id: 'blockchain.tweaks.subscribe:${height + count}',
method: 'blockchain.tweaks.subscribe',
params: [height, TWEAKS_COUNT],
params: [height, count],
);
}

View file

@ -48,6 +48,8 @@ part 'electrum_wallet.g.dart';
class ElectrumWallet = ElectrumWalletBase with _$ElectrumWallet;
const int TWEAKS_COUNT = 25;
abstract class ElectrumWalletBase
extends WalletBase<ElectrumBalance, ElectrumTransactionHistory, ElectrumTransactionInfo>
with Store {
@ -154,8 +156,6 @@ abstract class ElectrumWalletBase
silentPaymentsScanningActive = active;
if (active) {
await _setInitialHeight();
if ((await getCurrentChainTip()) > walletInfo.restoreHeight) {
_setListeners(walletInfo.restoreHeight, chainTipParam: _currentChainTip);
}
@ -1855,19 +1855,22 @@ Future<void> startRefresh(ScanData scanData) async {
final electrumClient = await getElectrumConnection();
if (tweaksSubscription == null) {
try {
tweaksSubscription = await electrumClient.tweaksSubscribe(height: syncHeight);
final count = scanData.isSingleScan ? 1 : TWEAKS_COUNT;
tweaksSubscription?.listen((t) {
try {
tweaksSubscription = await electrumClient.tweaksSubscribe(height: syncHeight, count: count);
tweaksSubscription?.listen((t) async {
final tweaks = t as Map<String, dynamic>;
if (tweaks["message"] != null) {
if (tweaks["message"] != null && !scanData.isSingleScan) {
// re-subscribe to continue receiving messages
electrumClient.tweaksSubscribe(height: syncHeight);
electrumClient.tweaksSubscribe(height: syncHeight, count: count);
return;
}
final blockHeight = tweaks.keys.first;
final tweakHeight = int.parse(blockHeight);
try {
final blockTweaks = tweaks[blockHeight] as Map<String, dynamic>;
@ -1901,13 +1904,13 @@ Future<void> startRefresh(ScanData scanData) async {
final txInfo = ElectrumTransactionInfo(
WalletType.bitcoin,
id: txid,
height: syncHeight,
height: tweakHeight,
amount: 0,
fee: 0,
direction: TransactionDirection.incoming,
isPending: false,
date: DateTime.now(),
confirmations: scanData.chainTip - int.parse(blockHeight) + 1,
confirmations: scanData.chainTip - tweakHeight + 1,
unspents: [],
);
@ -1961,7 +1964,7 @@ Future<void> startRefresh(ScanData scanData) async {
}
} catch (_) {}
syncHeight = int.parse(blockHeight);
syncHeight = tweakHeight;
scanData.sendPort.send(
SyncResponse(
syncHeight,
@ -1973,11 +1976,10 @@ Future<void> startRefresh(ScanData scanData) async {
),
);
if (int.parse(blockHeight) >= scanData.chainTip) {
if (int.parse(blockHeight) >= scanData.chainTip || scanData.isSingleScan) {
scanData.sendPort.send(SyncResponse(syncHeight, SyncedSyncStatus()));
await tweaksSubscription!.close();
}
return;
});
} catch (e) {
if (e is RequestFailedTimeoutException) {

View file

@ -264,10 +264,14 @@ const bitcoinDates = {
};
int getBitcoinHeightByDate({required DateTime date}) {
String closestKey =
bitcoinDates.keys.firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => '');
String dateKey = '${date.year}-${date.month.toString().padLeft(2, '0')}';
int startBlock = bitcoinDates[dateKey] ?? bitcoinDates.values.last;
final oldestHeight = bitcoinDates.values.last;
DateTime startOfMonth = DateTime(date.year, date.month);
int daysDifference = date.difference(startOfMonth).inDays;
return bitcoinDates[closestKey] ?? oldestHeight;
// approximately 6 blocks per hour, 24 hours per day
int estimatedBlocksSinceStartOfMonth = (daysDifference * 24 * 6);
return startBlock + estimatedBlocksSinceStartOfMonth;
}

View file

@ -3,15 +3,19 @@ import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/sync_status.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/store/settings_store.dart';
Timer? _checkConnectionTimer;
void startCheckConnectionReaction(
WalletBase wallet, SettingsStore settingsStore,
void startCheckConnectionReaction(WalletBase wallet, SettingsStore settingsStore,
{int timeInterval = 5}) {
_checkConnectionTimer?.cancel();
_checkConnectionTimer =
Timer.periodic(Duration(seconds: timeInterval), (_) async {
_checkConnectionTimer = Timer.periodic(Duration(seconds: timeInterval), (_) async {
if (wallet.type == WalletType.bitcoin && wallet.syncStatus is SyncingSyncStatus) {
return;
}
try {
final connectivityResult = await (Connectivity().checkConnectivity());
@ -20,14 +24,11 @@ void startCheckConnectionReaction(
return;
}
if (wallet.syncStatus is LostConnectionSyncStatus ||
wallet.syncStatus is FailedSyncStatus) {
final alive =
await settingsStore.getCurrentNode(wallet.type).requestNode();
if (wallet.syncStatus is LostConnectionSyncStatus || wallet.syncStatus is FailedSyncStatus) {
final alive = await settingsStore.getCurrentNode(wallet.type).requestNode();
if (alive) {
await wallet.connectToNode(
node: settingsStore.getCurrentNode(wallet.type));
await wallet.connectToNode(node: settingsStore.getCurrentNode(wallet.type));
}
}
} catch (e) {