Test fixed channel reserve checks on channel open 2021-11-fix-accept-chan-checks
authorMatt Corallo <git@bluematt.me>
Wed, 10 Nov 2021 04:40:33 +0000 (04:40 +0000)
committerMatt Corallo <git@bluematt.me>
Tue, 23 Nov 2021 01:20:43 +0000 (01:20 +0000)
lightning/src/ln/functional_tests.rs
lightning/src/ln/script.rs
lightning/src/util/errors.rs

index c593d7af8329fe7ac7e1e7bf9e0a60022abfc48a..520a86f4caa7fc02bf0ee8e9a5bc4ead794aa971 100644 (file)
@@ -1560,6 +1560,41 @@ fn test_chan_reserve_dust_inbound_htlcs_outbound_chan() {
                assert_eq!(err, "Cannot send value that would put counterparty balance under holder-announced channel reserve value"));
 }
 
+#[test]
+fn test_chan_init_feerate_unaffordability() {
+       // Test that we will reject channel opens which do not leave enough to pay for any HTLCs due to
+       // channel reserve and feerate requirements.
+       let mut chanmon_cfgs = create_chanmon_cfgs(2);
+       let feerate_per_kw = *chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+       let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       // Set the push_msat amount such that nodes[0] will not be able to afford to add even a single
+       // HTLC.
+       let mut push_amt = 100_000_000;
+       push_amt -= commit_tx_fee_msat(feerate_per_kw, MIN_AFFORDABLE_HTLC_COUNT as u64);
+       assert_eq!(nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, push_amt + 1, 42, None).unwrap_err(),
+               APIError::APIMisuseError { err: "Funding amount (356) can't even pay fee for initial commitment transaction fee of 357.".to_string() });
+
+       // During open, we don't have a "counterparty channel reserve" to check against, so that
+       // requirement only comes into play on the open_channel handling side.
+       push_amt -= Channel::<EnforcingSigner>::get_holder_selected_channel_reserve_satoshis(100_000) * 1000;
+       nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, push_amt, 42, None).unwrap();
+       let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+       open_channel_msg.push_msat += 1;
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_channel_msg);
+
+       let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(msg_events.len(), 1);
+       match msg_events[0] {
+               MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id: _ } => {
+                       assert_eq!(msg.data, "Insufficient funding amount for initial reserve");
+               },
+               _ => panic!("Unexpected event"),
+       }
+}
+
 #[test]
 fn test_chan_reserve_dust_inbound_htlcs_inbound_chan() {
        // Test that if we receive many dust HTLCs over an inbound channel, they don't count when
index 00ad48bb1e31c07cf695f52282ea2b746cf05455..0c060e4523374b71f569c5a4338d617177dfe6ba 100644 (file)
@@ -17,7 +17,7 @@ use io;
 /// A script pubkey for shutting down a channel as defined by [BOLT #2].
 ///
 /// [BOLT #2]: https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct ShutdownScript(ShutdownScriptImpl);
 
 /// An error occurring when converting from [`Script`] to [`ShutdownScript`].
@@ -29,7 +29,7 @@ pub struct InvalidShutdownScript {
        pub script: Script
 }
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 enum ShutdownScriptImpl {
        /// [`PublicKey`] used to form a P2WPKH script pubkey. Used to support backward-compatible
        /// serialization.
index 94ad965667873aa0b8f66d2e06427a491547e611..6495d9de4ed5363fb4a2b70c958366653797121c 100644 (file)
@@ -16,7 +16,7 @@ use core::fmt;
 
 /// Indicates an error on the client's part (usually some variant of attempting to use too-low or
 /// too-high values)
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub enum APIError {
        /// Indicates the API was wholly misused (see err for more). Cases where these can be returned
        /// are documented, but generally indicates some precondition of a function was violated.