Skip to content

Commit 305e68d

Browse files
committed
Wait to create a channel until after accepting.
Create a new table in 'peer_state' to maintain unaccepted inbound channels; i.e., a channel for which we've received an 'open_channel' message but that user code has not yet confirmed for acceptance. When user code accepts the channel (e.g. via 'accept_inbound_channel'), create the channel object and as before. Currently, the 'open_channel' message eagerly creates an InboundV1Channel object before determining if the channel should be accepted. Because this happens /before/ the channel has been assigned a user identity (which happens in the handler for OpenChannelRequest), the channel is assigned a random user identity. As part of the creation process, the channel's cryptographic material is initialized, which then uses this randomly generated value for the user's channel identity e.g. in SignerProvider::generate_channel_keys_id. By delaying the creation of the InboundV1Channel until /after/ the channel has been accepted, we ensure that we defer cryptographic initialization until we have given the user the opportunity to assign an identity to the channel.
1 parent 7e3de70 commit 305e68d

File tree

4 files changed

+131
-81
lines changed

4 files changed

+131
-81
lines changed

lightning/src/ln/channel.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6025,6 +6025,18 @@ pub(super) struct InboundV1Channel<Signer: ChannelSigner> {
60256025
pub unfunded_context: UnfundedChannelContext,
60266026
}
60276027

6028+
/// A not-yet-accepted inbound (from counterparty) channel. Once
6029+
/// accepted, the parameters will be used to construct a channel.
6030+
pub(super) struct InboundChannelRequest {
6031+
/// The counterparty node id that initiated the channel open.
6032+
pub counterparty_node_id: PublicKey,
6033+
/// The original OpenChannel message.
6034+
pub open_channel_msg: msgs::OpenChannel,
6035+
/// The outbound SCID alias assigned to the channel when we received
6036+
/// the OpenChannel request.
6037+
pub outbound_scid_alias: u64,
6038+
}
6039+
60286040
impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
60296041
/// Creates a new channel from a remote sides' request for one.
60306042
/// Assumes chain_hash has already been checked and corresponds with what we expect!

lightning/src/ln/channelmanager.rs

Lines changed: 107 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use crate::events::{Event, EventHandler, EventsProvider, MessageSendEvent, Messa
4040
// Since this struct is returned in `list_channels` methods, expose it here in case users want to
4141
// construct one themselves.
4242
use crate::ln::{inbound_payment, PaymentHash, PaymentPreimage, PaymentSecret};
43-
use crate::ln::channel::{Channel, ChannelContext, ChannelError, ChannelUpdateStatus, ShutdownResult, UnfundedChannelContext, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel};
43+
use crate::ln::channel::{Channel, ChannelContext, ChannelError, ChannelUpdateStatus, ShutdownResult, UnfundedChannelContext, UpdateFulfillCommitFetch, OutboundV1Channel, InboundChannelRequest, InboundV1Channel};
4444
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
4545
#[cfg(any(feature = "_test_utils", test))]
4646
use crate::ln::features::Bolt11InvoiceFeatures;
@@ -635,6 +635,13 @@ pub(super) struct PeerState<Signer: ChannelSigner> {
635635
/// been assigned a `channel_id`, the entry in this map is removed and one is created in
636636
/// `channel_by_id`.
637637
pub(super) inbound_v1_channel_by_id: HashMap<[u8; 32], InboundV1Channel<Signer>>,
638+
/// `temporary_channel_id` -> `InboundChannelRequest`.
639+
///
640+
/// When manual channel acceptance is enabled, this holds all unaccepted inbound channels where
641+
/// the peer is the counterparty. If the channel is accepted, then the entry in this table is
642+
/// removed, and an InboundV1Channel is created and placed in the `inbound_v1_channel_by_id` table. If
643+
/// the channel is rejected, then the entry is simply removed.
644+
pub(super) inbound_channel_request_by_id: HashMap<[u8; 32], InboundChannelRequest>,
638645
/// The latest `InitFeatures` we heard from the peer.
639646
latest_features: InitFeatures,
640647
/// Messages to send to the peer - pushed to in the same lock that they are generated in (except
@@ -689,7 +696,8 @@ impl <Signer: ChannelSigner> PeerState<Signer> {
689696
fn total_channel_count(&self) -> usize {
690697
self.channel_by_id.len() +
691698
self.outbound_v1_channel_by_id.len() +
692-
self.inbound_v1_channel_by_id.len()
699+
self.inbound_v1_channel_by_id.len() +
700+
self.inbound_channel_request_by_id.len()
693701
}
694702

695703
// Returns a bool indicating if the given `channel_id` matches a channel we have with this peer.
@@ -2559,6 +2567,15 @@ where
25592567
self.finish_force_close_channel(chan.context.force_shutdown(false));
25602568
// Unfunded channel has no update
25612569
(None, chan.context.get_counterparty_node_id())
2570+
} else if let Some(chan) = peer_state.inbound_channel_request_by_id.remove(channel_id) {
2571+
log_error!(self.logger, "Force-closing channel {}", log_bytes!(channel_id[..]));
2572+
// N.B. that we don't send any channel close event here: we
2573+
// don't have a user_channel_id, and we never sent any opening
2574+
// events anyway.
2575+
self.id_to_peer.lock().unwrap().remove(channel_id);
2576+
self.outbound_scid_aliases.lock().unwrap().remove(&chan.outbound_scid_alias);
2577+
self.short_to_chan_info.write().unwrap().remove(&chan.outbound_scid_alias);
2578+
(None, chan.counterparty_node_id)
25622579
} else {
25632580
return Err(APIError::ChannelUnavailable{ err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(*channel_id), peer_node_id) });
25642581
}
@@ -5187,49 +5204,54 @@ where
51875204
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
51885205
let peer_state = &mut *peer_state_lock;
51895206
let is_only_peer_channel = peer_state.total_channel_count() == 1;
5190-
match peer_state.inbound_v1_channel_by_id.entry(temporary_channel_id.clone()) {
5191-
hash_map::Entry::Occupied(mut channel) => {
5192-
if !channel.get().is_awaiting_accept() {
5193-
return Err(APIError::APIMisuseError { err: "The channel isn't currently awaiting to be accepted.".to_owned() });
5207+
5208+
// Find (and remove) the channel in the unaccepted table. If it's
5209+
// not there, something weird is happening and return an error.
5210+
let mut channel = match peer_state.inbound_channel_request_by_id.remove(temporary_channel_id) {
5211+
Some(unaccepted_channel) => {
5212+
let best_block_height = self.best_block.read().unwrap().height();
5213+
InboundV1Channel::new(&self.fee_estimator, &self.entropy_source, &self.signer_provider,
5214+
counterparty_node_id.clone(), &self.channel_type_features(), &peer_state.latest_features,
5215+
&unaccepted_channel.open_channel_msg, user_channel_id, &self.default_configuration, best_block_height,
5216+
&self.logger, unaccepted_channel.outbound_scid_alias).map_err(|e| APIError::ChannelUnavailable { err: e.to_string() })
5217+
}
5218+
_ => Err(APIError::APIMisuseError { err: "No such channel awaiting to be accepted.".to_owned() })
5219+
}?;
5220+
5221+
if accept_0conf {
5222+
channel.set_0conf();
5223+
} else if channel.context.get_channel_type().requires_zero_conf() {
5224+
let send_msg_err_event = events::MessageSendEvent::HandleError {
5225+
node_id: channel.context.get_counterparty_node_id(),
5226+
action: msgs::ErrorAction::SendErrorMessage{
5227+
msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "No zero confirmation channels accepted".to_owned(), }
51945228
}
5195-
if accept_0conf {
5196-
channel.get_mut().set_0conf();
5197-
} else if channel.get().context.get_channel_type().requires_zero_conf() {
5198-
let send_msg_err_event = events::MessageSendEvent::HandleError {
5199-
node_id: channel.get().context.get_counterparty_node_id(),
5200-
action: msgs::ErrorAction::SendErrorMessage{
5201-
msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "No zero confirmation channels accepted".to_owned(), }
5202-
}
5203-
};
5204-
peer_state.pending_msg_events.push(send_msg_err_event);
5205-
let _ = remove_channel!(self, channel);
5206-
return Err(APIError::APIMisuseError { err: "Please use accept_inbound_channel_from_trusted_peer_0conf to accept channels with zero confirmations.".to_owned() });
5207-
} else {
5208-
// If this peer already has some channels, a new channel won't increase our number of peers
5209-
// with unfunded channels, so as long as we aren't over the maximum number of unfunded
5210-
// channels per-peer we can accept channels from a peer with existing ones.
5211-
if is_only_peer_channel && peers_without_funded_channels >= MAX_UNFUNDED_CHANNEL_PEERS {
5212-
let send_msg_err_event = events::MessageSendEvent::HandleError {
5213-
node_id: channel.get().context.get_counterparty_node_id(),
5214-
action: msgs::ErrorAction::SendErrorMessage{
5215-
msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "Have too many peers with unfunded channels, not accepting new ones".to_owned(), }
5216-
}
5217-
};
5218-
peer_state.pending_msg_events.push(send_msg_err_event);
5219-
let _ = remove_channel!(self, channel);
5220-
return Err(APIError::APIMisuseError { err: "Too many peers with unfunded channels, refusing to accept new ones".to_owned() });
5229+
};
5230+
peer_state.pending_msg_events.push(send_msg_err_event);
5231+
return Err(APIError::APIMisuseError { err: "Please use accept_inbound_channel_from_trusted_peer_0conf to accept channels with zero confirmations.".to_owned() });
5232+
} else {
5233+
// If this peer already has some channels, a new channel won't increase our number of peers
5234+
// with unfunded channels, so as long as we aren't over the maximum number of unfunded
5235+
// channels per-peer we can accept channels from a peer with existing ones.
5236+
if is_only_peer_channel && peers_without_funded_channels >= MAX_UNFUNDED_CHANNEL_PEERS {
5237+
let send_msg_err_event = events::MessageSendEvent::HandleError {
5238+
node_id: channel.context.get_counterparty_node_id(),
5239+
action: msgs::ErrorAction::SendErrorMessage{
5240+
msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "Have too many peers with unfunded channels, not accepting new ones".to_owned(), }
52215241
}
5222-
}
5223-
5224-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
5225-
node_id: channel.get().context.get_counterparty_node_id(),
5226-
msg: channel.get_mut().accept_inbound_channel(user_channel_id),
5227-
});
5228-
}
5229-
hash_map::Entry::Vacant(_) => {
5230-
return Err(APIError::ChannelUnavailable { err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(*temporary_channel_id), counterparty_node_id) });
5242+
};
5243+
peer_state.pending_msg_events.push(send_msg_err_event);
5244+
return Err(APIError::APIMisuseError { err: "Too many peers with unfunded channels, refusing to accept new ones".to_owned() });
52315245
}
52325246
}
5247+
5248+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
5249+
node_id: channel.context.get_counterparty_node_id(),
5250+
msg: channel.accept_inbound_channel(user_channel_id),
5251+
});
5252+
5253+
peer_state.inbound_v1_channel_by_id.insert(temporary_channel_id.clone(), channel);
5254+
52335255
Ok(())
52345256
}
52355257

@@ -5274,7 +5296,7 @@ where
52745296
num_unfunded_channels += 1;
52755297
}
52765298
}
5277-
num_unfunded_channels
5299+
num_unfunded_channels + peer.inbound_channel_request_by_id.len()
52785300
}
52795301

52805302
fn internal_open_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<(), MsgHandleErrInternal> {
@@ -5325,6 +5347,32 @@ where
53255347
msg.temporary_channel_id.clone()));
53265348
}
53275349

5350+
let channel_id = msg.temporary_channel_id;
5351+
let channel_exists = peer_state.has_channel(&channel_id);
5352+
if channel_exists {
5353+
self.outbound_scid_aliases.lock().unwrap().remove(&outbound_scid_alias);
5354+
return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision for the same peer!".to_owned(), msg.temporary_channel_id.clone()));
5355+
}
5356+
5357+
// If we're doing manual acceptance checks on the channel, then defer creation until we're sure we want to accept.
5358+
if self.default_configuration.manually_accept_inbound_channels {
5359+
let mut pending_events = self.pending_events.lock().unwrap();
5360+
pending_events.push_back((events::Event::OpenChannelRequest {
5361+
temporary_channel_id: msg.temporary_channel_id.clone(),
5362+
counterparty_node_id: counterparty_node_id.clone(),
5363+
funding_satoshis: msg.funding_satoshis,
5364+
push_msat: msg.push_msat,
5365+
channel_type: msg.channel_type.clone().unwrap(),
5366+
}, None));
5367+
peer_state.inbound_channel_request_by_id.insert(channel_id, InboundChannelRequest {
5368+
counterparty_node_id: *counterparty_node_id,
5369+
open_channel_msg: msg.clone(),
5370+
outbound_scid_alias,
5371+
});
5372+
return Ok(());
5373+
}
5374+
5375+
// Otherwise create the channel right now.
53285376
let mut channel = match InboundV1Channel::new(&self.fee_estimator, &self.entropy_source, &self.signer_provider,
53295377
counterparty_node_id.clone(), &self.channel_type_features(), &peer_state.latest_features, msg, user_channel_id,
53305378
&self.default_configuration, best_block_height, &self.logger, outbound_scid_alias)
@@ -5335,36 +5383,19 @@ where
53355383
},
53365384
Ok(res) => res
53375385
};
5338-
let channel_id = channel.context.channel_id();
5339-
let channel_exists = peer_state.has_channel(&channel_id);
5340-
if channel_exists {
5341-
self.outbound_scid_aliases.lock().unwrap().remove(&outbound_scid_alias);
5342-
return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision for the same peer!".to_owned(), msg.temporary_channel_id.clone()))
5343-
} else {
5344-
if !self.default_configuration.manually_accept_inbound_channels {
5345-
let channel_type = channel.context.get_channel_type();
5346-
if channel_type.requires_zero_conf() {
5347-
return Err(MsgHandleErrInternal::send_err_msg_no_close("No zero confirmation channels accepted".to_owned(), msg.temporary_channel_id.clone()));
5348-
}
5349-
if channel_type.requires_anchors_zero_fee_htlc_tx() {
5350-
return Err(MsgHandleErrInternal::send_err_msg_no_close("No channels with anchor outputs accepted".to_owned(), msg.temporary_channel_id.clone()));
5351-
}
5352-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
5353-
node_id: counterparty_node_id.clone(),
5354-
msg: channel.accept_inbound_channel(user_channel_id),
5355-
});
5356-
} else {
5357-
let mut pending_events = self.pending_events.lock().unwrap();
5358-
pending_events.push_back((events::Event::OpenChannelRequest {
5359-
temporary_channel_id: msg.temporary_channel_id.clone(),
5360-
counterparty_node_id: counterparty_node_id.clone(),
5361-
funding_satoshis: msg.funding_satoshis,
5362-
push_msat: msg.push_msat,
5363-
channel_type: channel.context.get_channel_type().clone(),
5364-
}, None));
5365-
}
5366-
peer_state.inbound_v1_channel_by_id.insert(channel_id, channel);
5386+
5387+
let channel_type = channel.context.get_channel_type();
5388+
if channel_type.requires_zero_conf() {
5389+
return Err(MsgHandleErrInternal::send_err_msg_no_close("No zero confirmation channels accepted".to_owned(), msg.temporary_channel_id.clone()));
5390+
}
5391+
if channel_type.requires_anchors_zero_fee_htlc_tx() {
5392+
return Err(MsgHandleErrInternal::send_err_msg_no_close("No channels with anchor outputs accepted".to_owned(), msg.temporary_channel_id.clone()));
53675393
}
5394+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
5395+
node_id: counterparty_node_id.clone(),
5396+
msg: channel.accept_inbound_channel(user_channel_id),
5397+
});
5398+
peer_state.inbound_v1_channel_by_id.insert(channel_id, channel);
53685399
Ok(())
53695400
}
53705401

@@ -7279,6 +7310,7 @@ where
72797310
channel_by_id: HashMap::new(),
72807311
outbound_v1_channel_by_id: HashMap::new(),
72817312
inbound_v1_channel_by_id: HashMap::new(),
7313+
inbound_channel_request_by_id: HashMap::new(),
72827314
latest_features: init_msg.features.clone(),
72837315
pending_msg_events: Vec::new(),
72847316
in_flight_monitor_updates: BTreeMap::new(),
@@ -8475,6 +8507,7 @@ where
84758507
channel_by_id,
84768508
outbound_v1_channel_by_id: HashMap::new(),
84778509
inbound_v1_channel_by_id: HashMap::new(),
8510+
inbound_channel_request_by_id: HashMap::new(),
84788511
latest_features: InitFeatures::empty(),
84798512
pending_msg_events: Vec::new(),
84808513
in_flight_monitor_updates: BTreeMap::new(),
@@ -10192,7 +10225,9 @@ mod tests {
1019210225
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
1019310226
assert!(!open_channel_msg.channel_type.unwrap().supports_anchors_zero_fee_htlc_tx());
1019410227

10195-
check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed);
10228+
// Since nodes[1] should not have accepted the channel, it should
10229+
// not have generated any events.
10230+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
1019610231
}
1019710232

1019810233
#[test]

lightning/src/ln/functional_tests.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7870,9 +7870,12 @@ fn test_manually_reject_inbound_channel_request() {
78707870
}
78717871
_ => panic!("Unexpected event"),
78727872
}
7873-
check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed);
7873+
7874+
// There should be no more events to process, as the channel was never opened.
7875+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
78747876
}
78757877

7878+
#[ignore] // We cannot construct the accept message before creating the IncomingV1Channel object!
78767879
#[test]
78777880
fn test_reject_funding_before_inbound_channel_accepted() {
78787881
// This tests that when `UserConfig::manually_accept_inbound_channels` is set to true, inbound
@@ -7961,10 +7964,10 @@ fn test_can_not_accept_inbound_channel_twice() {
79617964
let api_res = nodes[1].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0);
79627965
match api_res {
79637966
Err(APIError::APIMisuseError { err }) => {
7964-
assert_eq!(err, "The channel isn't currently awaiting to be accepted.");
7967+
assert_eq!(err, "No such channel awaiting to be accepted.");
79657968
},
79667969
Ok(_) => panic!("Channel shouldn't be possible to be accepted twice"),
7967-
Err(_) => panic!("Unexpected Error"),
7970+
Err(e) => panic!("Unexpected Error {:?}", e),
79687971
}
79697972
}
79707973
_ => panic!("Unexpected event"),
@@ -7992,11 +7995,11 @@ fn test_can_not_accept_unknown_inbound_channel() {
79927995
let unknown_channel_id = [0; 32];
79937996
let api_res = nodes[0].node.accept_inbound_channel(&unknown_channel_id, &nodes[1].node.get_our_node_id(), 0);
79947997
match api_res {
7995-
Err(APIError::ChannelUnavailable { err }) => {
7996-
assert_eq!(err, format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(unknown_channel_id), nodes[1].node.get_our_node_id()));
7998+
Err(APIError::APIMisuseError { err }) => {
7999+
assert_eq!(err, "No such channel awaiting to be accepted.");
79978000
},
79988001
Ok(_) => panic!("It shouldn't be possible to accept an unkown channel"),
7999-
Err(_) => panic!("Unexpected Error"),
8002+
Err(e) => panic!("Unexpected Error: {:?}", e),
80008003
}
80018004
}
80028005

lightning/src/ln/shutdown_tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -742,13 +742,13 @@ fn test_invalid_upfront_shutdown_script() {
742742
open_channel.shutdown_scriptpubkey = Some(Builder::new().push_int(0)
743743
.push_slice(&[0, 0])
744744
.into_script());
745-
nodes[0].node.handle_open_channel(&nodes[1].node.get_our_node_id(), &open_channel);
745+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
746746

747-
let events = nodes[0].node.get_and_clear_pending_msg_events();
747+
let events = nodes[1].node.get_and_clear_pending_msg_events();
748748
assert_eq!(events.len(), 1);
749749
match events[0] {
750750
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
751-
assert_eq!(node_id, nodes[1].node.get_our_node_id());
751+
assert_eq!(node_id, nodes[0].node.get_our_node_id());
752752
assert_eq!(msg.data, "Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format: Script(OP_0 OP_PUSHBYTES_2 0000)");
753753
},
754754
_ => panic!("Unexpected event"),

0 commit comments

Comments
 (0)