@@ -11,7 +11,7 @@ use std::sync::{Arc, RwLock};
1111
1212use bitcoin:: secp256k1:: PublicKey ;
1313use lightning:: impl_writeable_tlv_based;
14- use lightning:: util:: persist:: KVStoreSync ;
14+ use lightning:: util:: persist:: KVStore ;
1515use lightning:: util:: ser:: { Readable , ReadableArgs , Writeable , Writer } ;
1616
1717use crate :: io:: {
2727 L :: Target : LdkLogger ,
2828{
2929 peers : RwLock < HashMap < PublicKey , PeerInfo > > ,
30+ mutation_lock : tokio:: sync:: Mutex < ( ) > ,
3031 kv_store : Arc < DynStore > ,
3132 logger : L ,
3233}
@@ -37,44 +38,60 @@ where
3738{
3839 pub ( crate ) fn new ( kv_store : Arc < DynStore > , logger : L ) -> Self {
3940 let peers = RwLock :: new ( HashMap :: new ( ) ) ;
40- Self { peers, kv_store, logger }
41+ let mutation_lock = tokio:: sync:: Mutex :: new ( ( ) ) ;
42+ Self { peers, mutation_lock, kv_store, logger }
4143 }
4244
43- pub ( crate ) fn add_peer ( & self , peer_info : PeerInfo ) -> Result < ( ) , Error > {
44- let mut locked_peers = self . peers . write ( ) . expect ( "lock" ) ;
45-
46- if locked_peers. contains_key ( & peer_info. node_id ) {
47- return Ok ( ( ) ) ;
48- }
49-
50- locked_peers. insert ( peer_info. node_id , peer_info) ;
51- self . persist_peers ( & * locked_peers)
45+ pub ( crate ) async fn add_peer ( & self , peer_info : PeerInfo ) -> Result < ( ) , Error > {
46+ let _guard = self . mutation_lock . lock ( ) . await ;
47+ let data = {
48+ let mut locked_peers = self . peers . write ( ) . expect ( "lock" ) ;
49+ if locked_peers. contains_key ( & peer_info. node_id ) {
50+ return Ok ( ( ) ) ;
51+ }
52+ locked_peers. insert ( peer_info. node_id , peer_info) ;
53+ PeerStoreSerWrapper ( & locked_peers) . encode ( )
54+ } ;
55+ self . persist_peers ( data) . await
5256 }
5357
54- pub ( crate ) fn remove_peer ( & self , node_id : & PublicKey ) -> Result < ( ) , Error > {
55- let mut locked_peers = self . peers . write ( ) . expect ( "lock" ) ;
56-
57- locked_peers. remove ( node_id) ;
58- self . persist_peers ( & * locked_peers)
58+ pub ( crate ) async fn remove_peer ( & self , node_id : & PublicKey ) -> Result < ( ) , Error > {
59+ let _guard = self . mutation_lock . lock ( ) . await ;
60+ let data = {
61+ let mut locked_peers = self . peers . write ( ) . expect ( "lock" ) ;
62+ locked_peers. remove ( node_id) ;
63+ PeerStoreSerWrapper ( & locked_peers) . encode ( )
64+ } ;
65+ self . persist_peers ( data) . await
5966 }
6067
68+ /// Returns the current in-memory peer set.
69+ ///
70+ /// The async mutation lock serializes `add_peer` and `remove_peer`, but this synchronous
71+ /// reader cannot wait on it. Until peer-store reads are async, callers may observe peer
72+ /// changes that are still being persisted.
6173 pub ( crate ) fn list_peers ( & self ) -> Vec < PeerInfo > {
6274 self . peers . read ( ) . expect ( "lock" ) . values ( ) . cloned ( ) . collect ( )
6375 }
6476
77+ /// Returns the current in-memory peer info for `node_id`.
78+ ///
79+ /// The async mutation lock serializes `add_peer` and `remove_peer`, but this synchronous
80+ /// reader cannot wait on it. Until peer-store reads are async, callers may observe peer
81+ /// changes that are still being persisted.
6582 pub ( crate ) fn get_peer ( & self , node_id : & PublicKey ) -> Option < PeerInfo > {
6683 self . peers . read ( ) . expect ( "lock" ) . get ( node_id) . cloned ( )
6784 }
6885
69- fn persist_peers ( & self , locked_peers : & HashMap < PublicKey , PeerInfo > ) -> Result < ( ) , Error > {
70- let data = PeerStoreSerWrapper ( & * locked_peers) . encode ( ) ;
71- KVStoreSync :: write (
86+ async fn persist_peers ( & self , data : Vec < u8 > ) -> Result < ( ) , Error > {
87+ KVStore :: write (
7288 & * self . kv_store ,
7389 PEER_INFO_PERSISTENCE_PRIMARY_NAMESPACE ,
7490 PEER_INFO_PERSISTENCE_SECONDARY_NAMESPACE ,
7591 PEER_INFO_PERSISTENCE_KEY ,
7692 data,
7793 )
94+ . await
7895 . map_err ( |e| {
7996 log_error ! (
8097 self . logger,
@@ -101,7 +118,8 @@ where
101118 let ( kv_store, logger) = args;
102119 let read_peers: PeerStoreDeserWrapper = Readable :: read ( reader) ?;
103120 let peers: RwLock < HashMap < PublicKey , PeerInfo > > = RwLock :: new ( read_peers. 0 ) ;
104- Ok ( Self { peers, kv_store, logger } )
121+ let mutation_lock = tokio:: sync:: Mutex :: new ( ( ) ) ;
122+ Ok ( Self { peers, mutation_lock, kv_store, logger } )
105123 }
106124}
107125
@@ -158,8 +176,8 @@ mod tests {
158176 use crate :: io:: test_utils:: InMemoryStore ;
159177 use crate :: types:: DynStoreWrapper ;
160178
161- #[ test]
162- fn peer_info_persistence ( ) {
179+ #[ tokio :: test]
180+ async fn peer_info_persistence ( ) {
163181 let store: Arc < DynStore > = Arc :: new ( DynStoreWrapper ( InMemoryStore :: new ( ) ) ) ;
164182 let logger = Arc :: new ( TestLogger :: new ( ) ) ;
165183 let peer_store = PeerStore :: new ( Arc :: clone ( & store) , Arc :: clone ( & logger) ) ;
@@ -170,22 +188,24 @@ mod tests {
170188 . unwrap ( ) ;
171189 let address = SocketAddress :: from_str ( "127.0.0.1:9738" ) . unwrap ( ) ;
172190 let expected_peer_info = PeerInfo { node_id, address } ;
173- assert ! ( KVStoreSync :: read(
191+ assert ! ( KVStore :: read(
174192 & * store,
175193 PEER_INFO_PERSISTENCE_PRIMARY_NAMESPACE ,
176194 PEER_INFO_PERSISTENCE_SECONDARY_NAMESPACE ,
177195 PEER_INFO_PERSISTENCE_KEY ,
178196 )
197+ . await
179198 . is_err( ) ) ;
180- peer_store. add_peer ( expected_peer_info. clone ( ) ) . unwrap ( ) ;
199+ peer_store. add_peer ( expected_peer_info. clone ( ) ) . await . unwrap ( ) ;
181200
182201 // Check we can read back what we persisted.
183- let persisted_bytes = KVStoreSync :: read (
202+ let persisted_bytes = KVStore :: read (
184203 & * store,
185204 PEER_INFO_PERSISTENCE_PRIMARY_NAMESPACE ,
186205 PEER_INFO_PERSISTENCE_SECONDARY_NAMESPACE ,
187206 PEER_INFO_PERSISTENCE_KEY ,
188207 )
208+ . await
189209 . unwrap ( ) ;
190210 let deser_peer_store =
191211 PeerStore :: read ( & mut & persisted_bytes[ ..] , ( Arc :: clone ( & store) , logger) ) . unwrap ( ) ;
0 commit comments