From 3ed82f6217b61e7e8a0e2dd9be363c3bb3f576e5 Mon Sep 17 00:00:00 2001 From: Daksh <41485688+Daksh14@users.noreply.github.com> Date: Tue, 8 Oct 2024 02:42:35 -0400 Subject: [PATCH] rusk-wallet: Add method to store last block height in cache Add sync status enum to display correct sync status to user and current synced block height from the cache --- rusk-wallet/src/bin/interactive.rs | 37 +++++++++++++++++++++++------- rusk-wallet/src/cache.rs | 26 +++++++++++++++++++++ rusk-wallet/src/clients.rs | 10 ++++---- rusk-wallet/src/lib.rs | 12 ++++++++++ rusk-wallet/src/wallet.rs | 7 ++++++ 5 files changed, 79 insertions(+), 13 deletions(-) diff --git a/rusk-wallet/src/bin/interactive.rs b/rusk-wallet/src/bin/interactive.rs index c3d0e8e529..af9f00f5dc 100644 --- a/rusk-wallet/src/bin/interactive.rs +++ b/rusk-wallet/src/bin/interactive.rs @@ -194,15 +194,36 @@ fn menu_addr(wallet: &Wallet) -> anyhow::Result { )); } + use rusk_wallet::SyncStatus; + if let Some(rx) = &wallet.state()?.sync_rx { - if let Ok(status) = rx.try_recv() { - action_menu = action_menu - .separator() - .separator_msg(format!("Sync Status: {}", status)); - } else { - action_menu = action_menu - .separator() - .separator_msg("Waiting for Sync to complete..".to_string()); + match rx.try_recv() { + Ok(status) => { + let last_height = wallet.last_block_height()?; + + action_menu = action_menu.separator().separator_msg(format!( + "Synced at last block height: {}", + last_height + )); + + match status { + SyncStatus::Synced => (), + SyncStatus::NotSynced => { + action_menu = action_menu + .separator_msg("Syncing in progress..".to_string()); + } + SyncStatus::Err(e) => { + action_menu = action_menu.separator().separator_msg( + format!("Sync failed with err: {:?}", e), + ) + } + } + } + Err(e) => { + action_menu = action_menu + .separator() + .separator_msg(format!("Sync failed with err: {:?}", e)) + } } } diff --git a/rusk-wallet/src/cache.rs b/rusk-wallet/src/cache.rs index 5cb15a7888..35dc4e1ee0 100644 --- a/rusk-wallet/src/cache.rs +++ b/rusk-wallet/src/cache.rs @@ -68,6 +68,9 @@ impl Cache { let data = rkyv::to_bytes::(&leaf) .map_err(|_| Error::Rkyv)?; + // keep track of max block height while inserting notes + self.insert_last_block_height(block_height)?; + let key = nullifier.to_bytes(); self.db.put_cf(&cf, key, data)?; @@ -98,6 +101,9 @@ impl Cache { .map_err(|_| Error::Rkyv)?; let key = nullifier.to_bytes(); + // keep track of max block height while inserting notes + self.insert_last_block_height(block_height)?; + self.db.put_cf(&cf, key, data)?; Ok(()) @@ -155,6 +161,26 @@ impl Cache { })) } + pub(crate) fn insert_last_block_height( + &self, + block_height: u64, + ) -> Result<(), Error> { + let last_block_height = self.last_block_height()?.unwrap_or(0); + let max = std::cmp::max(last_block_height, block_height); + + self.db.put(b"last_block_height", max.to_be_bytes())?; + + Ok(()) + } + + pub(crate) fn last_block_height(&self) -> Result, Error> { + Ok(self.db.get(b"last_block_height")?.map(|x| { + let buff: [u8; 8] = x.try_into().expect("Invalid u64 in cache db"); + + u64::from_be_bytes(buff) + })) + } + /// Returns an iterator over all unspent notes nullifier for the given pk. pub(crate) fn unspent_notes_id( &self, diff --git a/rusk-wallet/src/clients.rs b/rusk-wallet/src/clients.rs index ab3faa2319..abb22a5788 100644 --- a/rusk-wallet/src/clients.rs +++ b/rusk-wallet/src/clients.rs @@ -77,7 +77,7 @@ pub struct State { client: RuesHttpClient, prover: RuskHttpClient, store: LocalStore, - pub sync_rx: Option>, + pub sync_rx: Option>, sync_join_handle: Option>, } @@ -121,7 +121,7 @@ impl State { } pub async fn register_sync(&mut self) -> Result<(), Error> { - let (sync_tx, sync_rx) = flume::unbounded::(); + let (sync_tx, sync_rx) = flume::unbounded::(); self.sync_rx = Some(sync_rx); @@ -134,11 +134,11 @@ impl State { let handle = tokio::spawn(async move { loop { - let _ = sync_tx.send("Syncing..".to_string()); + let _ = sync_tx.send(SyncStatus::NotSynced); let _ = match sync_db(&client, &cache, &store, status).await { - Ok(_) => sync_tx.send("Syncing Complete".to_string()), - Err(e) => sync_tx.send(format!("Error during sync:.. {e}")), + Ok(_) => sync_tx.send(SyncStatus::Synced), + Err(e) => sync_tx.send(SyncStatus::Err(e)), }; sleep(Duration::from_secs(SYNC_INTERVAL_SECONDS)).await; diff --git a/rusk-wallet/src/lib.rs b/rusk-wallet/src/lib.rs index d33eeb3ef1..190ed23a6b 100644 --- a/rusk-wallet/src/lib.rs +++ b/rusk-wallet/src/lib.rs @@ -47,6 +47,18 @@ use execution_core::{ BlsScalar, }; +/// The enum that the sync status reciever emits so the binary can report +/// on the sync status +#[derive(Debug)] +pub enum SyncStatus { + /// Syncing is complete + Synced, + /// Syncing is in progress + NotSynced, + /// An error occurred while syncing + Err(Error), +} + use currency::Dusk; /// The largest amount of Dusk that is possible to convert diff --git a/rusk-wallet/src/wallet.rs b/rusk-wallet/src/wallet.rs index ce74ebff18..28785c06b3 100644 --- a/rusk-wallet/src/wallet.rs +++ b/rusk-wallet/src/wallet.rs @@ -1160,6 +1160,13 @@ impl Wallet { Ok(network_last_pos == db_pos) } + /// Fetch the last block height from the database + pub fn last_block_height(&self) -> Result { + let state = self.state()?; + + Ok(state.cache().last_block_height()?.unwrap_or(0)) + } + /// Close the wallet and zeroize the seed pub fn close(&mut self) { self.store.inner_mut().zeroize();