Makes ChannelManager::force_close_channel fail for unknown chan_ids

ChannelManager::force_close_channel does not fail if a non-existing channel id is being passed, making it hard to catch from an API point of view.

Makes force_close_channel return in the same way close_channel does so the user calling the method with an unknown id can be warned.
This commit is contained in:
Sergi Delgado Segura 2021-01-14 17:05:38 +01:00
parent d529a8827b
commit 821f6cdd1e
No known key found for this signature in database
GPG key ID: 633B3A2298D70DD8
5 changed files with 20 additions and 16 deletions

View file

@ -548,7 +548,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
let channel_id = get_slice!(1)[0] as usize;
if channel_id >= channels.len() { return; }
channels.sort_by(|a, b| { a.channel_id.cmp(&b.channel_id) });
channelmanager.force_close_channel(&channels[channel_id].channel_id);
channelmanager.force_close_channel(&channels[channel_id].channel_id).unwrap();
},
// 15 is above
_ => return,

View file

@ -240,7 +240,7 @@ mod tests {
// Force close because cooperative close doesn't result in any persisted
// updates.
nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id);
nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap();
check_closed_broadcast!(nodes[0], false);
check_added_monitors!(nodes[0], 1);
@ -354,7 +354,7 @@ mod tests {
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
nodes[1].node.force_close_channel(&chan.2);
nodes[1].node.force_close_channel(&chan.2).unwrap();
let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap();
// Set the persister's directory to read-only, which should result in
@ -390,7 +390,7 @@ mod tests {
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
nodes[1].node.force_close_channel(&chan.2);
nodes[1].node.force_close_channel(&chan.2).unwrap();
let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap();
// Create the persister with an invalid directory name and test that the

View file

@ -239,7 +239,7 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool, persister_fail
}
// ...and make sure we can force-close a frozen channel
nodes[0].node.force_close_channel(&channel_id);
nodes[0].node.force_close_channel(&channel_id).unwrap();
check_added_monitors!(nodes[0], 1);
check_closed_broadcast!(nodes[0], false);

View file

@ -917,8 +917,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
}
/// Force closes a channel, immediately broadcasting the latest local commitment transaction to
/// the chain and rejecting new HTLCs on the given channel.
pub fn force_close_channel(&self, channel_id: &[u8; 32]) {
/// the chain and rejecting new HTLCs on the given channel. Fails if channel_id is unknown to the manager.
pub fn force_close_channel(&self, channel_id: &[u8; 32]) -> Result<(), APIError>{
let _consistency_lock = self.total_consistency_lock.read().unwrap();
let mut chan = {
@ -930,7 +930,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
}
chan
} else {
return;
return Err(APIError::ChannelUnavailable{err: "No such channel".to_owned()});
}
};
log_trace!(self.logger, "Force-closing channel {}", log_bytes!(channel_id[..]));
@ -941,13 +941,15 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
msg: update
});
}
Ok(())
}
/// Force close all channels, immediately broadcasting the latest local commitment transaction
/// for each to the chain and rejecting new HTLCs on each.
pub fn force_close_all_channels(&self) {
for chan in self.list_channels() {
self.force_close_channel(&chan.channel_id);
let _ = self.force_close_channel(&chan.channel_id);
}
}
@ -3471,11 +3473,13 @@ impl<ChanSigner: ChannelKeys, M: Deref + Sync + Send, T: Deref + Sync + Send, K:
if msg.channel_id == [0; 32] {
for chan in self.list_channels() {
if chan.remote_network_id == *counterparty_node_id {
self.force_close_channel(&chan.channel_id);
// Untrusted messages from peer, we throw away the error if id points to a non-existent channel
let _ = self.force_close_channel(&msg.channel_id);
}
}
} else {
self.force_close_channel(&msg.channel_id);
// Untrusted messages from peer, we throw away the error if id points to a non-existent channel
let _ = self.force_close_channel(&msg.channel_id);
}
}
}

View file

@ -3396,7 +3396,7 @@ fn test_htlc_ignore_latest_remote_commitment() {
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
route_payment(&nodes[0], &[&nodes[1]], 10000000);
nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id);
nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap();
check_closed_broadcast!(nodes[0], false);
check_added_monitors!(nodes[0], 1);
@ -3457,7 +3457,7 @@ fn test_force_close_fail_back() {
// state or updated nodes[1]' state. Now force-close and broadcast that commitment/HTLC
// transaction and ensure nodes[1] doesn't fail-backwards (this was originally a bug!).
nodes[2].node.force_close_channel(&payment_event.commitment_msg.channel_id);
nodes[2].node.force_close_channel(&payment_event.commitment_msg.channel_id).unwrap();
check_closed_broadcast!(nodes[2], false);
check_added_monitors!(nodes[2], 1);
let tx = {
@ -4783,7 +4783,7 @@ fn test_claim_sizeable_push_msat() {
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 99000000, InitFeatures::known(), InitFeatures::known());
nodes[1].node.force_close_channel(&chan.2);
nodes[1].node.force_close_channel(&chan.2).unwrap();
check_closed_broadcast!(nodes[1], false);
check_added_monitors!(nodes[1], 1);
let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
@ -4810,7 +4810,7 @@ fn test_claim_on_remote_sizeable_push_msat() {
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 99000000, InitFeatures::known(), InitFeatures::known());
nodes[0].node.force_close_channel(&chan.2);
nodes[0].node.force_close_channel(&chan.2).unwrap();
check_closed_broadcast!(nodes[0], false);
check_added_monitors!(nodes[0], 1);
@ -8544,7 +8544,7 @@ fn do_test_onchain_htlc_settlement_after_close(broadcast_alice: bool, go_onchain
// responds by (1) broadcasting a channel update and (2) adding a new ChannelMonitor.
let mut force_closing_node = 0; // Alice force-closes
if !broadcast_alice { force_closing_node = 1; } // Bob force-closes
nodes[force_closing_node].node.force_close_channel(&chan_ab.2);
nodes[force_closing_node].node.force_close_channel(&chan_ab.2).unwrap();
check_closed_broadcast!(nodes[force_closing_node], false);
check_added_monitors!(nodes[force_closing_node], 1);
if go_onchain_before_fulfill {