@@ -85,6 +85,7 @@ pub struct OnionMessenger<Signer: Sign, K: Deref, L: Deref>
85
85
keys_manager : K ,
86
86
logger : L ,
87
87
pending_messages : Mutex < HashMap < PublicKey , Vec < MessageSendEvent > > > ,
88
+ peer_set : Mutex < HashSet < PublicKey > > ,
88
89
secp_ctx : Secp256k1 < secp256k1:: All > ,
89
90
// Coming soon:
90
91
// invoice_handler: InvoiceHandler,
@@ -121,6 +122,9 @@ pub enum SendError {
121
122
/// The provided [`Destination`] was an invalid [`BlindedRoute`], due to having fewer than two
122
123
/// blinded hops.
123
124
TooFewBlindedHops ,
125
+ /// Our next-hop peer was offline or does not support onion message forwarding.
126
+ // See TODO in `peer_connected`
127
+ InvalidFirstHop ,
124
128
}
125
129
126
130
impl < Signer : Sign , K : Deref , L : Deref > OnionMessenger < Signer , K , L >
@@ -134,6 +138,7 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
134
138
secp_ctx. seeded_randomize ( & keys_manager. get_secure_random_bytes ( ) ) ;
135
139
OnionMessenger {
136
140
keys_manager,
141
+ peer_set : Mutex :: new ( HashSet :: new ( ) ) ,
137
142
pending_messages : Mutex :: new ( HashMap :: new ( ) ) ,
138
143
secp_ctx,
139
144
logger,
@@ -159,6 +164,9 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
159
164
( introduction_node_id, blinding_point) ,
160
165
}
161
166
} ;
167
+ if !self . peer_connected ( & introduction_node_id) {
168
+ return Err ( SendError :: InvalidFirstHop )
169
+ }
162
170
let ( packet_payloads, packet_keys) = packet_payloads_and_keys (
163
171
& self . secp_ctx , intermediate_nodes, destination, & blinding_secret)
164
172
. map_err ( |e| SendError :: Secp256k1 ( e) ) ?;
@@ -179,6 +187,11 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
179
187
Ok ( ( ) )
180
188
}
181
189
190
+ fn peer_connected ( & self , peer_node_id : & PublicKey ) -> bool {
191
+ let peers = self . peer_set . lock ( ) . unwrap ( ) ;
192
+ peers. contains ( peer_node_id)
193
+ }
194
+
182
195
#[ cfg( test) ]
183
196
pub ( super ) fn release_pending_msgs ( & self ) -> HashMap < PublicKey , Vec < MessageSendEvent > > {
184
197
let mut pending_msgs = self . pending_messages . lock ( ) . unwrap ( ) ;
@@ -229,6 +242,10 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Si
229
242
Ok ( ( Payload :: Forward ( ForwardControlTlvs :: Unblinded ( ForwardTlvs {
230
243
next_node_id, next_blinding_override
231
244
} ) ) , Some ( ( next_hop_hmac, new_packet_bytes) ) ) ) => {
245
+ if !self . peer_connected ( & next_node_id) {
246
+ log_trace ! ( self . logger, "Dropping onion message to disconnected peer {:?}" , next_node_id) ;
247
+ return
248
+ }
232
249
// TODO: we need to check whether `next_node_id` is our node, in which case this is a dummy
233
250
// blinded hop and this onion message is destined for us. In this situation, we should keep
234
251
// unwrapping the onion layers to get to the final payload. Since we don't have the option
@@ -282,6 +299,26 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Si
282
299
} ,
283
300
} ;
284
301
}
302
+
303
+ fn peer_connected ( & self , their_node_id : & PublicKey , _init : & msgs:: Init ) {
304
+ // TODO: check feature bits to see if onion message forwarding is supported
305
+ let mut peers = self . peer_set . lock ( ) . unwrap ( ) ;
306
+ peers. insert ( their_node_id. clone ( ) ) ;
307
+ }
308
+
309
+ fn peer_disconnected ( & self , their_node_id : & PublicKey , no_connection_possible : bool ) {
310
+ {
311
+ let mut peers = self . peer_set . lock ( ) . unwrap ( ) ;
312
+ peers. remove ( their_node_id) ;
313
+ }
314
+
315
+ let mut pending_msgs = self . pending_messages . lock ( ) . unwrap ( ) ;
316
+ if no_connection_possible {
317
+ pending_msgs. remove ( their_node_id) ;
318
+ } else if let Some ( msgs) = pending_msgs. get_mut ( their_node_id) {
319
+ msgs. clear ( ) ;
320
+ }
321
+ }
285
322
}
286
323
287
324
impl < Signer : Sign , K : Deref , L : Deref > OnionMessageProvider for OnionMessenger < Signer , K , L >
0 commit comments