55// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
66// accordance with one or both of these licenses.
77
8+ use std:: boxed:: Box ;
9+ use std:: collections:: { hash_map, HashMap } ;
10+ use std:: future:: Future ;
811use std:: panic:: RefUnwindSafe ;
912use std:: path:: PathBuf ;
13+ use std:: pin:: Pin ;
14+ use std:: sync:: Mutex ;
1015
1116use lightning:: events:: ClosureReason ;
1217use lightning:: ln:: functional_test_utils:: {
1318 connect_block, create_announced_chan_between_nodes, create_chanmon_cfgs, create_dummy_block,
1419 create_network, create_node_cfgs, create_node_chanmgrs, send_payment, TestChanMonCfg ,
1520} ;
1621use lightning:: util:: persist:: {
17- KVStoreSync , MonitorUpdatingPersister , KVSTORE_NAMESPACE_KEY_MAX_LEN ,
22+ KVStore , KVStoreSync , MonitorUpdatingPersister , KVSTORE_NAMESPACE_KEY_MAX_LEN ,
1823} ;
1924use lightning:: util:: test_utils;
20- use lightning:: { check_added_monitors, check_closed_broadcast, check_closed_event} ;
25+ use lightning:: { check_added_monitors, check_closed_broadcast, check_closed_event, io } ;
2126use rand:: distr:: Alphanumeric ;
2227use rand:: { rng, Rng } ;
2328
@@ -32,6 +37,125 @@ type TestMonitorUpdatePersister<'a, K> = MonitorUpdatingPersister<
3237
3338const EXPECTED_UPDATES_PER_PAYMENT : u64 = 5 ;
3439
40+ pub struct InMemoryStore {
41+ persisted_bytes : Mutex < HashMap < String , HashMap < String , Vec < u8 > > > > ,
42+ }
43+
44+ impl InMemoryStore {
45+ pub fn new ( ) -> Self {
46+ let persisted_bytes = Mutex :: new ( HashMap :: new ( ) ) ;
47+ Self { persisted_bytes }
48+ }
49+
50+ fn read_internal (
51+ & self , primary_namespace : & str , secondary_namespace : & str , key : & str ,
52+ ) -> io:: Result < Vec < u8 > > {
53+ let persisted_lock = self . persisted_bytes . lock ( ) . unwrap ( ) ;
54+ let prefixed = format ! ( "{primary_namespace}/{secondary_namespace}" ) ;
55+
56+ if let Some ( outer_ref) = persisted_lock. get ( & prefixed) {
57+ if let Some ( inner_ref) = outer_ref. get ( key) {
58+ let bytes = inner_ref. clone ( ) ;
59+ Ok ( bytes)
60+ } else {
61+ Err ( io:: Error :: new ( io:: ErrorKind :: NotFound , "Key not found" ) )
62+ }
63+ } else {
64+ Err ( io:: Error :: new ( io:: ErrorKind :: NotFound , "Namespace not found" ) )
65+ }
66+ }
67+
68+ fn write_internal (
69+ & self , primary_namespace : & str , secondary_namespace : & str , key : & str , buf : Vec < u8 > ,
70+ ) -> io:: Result < ( ) > {
71+ let mut persisted_lock = self . persisted_bytes . lock ( ) . unwrap ( ) ;
72+
73+ let prefixed = format ! ( "{primary_namespace}/{secondary_namespace}" ) ;
74+ let outer_e = persisted_lock. entry ( prefixed) . or_insert ( HashMap :: new ( ) ) ;
75+ outer_e. insert ( key. to_string ( ) , buf) ;
76+ Ok ( ( ) )
77+ }
78+
79+ fn remove_internal (
80+ & self , primary_namespace : & str , secondary_namespace : & str , key : & str , _lazy : bool ,
81+ ) -> io:: Result < ( ) > {
82+ let mut persisted_lock = self . persisted_bytes . lock ( ) . unwrap ( ) ;
83+
84+ let prefixed = format ! ( "{primary_namespace}/{secondary_namespace}" ) ;
85+ if let Some ( outer_ref) = persisted_lock. get_mut ( & prefixed) {
86+ outer_ref. remove ( & key. to_string ( ) ) ;
87+ }
88+
89+ Ok ( ( ) )
90+ }
91+
92+ fn list_internal (
93+ & self , primary_namespace : & str , secondary_namespace : & str ,
94+ ) -> io:: Result < Vec < String > > {
95+ let mut persisted_lock = self . persisted_bytes . lock ( ) . unwrap ( ) ;
96+
97+ let prefixed = format ! ( "{primary_namespace}/{secondary_namespace}" ) ;
98+ match persisted_lock. entry ( prefixed) {
99+ hash_map:: Entry :: Occupied ( e) => Ok ( e. get ( ) . keys ( ) . cloned ( ) . collect ( ) ) ,
100+ hash_map:: Entry :: Vacant ( _) => Ok ( Vec :: new ( ) ) ,
101+ }
102+ }
103+ }
104+
105+ impl KVStore for InMemoryStore {
106+ fn read (
107+ & self , primary_namespace : & str , secondary_namespace : & str , key : & str ,
108+ ) -> Pin < Box < dyn Future < Output = Result < Vec < u8 > , io:: Error > > + ' static + Send > > {
109+ let res = self . read_internal ( & primary_namespace, & secondary_namespace, & key) ;
110+ Box :: pin ( async move { res } )
111+ }
112+ fn write (
113+ & self , primary_namespace : & str , secondary_namespace : & str , key : & str , buf : Vec < u8 > ,
114+ ) -> Pin < Box < dyn Future < Output = Result < ( ) , io:: Error > > + ' static + Send > > {
115+ let res = self . write_internal ( & primary_namespace, & secondary_namespace, & key, buf) ;
116+ Box :: pin ( async move { res } )
117+ }
118+ fn remove (
119+ & self , primary_namespace : & str , secondary_namespace : & str , key : & str , lazy : bool ,
120+ ) -> Pin < Box < dyn Future < Output = Result < ( ) , io:: Error > > + ' static + Send > > {
121+ let res = self . remove_internal ( & primary_namespace, & secondary_namespace, & key, lazy) ;
122+ Box :: pin ( async move { res } )
123+ }
124+ fn list (
125+ & self , primary_namespace : & str , secondary_namespace : & str ,
126+ ) -> Pin < Box < dyn Future < Output = Result < Vec < String > , io:: Error > > + ' static + Send > > {
127+ let res = self . list_internal ( primary_namespace, secondary_namespace) ;
128+ Box :: pin ( async move { res } )
129+ }
130+ }
131+
132+ impl KVStoreSync for InMemoryStore {
133+ fn read (
134+ & self , primary_namespace : & str , secondary_namespace : & str , key : & str ,
135+ ) -> io:: Result < Vec < u8 > > {
136+ self . read_internal ( primary_namespace, secondary_namespace, key)
137+ }
138+
139+ fn write (
140+ & self , primary_namespace : & str , secondary_namespace : & str , key : & str , buf : Vec < u8 > ,
141+ ) -> io:: Result < ( ) > {
142+ self . write_internal ( primary_namespace, secondary_namespace, key, buf)
143+ }
144+
145+ fn remove (
146+ & self , primary_namespace : & str , secondary_namespace : & str , key : & str , lazy : bool ,
147+ ) -> io:: Result < ( ) > {
148+ self . remove_internal ( primary_namespace, secondary_namespace, key, lazy)
149+ }
150+
151+ fn list ( & self , primary_namespace : & str , secondary_namespace : & str ) -> io:: Result < Vec < String > > {
152+ self . list_internal ( primary_namespace, secondary_namespace)
153+ }
154+ }
155+
156+ unsafe impl Sync for InMemoryStore { }
157+ unsafe impl Send for InMemoryStore { }
158+
35159pub ( crate ) fn random_storage_path ( ) -> PathBuf {
36160 let mut temp_path = std:: env:: temp_dir ( ) ;
37161 let mut rng = rng ( ) ;
0 commit comments