Skip to content

Commit 73b3a36

Browse files
committed
Implement KVStoreUnpersister
1 parent 2618985 commit 73b3a36

File tree

4 files changed

+54
-8
lines changed

4 files changed

+54
-8
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ chrono = "0.4"
5151
futures = "0.3"
5252
serde_json = { version = "1.0" }
5353
tokio = { version = "1", default-features = false, features = [ "rt-multi-thread", "time", "sync" ] }
54+
libc = "0.2"
5455

5556
[dev-dependencies]
5657
electrsd = { version = "0.22.0", features = ["legacy", "esplora_a33e97e1", "bitcoind_23_0"] }

src/event.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
PaymentInfo, PaymentInfoStorage, PaymentStatus, Wallet,
44
};
55

6+
use crate::io_utils::KVStoreUnpersister;
67
use crate::logger::{log_error, log_info, Logger};
78

89
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
@@ -183,7 +184,7 @@ impl Writeable for EventQueueSerWrapper<'_> {
183184

184185
pub(crate) struct EventHandler<K: Deref, L: Deref>
185186
where
186-
K::Target: KVStorePersister,
187+
K::Target: KVStorePersister + KVStoreUnpersister,
187188
L::Target: Logger,
188189
{
189190
wallet: Arc<Wallet<bdk::database::SqliteDatabase>>,
@@ -199,7 +200,7 @@ where
199200

200201
impl<K: Deref, L: Deref> EventHandler<K, L>
201202
where
202-
K::Target: KVStorePersister,
203+
K::Target: KVStorePersister + KVStoreUnpersister,
203204
L::Target: Logger,
204205
{
205206
pub fn new(
@@ -224,7 +225,7 @@ where
224225

225226
impl<K: Deref, L: Deref> LdkEventHandler for EventHandler<K, L>
226227
where
227-
K::Target: KVStorePersister,
228+
K::Target: KVStorePersister + KVStoreUnpersister,
228229
L::Target: Logger,
229230
{
230231
fn handle_event(&self, event: LdkEvent) {

src/io_utils.rs

+37
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ use crate::{Config, Error, FilesystemLogger, NetworkGraph, Scorer};
33

44
use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringParameters};
55
use lightning::util::ser::{Readable, ReadableArgs};
6+
use lightning_persister::FilesystemPersister;
67

78
use rand::{thread_rng, RngCore};
89

910
use std::fs;
1011
use std::io::{BufReader, Write};
12+
use std::os::unix::io::AsRawFd;
1113
use std::path::Path;
14+
use std::path::PathBuf;
1215
use std::sync::Arc;
1316

1417
pub(crate) fn read_or_generate_seed_file(config: &Config) -> [u8; 32] {
@@ -82,3 +85,37 @@ pub(crate) fn read_payment_info(config: &Config) -> Vec<PaymentInfo> {
8285

8386
payments
8487
}
88+
89+
/// Provides an interface that allows a previously persisted key to be unpersisted.
90+
pub trait KVStoreUnpersister {
91+
/// Unpersist (i.e., remove) the writeable previously persisted under the provided key.
92+
/// Returns `true` if the key was present, and `false` otherwise.
93+
fn unpersist(&self, key: &str) -> std::io::Result<bool>;
94+
}
95+
96+
impl KVStoreUnpersister for FilesystemPersister {
97+
fn unpersist(&self, key: &str) -> std::io::Result<bool> {
98+
let mut dest_file = PathBuf::from(self.get_data_dir());
99+
dest_file.push(key);
100+
101+
if !dest_file.is_file() {
102+
return Ok(false);
103+
}
104+
105+
fs::remove_file(&dest_file)?;
106+
let parent_directory = dest_file.parent().unwrap();
107+
let dir_file = fs::OpenOptions::new().read(true).open(parent_directory)?;
108+
#[cfg(not(target_os = "windows"))]
109+
{
110+
unsafe {
111+
libc::fsync(dir_file.as_raw_fd());
112+
}
113+
}
114+
115+
if dest_file.is_file() {
116+
return Err(std::io::Error::new(std::io::ErrorKind::Other, "Unpersisting key failed"));
117+
}
118+
119+
return Ok(true);
120+
}
121+
}

src/payment_store.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::hex_utils;
2+
use crate::io_utils::KVStoreUnpersister;
23
use crate::Error;
34

45
use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
@@ -72,15 +73,15 @@ pub(crate) const PAYMENT_INFO_PERSISTENCE_PREFIX: &str = "payments";
7273

7374
pub(crate) struct PaymentInfoStorage<K: Deref>
7475
where
75-
K::Target: KVStorePersister,
76+
K::Target: KVStorePersister + KVStoreUnpersister,
7677
{
7778
payments: Mutex<HashMap<PaymentHash, PaymentInfo>>,
7879
persister: K,
7980
}
8081

8182
impl<K: Deref> PaymentInfoStorage<K>
8283
where
83-
K::Target: KVStorePersister,
84+
K::Target: KVStorePersister + KVStoreUnpersister,
8485
{
8586
pub(crate) fn from_payments(mut payments: Vec<PaymentInfo>, persister: K) -> Self {
8687
let payments = Mutex::new(HashMap::from_iter(
@@ -106,9 +107,15 @@ where
106107
return Ok(());
107108
}
108109

109-
// TODO: Need an `unpersist` method for this?
110-
//pub(crate) fn remove_payment(&self, payment_hash: &PaymentHash) -> Result<(), Error> {
111-
//}
110+
pub(crate) fn remove_payment(&self, payment_hash: &PaymentHash) -> Result<(), Error> {
111+
let key = format!(
112+
"{}/{}",
113+
PAYMENT_INFO_PERSISTENCE_PREFIX,
114+
hex_utils::to_string(&payment_hash.0)
115+
);
116+
self.persister.unpersist(&key).map_err(|_| Error::PersistenceFailed)?;
117+
Ok(())
118+
}
112119

113120
pub(crate) fn get(&self, payment_hash: &PaymentHash) -> Option<PaymentInfo> {
114121
self.payments.lock().unwrap().get(payment_hash).cloned()

0 commit comments

Comments
 (0)