From 81906559ba8c7b275845c861dc65b63c93e251a7 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Tue, 30 Jul 2024 14:13:42 +0200 Subject: [PATCH 1/3] cw add scanned height --- .../src/ui/components/base_node.rs | 3 +- .../src/ui/state/app_state.rs | 16 +++++++++ .../src/ui/state/wallet_event_monitor.rs | 36 +++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/applications/minotari_console_wallet/src/ui/components/base_node.rs b/applications/minotari_console_wallet/src/ui/components/base_node.rs index 561e877606..bd6e3b78fc 100644 --- a/applications/minotari_console_wallet/src/ui/components/base_node.rs +++ b/applications/minotari_console_wallet/src/ui/components/base_node.rs @@ -69,6 +69,7 @@ impl Component for BaseNode { let base_node_state = app_state.get_base_node_state(); if let Some(ref metadata) = base_node_state.chain_metadata { let tip = metadata.best_block_height(); + let scanned_height = app_state.get_wallet_scanned_height(); let synced = base_node_state.is_synced.unwrap_or_default(); let (tip_color, sync_text) = if synced { @@ -102,7 +103,7 @@ impl Component for BaseNode { let mut tip_info = vec![ Span::styled("Chain Tip:", Style::default().fg(Color::Magenta)), Span::raw(" "), - Span::styled(format!("#{}", tip), Style::default().fg(tip_color)), + Span::styled(format!("#{}({})", tip, scanned_height), Style::default().fg(tip_color)), Span::raw(" "), Span::styled(sync_text.to_string(), Style::default().fg(Color::White)), Span::raw(" "), diff --git a/applications/minotari_console_wallet/src/ui/state/app_state.rs b/applications/minotari_console_wallet/src/ui/state/app_state.rs index 59ef70dede..2973f5eba4 100644 --- a/applications/minotari_console_wallet/src/ui/state/app_state.rs +++ b/applications/minotari_console_wallet/src/ui/state/app_state.rs @@ -39,6 +39,7 @@ use minotari_wallet::{ storage::models::{CompletedTransaction, TxCancellationReason}, }, util::wallet_identity::WalletIdentity, + utxo_scanner_service::handle::UtxoScannerHandle, WalletConfig, WalletSqlite, }; @@ -556,6 +557,10 @@ impl AppState { &self.cached_data.base_node_state } + pub fn get_wallet_scanned_height(&self) -> u64 { + self.cached_data.wallet_scanned_height + } + pub fn get_wallet_connectivity(&self) -> WalletConnectivityHandle { self.wallet_connectivity.clone() } @@ -968,7 +973,12 @@ impl AppStateInner { pub async fn refresh_base_node_peer(&mut self, peer: Peer) -> Result<(), UiError> { self.data.base_node_selected = peer; self.updated = true; + Ok(()) + } + pub async fn trigger_wallet_scanned_height_update(&mut self, height: u64) -> Result<(), UiError> { + self.data.wallet_scanned_height = height; + self.updated = true; Ok(()) } @@ -996,6 +1006,10 @@ impl AppStateInner { self.wallet.wallet_connectivity.clone() } + pub fn get_wallet_utxo_scanner(&self) -> UtxoScannerHandle { + self.wallet.utxo_scanner_service.clone() + } + pub fn get_base_node_event_stream(&self) -> BaseNodeEventReceiver { self.wallet.base_node_service.get_event_stream() } @@ -1221,6 +1235,7 @@ struct AppStateData { all_events: VecDeque, notifications: Vec<(DateTime, String)>, new_notification_count: u32, + wallet_scanned_height: u64, } #[derive(Clone)] @@ -1299,6 +1314,7 @@ impl AppStateData { all_events: VecDeque::new(), notifications: Vec::new(), new_notification_count: 0, + wallet_scanned_height: 0, } } } diff --git a/applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs b/applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs index 91cdca75a8..7069102107 100644 --- a/applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs +++ b/applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs @@ -28,6 +28,7 @@ use minotari_wallet::{ connectivity_service::WalletConnectivityInterface, output_manager_service::handle::OutputManagerEvent, transaction_service::handle::TransactionEvent, + utxo_scanner_service::handle::UtxoScannerEvent, }; use tari_common_types::transaction::TxId; use tari_comms::{connectivity::ConnectivityEvent, peer_manager::Peer}; @@ -76,6 +77,12 @@ impl WalletEventMonitor { let mut base_node_events = self.app_state_inner.read().await.get_base_node_event_stream(); let mut contacts_liveness_events = self.app_state_inner.read().await.get_contacts_liveness_event_stream(); + let mut utxo_scanner_events = self + .app_state_inner + .read() + .await + .get_wallet_utxo_scanner() + .get_event_receiver(); info!(target: LOG_TARGET, "Wallet Event Monitor starting"); loop { @@ -213,6 +220,27 @@ impl WalletEventMonitor { Err(broadcast::error::RecvError::Closed) => {} } }, + result = utxo_scanner_events.recv() => match result { + Ok(event) => { + match event { + UtxoScannerEvent::Progress { + current_height,.. + }=> { + self.trigger_wallet_scanned_height_update(current_height).await; + } + UtxoScannerEvent::Completed { + final_height, + .. + }=> { + self.trigger_wallet_scanned_height_update(final_height).await; + }, + _ => {} + } + }, + Err(e) => { + warn!(target: LOG_TARGET, "Problem with utxo scanner: {}",e); + }, + }, _ = base_node_changed.changed() => { let peer = base_node_changed.borrow().as_ref().cloned(); if let Some(peer) = peer { @@ -333,6 +361,14 @@ impl WalletEventMonitor { } } + async fn trigger_wallet_scanned_height_update(&mut self, height: u64) { + let mut inner = self.app_state_inner.write().await; + + if let Err(e) = inner.trigger_wallet_scanned_height_update(height).await { + warn!(target: LOG_TARGET, "Error refresh app_state: {}", e); + } + } + async fn trigger_base_node_peer_refresh(&mut self, peer: Peer) { let mut inner = self.app_state_inner.write().await; From e805a11dbe01d5f6b7a84738476c14c6e206b284 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Wed, 31 Jul 2024 15:51:27 +0200 Subject: [PATCH 2/3] wip --- base_layer/wallet_ffi/src/callback_handler.rs | 43 +++++++++++++++++++ base_layer/wallet_ffi/src/lib.rs | 3 ++ base_layer/wallet_ffi/wallet.h | 1 + 3 files changed, 47 insertions(+) diff --git a/base_layer/wallet_ffi/src/callback_handler.rs b/base_layer/wallet_ffi/src/callback_handler.rs index cba4099123..eca2b154e1 100644 --- a/base_layer/wallet_ffi/src/callback_handler.rs +++ b/base_layer/wallet_ffi/src/callback_handler.rs @@ -55,6 +55,7 @@ use minotari_wallet::{ models::{CompletedTransaction, InboundTransaction}, }, }, + utxo_scanner_service::handle::{UtxoScannerEvent, UtxoScannerHandle}, }; use tari_common_types::{tari_address::TariAddress, transaction::TxId, types::BlockHash}; use tari_comms_dht::event::{DhtEvent, DhtEventReceiver}; @@ -85,12 +86,14 @@ where TBackend: TransactionBackend + 'static callback_transaction_validation_complete: unsafe extern "C" fn(u64, u64), callback_saf_messages_received: unsafe extern "C" fn(), callback_connectivity_status: unsafe extern "C" fn(u64), + callback_wallet_scanned_height: unsafe extern "C" fn(u64), callback_base_node_state: unsafe extern "C" fn(*mut TariBaseNodeState), db: TransactionDatabase, base_node_service_event_stream: BaseNodeEventReceiver, transaction_service_event_stream: TransactionEventReceiver, output_manager_service_event_stream: OutputManagerEventReceiver, output_manager_service: OutputManagerHandle, + utxo_scanner_service_events: broadcast::Receiver, dht_event_stream: DhtEventReceiver, shutdown_signal: Option, comms_address: TariAddress, @@ -109,6 +112,7 @@ where TBackend: TransactionBackend + 'static transaction_service_event_stream: TransactionEventReceiver, output_manager_service_event_stream: OutputManagerEventReceiver, output_manager_service: OutputManagerHandle, + utxo_scanner_service_events: broadcast::Receiver, dht_event_stream: DhtEventReceiver, shutdown_signal: ShutdownSignal, comms_address: TariAddress, @@ -130,6 +134,7 @@ where TBackend: TransactionBackend + 'static callback_transaction_validation_complete: unsafe extern "C" fn(u64, u64), callback_saf_messages_received: unsafe extern "C" fn(), callback_connectivity_status: unsafe extern "C" fn(u64), + callback_wallet_scanned_height: unsafe extern "C" fn(u64), callback_base_node_state: unsafe extern "C" fn(*mut TariBaseNodeState), ) -> Self { info!( @@ -196,6 +201,10 @@ where TBackend: TransactionBackend + 'static target: LOG_TARGET, "ConnectivityStatusCallback -> Assigning Fn: {:?}", callback_connectivity_status ); + info!( + target: LOG_TARGET, + "WalletScannedHeight -> Assigning Fn: {:?}", callback_wallet_scanned_height + ); Self { callback_received_transaction, @@ -214,12 +223,14 @@ where TBackend: TransactionBackend + 'static callback_transaction_validation_complete, callback_saf_messages_received, callback_connectivity_status, + callback_wallet_scanned_height, callback_base_node_state, db, base_node_service_event_stream, transaction_service_event_stream, output_manager_service_event_stream, output_manager_service, + utxo_scanner_service_events, dht_event_stream, shutdown_signal: Some(shutdown_signal), comms_address, @@ -334,6 +345,28 @@ where TBackend: TransactionBackend + 'static } }, + result = self.utxo_scanner_service_events.recv() => match result { + Ok(event) => { + match event { + UtxoScannerEvent::Progress { + current_height,.. + }=> { + self.scanned_height_changed(current_height); + } + UtxoScannerEvent::Completed { + final_height, + .. + }=> { + self.scanned_height_changed(final_height); + }, + _ => {} + } + }, + Err(e) => { + error!(target: LOG_TARGET, "Problem with utxo scanner: {}",e); + }, + }, + result = self.dht_event_stream.recv() => { match result { Ok(msg) => { @@ -652,6 +685,16 @@ where TBackend: TransactionBackend + 'static } } + fn scanned_height_changed(&mut self, height: u64) { + debug!( + target: LOG_TARGET, + "Calling Scanned height changed callback function" + ); + unsafe { + (self.callback_wallet_scanned_height)(height); + } + } + // casting here is okay as we dont care about the super high latency #[allow(clippy::cast_possible_truncation)] fn base_node_state_changed(&mut self, state: BaseNodeState) { diff --git a/base_layer/wallet_ffi/src/lib.rs b/base_layer/wallet_ffi/src/lib.rs index d86e97c447..4fd0d09baa 100644 --- a/base_layer/wallet_ffi/src/lib.rs +++ b/base_layer/wallet_ffi/src/lib.rs @@ -5693,6 +5693,7 @@ pub unsafe extern "C" fn wallet_create( callback_transaction_validation_complete: unsafe extern "C" fn(u64, u64), callback_saf_messages_received: unsafe extern "C" fn(), callback_connectivity_status: unsafe extern "C" fn(u64), + callback_wallet_scanned_height: unsafe extern "C" fn(u64), callback_base_node_state: unsafe extern "C" fn(*mut TariBaseNodeState), recovery_in_progress: *mut bool, error_out: *mut c_int, @@ -5961,6 +5962,7 @@ pub unsafe extern "C" fn wallet_create( w.transaction_service.get_event_stream(), w.output_manager_service.get_event_stream(), w.output_manager_service.clone(), + w.utxo_scanner_service.get_event_receiver(), w.dht_service.subscribe_dht_events(), w.comms.shutdown_signal(), wallet_address, @@ -5982,6 +5984,7 @@ pub unsafe extern "C" fn wallet_create( callback_transaction_validation_complete, callback_saf_messages_received, callback_connectivity_status, + callback_wallet_scanned_height, callback_base_node_state, ); diff --git a/base_layer/wallet_ffi/wallet.h b/base_layer/wallet_ffi/wallet.h index 576a0cc4bf..64849cba59 100644 --- a/base_layer/wallet_ffi/wallet.h +++ b/base_layer/wallet_ffi/wallet.h @@ -2954,6 +2954,7 @@ struct TariWallet *wallet_create(TariCommsConfig *config, void (*callback_transaction_validation_complete)(uint64_t, uint64_t), void (*callback_saf_messages_received)(void), void (*callback_connectivity_status)(uint64_t), + void (*callback_wallet_scanned_height)(uint64_t), void (*callback_base_node_state)(struct TariBaseNodeState*), bool *recovery_in_progress, int *error_out); From f56d9deae998f7c6fbc25a098305b8e1f2149820 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Wed, 31 Jul 2024 17:00:22 +0200 Subject: [PATCH 3/3] add test --- base_layer/wallet_ffi/src/callback_handler.rs | 2 +- .../wallet_ffi/src/callback_handler_tests.rs | 32 +++++++++++++++++++ base_layer/wallet_ffi/src/lib.rs | 21 +++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/base_layer/wallet_ffi/src/callback_handler.rs b/base_layer/wallet_ffi/src/callback_handler.rs index eca2b154e1..b25d12b05c 100644 --- a/base_layer/wallet_ffi/src/callback_handler.rs +++ b/base_layer/wallet_ffi/src/callback_handler.rs @@ -55,7 +55,7 @@ use minotari_wallet::{ models::{CompletedTransaction, InboundTransaction}, }, }, - utxo_scanner_service::handle::{UtxoScannerEvent, UtxoScannerHandle}, + utxo_scanner_service::handle::UtxoScannerEvent, }; use tari_common_types::{tari_address::TariAddress, transaction::TxId, types::BlockHash}; use tari_comms_dht::event::{DhtEvent, DhtEventReceiver}; diff --git a/base_layer/wallet_ffi/src/callback_handler_tests.rs b/base_layer/wallet_ffi/src/callback_handler_tests.rs index 337a07ce86..a381137a0c 100644 --- a/base_layer/wallet_ffi/src/callback_handler_tests.rs +++ b/base_layer/wallet_ffi/src/callback_handler_tests.rs @@ -28,6 +28,7 @@ mod test { sqlite_db::TransactionServiceSqliteDatabase, }, }, + utxo_scanner_service::handle::UtxoScannerEvent, }; use once_cell::sync::Lazy; use rand::{rngs::OsRng, RngCore}; @@ -92,6 +93,7 @@ mod test { pub callback_transaction_validation_complete: u32, pub saf_messages_received: bool, pub connectivity_status_callback_called: u64, + pub wallet_scanner_height_callback_called: u64, pub base_node_state_changed_callback_invoked: bool, } @@ -121,6 +123,7 @@ mod test { tx_cancellation_callback_called_outbound: false, saf_messages_received: false, connectivity_status_callback_called: 0, + wallet_scanner_height_callback_called: 0, base_node_state_changed_callback_invoked: false, } } @@ -255,6 +258,12 @@ mod test { drop(lock); } + unsafe extern "C" fn wallet_scanner_height_callback(height: u64) { + let mut lock = CALLBACK_STATE.lock().unwrap(); + lock.wallet_scanner_height_callback_called += height; + drop(lock); + } + unsafe extern "C" fn base_node_state_changed_callback(state: *mut TariBaseNodeState) { let mut lock = CALLBACK_STATE.lock().unwrap(); lock.base_node_state_changed_callback_invoked = true; @@ -466,6 +475,8 @@ mod test { let (connectivity_tx, connectivity_rx) = watch::channel(OnlineStatus::Offline); let (contacts_liveness_events_sender, _) = broadcast::channel(250); let contacts_liveness_events = contacts_liveness_events_sender.subscribe(); + let (utxo_scanner_events_sender, _) = broadcast::channel(250); + let utxo_scanner_events = utxo_scanner_events_sender.subscribe(); let comms_address = TariAddress::new_dual_address_with_default_features( PublicKey::from_secret_key(&PrivateKey::random(&mut OsRng)), PublicKey::from_secret_key(&PrivateKey::random(&mut OsRng)), @@ -478,6 +489,7 @@ mod test { transaction_event_receiver, oms_event_receiver, oms_handle, + utxo_scanner_events, dht_event_receiver, shutdown_signal.to_signal(), comms_address, @@ -499,6 +511,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanner_height_callback, base_node_state_changed_callback, ); @@ -843,6 +856,24 @@ mod test { thread::sleep(Duration::from_secs(10)); + utxo_scanner_events_sender + .send(UtxoScannerEvent::Progress { + current_height: 500, + tip_height: 600, + }) + .unwrap(); + + thread::sleep(Duration::from_secs(2)); + utxo_scanner_events_sender + .send(UtxoScannerEvent::Completed { + final_height: 600, + num_recovered: 0, + value_recovered: 0.into(), + time_taken: Duration::from_secs(0), + }) + .unwrap(); + + thread::sleep(Duration::from_secs(2)); let lock = CALLBACK_STATE.lock().unwrap(); assert!(lock.received_tx_callback_called); assert!(lock.received_tx_reply_callback_called); @@ -867,6 +898,7 @@ mod test { assert_eq!(lock.callback_balance_updated, 7); assert_eq!(lock.callback_transaction_validation_complete, 13); assert_eq!(lock.connectivity_status_callback_called, 7); + assert_eq!(lock.wallet_scanner_height_callback_called, 1100); drop(lock); } diff --git a/base_layer/wallet_ffi/src/lib.rs b/base_layer/wallet_ffi/src/lib.rs index 4fd0d09baa..7832de9ab5 100644 --- a/base_layer/wallet_ffi/src/lib.rs +++ b/base_layer/wallet_ffi/src/lib.rs @@ -5955,6 +5955,8 @@ pub unsafe extern "C" fn wallet_create( }, }; + let mut utxo_scanner = w.utxo_scanner_service.clone(); + // Start Callback Handler let callback_handler = CallbackHandler::new( TransactionDatabase::new(transaction_backend), @@ -5962,7 +5964,7 @@ pub unsafe extern "C" fn wallet_create( w.transaction_service.get_event_stream(), w.output_manager_service.get_event_stream(), w.output_manager_service.clone(), - w.utxo_scanner_service.get_event_receiver(), + utxo_scanner.get_event_receiver(), w.dht_service.subscribe_dht_events(), w.comms.shutdown_signal(), wallet_address, @@ -9470,6 +9472,10 @@ mod test { // assert!(true); //optimized out by compiler } + unsafe extern "C" fn wallet_scanned_height_callback(_height: u64) { + // assert!(true); //optimized out by compiler + } + unsafe extern "C" fn base_node_state_callback(_state: *mut TariBaseNodeState) { // assert!(true); //optimized out by compiler } @@ -10156,6 +10162,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -10202,6 +10209,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -10317,6 +10325,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -10543,6 +10552,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -10609,6 +10619,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -10687,6 +10698,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -10863,6 +10875,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -11000,6 +11013,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -11217,6 +11231,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -11442,6 +11457,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -11701,6 +11717,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -12078,6 +12095,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr, @@ -12141,6 +12159,7 @@ mod test { transaction_validation_complete_callback, saf_messages_received_callback, connectivity_status_callback, + wallet_scanned_height_callback, base_node_state_callback, recovery_in_progress_ptr, error_ptr,