Skip to content

Commit 9ca2280

Browse files
authored
Merge pull request #2953 from dunxen/2024-03-fix2941
Fix `ChannelManager::accept_inbound_channel` error handling
2 parents 19bcb1c + 3206d1f commit 9ca2280

File tree

2 files changed

+91
-49
lines changed

2 files changed

+91
-49
lines changed

lightning/src/ln/channelmanager.rs

+58-49
Original file line numberDiff line numberDiff line change
@@ -6112,73 +6112,82 @@ where
61126112
// happening and return an error. N.B. that we create channel with an outbound SCID of zero so
61136113
// that we can delay allocating the SCID until after we're sure that the checks below will
61146114
// succeed.
6115-
let mut channel = match peer_state.inbound_channel_request_by_id.remove(temporary_channel_id) {
6115+
let res = match peer_state.inbound_channel_request_by_id.remove(temporary_channel_id) {
61166116
Some(unaccepted_channel) => {
61176117
let best_block_height = self.best_block.read().unwrap().height;
61186118
InboundV1Channel::new(&self.fee_estimator, &self.entropy_source, &self.signer_provider,
61196119
counterparty_node_id.clone(), &self.channel_type_features(), &peer_state.latest_features,
61206120
&unaccepted_channel.open_channel_msg, user_channel_id, &self.default_configuration, best_block_height,
6121-
&self.logger, accept_0conf).map_err(|e| {
6122-
let err_str = e.to_string();
6123-
log_error!(logger, "{}", err_str);
6124-
6125-
APIError::ChannelUnavailable { err: err_str }
6126-
})
6127-
}
6121+
&self.logger, accept_0conf).map_err(|err| MsgHandleErrInternal::from_chan_no_close(err, *temporary_channel_id))
6122+
},
61286123
_ => {
61296124
let err_str = "No such channel awaiting to be accepted.".to_owned();
61306125
log_error!(logger, "{}", err_str);
61316126

6132-
Err(APIError::APIMisuseError { err: err_str })
6127+
return Err(APIError::APIMisuseError { err: err_str });
61336128
}
6134-
}?;
6129+
};
61356130

6136-
if accept_0conf {
6137-
// This should have been correctly configured by the call to InboundV1Channel::new.
6138-
debug_assert!(channel.context.minimum_depth().unwrap() == 0);
6139-
} else if channel.context.get_channel_type().requires_zero_conf() {
6140-
let send_msg_err_event = events::MessageSendEvent::HandleError {
6141-
node_id: channel.context.get_counterparty_node_id(),
6142-
action: msgs::ErrorAction::SendErrorMessage{
6143-
msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "No zero confirmation channels accepted".to_owned(), }
6131+
match res {
6132+
Err(err) => {
6133+
mem::drop(peer_state_lock);
6134+
mem::drop(per_peer_state);
6135+
match handle_error!(self, Result::<(), MsgHandleErrInternal>::Err(err), *counterparty_node_id) {
6136+
Ok(_) => unreachable!("`handle_error` only returns Err as we've passed in an Err"),
6137+
Err(e) => {
6138+
return Err(APIError::ChannelUnavailable { err: e.err });
6139+
},
61446140
}
6145-
};
6146-
peer_state.pending_msg_events.push(send_msg_err_event);
6147-
let err_str = "Please use accept_inbound_channel_from_trusted_peer_0conf to accept channels with zero confirmations.".to_owned();
6148-
log_error!(logger, "{}", err_str);
6141+
}
6142+
Ok(mut channel) => {
6143+
if accept_0conf {
6144+
// This should have been correctly configured by the call to InboundV1Channel::new.
6145+
debug_assert!(channel.context.minimum_depth().unwrap() == 0);
6146+
} else if channel.context.get_channel_type().requires_zero_conf() {
6147+
let send_msg_err_event = events::MessageSendEvent::HandleError {
6148+
node_id: channel.context.get_counterparty_node_id(),
6149+
action: msgs::ErrorAction::SendErrorMessage{
6150+
msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "No zero confirmation channels accepted".to_owned(), }
6151+
}
6152+
};
6153+
peer_state.pending_msg_events.push(send_msg_err_event);
6154+
let err_str = "Please use accept_inbound_channel_from_trusted_peer_0conf to accept channels with zero confirmations.".to_owned();
6155+
log_error!(logger, "{}", err_str);
61496156

6150-
return Err(APIError::APIMisuseError { err: err_str });
6151-
} else {
6152-
// If this peer already has some channels, a new channel won't increase our number of peers
6153-
// with unfunded channels, so as long as we aren't over the maximum number of unfunded
6154-
// channels per-peer we can accept channels from a peer with existing ones.
6155-
if is_only_peer_channel && peers_without_funded_channels >= MAX_UNFUNDED_CHANNEL_PEERS {
6156-
let send_msg_err_event = events::MessageSendEvent::HandleError {
6157-
node_id: channel.context.get_counterparty_node_id(),
6158-
action: msgs::ErrorAction::SendErrorMessage{
6159-
msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "Have too many peers with unfunded channels, not accepting new ones".to_owned(), }
6160-
}
6161-
};
6162-
peer_state.pending_msg_events.push(send_msg_err_event);
6163-
let err_str = "Too many peers with unfunded channels, refusing to accept new ones".to_owned();
6164-
log_error!(logger, "{}", err_str);
6157+
return Err(APIError::APIMisuseError { err: err_str });
6158+
} else {
6159+
// If this peer already has some channels, a new channel won't increase our number of peers
6160+
// with unfunded channels, so as long as we aren't over the maximum number of unfunded
6161+
// channels per-peer we can accept channels from a peer with existing ones.
6162+
if is_only_peer_channel && peers_without_funded_channels >= MAX_UNFUNDED_CHANNEL_PEERS {
6163+
let send_msg_err_event = events::MessageSendEvent::HandleError {
6164+
node_id: channel.context.get_counterparty_node_id(),
6165+
action: msgs::ErrorAction::SendErrorMessage{
6166+
msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "Have too many peers with unfunded channels, not accepting new ones".to_owned(), }
6167+
}
6168+
};
6169+
peer_state.pending_msg_events.push(send_msg_err_event);
6170+
let err_str = "Too many peers with unfunded channels, refusing to accept new ones".to_owned();
6171+
log_error!(logger, "{}", err_str);
61656172

6166-
return Err(APIError::APIMisuseError { err: err_str });
6167-
}
6168-
}
6173+
return Err(APIError::APIMisuseError { err: err_str });
6174+
}
6175+
}
61696176

6170-
// Now that we know we have a channel, assign an outbound SCID alias.
6171-
let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
6172-
channel.context.set_outbound_scid_alias(outbound_scid_alias);
6177+
// Now that we know we have a channel, assign an outbound SCID alias.
6178+
let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
6179+
channel.context.set_outbound_scid_alias(outbound_scid_alias);
61736180

6174-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
6175-
node_id: channel.context.get_counterparty_node_id(),
6176-
msg: channel.accept_inbound_channel(),
6177-
});
6181+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
6182+
node_id: channel.context.get_counterparty_node_id(),
6183+
msg: channel.accept_inbound_channel(),
6184+
});
61786185

6179-
peer_state.channel_by_id.insert(temporary_channel_id.clone(), ChannelPhase::UnfundedInboundV1(channel));
6186+
peer_state.channel_by_id.insert(temporary_channel_id.clone(), ChannelPhase::UnfundedInboundV1(channel));
61806187

6181-
Ok(())
6188+
Ok(())
6189+
},
6190+
}
61826191
}
61836192

61846193
/// Gets the number of peers which match the given filter and do not have any funded, outbound,

lightning/src/ln/functional_tests.rs

+33
Original file line numberDiff line numberDiff line change
@@ -10983,3 +10983,36 @@ fn test_funding_and_commitment_tx_confirm_same_block() {
1098310983
do_test_funding_and_commitment_tx_confirm_same_block(false);
1098410984
do_test_funding_and_commitment_tx_confirm_same_block(true);
1098510985
}
10986+
10987+
#[test]
10988+
fn test_accept_inbound_channel_errors_queued() {
10989+
// For manually accepted inbound channels, tests that a close error is correctly handled
10990+
// and the channel fails for the initiator.
10991+
let mut config0 = test_default_channel_config();
10992+
let mut config1 = config0.clone();
10993+
config1.channel_handshake_limits.their_to_self_delay = 1000;
10994+
config1.manually_accept_inbound_channels = true;
10995+
config0.channel_handshake_config.our_to_self_delay = 2000;
10996+
10997+
let chanmon_cfgs = create_chanmon_cfgs(2);
10998+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
10999+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config0), Some(config1)]);
11000+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
11001+
11002+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None, None).unwrap();
11003+
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
11004+
11005+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
11006+
let events = nodes[1].node.get_and_clear_pending_events();
11007+
match events[0] {
11008+
Event::OpenChannelRequest { temporary_channel_id, .. } => {
11009+
match nodes[1].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 23) {
11010+
Err(APIError::ChannelUnavailable { err: _ }) => (),
11011+
_ => panic!(),
11012+
}
11013+
}
11014+
_ => panic!("Unexpected event"),
11015+
}
11016+
assert_eq!(get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id()).channel_id,
11017+
open_channel_msg.common_fields.temporary_channel_id);
11018+
}

0 commit comments

Comments
 (0)