feat(cw_tari): Enhance recovery process and callback handling

This commit is contained in:
Konstantin Ullrich 2025-06-14 00:13:07 +02:00
parent ddbc718e12
commit 53d4aa8a97
No known key found for this signature in database
GPG key ID: 6B3199AD9B3D23B8
2 changed files with 142 additions and 78 deletions

View file

@ -1,89 +1,112 @@
import 'dart:ffi';
import 'package:tari/src/generated_bindings_tari.freeze.g.dart';
import 'package:tari/tari.dart';
import 'package:ffi/ffi.dart';
import 'package:tari/ffi.dart';
class CallbackPlaceholders {
static int _chainTipHeight = 0;
static int _scannedHeight = 0;
static int get chainTipHeight => _chainTipHeight;
static int get scannedHeight => _scannedHeight;
// Placeholder for callback_received_transaction
static void callbackReceivedTransaction(Pointer<Void> context,
Pointer<TariPendingInboundTransaction> transaction) {
print('callbackReceivedTransaction called');
// print('callbackReceivedTransaction called');
}
// Placeholder for callback_received_transaction_reply
static void callbackReceivedTransactionReply(
Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) {
print('callbackReceivedTransactionReply called');
// print('callbackReceivedTransactionReply called');
}
static NativeCallable<CallbackReceivedTransactionReply>
get callbackReceivedTransactionReplyPtr =>
NativeCallable<CallableReceivedTransactionReply>.listener(callbackReceivedTransactionReply);
static Pointer<
NativeFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>>
get callbackReceivedTransactionReplyPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>(
callbackReceivedTransactionReply);
// Placeholder for callback_received_finalized_transaction
static void callbackReceivedFinalizedTransaction(
Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) {
print('callbackReceivedFinalizedTransaction called');
// print('callbackReceivedFinalizedTransaction called');
}
static NativeCallable<CallableReceivedFinalizedTransaction>
get callbackReceivedFinalizedTransactionPtr =>
NativeCallable<CallableReceivedFinalizedTransaction>.listener(
callbackReceivedFinalizedTransaction);
static Pointer<
NativeFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>>
get callbackReceivedFinalizedTransactionPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>(
callbackReceivedFinalizedTransaction);
// Placeholder for callback_transaction_broadcast
static void callbackTransactionBroadcast(
Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) {
print('callbackTransactionBroadcast called');
// print('callbackTransactionBroadcast called');
}
static NativeCallable<CallableReceivedTransactionBroadcast>
get callbackTransactionBroadcastPtr =>
NativeCallable<CallableReceivedTransactionBroadcast>.listener(
callbackTransactionBroadcast);
static Pointer<
NativeFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>>
get callbackTransactionBroadcastPtr => Pointer.fromFunction<
Void Function(Pointer<Void>,
Pointer<TariCompletedTransaction>)>(callbackTransactionBroadcast);
// Placeholder for callback_transaction_mined
static void callbackTransactionMined(
Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) {
print('callbackTransactionMined called');
// print('callbackTransactionMined called');
}
static NativeCallable<CallableReceivedTransactionMined>
get callbackTransactionMinedPtr =>
NativeCallable<CallableReceivedTransactionMined>.listener(callbackTransactionMined);
static Pointer<
NativeFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>>
get callbackTransactionMinedPtr => Pointer.fromFunction<
Void Function(Pointer<Void>,
Pointer<TariCompletedTransaction>)>(callbackTransactionMined);
// Placeholder for callback_transaction_mined_unconfirmed
static void callbackTransactionMinedUnconfirmed(Pointer<Void> context,
Pointer<TariCompletedTransaction> transaction, int unconfirmed) {
print('callbackTransactionMinedUnconfirmed called');
// print('callbackTransactionMinedUnconfirmed called');
}
static NativeCallable<CallableReceivedTransactionMinedUnconfirmed>
get callbackTransactionMinedUnconfirmedPtr =>
NativeCallable<CallableReceivedTransactionMinedUnconfirmed>.listener(
callbackTransactionMinedUnconfirmed);
static Pointer<
NativeFunction<
Void Function(
Pointer<Void>, Pointer<TariCompletedTransaction>, Uint64)>>
get callbackTransactionMinedUnconfirmedPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>,
Uint64)>(callbackTransactionMinedUnconfirmed);
// Placeholder for callback_faux_transaction_confirmed
static void callbackFauxTransactionConfirmed(
Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) {
print('callbackFauxTransactionConfirmed called');
// print('callbackFauxTransactionConfirmed called');
}
static NativeCallable<CallableFauxTransactionMinedConfirmed>
get callbackFauxTransactionConfirmedPtr =>
NativeCallable<CallableFauxTransactionMinedConfirmed>.listener(
callbackFauxTransactionConfirmed);
static Pointer<
NativeFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>>
get callbackFauxTransactionConfirmedPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>(
callbackFauxTransactionConfirmed);
// Placeholder for callback_faux_transaction_unconfirmed
static void callbackFauxTransactionUnconfirmed(Pointer<Void> context,
Pointer<TariCompletedTransaction> transaction, int unconfirmed) {
print('callbackFauxTransactionUnconfirmed called');
// print('callbackFauxTransactionUnconfirmed called');
}
static NativeCallable<CallableFauxTransactionMinedUnconfirmed>
get callbackFauxTransactionUnconfirmedPtr =>
NativeCallable<CallableFauxTransactionMinedUnconfirmed>.listener(
callbackFauxTransactionUnconfirmed);
static Pointer<
NativeFunction<
Void Function(
Pointer<Void>, Pointer<TariCompletedTransaction>, Uint64)>>
get callbackFauxTransactionUnconfirmedPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>,
Uint64)>(callbackFauxTransactionUnconfirmed);
// Placeholder for callback_transaction_send_result
static void callbackTransactionSendResult(Pointer<Void> context, int result,
@ -91,11 +114,14 @@ class CallbackPlaceholders {
print('callbackTransactionSendResult called');
}
static NativeCallable<
static Pointer<
NativeFunction<
Void Function(Pointer<Void>, UnsignedLongLong,
Pointer<TariTransactionSendStatus>)>>
get callbackTransactionSendResultPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, UnsignedLongLong,
Pointer<TariTransactionSendStatus>)> get callbackTransactionSendResultPtr =>
NativeCallable<CallableTransactionSendResult>.listener(
callbackTransactionSendResult);
Pointer<TariTransactionSendStatus>)>(
callbackTransactionSendResult);
// Placeholder for callback_transaction_cancellation
static void callbackTransactionCancellation(Pointer<Void> context,
@ -103,64 +129,70 @@ class CallbackPlaceholders {
print('callbackTransactionCancellation called');
}
static NativeCallable<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>, Uint64)>
get callbackTransactionCancellationPtr =>
NativeCallable<CallableTransactionCancellation>.listener(
callbackTransactionCancellation);
static Pointer<
NativeFunction<
Void Function(
Pointer<Void>, Pointer<TariCompletedTransaction>, Uint64)>>
get callbackTransactionCancellationPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>,
Uint64)>(callbackTransactionCancellation);
// Placeholder for callback_txo_validation_complete
static void callbackTxoValidationComplete(
Pointer<Void> context, int txo, int validation) {
print('callbackTxoValidationComplete called');
print('callbackTxoValidationComplete called $txo $validation');
}
static NativeCallable<Void Function(Pointer<Void>, Uint64, Uint64)>
static Pointer<NativeFunction<Void Function(Pointer<Void>, Uint64, Uint64)>>
get callbackTxoValidationCompletePtr =>
NativeCallable<CallableTxoValidationComplete>.listener(
Pointer.fromFunction<Void Function(Pointer<Void>, Uint64, Uint64)>(
callbackTxoValidationComplete);
// Placeholder for callback_contacts_liveness_data_updated
static void callbackContactsLivenessDataUpdated(
Pointer<Void> context, Pointer<TariContactsLivenessData> data) {
print('callbackContactsLivenessDataUpdated called');
// print('callbackContactsLivenessDataUpdated called');
}
static NativeCallable<
Void Function(Pointer<Void>, Pointer<TariContactsLivenessData>)>
get callbackContactsLivenessDataUpdatedPtr =>
NativeCallable<CallableContactsLivenessDataUpdated>.listener(
callbackContactsLivenessDataUpdated);
static Pointer<
NativeFunction<
Void Function(Pointer<Void>, Pointer<TariContactsLivenessData>)>>
get callbackContactsLivenessDataUpdatedPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariContactsLivenessData>)>(
callbackContactsLivenessDataUpdated);
// Placeholder for callback_balance_updated
static void callbackBalanceUpdated(
Pointer<Void> context, Pointer<TariBalance> balance) {
print('callbackBalanceUpdated called');
// print('callbackBalanceUpdated called');
}
static NativeCallable<Void Function(Pointer<Void>, Pointer<TariBalance>)>
get callbackBalanceUpdatedPtr =>
NativeCallable<CallableBalanceUpdated>.listener(callbackBalanceUpdated);
static Pointer<
NativeFunction<Void Function(Pointer<Void>, Pointer<TariBalance>)>>
get callbackBalanceUpdatedPtr => Pointer.fromFunction<
Void Function(
Pointer<Void>, Pointer<TariBalance>)>(callbackBalanceUpdated);
// Placeholder for callback_transaction_validation_complete
static void callbackTransactionValidationComplete(
Pointer<Void> context, int transaction, int validation) {
print('callbackTransactionValidationComplete called');
// print(
// 'callbackTransactionValidationComplete called $transaction $validation');
}
static NativeCallable<Void Function(Pointer<Void>, Uint64, Uint64)>
static Pointer<NativeFunction<Void Function(Pointer<Void>, Uint64, Uint64)>>
get callbackTransactionValidationCompletePtr =>
NativeCallable<CallableTransactionValidationComplete>.listener(
Pointer.fromFunction<Void Function(Pointer<Void>, Uint64, Uint64)>(
callbackTransactionValidationComplete);
// Placeholder for callback_saf_messages_received
static void callbackSafMessagesReceived(Pointer<Void> context) {
print('callbackSafMessagesReceived called');
// print('callbackSafMessagesReceived called');
}
static NativeCallable<Void Function(Pointer<Void>)>
static Pointer<NativeFunction<Void Function(Pointer<Void>)>>
get callbackSafMessagesReceivedPtr =>
NativeCallable<CallableSafMessagesReceived>.listener(
Pointer.fromFunction<Void Function(Pointer<Void>)>(
callbackSafMessagesReceived);
// Placeholder for callback_connectivity_status
@ -179,28 +211,34 @@ class CallbackPlaceholders {
}
}
static NativeCallable<Void Function(Pointer<Void>, Uint64)>
static Pointer<NativeFunction<Void Function(Pointer<Void>, Uint64)>>
get callbackConnectivityStatusPtr =>
NativeCallable<CallableConnectivityStatus>.listener(
Pointer.fromFunction<Void Function(Pointer<Void>, Uint64)>(
callbackConnectivityStatus);
// Placeholder for callback_wallet_scanned_height
static void callbackWalletScannedHeight(Pointer<Void> context, int height) {
print('callbackWalletScannedHeight called');
print('Scanned height: $height / ${_chainTipHeight}');
_scannedHeight = height;
}
static NativeCallable<Void Function(Pointer<Void>, Uint64)>
static Pointer<NativeFunction<Void Function(Pointer<Void>, Uint64)>>
get callbackWalletScannedHeightPtr =>
NativeCallable<CallableWalletScannedHeight>.listener(
Pointer.fromFunction<Void Function(Pointer<Void>, Uint64)>(
callbackWalletScannedHeight);
// Placeholder for callback_base_node_state
static void callbackBaseNodeState(
Pointer<Void> context, Pointer<TariBaseNodeState> state) {
print('callbackBaseNodeState called');
final errorPtr = malloc<Int>();
_chainTipHeight = lib.basenode_state_get_height_of_the_longest_chain(state, errorPtr);
print('Current chain tip height: $_chainTipHeight');
}
static NativeCallable<Void Function(Pointer<Void>, Pointer<TariBaseNodeState>)>
get callbackBaseNodeStatePtr =>
NativeCallable<CallableBaseNodeState>.listener(callbackBaseNodeState);
static Pointer<
NativeFunction<
Void Function(Pointer<Void>, Pointer<TariBaseNodeState>)>>
get callbackBaseNodeStatePtr => Pointer.fromFunction<
Void Function(Pointer<Void>,
Pointer<TariBaseNodeState>)>(callbackBaseNodeState);
}

View file

@ -13,6 +13,7 @@ import 'package:cw_core/wallet_addresses.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_keys_file.dart';
import 'package:cw_tari/callback.dart';
import 'package:cw_tari/pending_tari_transaction.dart';
import 'package:cw_tari/tari_balance.dart';
import 'package:cw_tari/tari_transaction_history.dart';
@ -101,28 +102,53 @@ abstract class TariWalletBase
_walletFfi.setBaseNode();
await Future.delayed(Duration(seconds: 10)); // Give it time to connect to the base node
var isRecovering = true;
_walletFfi.startRecovery((_, event, arg1, arg2) {
switch (event) {
case 0:
print("[Recovery] Connecting to base node...");
break;
case 1:
print("[Recovery] Connection to base node established");
break;
case 2:
print("Connection to base node failed. Retry ${arg1}/${arg2}");
print("[Recovery] Connection to base node failed. Retry ${arg1}/${arg2}");
break;
case 3:
print("Scanning progress: ${arg1}/${arg2} blocks");
print("[Recovery] Scanning progress: ${arg1}/${arg2} blocks");
isRecovering = false;
break;
case 4:
print(
"Recovery completed! Recovered ${arg1} UTXOs (${arg2} MicroMinotari)");
"[Recovery] Recovery completed! Recovered ${arg1} UTXOs (${arg2} MicroMinotari)");
isRecovering = false;
break;
case 5:
print("Scanning round failed. Retry ${arg1}/${arg2}");
print("[Recovery] Scanning round failed. Retry ${arg1}/${arg2}");
break;
case 6:
print("Recovery failed!");
print("[Recovery] Recovery failed!");
isRecovering = false;
break;
default:
print("[Recovery] Unknown event: $event ${arg1} ${arg2}");
break;
}
});
await Future.delayed(Duration(seconds: 15)); // Give it time to scan the blocks
log(_walletFfi.isRecovering().toString());
while (isRecovering) {
await Future.delayed(Duration(seconds: 5)); // Check every 5 seconds
final balance = _walletFfi.getBalance();
print("Scanned height: ${CallbackPlaceholders.scannedHeight} / ${CallbackPlaceholders.chainTipHeight}");
print(
"Balance: ${balance.available} ${balance.pendingIncoming} ${balance.pendingOutgoing} ${balance.timeLocked}");
if (CallbackPlaceholders.scannedHeight >= CallbackPlaceholders.chainTipHeight && CallbackPlaceholders.chainTipHeight > 0) {
break;
}
}
// syncStatus = SyncedSyncStatus();
} catch (e) {