Skip to content

Commit

Permalink
Implement KVStoreUnpersister
Browse files Browse the repository at this point in the history
  • Loading branch information
tnull committed Mar 13, 2023
1 parent 5ffc2c0 commit 3b269c0
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 8 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ chrono = "0.4"
futures = "0.3"
serde_json = { version = "1.0" }
tokio = { version = "1", default-features = false, features = [ "rt-multi-thread", "time", "sync" ] }
libc = "0.2"

[dev-dependencies]
electrsd = { version = "0.22.0", features = ["legacy", "esplora_a33e97e1", "bitcoind_23_0"] }
Expand Down
7 changes: 4 additions & 3 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
PaymentInfo, PaymentInfoStorage, PaymentStatus, Wallet,
};

use crate::io_utils::KVStoreUnpersister;
use crate::logger::{log_error, log_info, Logger};

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

pub(crate) struct EventHandler<K: Deref, L: Deref>
where
K::Target: KVStorePersister,
K::Target: KVStorePersister + KVStoreUnpersister,
L::Target: Logger,
{
wallet: Arc<Wallet<bdk::database::SqliteDatabase>>,
Expand All @@ -199,7 +200,7 @@ where

impl<K: Deref, L: Deref> EventHandler<K, L>
where
K::Target: KVStorePersister,
K::Target: KVStorePersister + KVStoreUnpersister,
L::Target: Logger,
{
pub fn new(
Expand All @@ -224,7 +225,7 @@ where

impl<K: Deref, L: Deref> LdkEventHandler for EventHandler<K, L>
where
K::Target: KVStorePersister,
K::Target: KVStorePersister + KVStoreUnpersister,
L::Target: Logger,
{
fn handle_event(&self, event: LdkEvent) {
Expand Down
37 changes: 37 additions & 0 deletions src/io_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ use crate::{Config, Error, FilesystemLogger, NetworkGraph, Scorer};

use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringParameters};
use lightning::util::ser::{Readable, ReadableArgs};
use lightning_persister::FilesystemPersister;

use rand::{thread_rng, RngCore};

use std::fs;
use std::io::{BufReader, Write};
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;

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

payments
}

/// Provides an interface that allows a previously persisted key to be unpersisted.
pub trait KVStoreUnpersister {
/// Unpersist (i.e., remove) the writeable previously persisted under the provided key.
/// Returns `true` if the key was present, and `false` otherwise.
fn unpersist(&self, key: &str) -> std::io::Result<bool>;
}

impl KVStoreUnpersister for FilesystemPersister {
fn unpersist(&self, key: &str) -> std::io::Result<bool> {
let mut dest_file = PathBuf::from(self.get_data_dir());
dest_file.push(key);

if !dest_file.is_file() {
return Ok(false);
}

fs::remove_file(&dest_file)?;
let parent_directory = dest_file.parent().unwrap();
let dir_file = fs::OpenOptions::new().read(true).open(parent_directory)?;
#[cfg(not(target_os = "windows"))]
{
unsafe {
libc::fsync(dir_file.as_raw_fd());
}
}

if dest_file.is_file() {
return Err(std::io::Error::new(std::io::ErrorKind::Other, "Unpersisting key failed"));
}

return Ok(true);
}
}
17 changes: 12 additions & 5 deletions src/payment_store.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::hex_utils;
use crate::io_utils::KVStoreUnpersister;
use crate::Error;

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

pub(crate) struct PaymentInfoStorage<K: Deref>
where
K::Target: KVStorePersister,
K::Target: KVStorePersister + KVStoreUnpersister,
{
payments: Mutex<HashMap<PaymentHash, PaymentInfo>>,
persister: K,
}

impl<K: Deref> PaymentInfoStorage<K>
where
K::Target: KVStorePersister,
K::Target: KVStorePersister + KVStoreUnpersister,
{
pub(crate) fn from_payments(mut payments: Vec<PaymentInfo>, persister: K) -> Self {
let payments = Mutex::new(HashMap::from_iter(
Expand All @@ -106,9 +107,15 @@ where
return Ok(());
}

// TODO: Need an `unpersist` method for this?
//pub(crate) fn remove_payment(&self, payment_hash: &PaymentHash) -> Result<(), Error> {
//}
pub(crate) fn remove(&self, payment_hash: &PaymentHash) -> Result<(), Error> {
let key = format!(
"{}/{}",
PAYMENT_INFO_PERSISTENCE_PREFIX,
hex_utils::to_string(&payment_hash.0)
);
self.persister.unpersist(&key).map_err(|_| Error::PersistenceFailed)?;
Ok(())
}

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

0 comments on commit 3b269c0

Please sign in to comment.