Skip to content

Commit 93a8429

Browse files
committed
Respond to channel_reestablish out-of-band for ordered delivery
1 parent 5cf1bbb commit 93a8429

File tree

5 files changed

+147
-92
lines changed

5 files changed

+147
-92
lines changed

src/ln/channel.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ use crypto::digest::Digest;
1414
use crypto::hkdf::{hkdf_extract,hkdf_expand};
1515

1616
use ln::msgs;
17-
use ln::msgs::{ErrorAction, HandleError, RAACommitmentOrder};
17+
use ln::msgs::{ErrorAction, HandleError};
1818
use ln::channelmonitor::ChannelMonitor;
19-
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, PendingForwardHTLCInfo, HTLCFailReason, HTLCFailureMsg};
19+
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingForwardHTLCInfo, RAACommitmentOrder};
2020
use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
2121
use ln::chan_utils;
2222
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};

src/ln/channelmanager.rs

Lines changed: 142 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use ln::channel::{Channel, ChannelError, ChannelKeys};
2626
use ln::channelmonitor::{ChannelMonitorUpdateErr, ManyChannelMonitor, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS};
2727
use ln::router::{Route,RouteHop};
2828
use ln::msgs;
29-
use ln::msgs::{ChannelMessageHandler, HandleError, RAACommitmentOrder};
29+
use ln::msgs::{ChannelMessageHandler, HandleError};
3030
use util::{byte_utils, events, internal_traits, rng};
3131
use util::sha2::Sha256;
3232
use util::ser::{Readable, Writeable};
@@ -233,6 +233,18 @@ struct HTLCForwardInfo {
233233
forward_info: PendingForwardHTLCInfo,
234234
}
235235

236+
/// For events which result in both a RevokeAndACK and a CommitmentUpdate, by default they should
237+
/// be sent in the order they appear in the return value, however sometimes the order needs to be
238+
/// variable at runtime (eg Channel::channel_reestablish needs to re-send messages in the order
239+
/// they were originally sent). In those cases, this enum is also returned.
240+
#[derive(Clone, PartialEq)]
241+
pub(super) enum RAACommitmentOrder {
242+
/// Send the CommitmentUpdate messages first
243+
CommitmentFirst,
244+
/// Send the RevokeAndACK message first
245+
RevokeAndACKFirst,
246+
}
247+
236248
struct ChannelHolder {
237249
by_id: HashMap<[u8; 32], Channel>,
238250
short_to_id: HashMap<u64, [u8; 32]>,
@@ -2314,28 +2326,58 @@ impl ChannelManager {
23142326
Ok(())
23152327
}
23162328

2317-
fn internal_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, RAACommitmentOrder), MsgHandleErrInternal> {
2318-
let res = {
2319-
let mut channel_state = self.channel_state.lock().unwrap();
2320-
match channel_state.by_id.get_mut(&msg.channel_id) {
2321-
Some(chan) => {
2322-
if chan.get_their_node_id() != *their_node_id {
2323-
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
2329+
fn internal_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), MsgHandleErrInternal> {
2330+
let mut channel_state_lock = self.channel_state.lock().unwrap();
2331+
let channel_state = channel_state_lock.borrow_parts();
2332+
2333+
match channel_state.by_id.get_mut(&msg.channel_id) {
2334+
Some(chan) => {
2335+
if chan.get_their_node_id() != *their_node_id {
2336+
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
2337+
}
2338+
let (funding_locked, revoke_and_ack, commitment_update, channel_monitor, order) = chan.channel_reestablish(msg)
2339+
.map_err(|e| MsgHandleErrInternal::from_chan_maybe_close(e, msg.channel_id))?;
2340+
if let Some(monitor) = channel_monitor {
2341+
if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
2342+
unimplemented!();
23242343
}
2325-
let (funding_locked, revoke_and_ack, commitment_update, channel_monitor, order) = chan.channel_reestablish(msg)
2326-
.map_err(|e| MsgHandleErrInternal::from_chan_maybe_close(e, msg.channel_id))?;
2327-
if let Some(monitor) = channel_monitor {
2328-
if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
2329-
unimplemented!();
2330-
}
2344+
}
2345+
if let Some(msg) = funding_locked {
2346+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingLocked {
2347+
node_id: their_node_id.clone(),
2348+
msg
2349+
});
2350+
}
2351+
macro_rules! send_raa { () => {
2352+
if let Some(msg) = revoke_and_ack {
2353+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK {
2354+
node_id: their_node_id.clone(),
2355+
msg
2356+
});
23312357
}
2332-
Ok((funding_locked, revoke_and_ack, commitment_update, order))
2333-
},
2334-
None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id))
2335-
}
2336-
};
2337-
2338-
res
2358+
} }
2359+
macro_rules! send_cu { () => {
2360+
if let Some(updates) = commitment_update {
2361+
channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
2362+
node_id: their_node_id.clone(),
2363+
updates
2364+
});
2365+
}
2366+
} }
2367+
match order {
2368+
RAACommitmentOrder::RevokeAndACKFirst => {
2369+
send_raa!();
2370+
send_cu!();
2371+
},
2372+
RAACommitmentOrder::CommitmentFirst => {
2373+
send_cu!();
2374+
send_raa!();
2375+
},
2376+
}
2377+
Ok(())
2378+
},
2379+
None => Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id))
2380+
}
23392381
}
23402382

23412383
/// Begin Update fee process. Allowed only on an outbound channel.
@@ -2602,7 +2644,7 @@ impl ChannelMessageHandler for ChannelManager {
26022644
handle_error!(self, self.internal_announcement_signatures(their_node_id, msg), their_node_id)
26032645
}
26042646

2605-
fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, RAACommitmentOrder), HandleError> {
2647+
fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), HandleError> {
26062648
handle_error!(self, self.internal_channel_reestablish(their_node_id, msg), their_node_id)
26072649
}
26082650

@@ -2700,7 +2742,7 @@ mod tests {
27002742
use chain::chaininterface;
27012743
use chain::transaction::OutPoint;
27022744
use chain::chaininterface::ChainListener;
2703-
use ln::channelmanager::{ChannelManager,OnionKeys};
2745+
use ln::channelmanager::{ChannelManager,OnionKeys,RAACommitmentOrder};
27042746
use ln::channelmonitor::{ChannelMonitorUpdateErr, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS};
27052747
use ln::router::{Route, RouteHop, Router};
27062748
use ln::msgs;
@@ -5182,6 +5224,61 @@ mod tests {
51825224
assert_eq!(channel_state.short_to_id.len(), 0);
51835225
}
51845226

5227+
macro_rules! handle_chan_reestablish_msgs {
5228+
($src_node: expr, $dst_node: expr) => {
5229+
{
5230+
let msg_events = $src_node.node.get_and_clear_pending_msg_events();
5231+
let mut idx = 0;
5232+
let funding_locked = if let Some(&MessageSendEvent::SendFundingLocked { ref node_id, ref msg }) = msg_events.get(0) {
5233+
idx += 1;
5234+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
5235+
Some(msg.clone())
5236+
} else {
5237+
None
5238+
};
5239+
5240+
let mut revoke_and_ack = None;
5241+
let mut commitment_update = None;
5242+
let order = if let Some(ev) = msg_events.get(idx) {
5243+
idx += 1;
5244+
match ev {
5245+
&MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
5246+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
5247+
revoke_and_ack = Some(msg.clone());
5248+
RAACommitmentOrder::RevokeAndACKFirst
5249+
},
5250+
&MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
5251+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
5252+
commitment_update = Some(updates.clone());
5253+
RAACommitmentOrder::CommitmentFirst
5254+
},
5255+
_ => panic!("Unexpected event"),
5256+
}
5257+
} else {
5258+
RAACommitmentOrder::CommitmentFirst
5259+
};
5260+
5261+
if let Some(ev) = msg_events.get(idx) {
5262+
match ev {
5263+
&MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
5264+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
5265+
assert!(revoke_and_ack.is_none());
5266+
revoke_and_ack = Some(msg.clone());
5267+
},
5268+
&MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
5269+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
5270+
assert!(commitment_update.is_none());
5271+
commitment_update = Some(updates.clone());
5272+
},
5273+
_ => panic!("Unexpected event"),
5274+
}
5275+
}
5276+
5277+
(funding_locked, revoke_and_ack, commitment_update, order)
5278+
}
5279+
}
5280+
}
5281+
51855282
/// pending_htlc_adds includes both the holding cell and in-flight update_add_htlcs, whereas
51865283
/// for claims/fails they are separated out.
51875284
fn reconnect_nodes(node_a: &Node, node_b: &Node, pre_all_htlcs: bool, pending_htlc_adds: (i64, i64), pending_htlc_claims: (usize, usize), pending_cell_htlc_claims: (usize, usize), pending_cell_htlc_fails: (usize, usize), pending_raa: (bool, bool)) {
@@ -5190,7 +5287,8 @@ mod tests {
51905287

51915288
let mut resp_1 = Vec::new();
51925289
for msg in reestablish_1 {
5193-
resp_1.push(node_b.node.handle_channel_reestablish(&node_a.node.get_our_node_id(), &msg).unwrap());
5290+
node_b.node.handle_channel_reestablish(&node_a.node.get_our_node_id(), &msg).unwrap();
5291+
resp_1.push(handle_chan_reestablish_msgs!(node_b, node_a));
51945292
}
51955293
if pending_cell_htlc_claims.0 != 0 || pending_cell_htlc_fails.0 != 0 {
51965294
check_added_monitors!(node_b, 1);
@@ -5200,7 +5298,8 @@ mod tests {
52005298

52015299
let mut resp_2 = Vec::new();
52025300
for msg in reestablish_2 {
5203-
resp_2.push(node_a.node.handle_channel_reestablish(&node_b.node.get_our_node_id(), &msg).unwrap());
5301+
node_a.node.handle_channel_reestablish(&node_b.node.get_our_node_id(), &msg).unwrap();
5302+
resp_2.push(handle_chan_reestablish_msgs!(node_a, node_b));
52045303
}
52055304
if pending_cell_htlc_claims.1 != 0 || pending_cell_htlc_fails.1 != 0 {
52065305
check_added_monitors!(node_a, 1);
@@ -5226,7 +5325,7 @@ mod tests {
52265325
assert!(chan_msgs.0.is_none());
52275326
}
52285327
if pending_raa.0 {
5229-
assert!(chan_msgs.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst);
5328+
assert!(chan_msgs.3 == RAACommitmentOrder::RevokeAndACKFirst);
52305329
node_a.node.handle_revoke_and_ack(&node_b.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap();
52315330
assert!(node_a.node.get_and_clear_pending_msg_events().is_empty());
52325331
check_added_monitors!(node_a, 1);
@@ -5283,7 +5382,7 @@ mod tests {
52835382
assert!(chan_msgs.0.is_none());
52845383
}
52855384
if pending_raa.1 {
5286-
assert!(chan_msgs.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst);
5385+
assert!(chan_msgs.3 == RAACommitmentOrder::RevokeAndACKFirst);
52875386
node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap();
52885387
assert!(node_b.node.get_and_clear_pending_msg_events().is_empty());
52895388
check_added_monitors!(node_b, 1);
@@ -5687,16 +5786,18 @@ mod tests {
56875786
let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id());
56885787
assert_eq!(reestablish_2.len(), 1);
56895788

5690-
let as_resp = nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
5691-
let bs_resp = nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
5789+
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
5790+
let as_resp = handle_chan_reestablish_msgs!(nodes[0], nodes[1]);
5791+
nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
5792+
let bs_resp = handle_chan_reestablish_msgs!(nodes[1], nodes[0]);
56925793

56935794
assert!(as_resp.0.is_none());
56945795
assert!(bs_resp.0.is_none());
56955796

56965797
assert!(bs_resp.1.is_none());
56975798
assert!(bs_resp.2.is_none());
56985799

5699-
assert!(as_resp.3 == msgs::RAACommitmentOrder::CommitmentFirst);
5800+
assert!(as_resp.3 == RAACommitmentOrder::CommitmentFirst);
57005801

57015802
assert_eq!(as_resp.2.as_ref().unwrap().update_add_htlcs.len(), 1);
57025803
assert!(as_resp.2.as_ref().unwrap().update_fulfill_htlcs.is_empty());
@@ -5973,8 +6074,10 @@ mod tests {
59736074
let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id());
59746075
assert_eq!(reestablish_2.len(), 1);
59756076

5976-
let as_resp = nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
5977-
let bs_resp = nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
6077+
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
6078+
let as_resp = handle_chan_reestablish_msgs!(nodes[0], nodes[1]);
6079+
nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
6080+
let bs_resp = handle_chan_reestablish_msgs!(nodes[1], nodes[0]);
59786081

59796082
assert!(as_resp.0.is_none());
59806083
assert!(bs_resp.0.is_none());
@@ -5991,10 +6094,12 @@ mod tests {
59916094
let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id());
59926095
assert_eq!(reestablish_2.len(), 1);
59936096

5994-
let mut as_resp = nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
6097+
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
59956098
check_added_monitors!(nodes[0], 0);
5996-
let mut bs_resp = nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
6099+
let mut as_resp = handle_chan_reestablish_msgs!(nodes[0], nodes[1]);
6100+
nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
59976101
check_added_monitors!(nodes[1], 0);
6102+
let mut bs_resp = handle_chan_reestablish_msgs!(nodes[1], nodes[0]);
59986103

59996104
assert!(as_resp.0.is_none());
60006105
assert!(bs_resp.0.is_none());
@@ -6005,7 +6110,7 @@ mod tests {
60056110

60066111
assert!(as_resp.1.is_some());
60076112
assert!(as_resp.2.is_some());
6008-
assert!(as_resp.3 == msgs::RAACommitmentOrder::CommitmentFirst);
6113+
assert!(as_resp.3 == RAACommitmentOrder::CommitmentFirst);
60096114
} else {
60106115
assert!(bs_resp.2.as_ref().unwrap().update_add_htlcs.is_empty());
60116116
assert!(bs_resp.2.as_ref().unwrap().update_fail_htlcs.is_empty());
@@ -6114,7 +6219,7 @@ mod tests {
61146219
assert!(as_resp.2.unwrap() == as_commitment_update);
61156220
assert!(bs_resp.2.is_none());
61166221

6117-
assert!(as_resp.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst);
6222+
assert!(as_resp.3 == RAACommitmentOrder::RevokeAndACKFirst);
61186223
}
61196224

61206225
handle_initial_raa!();
@@ -6140,7 +6245,7 @@ mod tests {
61406245
assert!(as_resp.2.is_none());
61416246
assert!(bs_resp.2.unwrap() == bs_second_commitment_update);
61426247

6143-
assert!(bs_resp.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst);
6248+
assert!(bs_resp.3 == RAACommitmentOrder::RevokeAndACKFirst);
61446249
}
61456250

61466251
handle_bs_raa!();

src/ln/msgs.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -511,18 +511,6 @@ pub enum HTLCFailChannelUpdate {
511511
}
512512
}
513513

514-
/// For events which result in both a RevokeAndACK and a CommitmentUpdate, by default they should
515-
/// be sent in the order they appear in the return value, however sometimes the order needs to be
516-
/// variable at runtime (eg handle_channel_reestablish needs to re-send messages in the order they
517-
/// were originally sent). In those cases, this enum is also returned.
518-
#[derive(Clone, PartialEq)]
519-
pub enum RAACommitmentOrder {
520-
/// Send the CommitmentUpdate messages first
521-
CommitmentFirst,
522-
/// Send the RevokeAndACK message first
523-
RevokeAndACKFirst,
524-
}
525-
526514
/// A trait to describe an object which can receive channel messages.
527515
///
528516
/// Messages MAY be called in parallel when they originate from different their_node_ids, however
@@ -577,7 +565,7 @@ pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Syn
577565
/// Handle a peer reconnecting, possibly generating channel_reestablish message(s).
578566
fn peer_connected(&self, their_node_id: &PublicKey) -> Vec<ChannelReestablish>;
579567
/// Handle an incoming channel_reestablish message from the given peer.
580-
fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &ChannelReestablish) -> Result<(Option<FundingLocked>, Option<RevokeAndACK>, Option<CommitmentUpdate>, RAACommitmentOrder), HandleError>;
568+
fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &ChannelReestablish) -> Result<(), HandleError>;
581569

582570
// Error:
583571
/// Handle an incoming error message from the given peer.

src/ln/peer_handler.rs

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -619,45 +619,7 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
619619
},
620620
136 => {
621621
let msg = try_potential_decodeerror!(msgs::ChannelReestablish::read(&mut reader));
622-
let (funding_locked, revoke_and_ack, commitment_update, order) = try_potential_handleerror!(self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg));
623-
if let Some(lock_msg) = funding_locked {
624-
encode_and_send_msg!(lock_msg, 36);
625-
}
626-
macro_rules! handle_raa { () => {
627-
if let Some(revoke_msg) = revoke_and_ack {
628-
encode_and_send_msg!(revoke_msg, 133);
629-
}
630-
} }
631-
macro_rules! handle_cu { () => {
632-
match commitment_update {
633-
Some(resps) => {
634-
for resp in resps.update_add_htlcs {
635-
encode_and_send_msg!(resp, 128);
636-
}
637-
for resp in resps.update_fulfill_htlcs {
638-
encode_and_send_msg!(resp, 130);
639-
}
640-
for resp in resps.update_fail_htlcs {
641-
encode_and_send_msg!(resp, 131);
642-
}
643-
if let Some(resp) = resps.update_fee {
644-
encode_and_send_msg!(resp, 134);
645-
}
646-
encode_and_send_msg!(resps.commitment_signed, 132);
647-
},
648-
None => {},
649-
}
650-
} }
651-
match order {
652-
msgs::RAACommitmentOrder::RevokeAndACKFirst => {
653-
handle_raa!();
654-
handle_cu!();
655-
},
656-
msgs::RAACommitmentOrder::CommitmentFirst => {
657-
handle_cu!();
658-
handle_raa!();
659-
},
660-
}
622+
try_potential_handleerror!(self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg));
661623
},
662624

663625
// Routing control:

src/util/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
131131
fn handle_announcement_signatures(&self, _their_node_id: &PublicKey, _msg: &msgs::AnnouncementSignatures) -> Result<(), HandleError> {
132132
Err(HandleError { err: "", action: None })
133133
}
134-
fn handle_channel_reestablish(&self, _their_node_id: &PublicKey, _msg: &msgs::ChannelReestablish) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, msgs::RAACommitmentOrder), HandleError> {
134+
fn handle_channel_reestablish(&self, _their_node_id: &PublicKey, _msg: &msgs::ChannelReestablish) -> Result<(), HandleError> {
135135
Err(HandleError { err: "", action: None })
136136
}
137137
fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {}

0 commit comments

Comments
 (0)