Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion monero-harness/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ impl MoneroWallet {

/// Get non-strict balance per subaddress for main account (index 0).
pub async fn balance_per_subaddress(&self) -> Result<HashMap<u32, u64>> {
Ok(self.wallet.balance_per_subaddress().await)
self.wallet.balance_per_subaddress().await
}

pub async fn refresh(&self) -> Result<()> {
Expand Down
21 changes: 15 additions & 6 deletions monero-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub use bridge::wallet_listener;
pub use bridge::{TraceListener, WalletEventListener, WalletListenerBox};
pub use database::{Database, RecentWallet};
use std::panic::{AssertUnwindSafe, catch_unwind};
use std::sync::{Arc, Mutex};
use std::sync::{Arc, Mutex, Weak};
use std::{
any::Any, cmp::Ordering, collections::HashMap, fmt::Display, future::Future, ops::Deref,
pin::Pin, time::Duration,
Expand Down Expand Up @@ -682,10 +682,12 @@ impl WalletHandle {
/// Returns a map of subaddress index -> balance (in atomic units).
/// strict: If true, only includes confirmed and unlocked balance.
/// If false, pending and unconfirmed transactions are also included.
pub async fn balance_per_subaddress(&self) -> std::collections::HashMap<u32, u64> {
pub async fn balance_per_subaddress(
&self,
) -> anyhow::Result<std::collections::HashMap<u32, u64>> {
self.call(move |wallet| wallet.balance_per_subaddress_sync())
.await
.expect("wallet thread closed while fetching balance per subaddress")
.context("Couldn't complete wallet call")
}

/// Check if the wallet is synchronized.
Expand Down Expand Up @@ -3219,7 +3221,7 @@ impl Deref for TransactionInfoHandle {
/// This listener does things on certain events like storing the wallet to disk.
/// This is supposed to improve upon the behaviour of wallet2
pub struct WalletHandleListener {
wallet: Arc<WalletHandle>,
wallet: Weak<WalletHandle>,
/// We need a handle to the runtime to be able to spawn tasks
rt_handle: tokio::runtime::Handle,
/// We throttle the saving of the wallet to disk to avoid storing the wallet too often
Expand All @@ -3234,14 +3236,18 @@ impl WalletHandleListener {
pub fn new(wallet: Arc<WalletHandle>) -> Self {
// Get the current runtime handle
let rt_handle = tokio::runtime::Handle::current();
let wallet = Arc::downgrade(&wallet);

// Create a throttle wrapper around the save job
let store_job = {
let wallet = wallet.clone();
let rt = rt_handle.clone();

move |()| {
let wallet = wallet.clone();
let Some(wallet) = wallet.upgrade() else {
tracing::trace!("Skipping wallet store because wallet handle is gone");
return;
};
let rt = rt.clone();

rt.spawn(async move {
Expand Down Expand Up @@ -3291,7 +3297,10 @@ impl WalletEventListener for WalletHandleListener {
// When the wallet finishes refreshing, we start the refresh thread again.
// The purpose of this is to ensure that if the user does a rescan (restore height changed)
// We start the refresh thread again after the rescan is complete.
let handle = self.wallet.clone();
let Some(handle) = self.wallet.upgrade() else {
tracing::trace!("Skipping refresh thread restart because wallet handle is gone");
return;
};
self.rt_handle.spawn(async move {
if let Err(e) = handle.start_refresh_thread().await {
tracing::error!(error=%e, "Failed to start refresh thread");
Expand Down
21 changes: 17 additions & 4 deletions monero-wallet/src/listener.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::{sync::Arc, time::Duration};
use std::{
sync::{Arc, Weak},
time::Duration,
};

use monero_sys::WalletEventListener;

Expand Down Expand Up @@ -29,13 +32,17 @@ impl TauriWalletListener {

pub async fn new(tauri_handle: TauriHandle, wallet: Arc<Wallet>) -> Self {
let rt_handle = tokio::runtime::Handle::current();
let wallet: Weak<Wallet> = Arc::downgrade(&wallet);

let balance_job = {
let wallet = wallet.clone();
let tauri = tauri_handle.clone();
let rt = rt_handle.clone();
move |()| {
let wallet = wallet.clone();
let Some(wallet) = wallet.upgrade() else {
tracing::trace!("Skipping balance update because wallet handle is gone");
return;
};
let tauri = tauri.clone();
let rt = rt.clone();
rt.spawn(async move {
Expand Down Expand Up @@ -64,7 +71,10 @@ impl TauriWalletListener {
let tauri = tauri_handle.clone();
let rt = rt_handle.clone();
move |()| {
let wallet = wallet.clone();
let Some(wallet) = wallet.upgrade() else {
tracing::trace!("Skipping history update because wallet handle is gone");
return;
};
let tauri = tauri.clone();
let rt = rt.clone();
rt.spawn(async move {
Expand All @@ -86,7 +96,10 @@ impl TauriWalletListener {
let tauri = tauri_handle.clone();
let rt = rt_handle.clone();
move |()| {
let wallet = wallet.clone();
let Some(wallet) = wallet.upgrade() else {
tracing::trace!("Skipping sync update because wallet handle is gone");
return;
};
let tauri = tauri.clone();
let rt = rt.clone();
rt.spawn(async move {
Expand Down