11use std:: {
22 collections:: { hash_map:: Entry , HashMap , VecDeque } ,
3- sync:: { Arc , Mutex } ,
3+ sync:: Mutex ,
44} ;
55
6- use crate :: types :: OnionMessenger ;
6+ use lightning :: ln :: msgs :: OnionMessage ;
77
88pub ( crate ) struct OnionMessageMailbox {
99 map : Mutex < HashMap < bitcoin:: secp256k1:: PublicKey , VecDeque < lightning:: ln:: msgs:: OnionMessage > > > ,
10- onion_messenger : Arc < OnionMessenger > ,
1110}
1211
1312impl OnionMessageMailbox {
1413 const MAX_MESSAGES_PER_PEER : usize = 100 ;
14+ const MAX_PEERS : usize = 100 ;
1515
16- pub fn new ( onion_messenger : Arc < OnionMessenger > ) -> Self {
17- Self { map : Mutex :: new ( HashMap :: new ( ) ) , onion_messenger }
16+ pub fn new ( ) -> Self {
17+ Self { map : Mutex :: new ( HashMap :: new ( ) ) }
1818 }
1919
2020 pub ( crate ) fn onion_message_intercepted (
@@ -28,18 +28,74 @@ impl OnionMessageMailbox {
2828 queue. pop_front ( ) ;
2929 }
3030 queue. push_back ( message) ;
31+
32+ // Enforce a peers limit. If exceeded, evict the peer with the longest queue.
33+ if map. len ( ) > Self :: MAX_PEERS {
34+ let peer_to_remove = map
35+ . iter ( )
36+ . max_by_key ( |( _, queue) | queue. len ( ) )
37+ . map ( |( peer, _) | peer. clone ( ) )
38+ . unwrap ( ) ;
39+
40+ map. remove ( & peer_to_remove) ;
41+ }
3142 }
3243
33- pub ( crate ) fn onion_message_peer_connected ( & self , peer_node_id : bitcoin:: secp256k1:: PublicKey ) {
44+ pub ( crate ) fn onion_message_peer_connected (
45+ & self , peer_node_id : bitcoin:: secp256k1:: PublicKey ,
46+ ) -> Vec < OnionMessage > {
3447 let mut map = self . map . lock ( ) . unwrap ( ) ;
3548
36- let queue = match map. entry ( peer_node_id) {
37- Entry :: Occupied ( entry) => entry. into_mut ( ) ,
38- Entry :: Vacant ( _) => return ,
49+ match map. entry ( peer_node_id) {
50+ Entry :: Occupied ( mut entry) => {
51+ let queue = std:: mem:: take ( entry. get_mut ( ) ) ;
52+ queue. into ( )
53+ } ,
54+ Entry :: Vacant ( _) => Vec :: new ( ) ,
55+ }
56+ }
57+ }
58+
59+ mod tests {
60+ use bitcoin:: {
61+ key:: Secp256k1 ,
62+ secp256k1:: { PublicKey , SecretKey } ,
63+ } ;
64+ use lightning:: onion_message;
65+
66+ use crate :: om_mailbox:: OnionMessageMailbox ;
67+
68+ #[ test]
69+ fn onion_message_mailbox ( ) {
70+ let mailbox = OnionMessageMailbox :: new ( ) ;
71+
72+ let secp = Secp256k1 :: new ( ) ;
73+ let sk_bytes = [ 12 ; 32 ] ;
74+ let sk = SecretKey :: from_slice ( & sk_bytes) . unwrap ( ) ;
75+ let peer_node_id = PublicKey :: from_secret_key ( & secp, & sk) ;
76+
77+ let blinding_sk = SecretKey :: from_slice ( & [ 13 ; 32 ] ) . unwrap ( ) ;
78+ let blinding_point = PublicKey :: from_secret_key ( & secp, & blinding_sk) ;
79+
80+ let message_sk = SecretKey :: from_slice ( & [ 13 ; 32 ] ) . unwrap ( ) ;
81+ let message_point = PublicKey :: from_secret_key ( & secp, & message_sk) ;
82+
83+ let message = lightning:: ln:: msgs:: OnionMessage {
84+ blinding_point,
85+ onion_routing_packet : onion_message:: packet:: Packet {
86+ version : 0 ,
87+ public_key : message_point,
88+ hop_data : vec ! [ 1 , 2 , 3 ] ,
89+ hmac : [ 0 ; 32 ] ,
90+ } ,
3991 } ;
92+ mailbox. onion_message_intercepted ( peer_node_id, message. clone ( ) ) ;
4093
41- while let Some ( message) = queue. pop_front ( ) {
42- let _ = self . onion_messenger . forward_onion_message ( message, & peer_node_id) ;
43- }
94+ let messages = mailbox. onion_message_peer_connected ( peer_node_id) ;
95+ assert_eq ! ( messages. len( ) , 1 ) ;
96+ assert_eq ! ( messages[ 0 ] , message) ;
97+
98+ let messages = mailbox. onion_message_peer_connected ( peer_node_id) ;
99+ assert_eq ! ( messages. len( ) , 0 ) ;
44100 }
45101}
0 commit comments