Skip to content

Commit e2de49d

Browse files
committed
Respond to channel_reestablish out-of-band for ordered delivery
1 parent 4342114 commit e2de49d

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
@@ -13,9 +13,9 @@ use secp256k1;
1313
use crypto::digest::Digest;
1414

1515
use ln::msgs;
16-
use ln::msgs::{ErrorAction, HandleError, RAACommitmentOrder};
16+
use ln::msgs::{ErrorAction, HandleError};
1717
use ln::channelmonitor::ChannelMonitor;
18-
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, PendingForwardHTLCInfo, HTLCFailReason, HTLCFailureMsg};
18+
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingForwardHTLCInfo, RAACommitmentOrder};
1919
use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
2020
use ln::chan_utils;
2121
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};
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 chain::keysinterface::KeysInterface;
3131
use util::{byte_utils, events, internal_traits, rng};
3232
use util::sha2::Sha256;
@@ -244,6 +244,18 @@ struct HTLCForwardInfo {
244244
forward_info: PendingForwardHTLCInfo,
245245
}
246246

247+
/// For events which result in both a RevokeAndACK and a CommitmentUpdate, by default they should
248+
/// be sent in the order they appear in the return value, however sometimes the order needs to be
249+
/// variable at runtime (eg Channel::channel_reestablish needs to re-send messages in the order
250+
/// they were originally sent). In those cases, this enum is also returned.
251+
#[derive(Clone, PartialEq)]
252+
pub(super) enum RAACommitmentOrder {
253+
/// Send the CommitmentUpdate messages first
254+
CommitmentFirst,
255+
/// Send the RevokeAndACK message first
256+
RevokeAndACKFirst,
257+
}
258+
247259
struct ChannelHolder {
248260
by_id: HashMap<[u8; 32], Channel>,
249261
short_to_id: HashMap<u64, [u8; 32]>,
@@ -2287,28 +2299,58 @@ impl ChannelManager {
22872299
Ok(())
22882300
}
22892301

2290-
fn internal_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, RAACommitmentOrder), MsgHandleErrInternal> {
2291-
let res = {
2292-
let mut channel_state = self.channel_state.lock().unwrap();
2293-
match channel_state.by_id.get_mut(&msg.channel_id) {
2294-
Some(chan) => {
2295-
if chan.get_their_node_id() != *their_node_id {
2296-
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
2302+
fn internal_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), MsgHandleErrInternal> {
2303+
let mut channel_state_lock = self.channel_state.lock().unwrap();
2304+
let channel_state = channel_state_lock.borrow_parts();
2305+
2306+
match channel_state.by_id.get_mut(&msg.channel_id) {
2307+
Some(chan) => {
2308+
if chan.get_their_node_id() != *their_node_id {
2309+
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
2310+
}
2311+
let (funding_locked, revoke_and_ack, commitment_update, channel_monitor, order) = chan.channel_reestablish(msg)
2312+
.map_err(|e| MsgHandleErrInternal::from_chan_maybe_close(e, msg.channel_id))?;
2313+
if let Some(monitor) = channel_monitor {
2314+
if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
2315+
unimplemented!();
22972316
}
2298-
let (funding_locked, revoke_and_ack, commitment_update, channel_monitor, order) = chan.channel_reestablish(msg)
2299-
.map_err(|e| MsgHandleErrInternal::from_chan_maybe_close(e, msg.channel_id))?;
2300-
if let Some(monitor) = channel_monitor {
2301-
if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
2302-
unimplemented!();
2303-
}
2317+
}
2318+
if let Some(msg) = funding_locked {
2319+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingLocked {
2320+
node_id: their_node_id.clone(),
2321+
msg
2322+
});
2323+
}
2324+
macro_rules! send_raa { () => {
2325+
if let Some(msg) = revoke_and_ack {
2326+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK {
2327+
node_id: their_node_id.clone(),
2328+
msg
2329+
});
23042330
}
2305-
Ok((funding_locked, revoke_and_ack, commitment_update, order))
2306-
},
2307-
None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id))
2308-
}
2309-
};
2310-
2311-
res
2331+
} }
2332+
macro_rules! send_cu { () => {
2333+
if let Some(updates) = commitment_update {
2334+
channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
2335+
node_id: their_node_id.clone(),
2336+
updates
2337+
});
2338+
}
2339+
} }
2340+
match order {
2341+
RAACommitmentOrder::RevokeAndACKFirst => {
2342+
send_raa!();
2343+
send_cu!();
2344+
},
2345+
RAACommitmentOrder::CommitmentFirst => {
2346+
send_cu!();
2347+
send_raa!();
2348+
},
2349+
}
2350+
Ok(())
2351+
},
2352+
None => Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id))
2353+
}
23122354
}
23132355

23142356
/// Begin Update fee process. Allowed only on an outbound channel.
@@ -2575,7 +2617,7 @@ impl ChannelMessageHandler for ChannelManager {
25752617
handle_error!(self, self.internal_announcement_signatures(their_node_id, msg), their_node_id)
25762618
}
25772619

2578-
fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, RAACommitmentOrder), HandleError> {
2620+
fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), HandleError> {
25792621
handle_error!(self, self.internal_channel_reestablish(their_node_id, msg), their_node_id)
25802622
}
25812623

@@ -2675,7 +2717,7 @@ mod tests {
26752717
use chain::chaininterface::ChainListener;
26762718
use chain::keysinterface::KeysInterface;
26772719
use chain::keysinterface;
2678-
use ln::channelmanager::{ChannelManager,OnionKeys,PaymentFailReason};
2720+
use ln::channelmanager::{ChannelManager,OnionKeys,PaymentFailReason,RAACommitmentOrder};
26792721
use ln::channelmonitor::{ChannelMonitorUpdateErr, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS};
26802722
use ln::router::{Route, RouteHop, Router};
26812723
use ln::msgs;
@@ -5155,6 +5197,61 @@ mod tests {
51555197
assert_eq!(channel_state.short_to_id.len(), 0);
51565198
}
51575199

5200+
macro_rules! handle_chan_reestablish_msgs {
5201+
($src_node: expr, $dst_node: expr) => {
5202+
{
5203+
let msg_events = $src_node.node.get_and_clear_pending_msg_events();
5204+
let mut idx = 0;
5205+
let funding_locked = if let Some(&MessageSendEvent::SendFundingLocked { ref node_id, ref msg }) = msg_events.get(0) {
5206+
idx += 1;
5207+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
5208+
Some(msg.clone())
5209+
} else {
5210+
None
5211+
};
5212+
5213+
let mut revoke_and_ack = None;
5214+
let mut commitment_update = None;
5215+
let order = if let Some(ev) = msg_events.get(idx) {
5216+
idx += 1;
5217+
match ev {
5218+
&MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
5219+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
5220+
revoke_and_ack = Some(msg.clone());
5221+
RAACommitmentOrder::RevokeAndACKFirst
5222+
},
5223+
&MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
5224+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
5225+
commitment_update = Some(updates.clone());
5226+
RAACommitmentOrder::CommitmentFirst
5227+
},
5228+
_ => panic!("Unexpected event"),
5229+
}
5230+
} else {
5231+
RAACommitmentOrder::CommitmentFirst
5232+
};
5233+
5234+
if let Some(ev) = msg_events.get(idx) {
5235+
match ev {
5236+
&MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
5237+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
5238+
assert!(revoke_and_ack.is_none());
5239+
revoke_and_ack = Some(msg.clone());
5240+
},
5241+
&MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
5242+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
5243+
assert!(commitment_update.is_none());
5244+
commitment_update = Some(updates.clone());
5245+
},
5246+
_ => panic!("Unexpected event"),
5247+
}
5248+
}
5249+
5250+
(funding_locked, revoke_and_ack, commitment_update, order)
5251+
}
5252+
}
5253+
}
5254+
51585255
/// pending_htlc_adds includes both the holding cell and in-flight update_add_htlcs, whereas
51595256
/// for claims/fails they are separated out.
51605257
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)) {
@@ -5163,7 +5260,8 @@ mod tests {
51635260

51645261
let mut resp_1 = Vec::new();
51655262
for msg in reestablish_1 {
5166-
resp_1.push(node_b.node.handle_channel_reestablish(&node_a.node.get_our_node_id(), &msg).unwrap());
5263+
node_b.node.handle_channel_reestablish(&node_a.node.get_our_node_id(), &msg).unwrap();
5264+
resp_1.push(handle_chan_reestablish_msgs!(node_b, node_a));
51675265
}
51685266
if pending_cell_htlc_claims.0 != 0 || pending_cell_htlc_fails.0 != 0 {
51695267
check_added_monitors!(node_b, 1);
@@ -5173,7 +5271,8 @@ mod tests {
51735271

51745272
let mut resp_2 = Vec::new();
51755273
for msg in reestablish_2 {
5176-
resp_2.push(node_a.node.handle_channel_reestablish(&node_b.node.get_our_node_id(), &msg).unwrap());
5274+
node_a.node.handle_channel_reestablish(&node_b.node.get_our_node_id(), &msg).unwrap();
5275+
resp_2.push(handle_chan_reestablish_msgs!(node_a, node_b));
51775276
}
51785277
if pending_cell_htlc_claims.1 != 0 || pending_cell_htlc_fails.1 != 0 {
51795278
check_added_monitors!(node_a, 1);
@@ -5199,7 +5298,7 @@ mod tests {
51995298
assert!(chan_msgs.0.is_none());
52005299
}
52015300
if pending_raa.0 {
5202-
assert!(chan_msgs.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst);
5301+
assert!(chan_msgs.3 == RAACommitmentOrder::RevokeAndACKFirst);
52035302
node_a.node.handle_revoke_and_ack(&node_b.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap();
52045303
assert!(node_a.node.get_and_clear_pending_msg_events().is_empty());
52055304
check_added_monitors!(node_a, 1);
@@ -5256,7 +5355,7 @@ mod tests {
52565355
assert!(chan_msgs.0.is_none());
52575356
}
52585357
if pending_raa.1 {
5259-
assert!(chan_msgs.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst);
5358+
assert!(chan_msgs.3 == RAACommitmentOrder::RevokeAndACKFirst);
52605359
node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap();
52615360
assert!(node_b.node.get_and_clear_pending_msg_events().is_empty());
52625361
check_added_monitors!(node_b, 1);
@@ -5660,16 +5759,18 @@ mod tests {
56605759
let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id());
56615760
assert_eq!(reestablish_2.len(), 1);
56625761

5663-
let as_resp = nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
5664-
let bs_resp = nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
5762+
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
5763+
let as_resp = handle_chan_reestablish_msgs!(nodes[0], nodes[1]);
5764+
nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
5765+
let bs_resp = handle_chan_reestablish_msgs!(nodes[1], nodes[0]);
56655766

56665767
assert!(as_resp.0.is_none());
56675768
assert!(bs_resp.0.is_none());
56685769

56695770
assert!(bs_resp.1.is_none());
56705771
assert!(bs_resp.2.is_none());
56715772

5672-
assert!(as_resp.3 == msgs::RAACommitmentOrder::CommitmentFirst);
5773+
assert!(as_resp.3 == RAACommitmentOrder::CommitmentFirst);
56735774

56745775
assert_eq!(as_resp.2.as_ref().unwrap().update_add_htlcs.len(), 1);
56755776
assert!(as_resp.2.as_ref().unwrap().update_fulfill_htlcs.is_empty());
@@ -5946,8 +6047,10 @@ mod tests {
59466047
let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id());
59476048
assert_eq!(reestablish_2.len(), 1);
59486049

5949-
let as_resp = nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
5950-
let bs_resp = nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
6050+
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
6051+
let as_resp = handle_chan_reestablish_msgs!(nodes[0], nodes[1]);
6052+
nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
6053+
let bs_resp = handle_chan_reestablish_msgs!(nodes[1], nodes[0]);
59516054

59526055
assert!(as_resp.0.is_none());
59536056
assert!(bs_resp.0.is_none());
@@ -5964,10 +6067,12 @@ mod tests {
59646067
let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id());
59656068
assert_eq!(reestablish_2.len(), 1);
59666069

5967-
let mut as_resp = nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
6070+
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
59686071
check_added_monitors!(nodes[0], 0);
5969-
let mut bs_resp = nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
6072+
let mut as_resp = handle_chan_reestablish_msgs!(nodes[0], nodes[1]);
6073+
nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
59706074
check_added_monitors!(nodes[1], 0);
6075+
let mut bs_resp = handle_chan_reestablish_msgs!(nodes[1], nodes[0]);
59716076

59726077
assert!(as_resp.0.is_none());
59736078
assert!(bs_resp.0.is_none());
@@ -5978,7 +6083,7 @@ mod tests {
59786083

59796084
assert!(as_resp.1.is_some());
59806085
assert!(as_resp.2.is_some());
5981-
assert!(as_resp.3 == msgs::RAACommitmentOrder::CommitmentFirst);
6086+
assert!(as_resp.3 == RAACommitmentOrder::CommitmentFirst);
59826087
} else {
59836088
assert!(bs_resp.2.as_ref().unwrap().update_add_htlcs.is_empty());
59846089
assert!(bs_resp.2.as_ref().unwrap().update_fail_htlcs.is_empty());
@@ -6087,7 +6192,7 @@ mod tests {
60876192
assert!(as_resp.2.unwrap() == as_commitment_update);
60886193
assert!(bs_resp.2.is_none());
60896194

6090-
assert!(as_resp.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst);
6195+
assert!(as_resp.3 == RAACommitmentOrder::RevokeAndACKFirst);
60916196
}
60926197

60936198
handle_initial_raa!();
@@ -6113,7 +6218,7 @@ mod tests {
61136218
assert!(as_resp.2.is_none());
61146219
assert!(bs_resp.2.unwrap() == bs_second_commitment_update);
61156220

6116-
assert!(bs_resp.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst);
6221+
assert!(bs_resp.3 == RAACommitmentOrder::RevokeAndACKFirst);
61176222
}
61186223

61196224
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)