Skip to content

Commit 8854643

Browse files
authored
feat: Add atomic_write for atomic file writing (#245)
Introduces atomic file writes for all SPV storage operations with a tempfile + rename pattern to ensure files dont get corrupted if a crash happens during write. - Adds `atomic_write` function - Updates all file writes: headers, filter headers, index, chain state, sync state, checkpoints, chainlocks, metadata, peers, peer-reputation
1 parent 5d182ab commit 8854643

File tree

6 files changed

+289
-86
lines changed

6 files changed

+289
-86
lines changed

dash-spv/src/network/persist.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
55
use std::path::PathBuf;
66

77
use crate::error::{SpvError as Error, StorageError};
8+
use crate::storage::disk::io::atomic_write;
89

910
/// Peer persistence for saving and loading known peer addresses
1011
pub struct PeerStore {
@@ -61,9 +62,7 @@ impl PeerStore {
6162
let json = serde_json::to_string_pretty(&saved)
6263
.map_err(|e| Error::Storage(StorageError::Serialization(e.to_string())))?;
6364

64-
tokio::fs::write(&self.path, json)
65-
.await
66-
.map_err(|e| Error::Storage(StorageError::WriteFailed(e.to_string())))?;
65+
atomic_write(&self.path, json.as_bytes()).await.map_err(Error::Storage)?;
6766

6867
log::debug!("Saved {} peers to {:?}", saved.peers.len(), self.path);
6968
Ok(())

dash-spv/src/network/reputation.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use std::sync::Arc;
1212
use std::time::{Duration, Instant};
1313
use tokio::sync::RwLock;
1414

15+
use crate::storage::disk::io::atomic_write;
16+
1517
/// Maximum misbehavior score before a peer is banned
1618
const MAX_MISBEHAVIOR_SCORE: i32 = 100;
1719

@@ -424,7 +426,7 @@ impl PeerReputationManager {
424426
.collect();
425427

426428
let json = serde_json::to_string_pretty(&data)?;
427-
tokio::fs::write(path, json).await
429+
atomic_write(path, json.as_bytes()).await.map_err(std::io::Error::other)
428430
}
429431

430432
/// Load reputation data from persistent storage

dash-spv/src/storage/disk/filters.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use dashcore_hashes::Hash;
77

88
use crate::error::StorageResult;
99

10+
use super::io::atomic_write;
1011
use super::manager::DiskStorageManager;
1112
use super::segments::SegmentState;
1213

@@ -185,8 +186,7 @@ impl DiskStorageManager {
185186
/// Store a compact filter.
186187
pub async fn store_filter(&mut self, height: u32, filter: &[u8]) -> StorageResult<()> {
187188
let path = self.base_path.join(format!("filters/{}.dat", height));
188-
tokio::fs::write(path, filter).await?;
189-
Ok(())
189+
atomic_write(&path, filter).await
190190
}
191191

192192
/// Load a compact filter.

0 commit comments

Comments
 (0)