Skip to content

Commit 221a266

Browse files
committed
Add TestStore implementation of KVStore
1 parent 62222d9 commit 221a266

File tree

1 file changed

+92
-1
lines changed

1 file changed

+92
-1
lines changed

lightning/src/util/test_utils.rs

+92-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use crate::util::config::UserConfig;
3232
use crate::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
3333
use crate::util::logger::{Logger, Level, Record};
3434
use crate::util::ser::{Readable, ReadableArgs, Writer, Writeable};
35+
use crate::util::persist::KVStore;
3536

3637
use bitcoin::EcdsaSighashType;
3738
use bitcoin::blockdata::constants::ChainHash;
@@ -56,7 +57,7 @@ use crate::prelude::*;
5657
use core::cell::RefCell;
5758
use core::ops::DerefMut;
5859
use core::time::Duration;
59-
use crate::sync::{Mutex, Arc};
60+
use crate::sync::{Mutex, Arc, RwLock};
6061
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
6162
use core::mem;
6263
use bitcoin::bech32::u5;
@@ -316,6 +317,96 @@ impl<Signer: sign::WriteableEcdsaChannelSigner> chainmonitor::Persist<Signer> fo
316317
}
317318
}
318319

320+
pub(crate) struct TestStore {
321+
persisted_bytes: RwLock<HashMap<String, HashMap<String, Arc<RwLock<Vec<u8>>>>>>,
322+
did_persist: Arc<AtomicBool>,
323+
}
324+
325+
impl TestStore {
326+
pub fn new() -> Self {
327+
let persisted_bytes = RwLock::new(HashMap::new());
328+
let did_persist = Arc::new(AtomicBool::new(false));
329+
Self { persisted_bytes, did_persist }
330+
}
331+
332+
pub fn get_persisted_bytes(&self, namespace: &str, key: &str) -> Option<Vec<u8>> {
333+
if let Some(outer_ref) = self.persisted_bytes.read().unwrap().get(namespace) {
334+
if let Some(inner_ref) = outer_ref.get(key) {
335+
let locked = inner_ref.read().unwrap();
336+
return Some((*locked).clone());
337+
}
338+
}
339+
None
340+
}
341+
342+
pub fn get_and_clear_did_persist(&self) -> bool {
343+
self.did_persist.swap(false, Ordering::Relaxed)
344+
}
345+
}
346+
347+
impl KVStore for TestStore {
348+
type Reader = TestReader;
349+
350+
fn read(&self, namespace: &str, key: &str) -> io::Result<Self::Reader> {
351+
if let Some(outer_ref) = self.persisted_bytes.read().unwrap().get(namespace) {
352+
if let Some(inner_ref) = outer_ref.get(key) {
353+
Ok(TestReader::new(Arc::clone(inner_ref)))
354+
} else {
355+
Err(io::Error::new(io::ErrorKind::NotFound, "Key not found"))
356+
}
357+
} else {
358+
Err(io::Error::new(io::ErrorKind::NotFound, "Namespace not found"))
359+
}
360+
}
361+
362+
fn write(&self, namespace: &str, key: &str, buf: &[u8]) -> io::Result<()> {
363+
let mut guard = self.persisted_bytes.write().unwrap();
364+
let outer_e = guard.entry(namespace.to_string()).or_insert(HashMap::new());
365+
let inner_e = outer_e.entry(key.to_string()).or_insert(Arc::new(RwLock::new(Vec::new())));
366+
367+
let mut guard = inner_e.write().unwrap();
368+
guard.write_all(buf)?;
369+
self.did_persist.store(true, Ordering::SeqCst);
370+
Ok(())
371+
}
372+
373+
fn remove(&self, namespace: &str, key: &str) -> io::Result<()> {
374+
match self.persisted_bytes.write().unwrap().entry(namespace.to_string()) {
375+
hash_map::Entry::Occupied(mut e) => {
376+
self.did_persist.store(true, Ordering::SeqCst);
377+
e.get_mut().remove(&key.to_string());
378+
Ok(())
379+
}
380+
hash_map::Entry::Vacant(_) => Ok(()),
381+
}
382+
}
383+
384+
fn list(&self, namespace: &str) -> io::Result<Vec<String>> {
385+
match self.persisted_bytes.write().unwrap().entry(namespace.to_string()) {
386+
hash_map::Entry::Occupied(e) => Ok(e.get().keys().cloned().collect()),
387+
hash_map::Entry::Vacant(_) => Ok(Vec::new()),
388+
}
389+
}
390+
}
391+
392+
pub struct TestReader {
393+
entry_ref: Arc<RwLock<Vec<u8>>>,
394+
}
395+
396+
impl TestReader {
397+
pub fn new(entry_ref: Arc<RwLock<Vec<u8>>>) -> Self {
398+
Self { entry_ref }
399+
}
400+
}
401+
402+
impl io::Read for TestReader {
403+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
404+
let bytes = self.entry_ref.read().unwrap().clone();
405+
let mut reader = io::Cursor::new(bytes);
406+
reader.read(buf)
407+
}
408+
}
409+
319410
pub struct TestBroadcaster {
320411
pub txn_broadcasted: Mutex<Vec<Transaction>>,
321412
pub blocks: Arc<Mutex<Vec<(Block, u32)>>>,

0 commit comments

Comments
 (0)