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 'dart:ffi';
import 'package:tari/src/generated_bindings_tari.freeze.g.dart'; 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 { 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 // Placeholder for callback_received_transaction
static void callbackReceivedTransaction(Pointer<Void> context, static void callbackReceivedTransaction(Pointer<Void> context,
Pointer<TariPendingInboundTransaction> transaction) { Pointer<TariPendingInboundTransaction> transaction) {
print('callbackReceivedTransaction called'); // print('callbackReceivedTransaction called');
} }
// Placeholder for callback_received_transaction_reply // Placeholder for callback_received_transaction_reply
static void callbackReceivedTransactionReply( static void callbackReceivedTransactionReply(
Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) { Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) {
print('callbackReceivedTransactionReply called'); // print('callbackReceivedTransactionReply called');
} }
static NativeCallable<CallbackReceivedTransactionReply> static Pointer<
get callbackReceivedTransactionReplyPtr => NativeFunction<
NativeCallable<CallableReceivedTransactionReply>.listener(callbackReceivedTransactionReply); Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>>
get callbackReceivedTransactionReplyPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>(
callbackReceivedTransactionReply);
// Placeholder for callback_received_finalized_transaction // Placeholder for callback_received_finalized_transaction
static void callbackReceivedFinalizedTransaction( static void callbackReceivedFinalizedTransaction(
Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) { Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) {
print('callbackReceivedFinalizedTransaction called'); // print('callbackReceivedFinalizedTransaction called');
} }
static NativeCallable<CallableReceivedFinalizedTransaction> static Pointer<
get callbackReceivedFinalizedTransactionPtr => NativeFunction<
NativeCallable<CallableReceivedFinalizedTransaction>.listener( Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>>
callbackReceivedFinalizedTransaction); get callbackReceivedFinalizedTransactionPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>(
callbackReceivedFinalizedTransaction);
// Placeholder for callback_transaction_broadcast // Placeholder for callback_transaction_broadcast
static void callbackTransactionBroadcast( static void callbackTransactionBroadcast(
Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) { Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) {
print('callbackTransactionBroadcast called'); // print('callbackTransactionBroadcast called');
} }
static NativeCallable<CallableReceivedTransactionBroadcast> static Pointer<
get callbackTransactionBroadcastPtr => NativeFunction<
NativeCallable<CallableReceivedTransactionBroadcast>.listener( Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>>
callbackTransactionBroadcast); get callbackTransactionBroadcastPtr => Pointer.fromFunction<
Void Function(Pointer<Void>,
Pointer<TariCompletedTransaction>)>(callbackTransactionBroadcast);
// Placeholder for callback_transaction_mined // Placeholder for callback_transaction_mined
static void callbackTransactionMined( static void callbackTransactionMined(
Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) { Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) {
print('callbackTransactionMined called'); // print('callbackTransactionMined called');
} }
static NativeCallable<CallableReceivedTransactionMined> static Pointer<
get callbackTransactionMinedPtr => NativeFunction<
NativeCallable<CallableReceivedTransactionMined>.listener(callbackTransactionMined); Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>>
get callbackTransactionMinedPtr => Pointer.fromFunction<
Void Function(Pointer<Void>,
Pointer<TariCompletedTransaction>)>(callbackTransactionMined);
// Placeholder for callback_transaction_mined_unconfirmed // Placeholder for callback_transaction_mined_unconfirmed
static void callbackTransactionMinedUnconfirmed(Pointer<Void> context, static void callbackTransactionMinedUnconfirmed(Pointer<Void> context,
Pointer<TariCompletedTransaction> transaction, int unconfirmed) { Pointer<TariCompletedTransaction> transaction, int unconfirmed) {
print('callbackTransactionMinedUnconfirmed called'); // print('callbackTransactionMinedUnconfirmed called');
} }
static NativeCallable<CallableReceivedTransactionMinedUnconfirmed> static Pointer<
get callbackTransactionMinedUnconfirmedPtr => NativeFunction<
NativeCallable<CallableReceivedTransactionMinedUnconfirmed>.listener( Void Function(
callbackTransactionMinedUnconfirmed); Pointer<Void>, Pointer<TariCompletedTransaction>, Uint64)>>
get callbackTransactionMinedUnconfirmedPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>,
Uint64)>(callbackTransactionMinedUnconfirmed);
// Placeholder for callback_faux_transaction_confirmed // Placeholder for callback_faux_transaction_confirmed
static void callbackFauxTransactionConfirmed( static void callbackFauxTransactionConfirmed(
Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) { Pointer<Void> context, Pointer<TariCompletedTransaction> transaction) {
print('callbackFauxTransactionConfirmed called'); // print('callbackFauxTransactionConfirmed called');
} }
static NativeCallable<CallableFauxTransactionMinedConfirmed> static Pointer<
get callbackFauxTransactionConfirmedPtr => NativeFunction<
NativeCallable<CallableFauxTransactionMinedConfirmed>.listener( Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>>
callbackFauxTransactionConfirmed); get callbackFauxTransactionConfirmedPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>)>(
callbackFauxTransactionConfirmed);
// Placeholder for callback_faux_transaction_unconfirmed // Placeholder for callback_faux_transaction_unconfirmed
static void callbackFauxTransactionUnconfirmed(Pointer<Void> context, static void callbackFauxTransactionUnconfirmed(Pointer<Void> context,
Pointer<TariCompletedTransaction> transaction, int unconfirmed) { Pointer<TariCompletedTransaction> transaction, int unconfirmed) {
print('callbackFauxTransactionUnconfirmed called'); // print('callbackFauxTransactionUnconfirmed called');
} }
static NativeCallable<CallableFauxTransactionMinedUnconfirmed> static Pointer<
get callbackFauxTransactionUnconfirmedPtr => NativeFunction<
NativeCallable<CallableFauxTransactionMinedUnconfirmed>.listener( Void Function(
callbackFauxTransactionUnconfirmed); Pointer<Void>, Pointer<TariCompletedTransaction>, Uint64)>>
get callbackFauxTransactionUnconfirmedPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>,
Uint64)>(callbackFauxTransactionUnconfirmed);
// Placeholder for callback_transaction_send_result // Placeholder for callback_transaction_send_result
static void callbackTransactionSendResult(Pointer<Void> context, int result, static void callbackTransactionSendResult(Pointer<Void> context, int result,
@ -91,11 +114,14 @@ class CallbackPlaceholders {
print('callbackTransactionSendResult called'); print('callbackTransactionSendResult called');
} }
static NativeCallable< static Pointer<
NativeFunction<
Void Function(Pointer<Void>, UnsignedLongLong,
Pointer<TariTransactionSendStatus>)>>
get callbackTransactionSendResultPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, UnsignedLongLong, Void Function(Pointer<Void>, UnsignedLongLong,
Pointer<TariTransactionSendStatus>)> get callbackTransactionSendResultPtr => Pointer<TariTransactionSendStatus>)>(
NativeCallable<CallableTransactionSendResult>.listener( callbackTransactionSendResult);
callbackTransactionSendResult);
// Placeholder for callback_transaction_cancellation // Placeholder for callback_transaction_cancellation
static void callbackTransactionCancellation(Pointer<Void> context, static void callbackTransactionCancellation(Pointer<Void> context,
@ -103,64 +129,70 @@ class CallbackPlaceholders {
print('callbackTransactionCancellation called'); print('callbackTransactionCancellation called');
} }
static NativeCallable< static Pointer<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>, Uint64)> NativeFunction<
get callbackTransactionCancellationPtr => Void Function(
NativeCallable<CallableTransactionCancellation>.listener( Pointer<Void>, Pointer<TariCompletedTransaction>, Uint64)>>
callbackTransactionCancellation); get callbackTransactionCancellationPtr => Pointer.fromFunction<
Void Function(Pointer<Void>, Pointer<TariCompletedTransaction>,
Uint64)>(callbackTransactionCancellation);
// Placeholder for callback_txo_validation_complete // Placeholder for callback_txo_validation_complete
static void callbackTxoValidationComplete( static void callbackTxoValidationComplete(
Pointer<Void> context, int txo, int validation) { 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 => get callbackTxoValidationCompletePtr =>
NativeCallable<CallableTxoValidationComplete>.listener( Pointer.fromFunction<Void Function(Pointer<Void>, Uint64, Uint64)>(
callbackTxoValidationComplete); callbackTxoValidationComplete);
// Placeholder for callback_contacts_liveness_data_updated // Placeholder for callback_contacts_liveness_data_updated
static void callbackContactsLivenessDataUpdated( static void callbackContactsLivenessDataUpdated(
Pointer<Void> context, Pointer<TariContactsLivenessData> data) { Pointer<Void> context, Pointer<TariContactsLivenessData> data) {
print('callbackContactsLivenessDataUpdated called'); // print('callbackContactsLivenessDataUpdated called');
} }
static NativeCallable< static Pointer<
Void Function(Pointer<Void>, Pointer<TariContactsLivenessData>)> NativeFunction<
get callbackContactsLivenessDataUpdatedPtr => Void Function(Pointer<Void>, Pointer<TariContactsLivenessData>)>>
NativeCallable<CallableContactsLivenessDataUpdated>.listener( get callbackContactsLivenessDataUpdatedPtr => Pointer.fromFunction<
callbackContactsLivenessDataUpdated); Void Function(Pointer<Void>, Pointer<TariContactsLivenessData>)>(
callbackContactsLivenessDataUpdated);
// Placeholder for callback_balance_updated // Placeholder for callback_balance_updated
static void callbackBalanceUpdated( static void callbackBalanceUpdated(
Pointer<Void> context, Pointer<TariBalance> balance) { Pointer<Void> context, Pointer<TariBalance> balance) {
print('callbackBalanceUpdated called'); // print('callbackBalanceUpdated called');
} }
static NativeCallable<Void Function(Pointer<Void>, Pointer<TariBalance>)> static Pointer<
get callbackBalanceUpdatedPtr => NativeFunction<Void Function(Pointer<Void>, Pointer<TariBalance>)>>
NativeCallable<CallableBalanceUpdated>.listener(callbackBalanceUpdated); get callbackBalanceUpdatedPtr => Pointer.fromFunction<
Void Function(
Pointer<Void>, Pointer<TariBalance>)>(callbackBalanceUpdated);
// Placeholder for callback_transaction_validation_complete // Placeholder for callback_transaction_validation_complete
static void callbackTransactionValidationComplete( static void callbackTransactionValidationComplete(
Pointer<Void> context, int transaction, int validation) { 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 => get callbackTransactionValidationCompletePtr =>
NativeCallable<CallableTransactionValidationComplete>.listener( Pointer.fromFunction<Void Function(Pointer<Void>, Uint64, Uint64)>(
callbackTransactionValidationComplete); callbackTransactionValidationComplete);
// Placeholder for callback_saf_messages_received // Placeholder for callback_saf_messages_received
static void callbackSafMessagesReceived(Pointer<Void> context) { 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 => get callbackSafMessagesReceivedPtr =>
NativeCallable<CallableSafMessagesReceived>.listener( Pointer.fromFunction<Void Function(Pointer<Void>)>(
callbackSafMessagesReceived); callbackSafMessagesReceived);
// Placeholder for callback_connectivity_status // 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 => get callbackConnectivityStatusPtr =>
NativeCallable<CallableConnectivityStatus>.listener( Pointer.fromFunction<Void Function(Pointer<Void>, Uint64)>(
callbackConnectivityStatus); callbackConnectivityStatus);
// Placeholder for callback_wallet_scanned_height // Placeholder for callback_wallet_scanned_height
static void callbackWalletScannedHeight(Pointer<Void> context, int 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 => get callbackWalletScannedHeightPtr =>
NativeCallable<CallableWalletScannedHeight>.listener( Pointer.fromFunction<Void Function(Pointer<Void>, Uint64)>(
callbackWalletScannedHeight); callbackWalletScannedHeight);
// Placeholder for callback_base_node_state // Placeholder for callback_base_node_state
static void callbackBaseNodeState( static void callbackBaseNodeState(
Pointer<Void> context, Pointer<TariBaseNodeState> state) { 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>)> static Pointer<
get callbackBaseNodeStatePtr => NativeFunction<
NativeCallable<CallableBaseNodeState>.listener(callbackBaseNodeState); 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_base.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_keys_file.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/pending_tari_transaction.dart';
import 'package:cw_tari/tari_balance.dart'; import 'package:cw_tari/tari_balance.dart';
import 'package:cw_tari/tari_transaction_history.dart'; import 'package:cw_tari/tari_transaction_history.dart';
@ -101,28 +102,53 @@ abstract class TariWalletBase
_walletFfi.setBaseNode(); _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) { _walletFfi.startRecovery((_, event, arg1, arg2) {
switch (event) { switch (event) {
case 0:
print("[Recovery] Connecting to base node...");
break;
case 1:
print("[Recovery] Connection to base node established");
break;
case 2: case 2:
print("Connection to base node failed. Retry ${arg1}/${arg2}"); print("[Recovery] Connection to base node failed. Retry ${arg1}/${arg2}");
break; break;
case 3: case 3:
print("Scanning progress: ${arg1}/${arg2} blocks"); print("[Recovery] Scanning progress: ${arg1}/${arg2} blocks");
isRecovering = false;
break; break;
case 4: case 4:
print( print(
"Recovery completed! Recovered ${arg1} UTXOs (${arg2} MicroMinotari)"); "[Recovery] Recovery completed! Recovered ${arg1} UTXOs (${arg2} MicroMinotari)");
isRecovering = false;
break; break;
case 5: case 5:
print("Scanning round failed. Retry ${arg1}/${arg2}"); print("[Recovery] Scanning round failed. Retry ${arg1}/${arg2}");
break; break;
case 6: case 6:
print("Recovery failed!"); print("[Recovery] Recovery failed!");
isRecovering = false;
break;
default:
print("[Recovery] Unknown event: $event ${arg1} ${arg2}");
break; 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(); // syncStatus = SyncedSyncStatus();
} catch (e) { } catch (e) {