+ #[test]
+ fn test_connection_limiting() {
+ // Test that we limit un-channel'd peers and un-funded channels properly.
+ 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);
+
+ // Note that create_network connects the nodes together for us
+
+ nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None).unwrap();
+ let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+
+ let mut funding_tx = None;
+ for idx in 0..super::MAX_UNFUNDED_CHANS_PER_PEER {
+ nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
+ let accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
+
+ if idx == 0 {
+ nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
+ let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100_000, 42);
+ funding_tx = Some(tx.clone());
+ nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx).unwrap();
+ let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
+
+ nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
+ check_added_monitors!(nodes[1], 1);
+ expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
+
+ let funding_signed = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
+
+ nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed);
+ check_added_monitors!(nodes[0], 1);
+ expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
+ }
+ open_channel_msg.temporary_channel_id = nodes[0].keys_manager.get_secure_random_bytes();
+ }
+
+ // A MAX_UNFUNDED_CHANS_PER_PEER + 1 channel will be summarily rejected
+ open_channel_msg.temporary_channel_id = nodes[0].keys_manager.get_secure_random_bytes();
+ nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
+ assert_eq!(get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id()).channel_id,
+ open_channel_msg.temporary_channel_id);
+
+ // Further, because all of our channels with nodes[0] are inbound, and none of them funded,
+ // it doesn't count as a "protected" peer, i.e. it counts towards the MAX_NO_CHANNEL_PEERS
+ // limit.
+ let mut peer_pks = Vec::with_capacity(super::MAX_NO_CHANNEL_PEERS);
+ for _ in 1..super::MAX_NO_CHANNEL_PEERS {
+ let random_pk = PublicKey::from_secret_key(&nodes[0].node.secp_ctx,
+ &SecretKey::from_slice(&nodes[1].keys_manager.get_secure_random_bytes()).unwrap());
+ peer_pks.push(random_pk);
+ nodes[1].node.peer_connected(&random_pk, &msgs::Init {
+ features: nodes[0].node.init_features(), networks: None, remote_network_address: None
+ }, true).unwrap();
+ }
+ let last_random_pk = PublicKey::from_secret_key(&nodes[0].node.secp_ctx,
+ &SecretKey::from_slice(&nodes[1].keys_manager.get_secure_random_bytes()).unwrap());
+ nodes[1].node.peer_connected(&last_random_pk, &msgs::Init {
+ features: nodes[0].node.init_features(), networks: None, remote_network_address: None
+ }, true).unwrap_err();
+
+ // Also importantly, because nodes[0] isn't "protected", we will refuse a reconnection from
+ // them if we have too many un-channel'd peers.
+ nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
+ let chan_closed_events = nodes[1].node.get_and_clear_pending_events();
+ assert_eq!(chan_closed_events.len(), super::MAX_UNFUNDED_CHANS_PER_PEER - 1);
+ for ev in chan_closed_events {
+ if let Event::ChannelClosed { .. } = ev { } else { panic!(); }
+ }
+ nodes[1].node.peer_connected(&last_random_pk, &msgs::Init {
+ features: nodes[0].node.init_features(), networks: None, remote_network_address: None
+ }, true).unwrap();
+ nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init {
+ features: nodes[0].node.init_features(), networks: None, remote_network_address: None
+ }, true).unwrap_err();
+
+ // but of course if the connection is outbound its allowed...
+ nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init {
+ features: nodes[0].node.init_features(), networks: None, remote_network_address: None
+ }, false).unwrap();
+ nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
+
+ // Now nodes[0] is disconnected but still has a pending, un-funded channel lying around.
+ // Even though we accept one more connection from new peers, we won't actually let them
+ // open channels.
+ assert!(peer_pks.len() > super::MAX_UNFUNDED_CHANNEL_PEERS - 1);
+ for i in 0..super::MAX_UNFUNDED_CHANNEL_PEERS - 1 {
+ nodes[1].node.handle_open_channel(&peer_pks[i], &open_channel_msg);
+ get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, peer_pks[i]);
+ open_channel_msg.temporary_channel_id = nodes[0].keys_manager.get_secure_random_bytes();
+ }
+ nodes[1].node.handle_open_channel(&last_random_pk, &open_channel_msg);
+ assert_eq!(get_err_msg(&nodes[1], &last_random_pk).channel_id,
+ open_channel_msg.temporary_channel_id);
+
+ // Of course, however, outbound channels are always allowed
+ nodes[1].node.create_channel(last_random_pk, 100_000, 0, 42, None).unwrap();
+ get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, last_random_pk);
+
+ // If we fund the first channel, nodes[0] has a live on-chain channel with us, it is now
+ // "protected" and can connect again.
+ mine_transaction(&nodes[1], funding_tx.as_ref().unwrap());
+ nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init {
+ features: nodes[0].node.init_features(), networks: None, remote_network_address: None
+ }, true).unwrap();
+ get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
+
+ // Further, because the first channel was funded, we can open another channel with
+ // last_random_pk.
+ nodes[1].node.handle_open_channel(&last_random_pk, &open_channel_msg);
+ get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, last_random_pk);
+ }
+
+ #[test]
+ fn test_outbound_chans_unlimited() {
+ // Test that we never refuse an outbound channel even if a peer is unfuned-channel-limited
+ 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);
+
+ // Note that create_network connects the nodes together for us
+
+ nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None).unwrap();
+ let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+
+ for _ in 0..super::MAX_UNFUNDED_CHANS_PER_PEER {
+ nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
+ get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
+ open_channel_msg.temporary_channel_id = nodes[0].keys_manager.get_secure_random_bytes();
+ }
+
+ // Once we have MAX_UNFUNDED_CHANS_PER_PEER unfunded channels, new inbound channels will be
+ // rejected.
+ nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
+ assert_eq!(get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id()).channel_id,
+ open_channel_msg.temporary_channel_id);
+
+ // but we can still open an outbound channel.
+ nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 100_000, 0, 42, None).unwrap();
+ get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
+
+ // but even with such an outbound channel, additional inbound channels will still fail.
+ nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
+ assert_eq!(get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id()).channel_id,
+ open_channel_msg.temporary_channel_id);
+ }
+
+ #[test]
+ fn test_0conf_limiting() {
+ // Tests that we properly limit inbound channels when we have the manual-channel-acceptance
+ // flag set and (sometimes) accept channels as 0conf.
+ let chanmon_cfgs = create_chanmon_cfgs(2);
+ let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+ let mut settings = test_default_channel_config();
+ settings.manually_accept_inbound_channels = true;
+ let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(settings)]);
+ let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+ // Note that create_network connects the nodes together for us
+
+ nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None).unwrap();
+ let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+
+ // First, get us up to MAX_UNFUNDED_CHANNEL_PEERS so we can test at the edge
+ for _ in 0..super::MAX_UNFUNDED_CHANNEL_PEERS - 1 {
+ let random_pk = PublicKey::from_secret_key(&nodes[0].node.secp_ctx,
+ &SecretKey::from_slice(&nodes[1].keys_manager.get_secure_random_bytes()).unwrap());
+ nodes[1].node.peer_connected(&random_pk, &msgs::Init {
+ features: nodes[0].node.init_features(), networks: None, remote_network_address: None
+ }, true).unwrap();
+
+ nodes[1].node.handle_open_channel(&random_pk, &open_channel_msg);
+ let events = nodes[1].node.get_and_clear_pending_events();
+ match events[0] {
+ Event::OpenChannelRequest { temporary_channel_id, .. } => {
+ nodes[1].node.accept_inbound_channel(&temporary_channel_id, &random_pk, 23).unwrap();
+ }
+ _ => panic!("Unexpected event"),
+ }
+ get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, random_pk);
+ open_channel_msg.temporary_channel_id = nodes[0].keys_manager.get_secure_random_bytes();
+ }
+
+ // If we try to accept a channel from another peer non-0conf it will fail.
+ let last_random_pk = PublicKey::from_secret_key(&nodes[0].node.secp_ctx,
+ &SecretKey::from_slice(&nodes[1].keys_manager.get_secure_random_bytes()).unwrap());
+ nodes[1].node.peer_connected(&last_random_pk, &msgs::Init {
+ features: nodes[0].node.init_features(), networks: None, remote_network_address: None
+ }, true).unwrap();
+ nodes[1].node.handle_open_channel(&last_random_pk, &open_channel_msg);
+ let events = nodes[1].node.get_and_clear_pending_events();
+ match events[0] {
+ Event::OpenChannelRequest { temporary_channel_id, .. } => {
+ match nodes[1].node.accept_inbound_channel(&temporary_channel_id, &last_random_pk, 23) {
+ Err(APIError::APIMisuseError { err }) =>
+ assert_eq!(err, "Too many peers with unfunded channels, refusing to accept new ones"),
+ _ => panic!(),
+ }
+ }
+ _ => panic!("Unexpected event"),
+ }
+ assert_eq!(get_err_msg(&nodes[1], &last_random_pk).channel_id,
+ open_channel_msg.temporary_channel_id);
+
+ // ...however if we accept the same channel 0conf it should work just fine.
+ nodes[1].node.handle_open_channel(&last_random_pk, &open_channel_msg);
+ let events = nodes[1].node.get_and_clear_pending_events();
+ match events[0] {
+ Event::OpenChannelRequest { temporary_channel_id, .. } => {
+ nodes[1].node.accept_inbound_channel_from_trusted_peer_0conf(&temporary_channel_id, &last_random_pk, 23).unwrap();
+ }
+ _ => panic!("Unexpected event"),
+ }
+ get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, last_random_pk);
+ }
+
+ #[test]
+ fn reject_excessively_underpaying_htlcs() {
+ let chanmon_cfg = create_chanmon_cfgs(1);
+ let node_cfg = create_node_cfgs(1, &chanmon_cfg);
+ let node_chanmgr = create_node_chanmgrs(1, &node_cfg, &[None]);
+ let node = create_network(1, &node_cfg, &node_chanmgr);
+ let sender_intended_amt_msat = 100;
+ let extra_fee_msat = 10;
+ let hop_data = msgs::InboundOnionPayload::Receive {
+ amt_msat: 100,
+ outgoing_cltv_value: 42,
+ payment_metadata: None,
+ keysend_preimage: None,
+ payment_data: Some(msgs::FinalOnionHopData {
+ payment_secret: PaymentSecret([0; 32]), total_msat: sender_intended_amt_msat,
+ }),
+ };
+ // Check that if the amount we received + the penultimate hop extra fee is less than the sender
+ // intended amount, we fail the payment.
+ if let Err(crate::ln::channelmanager::InboundOnionErr { err_code, .. }) =
+ node[0].node.construct_recv_pending_htlc_info(hop_data, [0; 32], PaymentHash([0; 32]),
+ sender_intended_amt_msat - extra_fee_msat - 1, 42, None, true, Some(extra_fee_msat))
+ {
+ assert_eq!(err_code, 19);
+ } else { panic!(); }
+
+ // If amt_received + extra_fee is equal to the sender intended amount, we're fine.
+ let hop_data = msgs::InboundOnionPayload::Receive { // This is the same payload as above, InboundOnionPayload doesn't implement Clone
+ amt_msat: 100,
+ outgoing_cltv_value: 42,
+ payment_metadata: None,
+ keysend_preimage: None,
+ payment_data: Some(msgs::FinalOnionHopData {
+ payment_secret: PaymentSecret([0; 32]), total_msat: sender_intended_amt_msat,
+ }),
+ };
+ assert!(node[0].node.construct_recv_pending_htlc_info(hop_data, [0; 32], PaymentHash([0; 32]),
+ sender_intended_amt_msat - extra_fee_msat, 42, None, true, Some(extra_fee_msat)).is_ok());
+ }
+
+ #[test]
+ fn test_inbound_anchors_manual_acceptance() {
+ // Tests that we properly limit inbound channels when we have the manual-channel-acceptance
+ // flag set and (sometimes) accept channels as 0conf.
+ let mut anchors_cfg = test_default_channel_config();
+ anchors_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
+
+ let mut anchors_manual_accept_cfg = anchors_cfg.clone();
+ anchors_manual_accept_cfg.manually_accept_inbound_channels = true;
+
+ let chanmon_cfgs = create_chanmon_cfgs(3);
+ let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
+ let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs,
+ &[Some(anchors_cfg.clone()), Some(anchors_cfg.clone()), Some(anchors_manual_accept_cfg.clone())]);
+ let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+ nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None).unwrap();
+ let open_channel_msg = 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_msg);
+ assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
+ let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
+ match &msg_events[0] {
+ MessageSendEvent::HandleError { node_id, action } => {
+ assert_eq!(*node_id, nodes[0].node.get_our_node_id());
+ match action {
+ ErrorAction::SendErrorMessage { msg } =>
+ assert_eq!(msg.data, "No channels with anchor outputs accepted".to_owned()),
+ _ => panic!("Unexpected error action"),
+ }
+ }
+ _ => panic!("Unexpected event"),
+ }
+
+ nodes[2].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
+ let events = nodes[2].node.get_and_clear_pending_events();
+ match events[0] {
+ Event::OpenChannelRequest { temporary_channel_id, .. } =>
+ nodes[2].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 23).unwrap(),
+ _ => panic!("Unexpected event"),
+ }
+ get_event_msg!(nodes[2], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
+ }
+