X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_tests.rs;h=ed54522526d06e1dfd51e462070b314b0777cf0b;hb=bd6323e94b88f9f6c9f030a484f5b5e145d61c5b;hp=271ff541a84981733090b30600956886c2845d40;hpb=4c342bd6b6c8a989e6647de090c616d75b7d1f8c;p=rust-lightning diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 271ff541..ed545225 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -61,6 +61,8 @@ use crate::sync::{Arc, Mutex}; use crate::ln::functional_test_utils::*; use crate::ln::chan_utils::CommitmentTransaction; +use super::channel::UNFUNDED_CHANNEL_AGE_LIMIT_TICKS; + #[test] fn test_insane_channel_opens() { // Stand up a network of 2 nodes @@ -3583,7 +3585,9 @@ fn test_dup_events_on_peer_disconnect() { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id()); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id()); - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (1, 0), (0, 0), (0, 0), (0, 0), (false, false)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.pending_htlc_claims.0 = 1; + reconnect_nodes(reconnect_args); expect_payment_path_successful!(nodes[0]); } @@ -3640,7 +3644,9 @@ fn test_simple_peer_disconnect() { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id()); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id()); - reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.send_channel_ready = (true, true); + reconnect_nodes(reconnect_args); let payment_preimage_1 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).0; let payment_hash_2 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).1; @@ -3649,7 +3655,7 @@ fn test_simple_peer_disconnect() { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id()); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id()); - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); + reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1])); let (payment_preimage_3, payment_hash_3, _) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000); let payment_preimage_4 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).0; @@ -3662,7 +3668,10 @@ fn test_simple_peer_disconnect() { claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], true, payment_preimage_3); fail_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], true, payment_hash_5); - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (1, 0), (1, 0), (false, false)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.pending_cell_htlc_fails.0 = 1; + reconnect_args.pending_cell_htlc_claims.0 = 1; + reconnect_nodes(reconnect_args); { let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 4); @@ -3774,19 +3783,29 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken } // Even if the channel_ready messages get exchanged, as long as nothing further was // received on either side, both sides will need to resend them. - reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 1), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.send_channel_ready = (true, true); + reconnect_args.pending_htlc_adds.1 = 1; + reconnect_nodes(reconnect_args); } else if messages_delivered == 3 { // nodes[0] still wants its RAA + commitment_signed - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (-1, 0), (0, 0), (0, 0), (0, 0), (0, 0), (true, false)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.pending_htlc_adds.0 = -1; + reconnect_args.pending_raa.0 = true; + reconnect_nodes(reconnect_args); } else if messages_delivered == 4 { // nodes[0] still wants its commitment_signed - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (-1, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.pending_htlc_adds.0 = -1; + reconnect_nodes(reconnect_args); } else if messages_delivered == 5 { // nodes[1] still wants its final RAA - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, true)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.pending_raa.1 = true; + reconnect_nodes(reconnect_args); } else if messages_delivered == 6 { // Everything was delivered... - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); + reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1])); } let events_1 = nodes[1].node.get_and_clear_pending_events(); @@ -3810,7 +3829,7 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id()); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id()); - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); + reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1])); nodes[1].node.process_pending_htlc_forwards(); @@ -3894,7 +3913,9 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id()); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id()); if messages_delivered < 2 { - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (1, 0), (0, 0), (0, 0), (0, 0), (false, false)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.pending_htlc_claims.0 = 1; + reconnect_nodes(reconnect_args); if messages_delivered < 1 { expect_payment_sent!(nodes[0], payment_preimage_1); } else { @@ -3902,16 +3923,23 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken } } else if messages_delivered == 2 { // nodes[0] still wants its RAA + commitment_signed - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, -1), (0, 0), (0, 0), (0, 0), (0, 0), (false, true)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.pending_htlc_adds.1 = -1; + reconnect_args.pending_raa.1 = true; + reconnect_nodes(reconnect_args); } else if messages_delivered == 3 { // nodes[0] still wants its commitment_signed - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, -1), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.pending_htlc_adds.1 = -1; + reconnect_nodes(reconnect_args); } else if messages_delivered == 4 { // nodes[1] still wants its final RAA - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (true, false)); + let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); + reconnect_args.pending_raa.0 = true; + reconnect_nodes(reconnect_args); } else if messages_delivered == 5 { // Everything was delivered... - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); + reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1])); } if messages_delivered == 1 || messages_delivered == 2 { @@ -3921,7 +3949,7 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id()); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id()); } - reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); + reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1])); if messages_delivered > 2 { expect_payment_path_successful!(nodes[0]); @@ -8881,13 +8909,13 @@ fn test_duplicate_chan_id() { let (_, funding_created) = { let per_peer_state = nodes[0].node.per_peer_state.read().unwrap(); let mut a_peer_state = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap(); - // Once we call `get_outbound_funding_created` the channel has a duplicate channel_id as + // Once we call `get_funding_created` the channel has a duplicate channel_id as // another channel in the ChannelManager - an invalid state. Thus, we'd panic later when we // try to create another channel. Instead, we drop the channel entirely here (leaving the // channelmanager in a possibly nonsense state instead). let mut as_chan = a_peer_state.outbound_v1_channel_by_id.remove(&open_chan_2_msg.temporary_channel_id).unwrap(); let logger = test_utils::TestLogger::new(); - as_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap() + as_chan.get_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap() }; check_added_monitors!(nodes[0], 0); nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created); @@ -10017,3 +10045,89 @@ fn test_disconnects_peer_awaiting_response_ticks() { } } } + +#[test] +fn test_remove_expired_outbound_unfunded_channels() { + let chanmon_cfgs = create_chanmon_cfgs(2); + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + + let temp_channel_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None).unwrap(); + let open_channel_message = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); + nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_message); + let accept_channel_message = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()); + nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel_message); + + let events = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::FundingGenerationReady { .. } => (), + _ => panic!("Unexpected event"), + }; + + // Asserts the outbound channel has been removed from a nodes[0]'s peer state map. + let check_outbound_channel_existence = |should_exist: bool| { + let per_peer_state = nodes[0].node.per_peer_state.read().unwrap(); + let chan_lock = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap(); + assert_eq!(chan_lock.outbound_v1_channel_by_id.contains_key(&temp_channel_id), should_exist); + }; + + // Channel should exist without any timer ticks. + check_outbound_channel_existence(true); + + // Channel should exist with 1 timer tick less than required. + for _ in 0..UNFUNDED_CHANNEL_AGE_LIMIT_TICKS - 1 { + nodes[0].node.timer_tick_occurred(); + check_outbound_channel_existence(true) + } + + // Remove channel after reaching the required ticks. + nodes[0].node.timer_tick_occurred(); + check_outbound_channel_existence(false); + + check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed); +} + +#[test] +fn test_remove_expired_inbound_unfunded_channels() { + let chanmon_cfgs = create_chanmon_cfgs(2); + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + + let temp_channel_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None).unwrap(); + let open_channel_message = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); + nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_message); + let accept_channel_message = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()); + nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel_message); + + let events = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::FundingGenerationReady { .. } => (), + _ => panic!("Unexpected event"), + }; + + // Asserts the inbound channel has been removed from a nodes[1]'s peer state map. + let check_inbound_channel_existence = |should_exist: bool| { + let per_peer_state = nodes[1].node.per_peer_state.read().unwrap(); + let chan_lock = per_peer_state.get(&nodes[0].node.get_our_node_id()).unwrap().lock().unwrap(); + assert_eq!(chan_lock.inbound_v1_channel_by_id.contains_key(&temp_channel_id), should_exist); + }; + + // Channel should exist without any timer ticks. + check_inbound_channel_existence(true); + + // Channel should exist with 1 timer tick less than required. + for _ in 0..UNFUNDED_CHANNEL_AGE_LIMIT_TICKS - 1 { + nodes[1].node.timer_tick_occurred(); + check_inbound_channel_existence(true) + } + + // Remove channel after reaching the required ticks. + nodes[1].node.timer_tick_occurred(); + check_inbound_channel_existence(false); + + check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed); +}