@@ -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:: {
2727L :: Target : LdkLogger ,
2828{
2929peers : RwLock < HashMap < PublicKey , PeerInfo > > ,
30+ mutation_lock : tokio:: sync:: Mutex < ( ) > ,
3031kv_store : Arc < DynStore > ,
3132logger : L ,
3233}
@@ -37,44 +38,60 @@ where
3738{
3839pub ( crate ) fn new ( kv_store : Arc < DynStore > , logger : L ) -> Self {
3940let 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.
6173pub ( crate ) fn list_peers ( & self ) -> Vec < PeerInfo > {
6274self . 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.
6582pub ( crate ) fn get_peer ( & self , node_id : & PublicKey ) -> Option < PeerInfo > {
6683self . 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 ,
7389PEER_INFO_PERSISTENCE_PRIMARY_NAMESPACE ,
7490PEER_INFO_PERSISTENCE_SECONDARY_NAMESPACE ,
7591PEER_INFO_PERSISTENCE_KEY ,
7692 data,
7793)
94+ . await
7895. map_err ( |e| {
7996log_error ! (
8097self . logger,
@@ -101,7 +118,8 @@ where
101118let ( kv_store, logger) = args;
102119let read_peers: PeerStoreDeserWrapper = Readable :: read ( reader) ?;
103120let 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 {
158176use crate :: io:: test_utils:: InMemoryStore ;
159177use crate :: types:: DynStoreWrapper ;
160178
161- #[ test]
162- fn peer_info_persistence ( ) {
179+ #[ tokio :: test]
180+ async fn peer_info_persistence ( ) {
163181let store: Arc < DynStore > = Arc :: new ( DynStoreWrapper ( InMemoryStore :: new ( ) ) ) ;
164182let logger = Arc :: new ( TestLogger :: new ( ) ) ;
165183let peer_store = PeerStore :: new ( Arc :: clone ( & store) , Arc :: clone ( & logger) ) ;
@@ -170,22 +188,24 @@ mod tests {
170188. unwrap ( ) ;
171189let address = SocketAddress :: from_str ( "127.0.0.1:9738" ) . unwrap ( ) ;
172190let expected_peer_info = PeerInfo { node_id, address } ;
173- assert ! ( KVStoreSync :: read(
191+ assert ! ( KVStore :: read(
174192& * store,
175193PEER_INFO_PERSISTENCE_PRIMARY_NAMESPACE ,
176194PEER_INFO_PERSISTENCE_SECONDARY_NAMESPACE ,
177195PEER_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,
185204PEER_INFO_PERSISTENCE_PRIMARY_NAMESPACE ,
186205PEER_INFO_PERSISTENCE_SECONDARY_NAMESPACE ,
187206PEER_INFO_PERSISTENCE_KEY ,
188207)
208+ . await
189209. unwrap ( ) ;
190210let deser_peer_store =
191211PeerStore :: read ( & mut & persisted_bytes[ ..] , ( Arc :: clone ( & store) , logger) ) . unwrap ( ) ;
0 commit comments