Skip to content

Commit 07187cf

Browse files
committed
Implement KVStoreUnpersister
1 parent 374943a commit 07187cf

File tree

4 files changed

+55
-8
lines changed

4 files changed

+55
-8
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ chrono = "0.4"
4848
futures = "0.3"
4949
serde_json = { version = "1.0" }
5050
tokio = { version = "1", features = [ "full" ] }
51+
libc = "0.2"
5152

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

src/event.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use crate::{
33
PaymentInfo, PaymentInfoStorage, PaymentStatus, Wallet,
44
};
55

6+
use crate::io_utils::KVStoreUnpersister;
7+
68
use crate::logger::{log_error, log_given_level, log_info, log_internal, Logger};
79

810
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
@@ -230,7 +232,7 @@ impl Writeable for EventQueueSerWrapper<'_> {
230232

231233
pub(crate) struct EventHandler<K: Deref, L: Deref>
232234
where
233-
K::Target: KVStorePersister,
235+
K::Target: KVStorePersister + KVStoreUnpersister,
234236
L::Target: Logger,
235237
{
236238
wallet: Arc<Wallet<bdk::sled::Tree>>,
@@ -246,7 +248,7 @@ where
246248

247249
impl<K: Deref, L: Deref> EventHandler<K, L>
248250
where
249-
K::Target: KVStorePersister,
251+
K::Target: KVStorePersister + KVStoreUnpersister,
250252
L::Target: Logger,
251253
{
252254
pub fn new(
@@ -271,7 +273,7 @@ where
271273

272274
impl<K: Deref, L: Deref> LdkEventHandler for EventHandler<K, L>
273275
where
274-
K::Target: KVStorePersister,
276+
K::Target: KVStorePersister + KVStoreUnpersister,
275277
L::Target: Logger,
276278
{
277279
fn handle_event(&self, event: LdkEvent) {

src/io_utils.rs

Lines changed: 37 additions & 0 deletions
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] {
@@ -84,3 +87,37 @@ pub(crate) fn read_payment_info(config: &Config) -> Vec<PaymentInfo> {
8487

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

src/payment_store.rs

Lines changed: 12 additions & 5 deletions
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};
@@ -126,15 +127,15 @@ pub(crate) const PAYMENT_INFO_PERSISTENCE_PREFIX: &str = "payments";
126127

127128
pub(crate) struct PaymentInfoStorage<K: Deref>
128129
where
129-
K::Target: KVStorePersister,
130+
K::Target: KVStorePersister + KVStoreUnpersister,
130131
{
131132
payments: Mutex<HashMap<PaymentHash, PaymentInfo>>,
132133
persister: K,
133134
}
134135

135136
impl<K: Deref> PaymentInfoStorage<K>
136137
where
137-
K::Target: KVStorePersister,
138+
K::Target: KVStorePersister + KVStoreUnpersister,
138139
{
139140
pub(crate) fn from_payments(mut payments: Vec<PaymentInfo>, persister: K) -> Self {
140141
let payments = Mutex::new(HashMap::from_iter(
@@ -160,9 +161,15 @@ where
160161
return Ok(());
161162
}
162163

163-
// TODO: Need an `unpersist` method for this?
164-
//pub(crate) fn remove_payment(&self, payment_hash: &PaymentHash) -> Result<(), Error> {
165-
//}
164+
pub(crate) fn remove_payment(&self, payment_hash: &PaymentHash) -> Result<(), Error> {
165+
let key = format!(
166+
"{}/{}",
167+
PAYMENT_INFO_PERSISTENCE_PREFIX,
168+
hex_utils::to_string(&payment_hash.0)
169+
);
170+
self.persister.unpersist(&key).map_err(|_| Error::PersistenceFailed)?;
171+
Ok(())
172+
}
166173

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

0 commit comments

Comments
 (0)