Merge pull request #1526 from tnull/2022-06-fix-minimal-value-contrib
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Mon, 13 Jun 2022 17:50:19 +0000 (10:50 -0700)
committerGitHub <noreply@github.com>
Mon, 13 Jun 2022 17:50:19 +0000 (10:50 -0700)
Fix per-path minimal value contribution during route finding

23 files changed:
.github/workflows/build.yml
CHANGELOG.md
fuzz/src/chanmon_consistency.rs
fuzz/src/full_stack.rs
lightning-background-processor/Cargo.toml
lightning-background-processor/src/lib.rs
lightning-block-sync/Cargo.toml
lightning-invoice/Cargo.toml
lightning-invoice/src/utils.rs
lightning-net-tokio/Cargo.toml
lightning-persister/Cargo.toml
lightning-rapid-gossip-sync/Cargo.toml
lightning/Cargo.toml
lightning/src/ln/chanmon_update_fail_tests.rs
lightning/src/ln/channel.rs
lightning/src/ln/features.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/onion_route_tests.rs
lightning/src/ln/payment_tests.rs
lightning/src/ln/priv_short_conf_tests.rs
lightning/src/ln/shutdown_tests.rs
lightning/src/util/config.rs

index 59a11b4e4a11efc7788b51fe04ad664ca15da7f9..68cf376235f7edcb1e812da6027da9e608e97ed2 100644 (file)
@@ -275,6 +275,27 @@ jobs:
       - name: For each commit, run cargo check (including in fuzz)
         run: ci/check-each-commit.sh upstream/main
 
+  check_release:
+    runs-on: ubuntu-latest
+    env:
+      TOOLCHAIN: stable
+    steps:
+      - name: Checkout source code
+        uses: actions/checkout@v3
+        with:
+          fetch-depth: 0
+      - name: Install Rust ${{ env.TOOLCHAIN }} toolchain
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: ${{ env.TOOLCHAIN }}
+          override: true
+          profile: minimal
+      - name: Run cargo check for release build.
+        run: |
+          cargo check --release
+          cargo check --no-default-features --features=no-std --release
+          cargo doc --release
+
   fuzz:
     runs-on: ubuntu-latest
     env:
index 1cae3010f4e3c62143a6ab04d23e8200875c5d71..62b96df13d3b732b7a1d3ebaf6934389dcfb2b17 100644 (file)
@@ -1,3 +1,15 @@
+# 0.0.108 - 2022-06-10
+
+## Bug Fixes
+ * Fixed `lightning-background-processor` build in release mode.
+
+In total, this release features 9 files changed, 120 insertions, 74
+deletions in 5 commits from 4 authors, in alphabetical order:
+ * Elias Rohrer
+ * Matt Corallo
+ * Max Fang
+ * Viktor Tigerström
+
 # 0.0.107 - 2022-06-08
 
 ## API Updates
index 9625677c263378f3a9eed66be03e78989def25d4..8e70ba42eafecb63034678dd18a9ca2cb727f8c0 100644 (file)
@@ -357,7 +357,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
 
                        let mut config = UserConfig::default();
                        config.channel_options.forwarding_fee_proportional_millionths = 0;
-                       config.channel_options.announced_channel = true;
+                       config.own_channel_config.announced_channel = true;
                        let network = Network::Bitcoin;
                        let params = ChainParameters {
                                network,
@@ -377,7 +377,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
 
                        let mut config = UserConfig::default();
                        config.channel_options.forwarding_fee_proportional_millionths = 0;
-                       config.channel_options.announced_channel = true;
+                       config.own_channel_config.announced_channel = true;
 
                        let mut monitors = HashMap::new();
                        let mut old_monitors = $old_monitors.latest_monitors.lock().unwrap();
index eb270f6794d60b52eb19e5fce6765f9724e87312..782457cfe3d92dd47756fac47d0289ce98a44a74 100644 (file)
@@ -383,7 +383,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
        let keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone(), inbound_payment_key: KeyMaterial(inbound_payment_key.try_into().unwrap()), counter: AtomicU64::new(0) });
        let mut config = UserConfig::default();
        config.channel_options.forwarding_fee_proportional_millionths =  slice_to_be32(get_slice!(4));
-       config.channel_options.announced_channel = get_slice!(1)[0] != 0;
+       config.own_channel_config.announced_channel = get_slice!(1)[0] != 0;
        let network = Network::Bitcoin;
        let params = ChainParameters {
                network,
index 7f8fff7bb5cced1c592c1bc6b0d554770e4a0b4b..4833822f89efb1398b5cc62b30497f1dafe98a83 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning-background-processor"
-version = "0.0.107"
+version = "0.0.108"
 authors = ["Valentine Wallace <vwallace@protonmail.com>"]
 license = "MIT OR Apache-2.0"
 repository = "http://github.com/lightningdevkit/rust-lightning"
@@ -15,10 +15,10 @@ rustdoc-args = ["--cfg", "docsrs"]
 
 [dependencies]
 bitcoin = "0.28.1"
-lightning = { version = "0.0.107", path = "../lightning", features = ["std"] }
-lightning-rapid-gossip-sync = { version = "0.0.107", path = "../lightning-rapid-gossip-sync" }
+lightning = { version = "0.0.108", path = "../lightning", features = ["std"] }
+lightning-rapid-gossip-sync = { version = "0.0.108", path = "../lightning-rapid-gossip-sync" }
 
 [dev-dependencies]
-lightning = { version = "0.0.107", path = "../lightning", features = ["_test_utils"] }
-lightning-invoice = { version = "0.15.0", path = "../lightning-invoice" }
-lightning-persister = { version = "0.0.107", path = "../lightning-persister" }
+lightning = { version = "0.0.108", path = "../lightning", features = ["_test_utils"] }
+lightning-invoice = { version = "0.16.0", path = "../lightning-invoice" }
+lightning-persister = { version = "0.0.108", path = "../lightning-persister" }
index b2edc2301efda2b39224cf557b82b313ef46890f..bd9fde888050ad78f86e9d6e8c8284cf751db6f2 100644 (file)
@@ -79,7 +79,7 @@ const PING_TIMER: u64 = 1;
 /// Prune the network graph of stale entries hourly.
 const NETWORK_PRUNE_TIMER: u64 = 60 * 60;
 
-#[cfg(all(not(test), debug_assertions))]
+#[cfg(not(test))]
 const SCORER_PERSIST_TIMER: u64 = 30;
 #[cfg(test)]
 const SCORER_PERSIST_TIMER: u64 = 1;
index f67364807d958e73903b2755aaf5f3e7b6c0bc30..1358370d3db0e090c12d06c59aab87eb0aadd9c7 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning-block-sync"
-version = "0.0.107"
+version = "0.0.108"
 authors = ["Jeffrey Czyz", "Matt Corallo"]
 license = "MIT OR Apache-2.0"
 repository = "http://github.com/lightningdevkit/rust-lightning"
@@ -19,7 +19,7 @@ rpc-client = [ "serde", "serde_json", "chunked_transfer" ]
 
 [dependencies]
 bitcoin = "0.28.1"
-lightning = { version = "0.0.107", path = "../lightning" }
+lightning = { version = "0.0.108", path = "../lightning" }
 futures = { version = "0.3" }
 tokio = { version = "1.0", features = [ "io-util", "net", "time" ], optional = true }
 serde = { version = "1.0", features = ["derive"], optional = true }
index 7f3d14391d4650edc859b76c075654c2df976377..85cf1b3fea14a478cad116c5893c02f4483d4aec 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "lightning-invoice"
 description = "Data structures to parse and serialize BOLT11 lightning invoices"
-version = "0.15.0"
+version = "0.16.0"
 authors = ["Sebastian Geisler <sgeisler@wh2.tu-dresden.de>"]
 documentation = "https://docs.rs/lightning-invoice/"
 license = "MIT OR Apache-2.0"
@@ -20,7 +20,7 @@ std = ["bitcoin_hashes/std", "num-traits/std", "lightning/std", "bech32/std"]
 
 [dependencies]
 bech32 = { version = "0.8", default-features = false }
-lightning = { version = "0.0.107", path = "../lightning", default-features = false }
+lightning = { version = "0.0.108", path = "../lightning", default-features = false }
 secp256k1 = { version = "0.22", default-features = false, features = ["recovery", "alloc"] }
 num-traits = { version = "0.2.8", default-features = false }
 bitcoin_hashes = { version = "0.10", default-features = false }
@@ -28,5 +28,5 @@ hashbrown = { version = "0.11", optional = true }
 core2 = { version = "0.3.0", default-features = false, optional = true }
 
 [dev-dependencies]
-lightning = { version = "0.0.107", path = "../lightning", default-features = false, features = ["_test_utils"] }
+lightning = { version = "0.0.108", path = "../lightning", default-features = false, features = ["_test_utils"] }
 hex = "0.4"
index d42bc503f05df6679db447ac0ddf9c29ee927320..c79e590450a2dbda227db5aedc6645607c9b555c 100644 (file)
@@ -659,7 +659,7 @@ mod test {
                // `msgs::ChannelUpdate` is never handled for the node(s). As the `msgs::ChannelUpdate`
                // is never handled, the `channel.counterparty.forwarding_info` is never assigned.
                let mut private_chan_cfg = UserConfig::default();
-               private_chan_cfg.channel_options.announced_channel = false;
+               private_chan_cfg.own_channel_config.announced_channel = false;
                let temporary_channel_id = nodes[2].node.create_channel(nodes[0].node.get_our_node_id(), 1_000_000, 500_000_000, 42, Some(private_chan_cfg)).unwrap();
                let open_channel = get_event_msg!(nodes[2], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
                nodes[0].node.handle_open_channel(&nodes[2].node.get_our_node_id(), InitFeatures::known(), &open_channel);
@@ -1046,7 +1046,7 @@ mod test {
                // `msgs::ChannelUpdate` is never handled for the node(s). As the `msgs::ChannelUpdate`
                // is never handled, the `channel.counterparty.forwarding_info` is never assigned.
                let mut private_chan_cfg = UserConfig::default();
-               private_chan_cfg.channel_options.announced_channel = false;
+               private_chan_cfg.own_channel_config.announced_channel = false;
                let temporary_channel_id = nodes[1].node.create_channel(nodes[3].node.get_our_node_id(), 1_000_000, 500_000_000, 42, Some(private_chan_cfg)).unwrap();
                let open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[3].node.get_our_node_id());
                nodes[3].node.handle_open_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &open_channel);
index 24b9821b15cee0f4d0bb4d0f84703e6aed66d116..9f22e61140b19d860a8718c98c4a7eae99a8015c 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning-net-tokio"
-version = "0.0.107"
+version = "0.0.108"
 authors = ["Matt Corallo"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/lightningdevkit/rust-lightning/"
@@ -16,7 +16,7 @@ rustdoc-args = ["--cfg", "docsrs"]
 
 [dependencies]
 bitcoin = "0.28.1"
-lightning = { version = "0.0.107", path = "../lightning" }
+lightning = { version = "0.0.108", path = "../lightning" }
 tokio = { version = "1.0", features = [ "io-util", "macros", "rt", "sync", "net", "time" ] }
 
 [dev-dependencies]
index 1b62de987b743aa78a62e2a6a95a874ba4bbe893..4b4551182a84f961bd7e48f9ca2a5b3fc52f9d7b 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning-persister"
-version = "0.0.107"
+version = "0.0.108"
 authors = ["Valentine Wallace", "Matt Corallo"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/lightningdevkit/rust-lightning/"
@@ -17,11 +17,11 @@ _bench_unstable = ["lightning/_bench_unstable"]
 
 [dependencies]
 bitcoin = "0.28.1"
-lightning = { version = "0.0.107", path = "../lightning" }
+lightning = { version = "0.0.108", path = "../lightning" }
 libc = "0.2"
 
 [target.'cfg(windows)'.dependencies]
 winapi = { version = "0.3", features = ["winbase"] }
 
 [dev-dependencies]
-lightning = { version = "0.0.107", path = "../lightning", features = ["_test_utils"] }
+lightning = { version = "0.0.108", path = "../lightning", features = ["_test_utils"] }
index 734749caec53d0174fba5bef0d9bd7183442855b..a65e2853177e0828057355a14e0822b1010c6b15 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning-rapid-gossip-sync"
-version = "0.0.107"
+version = "0.0.108"
 authors = ["Arik Sosman <git@arik.io>"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/lightningdevkit/rust-lightning"
@@ -13,8 +13,8 @@ Utility to process gossip routing data from Rapid Gossip Sync Server.
 _bench_unstable = []
 
 [dependencies]
-lightning = { version = "0.0.107", path = "../lightning" }
+lightning = { version = "0.0.108", path = "../lightning" }
 bitcoin = { version = "0.28.1", default-features = false }
 
 [dev-dependencies]
-lightning = { version = "0.0.107", path = "../lightning", features = ["_test_utils"] }
+lightning = { version = "0.0.108", path = "../lightning", features = ["_test_utils"] }
index cec724cf6cd9fb9f8f4cb95808995705a374df05..b3e2af8c88eab1cde2a5e3441517e89cf4f40194 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning"
-version = "0.0.107"
+version = "0.0.108"
 authors = ["Matt Corallo"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/lightningdevkit/rust-lightning/"
index 495b507426c19bd7f31d6709da30db79c13f0dd9..710027706b066501c1b59e03a19967a869304599 100644 (file)
@@ -2541,7 +2541,7 @@ fn test_temporary_error_during_shutdown() {
        // Test that temporary failures when updating the monitor's shutdown script delay cooperative
        // close.
        let mut config = test_default_channel_config();
-       config.channel_options.commit_upfront_shutdown_pubkey = false;
+       config.own_channel_config.commit_upfront_shutdown_pubkey = false;
 
        let chanmon_cfgs = create_chanmon_cfgs(2);
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
@@ -2596,7 +2596,7 @@ fn test_permanent_error_during_sending_shutdown() {
        // Test that permanent failures when updating the monitor's shutdown script result in a force
        // close when initiating a cooperative close.
        let mut config = test_default_channel_config();
-       config.channel_options.commit_upfront_shutdown_pubkey = false;
+       config.own_channel_config.commit_upfront_shutdown_pubkey = false;
 
        let chanmon_cfgs = create_chanmon_cfgs(2);
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
@@ -2617,7 +2617,7 @@ fn test_permanent_error_during_handling_shutdown() {
        // Test that permanent failures when updating the monitor's shutdown script result in a force
        // close when handling a cooperative close.
        let mut config = test_default_channel_config();
-       config.channel_options.commit_upfront_shutdown_pubkey = false;
+       config.own_channel_config.commit_upfront_shutdown_pubkey = false;
 
        let chanmon_cfgs = create_chanmon_cfgs(2);
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
index 9737738afb5ae653cf63b035820a9740a674392b..f50865dc4af22044d9eaabedf560c1da845d98b4 100644 (file)
@@ -39,7 +39,7 @@ use util::events::ClosureReason;
 use util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
 use util::logger::Logger;
 use util::errors::APIError;
-use util::config::{UserConfig, ChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits};
+use util::config::{UserConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits};
 use util::scid_utils::scid_from_parts;
 
 use io;
@@ -491,9 +491,9 @@ pub(crate) const MIN_AFFORDABLE_HTLC_COUNT: usize = 4;
 // Counterparty designates channel data owned by the another channel participant entity.
 pub(super) struct Channel<Signer: Sign> {
        #[cfg(any(test, feature = "_test_utils"))]
-       pub(crate) config: ChannelConfig,
+       pub(crate) config: LegacyChannelConfig,
        #[cfg(not(any(test, feature = "_test_utils")))]
-       config: ChannelConfig,
+       config: LegacyChannelConfig,
 
        inbound_handshake_limits_override: Option<ChannelHandshakeLimits>,
 
@@ -855,7 +855,7 @@ impl<Signer: Sign> Channel<Signer> {
                // available. If it's private, we first try `scid_privacy` as it provides better privacy
                // with no other changes, and fall back to `only_static_remotekey`
                let mut ret = ChannelTypeFeatures::only_static_remote_key();
-               if !config.channel_options.announced_channel && config.own_channel_config.negotiate_scid_privacy {
+               if !config.own_channel_config.announced_channel && config.own_channel_config.negotiate_scid_privacy {
                        ret.set_scid_privacy_required();
                }
                ret
@@ -918,7 +918,7 @@ impl<Signer: Sign> Channel<Signer> {
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
 
-               let shutdown_scriptpubkey = if config.channel_options.commit_upfront_shutdown_pubkey {
+               let shutdown_scriptpubkey = if config.own_channel_config.commit_upfront_shutdown_pubkey {
                        Some(keys_provider.get_shutdown_scriptpubkey())
                } else { None };
 
@@ -930,7 +930,13 @@ impl<Signer: Sign> Channel<Signer> {
 
                Ok(Channel {
                        user_id,
-                       config: config.channel_options.clone(),
+
+                       config: LegacyChannelConfig {
+                               mutable: config.channel_options.clone(),
+                               announced_channel: config.own_channel_config.announced_channel,
+                               commit_upfront_shutdown_pubkey: config.own_channel_config.commit_upfront_shutdown_pubkey,
+                       },
+
                        inbound_handshake_limits_override: Some(config.peer_channel_config_limits.clone()),
 
                        channel_id: keys_provider.get_secure_random_bytes(),
@@ -1117,7 +1123,6 @@ impl<Signer: Sign> Channel<Signer> {
                        delayed_payment_basepoint: msg.delayed_payment_basepoint,
                        htlc_basepoint: msg.htlc_basepoint
                };
-               let mut local_config = (*config).channel_options.clone();
 
                if config.own_channel_config.our_to_self_delay < BREAKDOWN_TIMEOUT {
                        return Err(ChannelError::Close(format!("Configured with an unreasonable our_to_self_delay ({}) putting user funds at risks. It must be greater than {}", config.own_channel_config.our_to_self_delay, BREAKDOWN_TIMEOUT)));
@@ -1182,12 +1187,10 @@ impl<Signer: Sign> Channel<Signer> {
                // Convert things into internal flags and prep our state:
 
                if config.peer_channel_config_limits.force_announced_channel_preference {
-                       if local_config.announced_channel != announced_channel {
+                       if config.own_channel_config.announced_channel != announced_channel {
                                return Err(ChannelError::Close("Peer tried to open channel but their announcement preference is different from ours".to_owned()));
                        }
                }
-               // we either accept their preference or the preferences match
-               local_config.announced_channel = announced_channel;
 
                let holder_selected_channel_reserve_satoshis = Channel::<Signer>::get_holder_selected_channel_reserve_satoshis(msg.funding_satoshis);
                if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
@@ -1239,7 +1242,7 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                } else { None };
 
-               let shutdown_scriptpubkey = if config.channel_options.commit_upfront_shutdown_pubkey {
+               let shutdown_scriptpubkey = if config.own_channel_config.commit_upfront_shutdown_pubkey {
                        Some(keys_provider.get_shutdown_scriptpubkey())
                } else { None };
 
@@ -1254,7 +1257,13 @@ impl<Signer: Sign> Channel<Signer> {
 
                let chan = Channel {
                        user_id,
-                       config: local_config,
+
+                       config: LegacyChannelConfig {
+                               mutable: config.channel_options.clone(),
+                               announced_channel,
+                               commit_upfront_shutdown_pubkey: config.own_channel_config.commit_upfront_shutdown_pubkey,
+                       },
+
                        inbound_handshake_limits_override: None,
 
                        channel_id: msg.temporary_channel_id,
@@ -4011,7 +4020,7 @@ impl<Signer: Sign> Channel<Signer> {
                                // We always add force_close_avoidance_max_fee_satoshis to our normal
                                // feerate-calculated fee, but allow the max to be overridden if we're using a
                                // target feerate-calculated fee.
-                               cmp::max(normal_feerate as u64 * tx_weight / 1000 + self.config.force_close_avoidance_max_fee_satoshis,
+                               cmp::max(normal_feerate as u64 * tx_weight / 1000 + self.config.mutable.force_close_avoidance_max_fee_satoshis,
                                        proposed_max_feerate as u64 * tx_weight / 1000)
                        } else {
                                self.channel_value_satoshis - (self.value_to_self_msat + 999) / 1000
@@ -4471,15 +4480,15 @@ impl<Signer: Sign> Channel<Signer> {
        }
 
        pub fn get_fee_proportional_millionths(&self) -> u32 {
-               self.config.forwarding_fee_proportional_millionths
+               self.config.mutable.forwarding_fee_proportional_millionths
        }
 
        pub fn get_cltv_expiry_delta(&self) -> u16 {
-               cmp::max(self.config.cltv_expiry_delta, MIN_CLTV_EXPIRY_DELTA)
+               cmp::max(self.config.mutable.cltv_expiry_delta, MIN_CLTV_EXPIRY_DELTA)
        }
 
        pub fn get_max_dust_htlc_exposure_msat(&self) -> u64 {
-               self.config.max_dust_htlc_exposure_msat
+               self.config.mutable.max_dust_htlc_exposure_msat
        }
 
        pub fn get_feerate(&self) -> u32 {
@@ -4566,7 +4575,7 @@ impl<Signer: Sign> Channel<Signer> {
        /// Gets the fee we'd want to charge for adding an HTLC output to this Channel
        /// Allowed in any state (including after shutdown)
        pub fn get_outbound_forwarding_fee_base_msat(&self) -> u32 {
-               self.config.forwarding_fee_base_msat
+               self.config.mutable.forwarding_fee_base_msat
        }
 
        /// Returns true if we've ever received a message from the remote end for this Channel
@@ -6030,11 +6039,11 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
 
                let user_id = Readable::read(reader)?;
 
-               let mut config = Some(ChannelConfig::default());
+               let mut config = Some(LegacyChannelConfig::default());
                if ver == 1 {
                        // Read the old serialization of the ChannelConfig from version 0.0.98.
-                       config.as_mut().unwrap().forwarding_fee_proportional_millionths = Readable::read(reader)?;
-                       config.as_mut().unwrap().cltv_expiry_delta = Readable::read(reader)?;
+                       config.as_mut().unwrap().mutable.forwarding_fee_proportional_millionths = Readable::read(reader)?;
+                       config.as_mut().unwrap().mutable.cltv_expiry_delta = Readable::read(reader)?;
                        config.as_mut().unwrap().announced_channel = Readable::read(reader)?;
                        config.as_mut().unwrap().commit_upfront_shutdown_pubkey = Readable::read(reader)?;
                } else {
@@ -6926,7 +6935,7 @@ mod tests {
 
                let counterparty_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let mut config = UserConfig::default();
-               config.channel_options.announced_channel = false;
+               config.own_channel_config.announced_channel = false;
                let mut chan = Channel::<InMemorySigner>::new_outbound(&&feeest, &&keys_provider, counterparty_node_id, &InitFeatures::known(), 10_000_000, 100000, 42, &config, 0, 42).unwrap(); // Nothing uses their network key in this test
                chan.holder_dust_limit_satoshis = 546;
                chan.counterparty_selected_channel_reserve_satoshis = Some(0); // Filled in in accept_channel
index 775e070ed76798d4082a77e097fb0d770568b3b0..dbc17a34138b04b59ca9207b574494c9a8485009 100644 (file)
 //! supports a feature if it advertises the feature (as either required or optional) to its peers.
 //! And the implementation can interpret a feature if the feature is known to it.
 //!
+//! The following features are currently required in the LDK:
+//! - `VariableLengthOnion` - requires/supports variable-length routing onion payloads
+//!     (see [BOLT-4](https://github.com/lightning/bolts/blob/master/04-onion-routing.md) for more information).
+//! - `StaticRemoteKey` - requires/supports static key for remote output
+//!     (see [BOLT-3](https://github.com/lightning/bolts/blob/master/03-transactions.md) for more information).
+//!
+//! The following features are currently supported in the LDK:
+//! - `DataLossProtect` - requires/supports that a node which has somehow fallen behind, e.g., has been restored from an old backup,
+//!     can detect that it has fallen behind
+//!     (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md) for more information).
+//! - `InitialRoutingSync` - requires/supports that the sending node needs a complete routing information dump
+//!     (see [BOLT-7](https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#initial-sync) for more information).
+//! - `UpfrontShutdownScript` - commits to a shutdown scriptpubkey when opening a channel
+//!     (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-open_channel-message) for more information).
+//! - `GossipQueries` - requires/supports more sophisticated gossip control
+//!     (see [BOLT-7](https://github.com/lightning/bolts/blob/master/07-routing-gossip.md) for more information).
+//! - `PaymentSecret` - requires/supports that a node supports payment_secret field
+//!     (see [BOLT-4](https://github.com/lightning/bolts/blob/master/04-onion-routing.md) for more information).
+//! - `BasicMPP` - requires/supports that a node can receive basic multi-part payments
+//!     (see [BOLT-4](https://github.com/lightning/bolts/blob/master/04-onion-routing.md#basic-multi-part-payments) for more information).
+//! - `ShutdownAnySegwit` - requires/supports that future segwit versions are allowed in `shutdown`
+//!     (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md) for more information).
+//! - `ChannelType` - node supports the channel_type field in open/accept
+//!     (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md) for more information).
+//! - `SCIDPrivacy` - supply channel aliases for routing
+//!     (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md) for more information).
+//! - `Keysend` - send funds to a node without an invoice
+//!     (see the [`Keysend` feature assignment proposal](https://github.com/lightning/bolts/issues/605#issuecomment-606679798) for more information).
+//!
 //! [BOLT #9]: https://github.com/lightning/bolts/blob/master/09-features.md
 //! [messages]: crate::ln::msgs
 
index 0873127179f82a9060c716b7429b7e69957419e5..4b00c9b798f45e4b788da8ee213ed3a069ae6ccd 100644 (file)
@@ -15,7 +15,7 @@ use chain::channelmonitor::ChannelMonitor;
 use chain::transaction::OutPoint;
 use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA};
-use routing::gossip::{P2PGossipSync, NetworkGraph};
+use routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
 use routing::router::{PaymentParameters, Route, get_route};
 use ln::features::{InitFeatures, InvoiceFeatures};
 use ln::msgs;
@@ -772,7 +772,7 @@ pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a
 
 pub fn create_unannounced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize, channel_value: u64, push_msat: u64, a_flags: InitFeatures, b_flags: InitFeatures) -> (msgs::ChannelReady, Transaction) {
        let mut no_announce_cfg = test_default_channel_config();
-       no_announce_cfg.channel_options.announced_channel = false;
+       no_announce_cfg.own_channel_config.announced_channel = false;
        nodes[a].node.create_channel(nodes[b].node.get_our_node_id(), channel_value, push_msat, 42, Some(no_announce_cfg)).unwrap();
        let open_channel = get_event_msg!(nodes[a], MessageSendEvent::SendOpenChannel, nodes[b].node.get_our_node_id());
        nodes[b].node.handle_open_channel(&nodes[a].node.get_our_node_id(), a_flags, &open_channel);
@@ -1466,8 +1466,10 @@ impl<'a> PaymentFailedConditions<'a> {
 #[cfg(test)]
 macro_rules! expect_payment_failed_with_update {
        ($node: expr, $expected_payment_hash: expr, $rejected_by_dest: expr, $scid: expr, $chan_closed: expr) => {
-               expect_payment_failed_conditions!($node, $expected_payment_hash, $rejected_by_dest,
-                       $crate::ln::functional_test_utils::PaymentFailedConditions::new().blamed_scid($scid).blamed_chan_closed($chan_closed));
+               $crate::ln::functional_test_utils::expect_payment_failed_conditions(
+                       &$node, $expected_payment_hash, $rejected_by_dest,
+                       $crate::ln::functional_test_utils::PaymentFailedConditions::new()
+                               .blamed_scid($scid).blamed_chan_closed($chan_closed));
        }
 }
 
@@ -1479,64 +1481,72 @@ macro_rules! expect_payment_failed {
                $(
                        conditions = conditions.expected_htlc_error_data($expected_error_code, &$expected_error_data);
                )*
-               expect_payment_failed_conditions!($node, $expected_payment_hash, $rejected_by_dest, conditions);
+               $crate::ln::functional_test_utils::expect_payment_failed_conditions(&$node, $expected_payment_hash, $rejected_by_dest, conditions);
        };
 }
 
-#[cfg(test)]
-macro_rules! expect_payment_failed_conditions {
-       ($node: expr, $expected_payment_hash: expr, $rejected_by_dest: expr, $conditions: expr) => {
-               let events = $node.node.get_and_clear_pending_events();
-               assert_eq!(events.len(), 1);
-               let expected_payment_id = match events[0] {
-                       Event::PaymentPathFailed { ref payment_hash, rejected_by_dest, ref error_code, ref error_data, ref path, ref retry, ref payment_id, ref network_update, .. } => {
-                               assert_eq!(*payment_hash, $expected_payment_hash, "unexpected payment_hash");
-                               assert_eq!(rejected_by_dest, $rejected_by_dest, "unexpected rejected_by_dest value");
-                               assert!(retry.is_some(), "expected retry.is_some()");
-                               assert_eq!(retry.as_ref().unwrap().final_value_msat, path.last().unwrap().fee_msat, "Retry amount should match last hop in path");
-                               assert_eq!(retry.as_ref().unwrap().payment_params.payee_pubkey, path.last().unwrap().pubkey, "Retry payee node_id should match last hop in path");
-
+pub fn expect_payment_failed_conditions<'a, 'b, 'c, 'd, 'e>(
+       node: &'a Node<'b, 'c, 'd>, expected_payment_hash: PaymentHash, expected_rejected_by_dest: bool,
+       conditions: PaymentFailedConditions<'e>
+) {
+       let mut events = node.node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 1);
+       let expected_payment_id = match events.pop().unwrap() {
+               Event::PaymentPathFailed { payment_hash, rejected_by_dest, path, retry, payment_id, network_update,
+                       #[cfg(test)]
+                       error_code,
+                       #[cfg(test)]
+                       error_data, .. } => {
+                       assert_eq!(payment_hash, expected_payment_hash, "unexpected payment_hash");
+                       assert_eq!(rejected_by_dest, expected_rejected_by_dest, "unexpected rejected_by_dest value");
+                       assert!(retry.is_some(), "expected retry.is_some()");
+                       assert_eq!(retry.as_ref().unwrap().final_value_msat, path.last().unwrap().fee_msat, "Retry amount should match last hop in path");
+                       assert_eq!(retry.as_ref().unwrap().payment_params.payee_pubkey, path.last().unwrap().pubkey, "Retry payee node_id should match last hop in path");
+
+                       #[cfg(test)]
+                       {
                                assert!(error_code.is_some(), "expected error_code.is_some() = true");
                                assert!(error_data.is_some(), "expected error_data.is_some() = true");
-                               if let Some((code, data)) = $conditions.expected_htlc_error_data {
+                               if let Some((code, data)) = conditions.expected_htlc_error_data {
                                        assert_eq!(error_code.unwrap(), code, "unexpected error code");
                                        assert_eq!(&error_data.as_ref().unwrap()[..], data, "unexpected error data");
                                }
+                       }
 
-                               if let Some(chan_closed) = $conditions.expected_blamed_chan_closed {
-                                       match network_update {
-                                               &Some($crate::routing::gossip::NetworkUpdate::ChannelUpdateMessage { ref msg }) if !chan_closed => {
-                                                       if let Some(scid) = $conditions.expected_blamed_scid {
-                                                               assert_eq!(msg.contents.short_channel_id, scid);
-                                                       }
-                                                       assert_eq!(msg.contents.flags & 2, 0);
-                                               },
-                                               &Some($crate::routing::gossip::NetworkUpdate::ChannelFailure { short_channel_id, is_permanent }) if chan_closed => {
-                                                       if let Some(scid) = $conditions.expected_blamed_scid {
-                                                               assert_eq!(short_channel_id, scid);
-                                                       }
-                                                       assert!(is_permanent);
-                                               },
-                                               Some(_) => panic!("Unexpected update type"),
-                                               None => panic!("Expected update"),
-                                       }
+                       if let Some(chan_closed) = conditions.expected_blamed_chan_closed {
+                               match network_update {
+                                       Some(NetworkUpdate::ChannelUpdateMessage { ref msg }) if !chan_closed => {
+                                               if let Some(scid) = conditions.expected_blamed_scid {
+                                                       assert_eq!(msg.contents.short_channel_id, scid);
+                                               }
+                                               const CHAN_DISABLED_FLAG: u8 = 2;
+                                               assert_eq!(msg.contents.flags & CHAN_DISABLED_FLAG, 0);
+                                       },
+                                       Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent }) if chan_closed => {
+                                               if let Some(scid) = conditions.expected_blamed_scid {
+                                                       assert_eq!(short_channel_id, scid);
+                                               }
+                                               assert!(is_permanent);
+                                       },
+                                       Some(_) => panic!("Unexpected update type"),
+                                       None => panic!("Expected update"),
                                }
+                       }
 
-                               payment_id.unwrap()
-                       },
-                       _ => panic!("Unexpected event"),
-               };
-               if !$conditions.expected_mpp_parts_remain {
-                       $node.node.abandon_payment(expected_payment_id);
-                       let events = $node.node.get_and_clear_pending_events();
-                       assert_eq!(events.len(), 1);
-                       match events[0] {
-                               Event::PaymentFailed { ref payment_hash, ref payment_id } => {
-                                       assert_eq!(*payment_hash, $expected_payment_hash, "unexpected second payment_hash");
-                                       assert_eq!(*payment_id, expected_payment_id);
-                               }
-                               _ => panic!("Unexpected second event"),
+                       payment_id.unwrap()
+               },
+               _ => panic!("Unexpected event"),
+       };
+       if !conditions.expected_mpp_parts_remain {
+               node.node.abandon_payment(expected_payment_id);
+               let events = node.node.get_and_clear_pending_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       Event::PaymentFailed { ref payment_hash, ref payment_id } => {
+                               assert_eq!(*payment_hash, expected_payment_hash, "unexpected second payment_hash");
+                               assert_eq!(*payment_id, expected_payment_id);
                        }
+                       _ => panic!("Unexpected second event"),
                }
        }
 }
@@ -1679,7 +1689,9 @@ pub fn do_claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>,
                        ($node: expr, $prev_node: expr, $next_node: expr, $new_msgs: expr) => {
                                {
                                        $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
-                                       let fee = $node.node.channel_state.lock().unwrap().by_id.get(&next_msgs.as_ref().unwrap().0.channel_id).unwrap().config.forwarding_fee_base_msat;
+                                       let fee = $node.node.channel_state.lock().unwrap()
+                                               .by_id.get(&next_msgs.as_ref().unwrap().0.channel_id).unwrap()
+                                               .config.mutable.forwarding_fee_base_msat;
                                        expect_payment_forwarded!($node, $next_node, $prev_node, Some(fee as u64), false, false);
                                        expected_total_fee_msat += fee as u64;
                                        check_added_monitors!($node, 1);
@@ -1956,7 +1968,7 @@ pub fn test_default_channel_config() -> UserConfig {
        // Set cltv_expiry_delta slightly lower to keep the final CLTV values inside one byte in our
        // tests so that our script-length checks don't fail (see ACCEPTED_HTLC_SCRIPT_WEIGHT).
        default_config.channel_options.cltv_expiry_delta = MIN_CLTV_EXPIRY_DELTA;
-       default_config.channel_options.announced_channel = true;
+       default_config.own_channel_config.announced_channel = true;
        default_config.peer_channel_config_limits.force_announced_channel_preference = false;
        // When most of our tests were written, the default HTLC minimum was fixed at 1000.
        // It now defaults to 1, so we simply set it to the expected value here.
index 5a88d1b9efcd9792cf2c73db93d7b5fec8abb5ca..a716d80677c56a313b1e3fffef985a6a0eddfe89 100644 (file)
@@ -2362,11 +2362,11 @@ fn channel_monitor_network_test() {
 fn test_justice_tx() {
        // Test justice txn built on revoked HTLC-Success tx, against both sides
        let mut alice_config = UserConfig::default();
-       alice_config.channel_options.announced_channel = true;
+       alice_config.own_channel_config.announced_channel = true;
        alice_config.peer_channel_config_limits.force_announced_channel_preference = false;
        alice_config.own_channel_config.our_to_self_delay = 6 * 24 * 5;
        let mut bob_config = UserConfig::default();
-       bob_config.channel_options.announced_channel = true;
+       bob_config.own_channel_config.announced_channel = true;
        bob_config.peer_channel_config_limits.force_announced_channel_preference = false;
        bob_config.own_channel_config.our_to_self_delay = 6 * 24 * 3;
        let user_cfgs = [Some(alice_config), Some(bob_config)];
@@ -8282,16 +8282,16 @@ fn test_channel_update_has_correct_htlc_maximum_msat() {
        // 2. MUST be set to less than or equal to the `max_htlc_value_in_flight_msat` received from the peer.
 
        let mut config_30_percent = UserConfig::default();
-       config_30_percent.channel_options.announced_channel = true;
+       config_30_percent.own_channel_config.announced_channel = true;
        config_30_percent.own_channel_config.max_inbound_htlc_value_in_flight_percent_of_channel = 30;
        let mut config_50_percent = UserConfig::default();
-       config_50_percent.channel_options.announced_channel = true;
+       config_50_percent.own_channel_config.announced_channel = true;
        config_50_percent.own_channel_config.max_inbound_htlc_value_in_flight_percent_of_channel = 50;
        let mut config_95_percent = UserConfig::default();
-       config_95_percent.channel_options.announced_channel = true;
+       config_95_percent.own_channel_config.announced_channel = true;
        config_95_percent.own_channel_config.max_inbound_htlc_value_in_flight_percent_of_channel = 95;
        let mut config_100_percent = UserConfig::default();
-       config_100_percent.channel_options.announced_channel = true;
+       config_100_percent.own_channel_config.announced_channel = true;
        config_100_percent.own_channel_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100;
 
        let chanmon_cfgs = create_chanmon_cfgs(4);
@@ -9727,7 +9727,7 @@ fn do_test_dup_htlc_second_rejected(test_for_second_fail_panic: bool) {
                nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_updates_1.update_fail_htlcs[0]);
                commitment_signed_dance!(nodes[0], nodes[1], fail_updates_1.commitment_signed, false);
 
-               expect_payment_failed_conditions!(nodes[0], our_payment_hash, true, PaymentFailedConditions::new().mpp_parts_remain());
+               expect_payment_failed_conditions(&nodes[0], our_payment_hash, true, PaymentFailedConditions::new().mpp_parts_remain());
 
                claim_payment(&nodes[0], &[&nodes[1]], our_payment_preimage);
        }
@@ -9832,7 +9832,7 @@ fn test_inconsistent_mpp_params() {
        nodes[0].node.handle_update_fail_htlc(&nodes[2].node.get_our_node_id(), &fail_updates_2.update_fail_htlcs[0]);
        commitment_signed_dance!(nodes[0], nodes[2], fail_updates_2.commitment_signed, false);
 
-       expect_payment_failed_conditions!(nodes[0], our_payment_hash, true, PaymentFailedConditions::new().mpp_parts_remain());
+       expect_payment_failed_conditions(&nodes[0], our_payment_hash, true, PaymentFailedConditions::new().mpp_parts_remain());
 
        nodes[0].node.send_payment_along_path(&route.paths[1], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), 15_000_000, cur_height, payment_id, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
index eabd2222078b5a73c7456db15d65ff453a45ab05..51a3e048149a5b28ff966edf3c438e78efea61d8 100644 (file)
@@ -308,7 +308,7 @@ fn test_onion_failure() {
        // Channel::get_counterparty_htlc_minimum_msat().
        let mut node_2_cfg: UserConfig = Default::default();
        node_2_cfg.own_channel_config.our_htlc_minimum_msat = 2000;
-       node_2_cfg.channel_options.announced_channel = true;
+       node_2_cfg.own_channel_config.announced_channel = true;
        node_2_cfg.peer_channel_config_limits.force_announced_channel_preference = false;
 
        // When this test was written, the default base fee floated based on the HTLC count.
@@ -600,7 +600,7 @@ fn test_default_to_onion_payload_tlv_format() {
        // `features` for a node in the `network_graph` exists, or when the node isn't in the
        // `network_graph`, and no other known `features` for the node exists.
        let mut priv_channels_conf = UserConfig::default();
-       priv_channels_conf.channel_options.announced_channel = false;
+       priv_channels_conf.own_channel_config.announced_channel = false;
        let chanmon_cfgs = create_chanmon_cfgs(5);
        let node_cfgs = create_node_cfgs(5, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(5, &node_cfgs, &[None, None, None, None, Some(priv_channels_conf)]);
@@ -854,7 +854,7 @@ fn test_phantom_onion_hmac_failure() {
                .blamed_scid(phantom_scid)
                .blamed_chan_closed(true)
                .expected_htlc_error_data(0x8000 | 0x4000 | 5, &sha256_of_onion);
-       expect_payment_failed_conditions!(nodes[0], payment_hash, false, fail_conditions);
+       expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
 }
 
 #[test]
@@ -927,7 +927,7 @@ fn test_phantom_invalid_onion_payload() {
                .blamed_scid(phantom_scid)
                .blamed_chan_closed(true)
                .expected_htlc_error_data(0x4000 | 22, &error_data);
-       expect_payment_failed_conditions!(nodes[0], payment_hash, true, fail_conditions);
+       expect_payment_failed_conditions(&nodes[0], payment_hash, true, fail_conditions);
 }
 
 #[test]
@@ -983,7 +983,7 @@ fn test_phantom_final_incorrect_cltv_expiry() {
        let mut fail_conditions = PaymentFailedConditions::new()
                .blamed_scid(phantom_scid)
                .expected_htlc_error_data(18, &error_data);
-       expect_payment_failed_conditions!(nodes[0], payment_hash, false, fail_conditions);
+       expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
 }
 
 #[test]
@@ -1028,7 +1028,7 @@ fn test_phantom_failure_too_low_cltv() {
        let mut fail_conditions = PaymentFailedConditions::new()
                .blamed_scid(phantom_scid)
                .expected_htlc_error_data(17, &error_data);
-       expect_payment_failed_conditions!(nodes[0], payment_hash, false, fail_conditions);
+       expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
 }
 
 #[test]
@@ -1076,7 +1076,7 @@ fn test_phantom_failure_too_low_recv_amt() {
        let mut fail_conditions = PaymentFailedConditions::new()
                .blamed_scid(phantom_scid)
                .expected_htlc_error_data(0x4000 | 15, &error_data);
-       expect_payment_failed_conditions!(nodes[0], payment_hash, true, fail_conditions);
+       expect_payment_failed_conditions(&nodes[0], payment_hash, true, fail_conditions);
 }
 
 #[test]
@@ -1085,7 +1085,7 @@ fn test_phantom_dust_exposure_failure() {
        let max_dust_exposure = 546;
        let mut receiver_config = UserConfig::default();
        receiver_config.channel_options.max_dust_htlc_exposure_msat = max_dust_exposure;
-       receiver_config.channel_options.announced_channel = true;
+       receiver_config.own_channel_config.announced_channel = true;
 
        let chanmon_cfgs = create_chanmon_cfgs(2);
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
@@ -1123,7 +1123,7 @@ fn test_phantom_dust_exposure_failure() {
                .blamed_scid(channel.0.contents.short_channel_id)
                .blamed_chan_closed(false)
                .expected_htlc_error_data(0x1000 | 7, &err_data);
-               expect_payment_failed_conditions!(nodes[0], payment_hash, false, fail_conditions);
+               expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
 }
 
 #[test]
@@ -1174,5 +1174,5 @@ fn test_phantom_failure_reject_payment() {
        let mut fail_conditions = PaymentFailedConditions::new()
                .blamed_scid(phantom_scid)
                .expected_htlc_error_data(0x4000 | 15, &error_data);
-       expect_payment_failed_conditions!(nodes[0], payment_hash, true, fail_conditions);
+       expect_payment_failed_conditions(&nodes[0], payment_hash, true, fail_conditions);
 }
index 07e531c5b4b7e330b252414a89207ea70e698bc2..3d208dd29babdccc61a84b796cdb8d281723f000 100644 (file)
@@ -70,7 +70,7 @@ fn retry_single_path_payment() {
        check_added_monitors!(nodes[1], 1);
        nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &htlc_updates.update_fail_htlcs[0]);
        commitment_signed_dance!(nodes[0], nodes[1], htlc_updates.commitment_signed, false);
-       expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
+       expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
 
        // Rebalance the channel so the retry succeeds.
        send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000);
@@ -173,7 +173,7 @@ fn mpp_retry() {
        check_added_monitors!(nodes[2], 1);
        nodes[0].node.handle_update_fail_htlc(&nodes[2].node.get_our_node_id(), &htlc_updates.update_fail_htlcs[0]);
        commitment_signed_dance!(nodes[0], nodes[2], htlc_updates.commitment_signed, false);
-       expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
+       expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
 
        // Rebalance the channel so the second half of the payment can succeed.
        send_payment(&nodes[3], &vec!(&nodes[2])[..], 1_500_000);
@@ -251,7 +251,7 @@ fn do_mpp_receive_timeout(send_partial_mpp: bool) {
                check_added_monitors!(nodes[1], 1);
                commitment_signed_dance!(nodes[0], nodes[1], htlc_fail_updates_1_0.commitment_signed, false);
 
-               expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain().expected_htlc_error_data(23, &[][..]));
+               expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain().expected_htlc_error_data(23, &[][..]));
        } else {
                // Pass half of the payment along the second path.
                pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash, Some(payment_secret), events.remove(0), true, None);
@@ -521,7 +521,7 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
                confirm_transaction(&nodes[0], &first_htlc_timeout_tx);
        }
        nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clear();
-       expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
+       expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
 
        // Finally, retry the payment (which was reloaded from the ChannelMonitor when nodes[0] was
        // reloaded) via a route over the new channel, which work without issue and eventually be
@@ -531,7 +531,8 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
        // Update the fee on the middle hop to ensure PaymentSent events have the correct (retried) fee
        // and not the original fee. We also update node[1]'s relevant config as
        // do_claim_payment_along_route expects us to never overpay.
-       nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan_id_2).unwrap().config.forwarding_fee_base_msat += 100_000;
+       nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan_id_2).unwrap()
+               .config.mutable.forwarding_fee_base_msat += 100_000;
        new_route.paths[0][0].fee_msat += 100_000;
 
        assert!(nodes[0].node.retry_payment(&new_route, payment_id_1).is_err()); // Shouldn't be allowed to retry a fulfilled payment
index 051703a7fcc04b2121a82c207cb18bdd99829cb9..6b2a361244f03cc3ef43a0d231c6c0fc0544451d 100644 (file)
@@ -171,11 +171,11 @@ fn do_test_1_conf_open(connect_style: ConnectStyle) {
        // tests that we properly send one in that case.
        let mut alice_config = UserConfig::default();
        alice_config.own_channel_config.minimum_depth = 1;
-       alice_config.channel_options.announced_channel = true;
+       alice_config.own_channel_config.announced_channel = true;
        alice_config.peer_channel_config_limits.force_announced_channel_preference = false;
        let mut bob_config = UserConfig::default();
        bob_config.own_channel_config.minimum_depth = 1;
-       bob_config.channel_options.announced_channel = true;
+       bob_config.own_channel_config.announced_channel = true;
        bob_config.peer_channel_config_limits.force_announced_channel_preference = false;
        let chanmon_cfgs = create_chanmon_cfgs(2);
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
@@ -308,7 +308,7 @@ fn test_scid_privacy_on_pub_channel() {
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        let mut scid_privacy_cfg = test_default_channel_config();
-       scid_privacy_cfg.channel_options.announced_channel = true;
+       scid_privacy_cfg.own_channel_config.announced_channel = true;
        scid_privacy_cfg.own_channel_config.negotiate_scid_privacy = true;
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, Some(scid_privacy_cfg)).unwrap();
        let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
@@ -332,7 +332,7 @@ fn test_scid_privacy_negotiation() {
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        let mut scid_privacy_cfg = test_default_channel_config();
-       scid_privacy_cfg.channel_options.announced_channel = false;
+       scid_privacy_cfg.own_channel_config.announced_channel = false;
        scid_privacy_cfg.own_channel_config.negotiate_scid_privacy = true;
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, Some(scid_privacy_cfg)).unwrap();
 
@@ -378,7 +378,7 @@ fn test_inbound_scid_privacy() {
        create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, InitFeatures::known(), InitFeatures::known());
 
        let mut no_announce_cfg = test_default_channel_config();
-       no_announce_cfg.channel_options.announced_channel = false;
+       no_announce_cfg.own_channel_config.announced_channel = false;
        no_announce_cfg.own_channel_config.negotiate_scid_privacy = true;
        nodes[1].node.create_channel(nodes[2].node.get_our_node_id(), 100_000, 10_000, 42, Some(no_announce_cfg)).unwrap();
        let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[2].node.get_our_node_id());
@@ -460,7 +460,7 @@ fn test_inbound_scid_privacy() {
        nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
        commitment_signed_dance!(nodes[0], nodes[1], updates.commitment_signed, false);
 
-       expect_payment_failed_conditions!(nodes[0], payment_hash_2, false,
+       expect_payment_failed_conditions(&nodes[0], payment_hash_2, false,
                PaymentFailedConditions::new().blamed_scid(last_hop[0].short_channel_id.unwrap())
                        .blamed_chan_closed(true).expected_htlc_error_data(0x4000|10, &[0; 0]));
 }
@@ -537,7 +537,7 @@ fn test_scid_alias_returned() {
        err_data.extend_from_slice(&ChannelUpdate::TYPE.to_be_bytes());
        err_data.extend_from_slice(&msg.encode());
 
-       expect_payment_failed_conditions!(nodes[0], payment_hash, false,
+       expect_payment_failed_conditions(&nodes[0], payment_hash, false,
                PaymentFailedConditions::new().blamed_scid(last_hop[0].inbound_scid_alias.unwrap())
                        .blamed_chan_closed(false).expected_htlc_error_data(0x1000|7, &err_data));
 
@@ -560,7 +560,7 @@ fn test_scid_alias_returned() {
        err_data.extend_from_slice(&(msg.serialized_length() as u16 + 2).to_be_bytes());
        err_data.extend_from_slice(&ChannelUpdate::TYPE.to_be_bytes());
        err_data.extend_from_slice(&msg.encode());
-       expect_payment_failed_conditions!(nodes[0], payment_hash, false,
+       expect_payment_failed_conditions(&nodes[0], payment_hash, false,
                PaymentFailedConditions::new().blamed_scid(last_hop[0].inbound_scid_alias.unwrap())
                        .blamed_chan_closed(false).expected_htlc_error_data(0x1000|12, &err_data));
 }
@@ -665,7 +665,7 @@ fn test_0conf_channel_with_async_monitor() {
 
        create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0, InitFeatures::known(), InitFeatures::known());
 
-       chan_config.channel_options.announced_channel = false;
+       chan_config.own_channel_config.announced_channel = false;
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, Some(chan_config)).unwrap();
        let open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
 
@@ -811,7 +811,7 @@ fn test_0conf_close_no_early_chan_update() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // This is the default but we force it on anyway
-       chan_config.channel_options.announced_channel = true;
+       chan_config.own_channel_config.announced_channel = true;
        open_zero_conf_channel(&nodes[0], &nodes[1], Some(chan_config));
 
        // We can use the channel immediately, but won't generate a channel_update until we get confs
@@ -835,7 +835,7 @@ fn test_public_0conf_channel() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // This is the default but we force it on anyway
-       chan_config.channel_options.announced_channel = true;
+       chan_config.own_channel_config.announced_channel = true;
        let tx = open_zero_conf_channel(&nodes[0], &nodes[1], Some(chan_config));
 
        // We can use the channel immediately, but we can't announce it until we get 6+ confirmations
@@ -888,7 +888,7 @@ fn test_0conf_channel_reorg() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // This is the default but we force it on anyway
-       chan_config.channel_options.announced_channel = true;
+       chan_config.own_channel_config.announced_channel = true;
        let tx = open_zero_conf_channel(&nodes[0], &nodes[1], Some(chan_config));
 
        // We can use the channel immediately, but we can't announce it until we get 6+ confirmations
index 3dc245877e759fb8816ba0faa846f42386040f1a..edfa596f685db685a492906c9800dfcea5e74168 100644 (file)
@@ -409,9 +409,9 @@ fn test_upfront_shutdown_script() {
        // enforce it at shutdown message
 
        let mut config = UserConfig::default();
-       config.channel_options.announced_channel = true;
+       config.own_channel_config.announced_channel = true;
        config.peer_channel_config_limits.force_announced_channel_preference = false;
-       config.channel_options.commit_upfront_shutdown_pubkey = false;
+       config.own_channel_config.commit_upfront_shutdown_pubkey = false;
        let user_cfgs = [None, Some(config), None];
        let chanmon_cfgs = create_chanmon_cfgs(3);
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
@@ -574,9 +574,9 @@ fn test_invalid_upfront_shutdown_script() {
 #[test]
 fn test_segwit_v0_shutdown_script() {
        let mut config = UserConfig::default();
-       config.channel_options.announced_channel = true;
+       config.own_channel_config.announced_channel = true;
        config.peer_channel_config_limits.force_announced_channel_preference = false;
-       config.channel_options.commit_upfront_shutdown_pubkey = false;
+       config.own_channel_config.commit_upfront_shutdown_pubkey = false;
        let user_cfgs = [None, Some(config), None];
        let chanmon_cfgs = create_chanmon_cfgs(3);
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
@@ -609,9 +609,9 @@ fn test_segwit_v0_shutdown_script() {
 #[test]
 fn test_anysegwit_shutdown_script() {
        let mut config = UserConfig::default();
-       config.channel_options.announced_channel = true;
+       config.own_channel_config.announced_channel = true;
        config.peer_channel_config_limits.force_announced_channel_preference = false;
-       config.channel_options.commit_upfront_shutdown_pubkey = false;
+       config.own_channel_config.commit_upfront_shutdown_pubkey = false;
        let user_cfgs = [None, Some(config), None];
        let chanmon_cfgs = create_chanmon_cfgs(3);
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
@@ -644,9 +644,9 @@ fn test_anysegwit_shutdown_script() {
 #[test]
 fn test_unsupported_anysegwit_shutdown_script() {
        let mut config = UserConfig::default();
-       config.channel_options.announced_channel = true;
+       config.own_channel_config.announced_channel = true;
        config.peer_channel_config_limits.force_announced_channel_preference = false;
-       config.channel_options.commit_upfront_shutdown_pubkey = false;
+       config.own_channel_config.commit_upfront_shutdown_pubkey = false;
        let user_cfgs = [None, Some(config), None];
        let chanmon_cfgs = create_chanmon_cfgs(3);
        let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
@@ -686,9 +686,9 @@ fn test_unsupported_anysegwit_shutdown_script() {
 #[test]
 fn test_invalid_shutdown_script() {
        let mut config = UserConfig::default();
-       config.channel_options.announced_channel = true;
+       config.own_channel_config.announced_channel = true;
        config.peer_channel_config_limits.force_announced_channel_preference = false;
-       config.channel_options.commit_upfront_shutdown_pubkey = false;
+       config.own_channel_config.commit_upfront_shutdown_pubkey = false;
        let user_cfgs = [None, Some(config), None];
        let chanmon_cfgs = create_chanmon_cfgs(3);
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
index bdd222e31c58f0ab921ae2f3f057d8264b68b560..570e570a893e9583e4bb57ca18d4cb7c515a581c 100644 (file)
@@ -87,21 +87,45 @@ pub struct ChannelHandshakeConfig {
        ///
        /// If this option is set, channels may be created that will not be readable by LDK versions
        /// prior to 0.0.106, causing [`ChannelManager`]'s read method to return a
-       /// [`DecodeError:InvalidValue`].
+       /// [`DecodeError::InvalidValue`].
        ///
        /// Note that setting this to true does *not* prevent us from opening channels with
        /// counterparties that do not support the `scid_alias` option; we will simply fall back to a
        /// private channel without that option.
        ///
        /// Ignored if the channel is negotiated to be announced, see
-       /// [`ChannelConfig::announced_channel`] and
+       /// [`ChannelHandshakeConfig::announced_channel`] and
        /// [`ChannelHandshakeLimits::force_announced_channel_preference`] for more.
        ///
        /// Default value: false. This value is likely to change to true in the future.
        ///
        /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
-       /// [`DecodeError:InvalidValue`]: crate::ln::msgs::DecodeError::InvalidValue
+       /// [`DecodeError::InvalidValue`]: crate::ln::msgs::DecodeError::InvalidValue
        pub negotiate_scid_privacy: bool,
+       /// Set to announce the channel publicly and notify all nodes that they can route via this
+       /// channel.
+       ///
+       /// This should only be set to true for nodes which expect to be online reliably.
+       ///
+       /// As the node which funds a channel picks this value this will only apply for new outbound
+       /// channels unless [`ChannelHandshakeLimits::force_announced_channel_preference`] is set.
+       ///
+       /// Default value: false.
+       pub announced_channel: bool,
+       /// When set, we commit to an upfront shutdown_pubkey at channel open. If our counterparty
+       /// supports it, they will then enforce the mutual-close output to us matches what we provided
+       /// at intialization, preventing us from closing to an alternate pubkey.
+       ///
+       /// This is set to true by default to provide a slight increase in security, though ultimately
+       /// any attacker who is able to take control of a channel can just as easily send the funds via
+       /// lightning payments, so we never require that our counterparties support this option.
+       ///
+       /// The upfront key committed is provided from [`KeysInterface::get_shutdown_scriptpubkey`].
+       ///
+       /// Default value: true.
+       ///
+       /// [`KeysInterface::get_shutdown_scriptpubkey`]: crate::chain::keysinterface::KeysInterface::get_shutdown_scriptpubkey
+       pub commit_upfront_shutdown_pubkey: bool,
 }
 
 impl Default for ChannelHandshakeConfig {
@@ -112,6 +136,8 @@ impl Default for ChannelHandshakeConfig {
                        our_htlc_minimum_msat: 1,
                        max_inbound_htlc_value_in_flight_percent_of_channel: 10,
                        negotiate_scid_privacy: false,
+                       announced_channel: false,
+                       commit_upfront_shutdown_pubkey: true,
                }
        }
 }
@@ -186,10 +212,10 @@ pub struct ChannelHandshakeLimits {
        /// Default value: true
        pub trust_own_funding_0conf: bool,
        /// Set to force an incoming channel to match our announced channel preference in
-       /// [`ChannelConfig::announced_channel`].
+       /// [`ChannelHandshakeConfig::announced_channel`].
        ///
        /// For a node which is not online reliably, this should be set to true and
-       /// [`ChannelConfig::announced_channel`] set to false, ensuring that no announced (aka public)
+       /// [`ChannelHandshakeConfig::announced_channel`] set to false, ensuring that no announced (aka public)
        /// channels will ever be opened.
        ///
        /// Default value: true.
@@ -265,30 +291,6 @@ pub struct ChannelConfig {
        ///
        /// [`MIN_CLTV_EXPIRY_DELTA`]: crate::ln::channelmanager::MIN_CLTV_EXPIRY_DELTA
        pub cltv_expiry_delta: u16,
-       /// Set to announce the channel publicly and notify all nodes that they can route via this
-       /// channel.
-       ///
-       /// This should only be set to true for nodes which expect to be online reliably.
-       ///
-       /// As the node which funds a channel picks this value this will only apply for new outbound
-       /// channels unless [`ChannelHandshakeLimits::force_announced_channel_preference`] is set.
-       ///
-       /// This cannot be changed after the initial channel handshake.
-       ///
-       /// Default value: false.
-       pub announced_channel: bool,
-       /// When set, we commit to an upfront shutdown_pubkey at channel open. If our counterparty
-       /// supports it, they will then enforce the mutual-close output to us matches what we provided
-       /// at intialization, preventing us from closing to an alternate pubkey.
-       ///
-       /// This is set to true by default to provide a slight increase in security, though ultimately
-       /// any attacker who is able to take control of a channel can just as easily send the funds via
-       /// lightning payments, so we never require that our counterparties support this option.
-       ///
-       /// This cannot be changed after a channel has been initialized.
-       ///
-       /// Default value: true.
-       pub commit_upfront_shutdown_pubkey: bool,
        /// Limit our total exposure to in-flight HTLCs which are burned to fees as they are too
        /// small to claim on-chain.
        ///
@@ -337,23 +339,83 @@ impl Default for ChannelConfig {
                        forwarding_fee_proportional_millionths: 0,
                        forwarding_fee_base_msat: 1000,
                        cltv_expiry_delta: 6 * 12, // 6 blocks/hour * 12 hours
-                       announced_channel: false,
-                       commit_upfront_shutdown_pubkey: true,
                        max_dust_htlc_exposure_msat: 5_000_000,
                        force_close_avoidance_max_fee_satoshis: 1000,
                }
        }
 }
 
-impl_writeable_tlv_based!(ChannelConfig, {
-       (0, forwarding_fee_proportional_millionths, required),
-       (1, max_dust_htlc_exposure_msat, (default_value, 5_000_000)),
-       (2, cltv_expiry_delta, required),
-       (3, force_close_avoidance_max_fee_satoshis, (default_value, 1000)),
-       (4, announced_channel, required),
-       (6, commit_upfront_shutdown_pubkey, required),
-       (8, forwarding_fee_base_msat, required),
-});
+/// Legacy version of [`ChannelConfig`] that stored the static
+/// [`ChannelHandshakeConfig::announced_channel`] and
+/// [`ChannelHandshakeConfig::commit_upfront_shutdown_pubkey`] fields.
+#[derive(Copy, Clone, Debug)]
+pub(crate) struct LegacyChannelConfig {
+       pub(crate) mutable: ChannelConfig,
+       /// Deprecated but may still be read from. See [`ChannelHandshakeConfig::announced_channel`] to
+       /// set this when opening/accepting a channel.
+       pub(crate) announced_channel: bool,
+       /// Deprecated but may still be read from. See
+       /// [`ChannelHandshakeConfig::commit_upfront_shutdown_pubkey`] to set this when
+       /// opening/accepting a channel.
+       pub(crate) commit_upfront_shutdown_pubkey: bool,
+}
+
+impl Default for LegacyChannelConfig {
+       fn default() -> Self {
+               Self {
+                       mutable: ChannelConfig::default(),
+                       announced_channel: false,
+                       commit_upfront_shutdown_pubkey: true,
+               }
+       }
+}
+
+impl ::util::ser::Writeable for LegacyChannelConfig {
+       fn write<W: ::util::ser::Writer>(&self, writer: &mut W) -> Result<(), ::io::Error> {
+               write_tlv_fields!(writer, {
+                       (0, self.mutable.forwarding_fee_proportional_millionths, required),
+                       (1, self.mutable.max_dust_htlc_exposure_msat, (default_value, 5_000_000)),
+                       (2, self.mutable.cltv_expiry_delta, required),
+                       (3, self.mutable.force_close_avoidance_max_fee_satoshis, (default_value, 1000)),
+                       (4, self.announced_channel, required),
+                       (6, self.commit_upfront_shutdown_pubkey, required),
+                       (8, self.mutable.forwarding_fee_base_msat, required),
+               });
+               Ok(())
+       }
+}
+
+impl ::util::ser::Readable for LegacyChannelConfig {
+       fn read<R: ::io::Read>(reader: &mut R) -> Result<Self, ::ln::msgs::DecodeError> {
+               let mut forwarding_fee_proportional_millionths = 0;
+               let mut max_dust_htlc_exposure_msat = 5_000_000;
+               let mut cltv_expiry_delta = 0;
+               let mut force_close_avoidance_max_fee_satoshis = 1000;
+               let mut announced_channel = false;
+               let mut commit_upfront_shutdown_pubkey = false;
+               let mut forwarding_fee_base_msat = 0;
+               read_tlv_fields!(reader, {
+                       (0, forwarding_fee_proportional_millionths, required),
+                       (1, max_dust_htlc_exposure_msat, (default_value, 5_000_000)),
+                       (2, cltv_expiry_delta, required),
+                       (3, force_close_avoidance_max_fee_satoshis, (default_value, 1000)),
+                       (4, announced_channel, required),
+                       (6, commit_upfront_shutdown_pubkey, required),
+                       (8, forwarding_fee_base_msat, required),
+               });
+               Ok(Self {
+                       mutable: ChannelConfig {
+                               forwarding_fee_proportional_millionths,
+                               max_dust_htlc_exposure_msat,
+                               cltv_expiry_delta,
+                               force_close_avoidance_max_fee_satoshis,
+                               forwarding_fee_base_msat,
+                       },
+                       announced_channel,
+                       commit_upfront_shutdown_pubkey,
+               })
+       }
+}
 
 /// Top-level config which holds ChannelHandshakeLimits and ChannelConfig.
 ///
@@ -372,7 +434,7 @@ pub struct UserConfig {
        /// node which is not online reliably.
        ///
        /// For nodes which are not online reliably, you should set all channels to *not* be announced
-       /// (using [`ChannelConfig::announced_channel`] and
+       /// (using [`ChannelHandshakeConfig::announced_channel`] and
        /// [`ChannelHandshakeLimits::force_announced_channel_preference`]) and set this to false to
        /// ensure you are not exposed to any forwarding risk.
        ///