Skip to content

Commit df4c3dc

Browse files
Reject FundingCreated before channel accepted test
1 parent 8c30b59 commit df4c3dc

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

lightning/src/ln/channel.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4526,6 +4526,10 @@ impl<Signer: Sign> Channel<Signer> {
45264526
self.inbound_awaiting_accept
45274527
}
45284528

4529+
pub fn set_is_awaiting_accept(&mut self) {
4530+
self.inbound_awaiting_accept = true;
4531+
}
4532+
45294533
pub fn get_accept_channel(&mut self) -> msgs::AcceptChannel {
45304534
if self.is_outbound() {
45314535
panic!("Tried to send accept_channel for an outbound channel?");

lightning/src/ln/functional_tests.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8247,6 +8247,80 @@ fn test_manually_reject_inbound_channel_request() {
82478247
check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed);
82488248
}
82498249

8250+
#[test]
8251+
fn test_reject_funding_before_inbound_channel_accepted() {
8252+
// This tests that when the util::config::UserConfig.manually_accept_inbound_channels is set to
8253+
// true, inbound channels must to be manually accepted through the
8254+
// ln::channelmanager::ChannelManager::accept_inbound_channel function by the node operator
8255+
// before the counterparty sends a `FundingCreated` message. If a `FundingCreated` message is
8256+
// received before the channel is accepted, it should be rejected and the channel should be
8257+
// closed.
8258+
let mut manually_accept_conf = UserConfig::default();
8259+
manually_accept_conf.manually_accept_inbound_channels = true;
8260+
let chanmon_cfgs = create_chanmon_cfgs(2);
8261+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
8262+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(manually_accept_conf.clone())]);
8263+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
8264+
8265+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, Some(manually_accept_conf)).unwrap();
8266+
let res = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
8267+
let temp_channel_id = res.temporary_channel_id;
8268+
8269+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &res);
8270+
8271+
// Assert that node[1] has no MessageSendEvent::SendAcceptChannel in the msg_events before rejecting the inbound request
8272+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
8273+
8274+
// Clear the Event::OpenChannelRequest event without responding to the request.
8275+
nodes[1].node.get_and_clear_pending_events();
8276+
8277+
// Get the `AcceptChannel` message of nodes[1] without calling the
8278+
// ChannelManager::accept_inbound_channel function, which generates the
8279+
// MessageSendEvent::SendAcceptChannel event. This is passed to nodes[0] handle_accept_channel
8280+
// function, which is required in order for the create_funding_transaction function not to
8281+
// crash when nodes[0] is passed to it.
8282+
{
8283+
let mut channel_state_lock = nodes[1].node.channel_state.lock().unwrap();
8284+
let channel_state = &mut *channel_state_lock;
8285+
match channel_state.by_id.entry(temp_channel_id.clone()) {
8286+
hash_map::Entry::Occupied(mut channel) => {
8287+
let accept_chan_msg = channel.get_mut().get_accept_channel();
8288+
// As this test doesn't intend to actually accept the channel by nodes[1], we reset
8289+
// Channel::inbound_awaiting_accept flag which was mutated by the
8290+
// get_accept_channel call.
8291+
channel.get_mut().set_is_awaiting_accept();
8292+
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_chan_msg);
8293+
}
8294+
hash_map::Entry::Vacant(_) => {
8295+
panic!("Should have found the created channel")
8296+
}
8297+
}
8298+
}
8299+
8300+
let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], 100000, 42);
8301+
8302+
nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap();
8303+
let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
8304+
8305+
// The funding_created_msg should be rejected by nodes[1] as it hasn't accepted the channel.
8306+
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
8307+
8308+
let close_msg_ev = nodes[1].node.get_and_clear_pending_msg_events();
8309+
assert_eq!(close_msg_ev.len(), 1);
8310+
8311+
let expected_err = "FundingCreated message received before the channel was accepted";
8312+
match close_msg_ev[0] {
8313+
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, ref node_id, } => {
8314+
assert_eq!(msg.channel_id, temp_channel_id);
8315+
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
8316+
assert_eq!(msg.data, expected_err);
8317+
}
8318+
_ => panic!("Unexpected event"),
8319+
}
8320+
8321+
check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: expected_err.to_string() });
8322+
}
8323+
82508324
#[test]
82518325
fn test_simple_mpp() {
82528326
// Simple test of sending a multi-path payment.

0 commit comments

Comments
 (0)