Skip to content

Commit 91b964a

Browse files
committed
Basic error handling framework in peer_handler
1 parent 4fbc0b3 commit 91b964a

File tree

3 files changed

+101
-46
lines changed

3 files changed

+101
-46
lines changed

src/ln/channelmanager.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,37 @@ impl ChannelMessageHandler for ChannelManager {
14811481
pending_events.push(events::Event::BroadcastChannelAnnouncement { msg: chan_announcement, update_msg: chan_update });
14821482
Ok(())
14831483
}
1484+
1485+
fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool) {
1486+
let mut channel_state_lock = self.channel_state.lock().unwrap();
1487+
let channel_state = channel_state_lock.borrow_parts();
1488+
let short_to_id = channel_state.short_to_id;
1489+
if no_connection_possible {
1490+
channel_state.by_id.retain(move |_, chan| {
1491+
if chan.get_their_node_id() == *their_node_id {
1492+
match chan.get_short_channel_id() {
1493+
Some(short_id) => {
1494+
short_to_id.remove(&short_id);
1495+
},
1496+
None => {},
1497+
}
1498+
//TODO: get the latest commitment tx, any HTLC txn built on top of it, etc out
1499+
//of the channel and throw those into the announcement blackhole.
1500+
false
1501+
} else {
1502+
true
1503+
}
1504+
});
1505+
} else {
1506+
for chan in channel_state.by_id {
1507+
if chan.1.get_their_node_id() == *their_node_id {
1508+
//TODO: mark channel disabled (and maybe announce such after a timeout). Also
1509+
//fail and wipe any uncommitted outbound HTLCs as those are considered after
1510+
//reconnect.
1511+
}
1512+
}
1513+
}
1514+
}
14841515
}
14851516

14861517
#[cfg(test)]

src/ln/msgs.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,13 @@ pub trait ChannelMessageHandler : events::EventsProvider {
381381

382382
// Channel-to-announce:
383383
fn handle_announcement_signatures(&self, their_node_id: &PublicKey, msg: &AnnouncementSignatures) -> Result<(), HandleError>;
384+
385+
// Informational:
386+
/// Indicates a connection to the peer failed/an existing connection was lost. If no connection
387+
/// is believed to be possible in the future (eg they're sending us messages we don't
388+
/// understand or indicate they require unknown feature bits), no_connection_possible is set
389+
/// and any outstanding channels should be failed.
390+
fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool);
384391
}
385392

386393
pub trait RoutingMessageHandler {

src/ln/peer_handler.rs

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
223223
match self.do_read_event(peer_descriptor, data) {
224224
Ok(res) => Ok(res),
225225
Err(e) => {
226-
self.disconnect_event(peer_descriptor);
226+
self.disconnect_event_internal(peer_descriptor, e.no_connection_possible);
227227
Err(e)
228228
}
229229
}
@@ -238,38 +238,7 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
238238
assert!(peer.pending_read_buffer.len() > 0);
239239
assert!(peer.pending_read_buffer.len() > peer.pending_read_buffer_pos);
240240

241-
macro_rules! try_potential_handleerror {
242-
($thing: expr) => {
243-
match $thing {
244-
Ok(x) => x,
245-
Err(_e) => {
246-
//TODO: Handle e appropriately!
247-
return Err(PeerHandleError{});
248-
}
249-
};
250-
}
251-
}
252-
253-
macro_rules! try_potential_decodeerror {
254-
($thing: expr) => {
255-
match $thing {
256-
Ok(x) => x,
257-
Err(_e) => {
258-
//TODO: Handle e?
259-
return Err(PeerHandleError{});
260-
}
261-
};
262-
}
263-
}
264-
265-
macro_rules! encode_and_send_msg {
266-
($msg: expr, $msg_code: expr) => {
267-
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!($msg, $msg_code)[..]));
268-
}
269-
}
270-
271241
let mut insert_node_id = None;
272-
273242
let mut read_pos = 0;
274243
while read_pos < data.len() {
275244
{
@@ -278,7 +247,52 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
278247
read_pos += data_to_copy;
279248
peer.pending_read_buffer_pos += data_to_copy;
280249
}
250+
281251
if peer.pending_read_buffer_pos == peer.pending_read_buffer.len() {
252+
peer.pending_read_buffer_pos = 0;
253+
254+
macro_rules! encode_and_send_msg {
255+
($msg: expr, $msg_code: expr) => {
256+
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!($msg, $msg_code)[..]));
257+
}
258+
}
259+
260+
macro_rules! try_potential_handleerror {
261+
($thing: expr) => {
262+
match $thing {
263+
Ok(x) => x,
264+
Err(e) => {
265+
// TODO: Log e.err
266+
if let Some(action) = e.msg {
267+
match action {
268+
msgs::ErrorAction::UpdateFailHTLC { msg } => {
269+
encode_and_send_msg!(msg, 131);
270+
continue;
271+
},
272+
msgs::ErrorAction::DisconnectPeer {} => {
273+
return Err(PeerHandleError{ no_connection_possible: false });
274+
},
275+
}
276+
} else {
277+
return Err(PeerHandleError{ no_connection_possible: false });
278+
}
279+
}
280+
};
281+
}
282+
}
283+
284+
macro_rules! try_potential_decodeerror {
285+
($thing: expr) => {
286+
match $thing {
287+
Ok(x) => x,
288+
Err(_e) => {
289+
//TODO: Handle e?
290+
return Err(PeerHandleError{ no_connection_possible: false });
291+
}
292+
};
293+
}
294+
}
295+
282296
let next_step = peer.channel_encryptor.get_noise_step();
283297
match next_step {
284298
NextNoiseStep::ActOne => {
@@ -311,27 +325,31 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
311325
peer.pending_read_buffer = Vec::with_capacity(msg_len as usize + 16);
312326
peer.pending_read_buffer.resize(msg_len as usize + 16, 0);
313327
if msg_len < 2 { // Need at least the message type tag
314-
return Err(PeerHandleError{});
328+
return Err(PeerHandleError{ no_connection_possible: false });
315329
}
316330
peer.pending_read_is_header = false;
317331
} else {
318332
let msg_data = try_potential_handleerror!(peer.channel_encryptor.decrypt_message(&peer.pending_read_buffer[..]));
319333
assert!(msg_data.len() >= 2);
320334

335+
// Reset read buffer
336+
peer.pending_read_buffer = [0; 18].to_vec();
337+
peer.pending_read_is_header = true;
338+
321339
let msg_type = byte_utils::slice_to_be16(&msg_data[0..2]);
322340
if msg_type != 16 && peer.their_global_features.is_none() {
323341
// Need an init message as first message
324-
return Err(PeerHandleError{});
342+
return Err(PeerHandleError{ no_connection_possible: false });
325343
}
326344
match msg_type {
327345
// Connection control:
328346
16 => {
329347
let msg = try_potential_decodeerror!(msgs::Init::decode(&msg_data[2..]));
330348
if msg.global_features.requires_unknown_bits() {
331-
return Err(PeerHandleError{});
349+
return Err(PeerHandleError{ no_connection_possible: true });
332350
}
333351
if msg.local_features.requires_unknown_bits() {
334-
return Err(PeerHandleError{});
352+
return Err(PeerHandleError{ no_connection_possible: true });
335353
}
336354
peer.their_global_features = Some(msg.global_features);
337355
peer.their_local_features = Some(msg.local_features);
@@ -460,18 +478,13 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
460478
},
461479
_ => {
462480
if (msg_type & 1) == 0 {
463-
//TODO: Fail all channels. Kill the peer!
464-
return Err(PeerHandleError{});
481+
return Err(PeerHandleError{ no_connection_possible: true });
465482
}
466483
},
467484
}
468-
469-
peer.pending_read_buffer = [0; 18].to_vec();
470-
peer.pending_read_is_header = true;
471485
}
472486
}
473487
}
474-
peer.pending_read_buffer_pos = 0;
475488
}
476489
}
477490

@@ -623,18 +636,22 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
623636
/// but must NOT be called if a PeerHandleError was provided out of a new_*_connection event!
624637
/// Panics if the descriptor was not previously registered in a successful new_*_connection event.
625638
pub fn disconnect_event(&self, descriptor: &Descriptor) {
639+
self.disconnect_event_internal(descriptor, false);
640+
}
641+
642+
fn disconnect_event_internal(&self, descriptor: &Descriptor, no_connection_possible: bool) {
626643
let mut peers = self.peers.lock().unwrap();
627644
let peer_option = peers.peers.remove(descriptor);
628645
match peer_option {
629646
None => panic!("Descriptor for disconnect_event is not already known to PeerManager"),
630647
Some(peer) => {
631648
match peer.their_node_id {
632-
Some(node_id) => { peers.node_id_to_descriptor.remove(&node_id); },
649+
Some(node_id) => {
650+
peers.node_id_to_descriptor.remove(&node_id);
651+
self.message_handler.chan_handler.peer_disconnected(&node_id, no_connection_possible);
652+
},
633653
None => {}
634654
}
635-
//TODO: Notify the chan_handler that this node disconnected, and do something about
636-
//handling response messages that were queued for sending (maybe the send buffer
637-
//needs to be unencrypted?)
638655
}
639656
};
640657
}

0 commit comments

Comments
 (0)