@@ -721,6 +721,9 @@ pub(super) struct PeerState<SP: Deref> where SP::Target: SignerProvider {
721
721
/// removed, and an InboundV1Channel is created and placed in the `inbound_v1_channel_by_id` table. If
722
722
/// the channel is rejected, then the entry is simply removed.
723
723
pub(super) inbound_channel_request_by_id: HashMap<ChannelId, InboundChannelRequest>,
724
+ ///
725
+ /// Outbound channel unsent by us.
726
+ pub(super) outbound_channel_unsent_by_id: HashMap<ChannelId, OutboundChannelRequest>,
724
727
/// The latest `InitFeatures` we heard from the peer.
725
728
latest_features: InitFeatures,
726
729
/// Messages to send to the peer - pushed to in the same lock that they are generated in (except
@@ -797,6 +800,18 @@ pub(super) struct InboundChannelRequest {
797
800
/// accepted. An unaccepted channel that exceeds this limit will be abandoned.
798
801
const UNACCEPTED_INBOUND_CHANNEL_AGE_LIMIT_TICKS: i32 = 2;
799
802
803
+ /// A not-yet-accpted outbound channel.
804
+ pub(super) struct OutboundChannelRequest {
805
+ /// The original OpenChannel message.
806
+ pub open_channel_msg: MessageSendEvent,
807
+ /// The number of ticks remaining before the request expires
808
+ pub ticks_remaining: i32,
809
+ }
810
+
811
+ /// The number of ticks that may elapse while waiting for an outbound channel request to be sent.
812
+ /// An unsent channel that exceeds this limit will be abondoned.
813
+ const UNSENT_OUTBOUND_CHANNEL_AGE_LIMIT_TICKS: i32 = 2;
814
+
800
815
/// Stores a PaymentSecret and any other data we may need to validate an inbound payment is
801
816
/// actually ours and not some duplicate HTLC sent to us by a node along the route.
802
817
///
@@ -2400,6 +2415,7 @@ where
2400
2415
/// [`Event::FundingGenerationReady::user_channel_id`]: events::Event::FundingGenerationReady::user_channel_id
2401
2416
/// [`Event::FundingGenerationReady::temporary_channel_id`]: events::Event::FundingGenerationReady::temporary_channel_id
2402
2417
/// [`Event::ChannelClosed::channel_id`]: events::Event::ChannelClosed::channel_id
2418
+
2403
2419
pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_channel_id: u128, override_config: Option<UserConfig>) -> Result<ChannelId, APIError> {
2404
2420
if channel_value_satoshis < 1000 {
2405
2421
return Err(APIError::APIMisuseError { err: format!("Channel value must be at least 1000 satoshis. It was {}", channel_value_satoshis) });
@@ -2444,10 +2460,22 @@ where
2444
2460
hash_map::Entry::Vacant(entry) => { entry.insert(ChannelPhase::UnfundedOutboundV1(channel)); }
2445
2461
}
2446
2462
2447
- peer_state.pending_msg_events.push( events::MessageSendEvent::SendOpenChannel {
2463
+ let msg_event = events::MessageSendEvent::SendOpenChannel {
2448
2464
node_id: their_network_key,
2449
2465
msg: res,
2450
- });
2466
+ };
2467
+
2468
+ if peer_state.is_connected {
2469
+ peer_state.pending_msg_events.push(msg_event);
2470
+ }
2471
+
2472
+ else {
2473
+ peer_state.outbound_channel_unsent_by_id.insert(temporary_channel_id, OutboundChannelRequest {
2474
+ open_channel_msg: msg_event,
2475
+ ticks_remaining: UNSENT_OUTBOUND_CHANNEL_AGE_LIMIT_TICKS,
2476
+ });
2477
+ }
2478
+
2451
2479
Ok(temporary_channel_id)
2452
2480
}
2453
2481
@@ -5009,6 +5037,21 @@ where
5009
5037
}
5010
5038
peer_state.inbound_channel_request_by_id.retain(|_, req| req.ticks_remaining > 0);
5011
5039
5040
+
5041
+ // Check if the channel was sent in timely manner and if not closing the channel between peer and counterparty
5042
+ for (chan_id, req) in peer_state.outbound_channel_unsent_by_id.iter_mut() {
5043
+ if { req.ticks_remaining -= 1 ; req.ticks_remaining } <= 0 {
5044
+
5045
+ let node_id_ = match req.open_channel_msg {
5046
+ MessageSendEvent::SendOpenChannel{ node_id, msg: _} => Some(node_id),
5047
+ _ => None,
5048
+ };
5049
+
5050
+ let _ = self.force_close_sending_error(&chan_id, &node_id_.unwrap(), true);
5051
+ }
5052
+ }
5053
+ peer_state.outbound_channel_unsent_by_id.retain(|_, req| req.ticks_remaining > 0);
5054
+
5012
5055
if peer_state.ok_to_remove(true) {
5013
5056
pending_peers_awaiting_removal.push(counterparty_node_id);
5014
5057
}
@@ -8689,6 +8732,7 @@ where
8689
8732
e.insert(Mutex::new(PeerState {
8690
8733
channel_by_id: HashMap::new(),
8691
8734
inbound_channel_request_by_id: HashMap::new(),
8735
+ outbound_channel_unsent_by_id: HashMap::new(),
8692
8736
latest_features: init_msg.features.clone(),
8693
8737
pending_msg_events: Vec::new(),
8694
8738
in_flight_monitor_updates: BTreeMap::new(),
@@ -8724,11 +8768,24 @@ where
8724
8768
let peer_state = &mut *peer_state_lock;
8725
8769
let pending_msg_events = &mut peer_state.pending_msg_events;
8726
8770
8771
+ // For the pending OpenChannelMessage that were not sent due to peer disconnecting at time of channel creation
8772
+ for (_, chan_request) in peer_state.outbound_channel_unsent_by_id.iter_mut() {
8773
+ pending_msg_events.push(chan_request.open_channel_msg.clone());
8774
+ }
8775
+
8727
8776
peer_state.channel_by_id.iter_mut().filter_map(|(_, phase)|
8728
8777
if let ChannelPhase::Funded(chan) = phase { Some(chan) } else {
8729
8778
// Since unfunded channel maps are cleared upon disconnecting a peer, and they're not persisted
8730
8779
// (so won't be recovered after a crash), they shouldn't exist here and we would never need to
8731
8780
// worry about closing and removing them.
8781
+
8782
+ // TODO: Make this optional exception work
8783
+ // // An exception are the channel created just when peer was disconnected, so the process of
8784
+ // // channel creation was held mid way.
8785
+ // if !&peer_state.outbound_channel_unsent_by_id.contains_key(chan_id) {
8786
+ // debug_assert!(false);
8787
+ // }
8788
+
8732
8789
debug_assert!(false);
8733
8790
None
8734
8791
}
@@ -8738,6 +8795,9 @@ where
8738
8795
msg: chan.get_channel_reestablish(&self.logger),
8739
8796
});
8740
8797
});
8798
+
8799
+ // And now the request are sent to pending_msg_events, we can clear the vector
8800
+ peer_state.outbound_channel_unsent_by_id.clear();
8741
8801
}
8742
8802
8743
8803
return NotifyOption::SkipPersistHandleEvents;
@@ -10085,6 +10145,7 @@ where
10085
10145
PeerState {
10086
10146
channel_by_id,
10087
10147
inbound_channel_request_by_id: HashMap::new(),
10148
+ outbound_channel_unsent_by_id: HashMap::new(),
10088
10149
latest_features: InitFeatures::empty(),
10089
10150
pending_msg_events: Vec::new(),
10090
10151
in_flight_monitor_updates: BTreeMap::new(),
0 commit comments