fixed cache clearing bugs and syncing timing issue

This commit is contained in:
viraladmin 2026-07-20 13:54:13 -06:00
parent 026bded7f9
commit 7286741c41
4 changed files with 28 additions and 5 deletions

View File

@ -421,7 +421,7 @@ const DASHBOARD_LATEST_REFRESH_MS = 5000;
const DASHBOARD_INITIAL_TX_FETCH_DELAY_MS = 500; const DASHBOARD_INITIAL_TX_FETCH_DELAY_MS = 500;
const DASHBOARD_REFRESH_TX_FETCH_DELAY_MS = 2000; const DASHBOARD_REFRESH_TX_FETCH_DELAY_MS = 2000;
const BACKGROUND_TX_FETCH_DELAY_MS = 2000; const BACKGROUND_TX_FETCH_DELAY_MS = 2000;
const HISTORY_REFRESH_MS = 5000; const HISTORY_REFRESH_MS = 2000;
const HISTORY_PAGE_SIZE = 100; const HISTORY_PAGE_SIZE = 100;
const WALLET_RPC_RETRY_LIMIT = 3; const WALLET_RPC_RETRY_LIMIT = 3;
const WALLET_RPC_BACKOFF_BASE_MS = 1500; const WALLET_RPC_BACKOFF_BASE_MS = 1500;

View File

@ -140,6 +140,9 @@ fn main() {
.manage(WalletState { .manage(WalletState {
active_wallet: Mutex::new(None), active_wallet: Mutex::new(None),
rpc_scheduler: WalletRpcScheduler::new(), rpc_scheduler: WalletRpcScheduler::new(),
history_cache_io: AsyncMutex::new(()),
nft_cache_io: AsyncMutex::new(()),
address_book_io: AsyncMutex::new(()),
}) })
.on_window_event(|_, event| { .on_window_event(|_, event| {
if matches!(event, tauri::WindowEvent::CloseRequested { .. }) { if matches!(event, tauri::WindowEvent::CloseRequested { .. }) {

View File

@ -88,8 +88,9 @@ async fn test_broadcast_node_time(
} }
#[tauri::command] #[tauri::command]
async fn read_local_transaction_cache(state: State<'_, WalletState>) -> Result<String, String> { async fn read_local_transaction_cache(state: State<'_, WalletState>) -> Result<String, String> {
let cache_path = active_wallet_cache_path(&state)?; let _cache_guard = state.history_cache_io.lock().await;
let cache_path = active_wallet_cache_path(&state)?;
match read(&cache_path).await { match read(&cache_path).await {
Ok(bytes) => String::from_utf8(bytes) Ok(bytes) => String::from_utf8(bytes)
.map_err(|_| "Local transaction cache is not valid UTF-8.".to_string()), .map_err(|_| "Local transaction cache is not valid UTF-8.".to_string()),
@ -103,7 +104,8 @@ async fn write_local_transaction_cache(
state: State<'_, WalletState>, state: State<'_, WalletState>,
cache_json: String, cache_json: String,
) -> Result<(), String> { ) -> Result<(), String> {
let cache_path = active_wallet_cache_path(&state)?; let _cache_guard = state.history_cache_io.lock().await;
let cache_path = active_wallet_cache_path(&state)?;
let parsed: JsonValue = serde_json::from_str(&cache_json) let parsed: JsonValue = serde_json::from_str(&cache_json)
.map_err(|err| format!("Transaction cache must be valid JSON: {err}"))?; .map_err(|err| format!("Transaction cache must be valid JSON: {err}"))?;
let normalized = serde_json::to_string_pretty(&parsed) let normalized = serde_json::to_string_pretty(&parsed)
@ -116,6 +118,7 @@ async fn write_local_transaction_cache(
#[tauri::command] #[tauri::command]
async fn read_local_transaction_index(state: State<'_, WalletState>) -> Result<String, String> { async fn read_local_transaction_index(state: State<'_, WalletState>) -> Result<String, String> {
let _cache_guard = state.history_cache_io.lock().await;
let history_dir = active_wallet_history_dir(&state)?; let history_dir = active_wallet_history_dir(&state)?;
let index_path = history_dir.join("index.json"); let index_path = history_dir.join("index.json");
match read(&index_path).await { match read(&index_path).await {
@ -131,6 +134,7 @@ async fn write_local_transaction_index(
state: State<'_, WalletState>, state: State<'_, WalletState>,
index_json: String, index_json: String,
) -> Result<(), String> { ) -> Result<(), String> {
let _cache_guard = state.history_cache_io.lock().await;
let history_dir = active_wallet_history_dir(&state)?; let history_dir = active_wallet_history_dir(&state)?;
create_dir_all(&history_dir) create_dir_all(&history_dir)
.await .await
@ -150,6 +154,7 @@ async fn read_local_transaction_record(
state: State<'_, WalletState>, state: State<'_, WalletState>,
file_name: String, file_name: String,
) -> Result<String, String> { ) -> Result<String, String> {
let _cache_guard = state.history_cache_io.lock().await;
let history_dir = active_wallet_history_dir(&state)?; let history_dir = active_wallet_history_dir(&state)?;
let file_name = validate_transaction_record_file(&file_name)?; let file_name = validate_transaction_record_file(&file_name)?;
match read(history_dir.join(file_name)).await { match read(history_dir.join(file_name)).await {
@ -166,6 +171,7 @@ async fn write_local_transaction_record(
file_name: String, file_name: String,
record_json: String, record_json: String,
) -> Result<(), String> { ) -> Result<(), String> {
let _cache_guard = state.history_cache_io.lock().await;
let history_dir = active_wallet_history_dir(&state)?; let history_dir = active_wallet_history_dir(&state)?;
create_dir_all(&history_dir) create_dir_all(&history_dir)
.await .await
@ -248,6 +254,7 @@ async fn read_nft_cache(
nft_name: String, nft_name: String,
series: u32, series: u32,
) -> Result<Option<NftCacheRecordView>, String> { ) -> Result<Option<NftCacheRecordView>, String> {
let _cache_guard = state.nft_cache_io.lock().await;
let cache_dir = active_wallet_nft_dir(&state)?; let cache_dir = active_wallet_nft_dir(&state)?;
let key = validate_nft_cache_key(&nft_name, series)?; let key = validate_nft_cache_key(&nft_name, series)?;
let record_dir = cache_dir.join(key); let record_dir = cache_dir.join(key);
@ -267,6 +274,7 @@ async fn write_nft_cache(
metadata_json: String, metadata_json: String,
image_url: String, image_url: String,
) -> Result<NftCacheRecordView, String> { ) -> Result<NftCacheRecordView, String> {
let _cache_guard = state.nft_cache_io.lock().await;
let cache_dir = active_wallet_nft_dir(&state)?; let cache_dir = active_wallet_nft_dir(&state)?;
let key = validate_nft_cache_key(&nft_name, series)?; let key = validate_nft_cache_key(&nft_name, series)?;
let record_dir = cache_dir.join(key); let record_dir = cache_dir.join(key);
@ -350,6 +358,7 @@ async fn prune_nft_cache(
state: State<'_, WalletState>, state: State<'_, WalletState>,
keep_keys: Vec<String>, keep_keys: Vec<String>,
) -> Result<(), String> { ) -> Result<(), String> {
let _cache_guard = state.nft_cache_io.lock().await;
let cache_dir = active_wallet_nft_dir(&state)?; let cache_dir = active_wallet_nft_dir(&state)?;
let keep: std::collections::HashSet<String> = keep_keys let keep: std::collections::HashSet<String> = keep_keys
.into_iter() .into_iter()
@ -422,22 +431,29 @@ async fn clear_nft_cache_files(cache_dir: &Path, file_name: &str) -> Result<(),
async fn clear_wallet_cache(state: State<'_, WalletState>, cache_kind: String) -> Result<(), String> { async fn clear_wallet_cache(state: State<'_, WalletState>, cache_kind: String) -> Result<(), String> {
match cache_kind.trim().to_ascii_lowercase().as_str() { match cache_kind.trim().to_ascii_lowercase().as_str() {
"history" => { "history" => {
let _cache_guard = state.history_cache_io.lock().await;
remove_file_if_exists(&active_wallet_cache_path(&state)?).await?; remove_file_if_exists(&active_wallet_cache_path(&state)?).await?;
remove_dir_if_exists(&active_wallet_history_dir(&state)?).await remove_dir_if_exists(&active_wallet_history_dir(&state)?).await
} }
"nft" | "nft_images" | "nft_media" => { "nft" | "nft_images" | "nft_media" => {
let _cache_guard = state.nft_cache_io.lock().await;
clear_nft_cache_files(&active_wallet_nft_dir(&state)?, "image.bin").await clear_nft_cache_files(&active_wallet_nft_dir(&state)?, "image.bin").await
} }
"nft_details" => { "nft_details" => {
let _cache_guard = state.nft_cache_io.lock().await;
clear_nft_cache_files(&active_wallet_nft_dir(&state)?, "record.json").await clear_nft_cache_files(&active_wallet_nft_dir(&state)?, "record.json").await
} }
"address_book" => remove_file_if_exists(&active_wallet_address_book_path(&state)?).await, "address_book" => {
let _cache_guard = state.address_book_io.lock().await;
remove_file_if_exists(&active_wallet_address_book_path(&state)?).await
}
_ => Err("Unknown cache type.".to_string()), _ => Err("Unknown cache type.".to_string()),
} }
} }
#[tauri::command] #[tauri::command]
async fn read_address_book(state: State<'_, WalletState>) -> Result<String, String> { async fn read_address_book(state: State<'_, WalletState>) -> Result<String, String> {
let _cache_guard = state.address_book_io.lock().await;
let address_book_path = active_wallet_address_book_path(&state)?; let address_book_path = active_wallet_address_book_path(&state)?;
match read(&address_book_path).await { match read(&address_book_path).await {
Ok(bytes) => String::from_utf8(bytes) Ok(bytes) => String::from_utf8(bytes)
@ -454,6 +470,7 @@ async fn write_address_book(
state: State<'_, WalletState>, state: State<'_, WalletState>,
address_book_json: String, address_book_json: String,
) -> Result<(), String> { ) -> Result<(), String> {
let _cache_guard = state.address_book_io.lock().await;
let address_book_path = active_wallet_address_book_path(&state)?; let address_book_path = active_wallet_address_book_path(&state)?;
let parsed: JsonValue = serde_json::from_str(&address_book_json) let parsed: JsonValue = serde_json::from_str(&address_book_json)
.map_err(|err| format!("Address book must be valid JSON: {err}"))?; .map_err(|err| format!("Address book must be valid JSON: {err}"))?;

View File

@ -342,4 +342,7 @@ struct ActiveWallet {
struct WalletState { struct WalletState {
active_wallet: Mutex<Option<ActiveWallet>>, active_wallet: Mutex<Option<ActiveWallet>>,
rpc_scheduler: WalletRpcScheduler, rpc_scheduler: WalletRpcScheduler,
history_cache_io: AsyncMutex<()>,
nft_cache_io: AsyncMutex<()>,
address_book_io: AsyncMutex<()>,
} }