Merge pull request #2071 from TheBlueMatt/2023-01-fix-fast-extra-ready-panic
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Fri, 3 Mar 2023 23:32:42 +0000 (23:32 +0000)
committerGitHub <noreply@github.com>
Fri, 3 Mar 2023 23:32:42 +0000 (23:32 +0000)
Fix panic on receiving `channel_ready` after 1st commitment update

128 files changed:
.github/workflows/build.yml
.gitignore
ARCH.md
CONTRIBUTING.md
Cargo.toml
SECURITY.md
fuzz/Cargo.toml
fuzz/src/bech32_parse.rs [new file with mode: 0644]
fuzz/src/bin/bech32_parse_target.rs [new file with mode: 0644]
fuzz/src/bin/gen_target.sh
fuzz/src/bin/indexedmap_target.rs [new file with mode: 0644]
fuzz/src/bin/invoice_deser_target.rs [new file with mode: 0644]
fuzz/src/bin/invoice_request_deser_target.rs [new file with mode: 0644]
fuzz/src/bin/msg_channel_details_target.rs [new file with mode: 0644]
fuzz/src/bin/offer_deser_target.rs [new file with mode: 0644]
fuzz/src/bin/refund_deser_target.rs [new file with mode: 0644]
fuzz/src/chanmon_consistency.rs
fuzz/src/chanmon_deser.rs
fuzz/src/full_stack.rs
fuzz/src/indexedmap.rs [new file with mode: 0644]
fuzz/src/invoice_deser.rs [new file with mode: 0644]
fuzz/src/invoice_request_deser.rs [new file with mode: 0644]
fuzz/src/lib.rs
fuzz/src/offer_deser.rs [new file with mode: 0644]
fuzz/src/onion_message.rs
fuzz/src/peer_crypt.rs
fuzz/src/process_network_graph.rs
fuzz/src/refund_deser.rs [new file with mode: 0644]
fuzz/src/router.rs
fuzz/src/utils/test_persister.rs
fuzz/targets.h
lightning-background-processor/Cargo.toml
lightning-background-processor/src/lib.rs
lightning-block-sync/Cargo.toml
lightning-block-sync/src/init.rs
lightning-block-sync/src/lib.rs
lightning-block-sync/src/rpc.rs
lightning-custom-message/Cargo.toml [new file with mode: 0644]
lightning-custom-message/src/lib.rs [new file with mode: 0644]
lightning-invoice/src/de.rs
lightning-invoice/src/lib.rs
lightning-invoice/src/payment.rs
lightning-invoice/src/ser.rs
lightning-invoice/src/utils.rs
lightning-invoice/tests/ser_de.rs
lightning-net-tokio/Cargo.toml
lightning-net-tokio/src/lib.rs
lightning-persister/src/lib.rs
lightning-rapid-gossip-sync/src/lib.rs
lightning-rapid-gossip-sync/src/processing.rs
lightning-transaction-sync/Cargo.toml [new file with mode: 0644]
lightning-transaction-sync/src/common.rs [new file with mode: 0644]
lightning-transaction-sync/src/error.rs [new file with mode: 0644]
lightning-transaction-sync/src/esplora.rs [new file with mode: 0644]
lightning-transaction-sync/src/lib.rs [new file with mode: 0644]
lightning-transaction-sync/tests/integration_tests.rs [new file with mode: 0644]
lightning/src/chain/chaininterface.rs
lightning/src/chain/chainmonitor.rs
lightning/src/chain/channelmonitor.rs
lightning/src/chain/keysinterface.rs
lightning/src/chain/mod.rs
lightning/src/chain/onchaintx.rs
lightning/src/chain/package.rs
lightning/src/debug_sync.rs [deleted file]
lightning/src/lib.rs
lightning/src/ln/chan_utils.rs
lightning/src/ln/chanmon_update_fail_tests.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/features.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/inbound_payment.rs
lightning/src/ln/monitor_tests.rs
lightning/src/ln/msgs.rs
lightning/src/ln/onion_route_tests.rs
lightning/src/ln/onion_utils.rs
lightning/src/ln/outbound_payment.rs
lightning/src/ln/payment_tests.rs
lightning/src/ln/peer_channel_encryptor.rs
lightning/src/ln/peer_handler.rs
lightning/src/ln/priv_short_conf_tests.rs
lightning/src/ln/reload_tests.rs
lightning/src/ln/reorg_tests.rs
lightning/src/ln/script.rs
lightning/src/ln/shutdown_tests.rs
lightning/src/offers/invoice.rs [new file with mode: 0644]
lightning/src/offers/invoice_request.rs
lightning/src/offers/merkle.rs
lightning/src/offers/mod.rs
lightning/src/offers/offer.rs
lightning/src/offers/parse.rs
lightning/src/offers/payer.rs
lightning/src/offers/refund.rs
lightning/src/onion_message/blinded_path.rs
lightning/src/onion_message/functional_tests.rs
lightning/src/onion_message/messenger.rs
lightning/src/onion_message/packet.rs
lightning/src/routing/gossip.rs
lightning/src/routing/mod.rs
lightning/src/routing/router.rs
lightning/src/routing/scoring.rs
lightning/src/routing/test_utils.rs
lightning/src/routing/utxo.rs [new file with mode: 0644]
lightning/src/sync.rs [deleted file]
lightning/src/sync/debug_sync.rs [new file with mode: 0644]
lightning/src/sync/fairrwlock.rs [new file with mode: 0644]
lightning/src/sync/mod.rs [new file with mode: 0644]
lightning/src/sync/nostd_sync.rs [new file with mode: 0644]
lightning/src/sync/test_lockorder_checks.rs [new file with mode: 0644]
lightning/src/util/chacha20poly1305rfc.rs
lightning/src/util/config.rs
lightning/src/util/enforcing_trait_impls.rs
lightning/src/util/errors.rs
lightning/src/util/events.rs
lightning/src/util/fairrwlock.rs [deleted file]
lightning/src/util/indexed_map.rs [new file with mode: 0644]
lightning/src/util/macro_logger.rs
lightning/src/util/mod.rs
lightning/src/util/persist.rs
lightning/src/util/scid_utils.rs
lightning/src/util/ser.rs
lightning/src/util/ser_macros.rs
lightning/src/util/test_utils.rs
lightning/src/util/wakers.rs
no-std-check/Cargo.toml
pending_changelog/1878.txt [new file with mode: 0644]
pending_changelog/2043.txt [new file with mode: 0644]

index f27a2ccf863fa0348295a3f0c56810fa48280eb7..1c1472a1007cd214ff8248e186cbf5cfab1d8d89 100644 (file)
@@ -12,7 +12,7 @@ jobs:
                      beta,
                      # 1.41.1 is MSRV for Rust-Lightning, lightning-invoice, and lightning-persister
                      1.41.1,
-                     # 1.45.2 is MSRV for lightning-net-tokio, lightning-block-sync, lightning-background-processor, and coverage generation
+                     # 1.45.2 is MSRV for lightning-net-tokio, lightning-block-sync, lightning-background-processor
                      1.45.2,
                      # 1.47.0 will be the MSRV for no-std builds using hashbrown once core2 is updated
                      1.47.0]
@@ -21,43 +21,56 @@ jobs:
             build-net-tokio: true
             build-no-std: true
             build-futures: true
+            build-tx-sync: true
+            coverage: true
           - toolchain: stable
             platform: macos-latest
             build-net-tokio: true
             build-no-std: true
             build-futures: true
+            build-tx-sync: true
+          - toolchain: stable
+            test-custom-message: true
           - toolchain: beta
             platform: macos-latest
             build-net-tokio: true
             build-no-std: true
             build-futures: true
+            build-tx-sync: true
           - toolchain: stable
             platform: windows-latest
             build-net-tokio: true
             build-no-std: true
             build-futures: true
+            build-tx-sync: false
           - toolchain: beta
             platform: windows-latest
             build-net-tokio: true
             build-no-std: true
             build-futures: true
+            build-tx-sync: false
           - toolchain: beta
             build-net-tokio: true
             build-no-std: true
             build-futures: true
+            build-tx-sync: true
+          - toolchain: beta
+            test-custom-message: true
           - toolchain: 1.41.1
             build-no-std: false
             test-log-variants: true
             build-futures: false
+            build-tx-sync: false
           - toolchain: 1.45.2
             build-net-old-tokio: true
             build-net-tokio: true
             build-no-std: false
             build-futures: true
-            coverage: true
+            build-tx-sync: false
           - toolchain: 1.47.0
             build-futures: true
             build-no-std: true
+            build-tx-sync: false
     runs-on: ${{ matrix.platform }}
     steps:
       - name: Checkout source code
@@ -76,7 +89,7 @@ jobs:
       - name: Build on Rust ${{ matrix.toolchain }} with net-tokio
         if: "matrix.build-net-tokio && !matrix.coverage"
         run: cargo build --verbose --color always
-      - name: Build on Rust ${{ matrix.toolchain }} with net-tokio and full code-linking for coverage generation
+      - name: Build on Rust ${{ matrix.toolchain }} with net-tokio, and full code-linking for coverage generation
         if: matrix.coverage
         run: RUSTFLAGS="-C link-dead-code" cargo build --verbose --color always
       - name: Build on Rust ${{ matrix.toolchain }}
@@ -108,14 +121,33 @@ jobs:
           RUSTFLAGS="-C link-dead-code" cargo build --verbose --color always --features rpc-client
           RUSTFLAGS="-C link-dead-code" cargo build --verbose --color always --features rpc-client,rest-client
           RUSTFLAGS="-C link-dead-code" cargo build --verbose --color always --features rpc-client,rest-client,tokio
+      - name: Build Transaction Sync Clients on Rust ${{ matrix.toolchain }} with features
+        if: "matrix.build-tx-sync && !matrix.coverage"
+        run: |
+          cd lightning-transaction-sync
+          cargo build --verbose --color always --features esplora-blocking
+          cargo build --verbose --color always --features esplora-async
+      - name: Build transaction sync clients on Rust ${{ matrix.toolchain }} with features and full code-linking for coverage generation
+        if: "matrix.build-tx-sync && matrix.coverage"
+        run: |
+          cd lightning-transaction-sync
+          RUSTFLAGS="-C link-dead-code" cargo build --verbose --color always --features esplora-blocking
+          RUSTFLAGS="-C link-dead-code" cargo build --verbose --color always --features esplora-async
+      - name: Test transaction sync clients on Rust ${{ matrix.toolchain }} with features
+        if: "matrix.build-tx-sync"
+        run: |
+          cd lightning-transaction-sync
+          cargo test --verbose --color always --features esplora-blocking
+          cargo test --verbose --color always --features esplora-async
       - name: Test backtrace-debug builds on Rust ${{ matrix.toolchain }}
         if: "matrix.toolchain == 'stable'"
+        shell: bash # Default on Winblows is powershell
         run: |
-          cd lightning && cargo test --verbose --color always --features backtrace
+          cd lightning && RUST_BACKTRACE=1 cargo test --verbose --color always --features backtrace
       - name: Test on Rust ${{ matrix.toolchain }} with net-tokio
         if: "matrix.build-net-tokio && !matrix.coverage"
         run: cargo test --verbose --color always
-      - name: Test on Rust ${{ matrix.toolchain }} with net-tokio and full code-linking for coverage generation
+      - name: Test on Rust ${{ matrix.toolchain }} with net-tokio, and full code-linking for coverage generation
         if: matrix.coverage
         run: RUSTFLAGS="-C link-dead-code" cargo test --verbose --color always
       - name: Test no-std builds on Rust ${{ matrix.toolchain }}
@@ -136,7 +168,7 @@ jobs:
           done
           # check no-std compatibility across dependencies
           cd no-std-check
-          cargo check --verbose --color always
+          cargo check --verbose --color always --features lightning-transaction-sync
       - name: Build no-std-check on Rust ${{ matrix.toolchain }} for ARM Embedded
         if: "matrix.build-no-std && matrix.platform == 'ubuntu-latest'"
         run: |
@@ -192,6 +224,11 @@ jobs:
           RUSTFLAGS="-C link-dead-code" cargo test --verbose --color always --features rpc-client
           RUSTFLAGS="-C link-dead-code" cargo test --verbose --color always --features rpc-client,rest-client
           RUSTFLAGS="-C link-dead-code" cargo test --verbose --color always --features rpc-client,rest-client,tokio
+      - name: Test Custom Message Macros on Rust ${{ matrix.toolchain }}
+        if: "matrix.test-custom-message"
+        run: |
+          cd lightning-custom-message
+          cargo test --verbose --color always
       - name: Install deps for kcov
         if: matrix.coverage
         run: |
@@ -242,19 +279,19 @@ jobs:
         id: cache-graph
         uses: actions/cache@v3
         with:
-          path: lightning/net_graph-2021-05-31.bin
-          key: ldk-net_graph-v0.0.15-2021-05-31.bin
+          path: lightning/net_graph-2023-01-18.bin
+          key: ldk-net_graph-v0.0.113-2023-01-18.bin
       - name: Fetch routing graph snapshot
         if: steps.cache-graph.outputs.cache-hit != 'true'
         run: |
-          curl --verbose -L -o lightning/net_graph-2021-05-31.bin https://bitcoin.ninja/ldk-net_graph-v0.0.15-2021-05-31.bin
-          echo "Sha sum: $(sha256sum lightning/net_graph-2021-05-31.bin | awk '{ print $1 }')"
-          if [ "$(sha256sum lightning/net_graph-2021-05-31.bin | awk '{ print $1 }')" != "${EXPECTED_ROUTING_GRAPH_SNAPSHOT_SHASUM}" ]; then
+          curl --verbose -L -o lightning/net_graph-2023-01-18.bin https://bitcoin.ninja/ldk-net_graph-v0.0.113-2023-01-18.bin
+          echo "Sha sum: $(sha256sum lightning/net_graph-2023-01-18.bin | awk '{ print $1 }')"
+          if [ "$(sha256sum lightning/net_graph-2023-01-18.bin | awk '{ print $1 }')" != "${EXPECTED_ROUTING_GRAPH_SNAPSHOT_SHASUM}" ]; then
             echo "Bad hash"
             exit 1
           fi
         env:
-          EXPECTED_ROUTING_GRAPH_SNAPSHOT_SHASUM: 05a5361278f68ee2afd086cc04a1f927a63924be451f3221d380533acfacc303
+          EXPECTED_ROUTING_GRAPH_SNAPSHOT_SHASUM: da6066f2bddcddbe7d8a6debbd53545697137b310bbb8c4911bc8c81fc5ff48c
       - name: Fetch rapid graph sync reference input
         run: |
           curl --verbose -L -o lightning-rapid-gossip-sync/res/full_graph.lngossip https://bitcoin.ninja/ldk-compressed_graph-285cb27df79-2022-07-21.bin
@@ -349,7 +386,7 @@ jobs:
   linting:
     runs-on: ubuntu-latest
     env:
-      TOOLCHAIN: 1.47.0
+      TOOLCHAIN: stable
     steps:
       - name: Checkout source code
         uses: actions/checkout@v3
index d99c5a4ddf6603b32fb97d666d49c3ebb631df79..7a889b5b8230af929cd28134454d2f93502531bd 100644 (file)
@@ -9,5 +9,5 @@ Cargo.lock
 .idea
 lightning/target
 lightning/ldk-net_graph-*.bin
+lightning-custom-message/target
 no-std-check/target
-
diff --git a/ARCH.md b/ARCH.md
index 9efccd9c9ddcec9d9812e0d0eb420975b3a0e98c..bd5fc1bd3164a5ce749ade66c19bb55f6fd74700 100644 (file)
--- a/ARCH.md
+++ b/ARCH.md
@@ -51,9 +51,9 @@ At a high level, some of the common interfaces fit together as follows:
 --------------- /                  (as EventsProvider)         ^            |           |
 | PeerManager |-                             \                 |            |           |
 ---------------                               \                | (is-a)     |           |
- |                    -----------------        \       _----------------   /           /
- |                    | chain::Access |         \     / | ChainMonitor |---------------
- |                    -----------------          \   /  ----------------
+ |                    --------------           \       _----------------   /           /
+ |                    | UtxoLookup |            \     / | ChainMonitor |---------------
+ |                    --------------             \   /  ----------------
  |                            ^                   \ /          |
 (as RoutingMessageHandler)    |                    v           v
   \                   -----------------        ---------   -----------------
index 6f12c21e9f9d6c9035d3225316d3e5ed42b5d3eb..e795ecb9fba7b3c48a5f7732ce96719b28d32c16 100644 (file)
@@ -12,6 +12,8 @@ testing and risk-minimization. Any bug may cost users real money. That being
 said, we deeply welcome people contributing for the first time to an open source
 project or pick up Rust while contributing. Don't be shy, you'll learn.
 
+For the project Code of Conduct, see our [website](https://lightningdevkit.org/code_of_conduct).
+
 Communication Channels
 -----------------------
 
@@ -41,7 +43,7 @@ This doesn't mean don't be ambitious with the breadth and depth of your
 contributions but rather understand the project culture before investing an
 asymmetric number of hours on development compared to your merged work.
 
-Browsing through the [meeting minutes](https://github.com/lightningdevkit/rust-lightning/wiki/Meetings)
+Browsing through the [meeting minutes](https://github.com/lightningdevkit/rust-lightning/wiki/Meeting-Notes)
 is a good first step. You will learn who is working on what, how releases are
 drafted, what are the pending tasks to deliver, where you can contribute review
 bandwidth, etc.
index 89b92a8c6e4ba4e6a7bbd230d0e721230a552e6f..5412c496eac6afad0fa1bfe2ff8ec514a145eb6c 100644 (file)
@@ -11,6 +11,8 @@ members = [
 ]
 
 exclude = [
+    "lightning-custom-message",
+    "lightning-transaction-sync",
     "no-std-check",
 ]
 
index d4b33ec3609019497ac93bfee2c6e6579f70644e..3f6b25fe8b993da805c3a8656527e74a50568fb8 100644 (file)
@@ -13,7 +13,7 @@ your own public key as an attachment or inline for replies.
 
  * 07DF3E57A548CCFB7530709189BBB8663E2E65CE (Matt Corallo)
  * 5DBC576CCCF546CA72AB06CE912EF12EA67705F5 (Jeffrey Czyz)
- * 729E9D9D92C75A5FBFEEE057B5DD717BEF7CA5B1 (Wilmer Paulino)
+ * 0A156842CF60B58BD826ABDD808FC696767C6147 (Wilmer Paulino)
  * BD6EED4D339EDBF7E7CE7F8836153082BDF676FD (Elias Rohrer)
  * 6E0287D8849AE741E47CC586FD3E106A2CE099B4 (Valentine Wallace)
  * 69CFEA635D0E6E6F13FD9D9136D932FCAC0305F0 (Arik Sosman)
index b2ec5e18ea418774616f23bb3734c9003dce81ad..5daebb3506681503e197ba92656eb1ddd4eb4c06 100644 (file)
@@ -18,11 +18,13 @@ libfuzzer_fuzz = ["libfuzzer-sys"]
 stdin_fuzz = []
 
 [dependencies]
-afl = { version = "0.4", optional = true }
-lightning = { path = "../lightning", features = ["regex"] }
+lightning = { path = "../lightning", features = ["regex", "hashbrown", "_test_utils"] }
 lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync" }
 bitcoin = { version = "0.29.0", features = ["secp-lowmemory"] }
 hex = "0.3"
+hashbrown = "0.8"
+
+afl = { version = "0.12", optional = true }
 honggfuzz = { version = "0.5", optional = true, default-features = false }
 libfuzzer-sys = { version = "0.4", optional = true }
 
@@ -36,6 +38,8 @@ members = ["."]
 [profile.release]
 lto = true
 codegen-units = 1
+debug-assertions = true
+overflow-checks = true
 
 # When testing a large fuzz corpus, -O1 offers a nice speedup
 [profile.dev]
diff --git a/fuzz/src/bech32_parse.rs b/fuzz/src/bech32_parse.rs
new file mode 100644 (file)
index 0000000..f3dd5ac
--- /dev/null
@@ -0,0 +1,57 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+use crate::utils::test_logger;
+use core::convert::TryFrom;
+use lightning::offers::parse::{Bech32Encode, ParseError};
+
+#[inline]
+pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
+       if let Ok(bech32_encoded) = std::str::from_utf8(data) {
+               if let Ok(bytes) = Bytes::from_bech32_str(bech32_encoded) {
+                       let bech32_encoded = bytes.to_string();
+                       assert_eq!(bytes, Bytes::from_bech32_str(&bech32_encoded).unwrap());
+               }
+       }
+}
+
+#[derive(Debug, PartialEq)]
+struct Bytes(Vec<u8>);
+
+impl Bech32Encode for Bytes {
+       const BECH32_HRP: &'static str = "lno";
+}
+
+impl AsRef<[u8]> for Bytes {
+       fn as_ref(&self) -> &[u8] {
+               &self.0
+       }
+}
+
+impl TryFrom<Vec<u8>> for Bytes {
+       type Error = ParseError;
+       fn try_from(data: Vec<u8>) -> Result<Self, ParseError> {
+               Ok(Bytes(data))
+       }
+}
+
+impl core::fmt::Display for Bytes {
+       fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
+               self.fmt_bech32_str(f)
+       }
+}
+
+pub fn bech32_parse_test<Out: test_logger::Output>(data: &[u8], out: Out) {
+       do_test(data, out);
+}
+
+#[no_mangle]
+pub extern "C" fn bech32_parse_run(data: *const u8, datalen: usize) {
+       do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {});
+}
diff --git a/fuzz/src/bin/bech32_parse_target.rs b/fuzz/src/bin/bech32_parse_target.rs
new file mode 100644 (file)
index 0000000..629112f
--- /dev/null
@@ -0,0 +1,113 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+// This file is auto-generated by gen_target.sh based on target_template.txt
+// To modify it, modify target_template.txt and run gen_target.sh instead.
+
+#![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
+
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
+extern crate lightning_fuzz;
+use lightning_fuzz::bech32_parse::*;
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               bech32_parse_run(data.as_ptr(), data.len());
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       bech32_parse_run(data.as_ptr(), data.len());
+               });
+       }
+}
+
+#[cfg(feature = "libfuzzer_fuzz")]
+#[macro_use] extern crate libfuzzer_sys;
+#[cfg(feature = "libfuzzer_fuzz")]
+fuzz_target!(|data: &[u8]| {
+       bech32_parse_run(data.as_ptr(), data.len());
+});
+
+#[cfg(feature = "stdin_fuzz")]
+fn main() {
+       use std::io::Read;
+
+       let mut data = Vec::with_capacity(8192);
+       std::io::stdin().read_to_end(&mut data).unwrap();
+       bech32_parse_run(data.as_ptr(), data.len());
+}
+
+#[test]
+fn run_test_cases() {
+       use std::fs;
+       use std::io::Read;
+       use lightning_fuzz::utils::test_logger::StringBuffer;
+
+       use std::sync::{atomic, Arc};
+       {
+               let data: Vec<u8> = vec![0];
+               bech32_parse_run(data.as_ptr(), data.len());
+       }
+       let mut threads = Vec::new();
+       let threads_running = Arc::new(atomic::AtomicUsize::new(0));
+       if let Ok(tests) = fs::read_dir("test_cases/bech32_parse") {
+               for test in tests {
+                       let mut data: Vec<u8> = Vec::new();
+                       let path = test.unwrap().path();
+                       fs::File::open(&path).unwrap().read_to_end(&mut data).unwrap();
+                       threads_running.fetch_add(1, atomic::Ordering::AcqRel);
+
+                       let thread_count_ref = Arc::clone(&threads_running);
+                       let main_thread_ref = std::thread::current();
+                       threads.push((path.file_name().unwrap().to_str().unwrap().to_string(),
+                               std::thread::spawn(move || {
+                                       let string_logger = StringBuffer::new();
+
+                                       let panic_logger = string_logger.clone();
+                                       let res = if ::std::panic::catch_unwind(move || {
+                                               bech32_parse_test(&data, panic_logger);
+                                       }).is_err() {
+                                               Some(string_logger.into_string())
+                                       } else { None };
+                                       thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel);
+                                       main_thread_ref.unpark();
+                                       res
+                               })
+                       ));
+                       while threads_running.load(atomic::Ordering::Acquire) > 32 {
+                               std::thread::park();
+                       }
+               }
+       }
+       let mut failed_outputs = Vec::new();
+       for (test, thread) in threads.drain(..) {
+               if let Some(output) = thread.join().unwrap() {
+                       println!("\nOutput of {}:\n{}\n", test, output);
+                       failed_outputs.push(test);
+               }
+       }
+       if !failed_outputs.is_empty() {
+               println!("Test cases which failed: ");
+               for case in failed_outputs {
+                       println!("{}", case);
+               }
+               panic!();
+       }
+}
index 95e65695eb868c798aba81b1d3684ba870154521..d7928188d8c57d4cbc959943d40e89a3c1e2a6d6 100755 (executable)
@@ -6,14 +6,20 @@ GEN_TEST() {
        echo "void $1_run(const unsigned char* data, size_t data_len);" >> ../../targets.h
 }
 
+GEN_TEST bech32_parse
 GEN_TEST chanmon_deser
 GEN_TEST chanmon_consistency
 GEN_TEST full_stack
+GEN_TEST invoice_deser
+GEN_TEST invoice_request_deser
+GEN_TEST offer_deser
 GEN_TEST onion_message
 GEN_TEST peer_crypt
 GEN_TEST process_network_graph
+GEN_TEST refund_deser
 GEN_TEST router
 GEN_TEST zbase32
+GEN_TEST indexedmap
 
 GEN_TEST msg_accept_channel msg_targets::
 GEN_TEST msg_announcement_signatures msg_targets::
diff --git a/fuzz/src/bin/indexedmap_target.rs b/fuzz/src/bin/indexedmap_target.rs
new file mode 100644 (file)
index 0000000..238566d
--- /dev/null
@@ -0,0 +1,113 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+// This file is auto-generated by gen_target.sh based on target_template.txt
+// To modify it, modify target_template.txt and run gen_target.sh instead.
+
+#![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
+
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
+extern crate lightning_fuzz;
+use lightning_fuzz::indexedmap::*;
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               indexedmap_run(data.as_ptr(), data.len());
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       indexedmap_run(data.as_ptr(), data.len());
+               });
+       }
+}
+
+#[cfg(feature = "libfuzzer_fuzz")]
+#[macro_use] extern crate libfuzzer_sys;
+#[cfg(feature = "libfuzzer_fuzz")]
+fuzz_target!(|data: &[u8]| {
+       indexedmap_run(data.as_ptr(), data.len());
+});
+
+#[cfg(feature = "stdin_fuzz")]
+fn main() {
+       use std::io::Read;
+
+       let mut data = Vec::with_capacity(8192);
+       std::io::stdin().read_to_end(&mut data).unwrap();
+       indexedmap_run(data.as_ptr(), data.len());
+}
+
+#[test]
+fn run_test_cases() {
+       use std::fs;
+       use std::io::Read;
+       use lightning_fuzz::utils::test_logger::StringBuffer;
+
+       use std::sync::{atomic, Arc};
+       {
+               let data: Vec<u8> = vec![0];
+               indexedmap_run(data.as_ptr(), data.len());
+       }
+       let mut threads = Vec::new();
+       let threads_running = Arc::new(atomic::AtomicUsize::new(0));
+       if let Ok(tests) = fs::read_dir("test_cases/indexedmap") {
+               for test in tests {
+                       let mut data: Vec<u8> = Vec::new();
+                       let path = test.unwrap().path();
+                       fs::File::open(&path).unwrap().read_to_end(&mut data).unwrap();
+                       threads_running.fetch_add(1, atomic::Ordering::AcqRel);
+
+                       let thread_count_ref = Arc::clone(&threads_running);
+                       let main_thread_ref = std::thread::current();
+                       threads.push((path.file_name().unwrap().to_str().unwrap().to_string(),
+                               std::thread::spawn(move || {
+                                       let string_logger = StringBuffer::new();
+
+                                       let panic_logger = string_logger.clone();
+                                       let res = if ::std::panic::catch_unwind(move || {
+                                               indexedmap_test(&data, panic_logger);
+                                       }).is_err() {
+                                               Some(string_logger.into_string())
+                                       } else { None };
+                                       thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel);
+                                       main_thread_ref.unpark();
+                                       res
+                               })
+                       ));
+                       while threads_running.load(atomic::Ordering::Acquire) > 32 {
+                               std::thread::park();
+                       }
+               }
+       }
+       let mut failed_outputs = Vec::new();
+       for (test, thread) in threads.drain(..) {
+               if let Some(output) = thread.join().unwrap() {
+                       println!("\nOutput of {}:\n{}\n", test, output);
+                       failed_outputs.push(test);
+               }
+       }
+       if !failed_outputs.is_empty() {
+               println!("Test cases which failed: ");
+               for case in failed_outputs {
+                       println!("{}", case);
+               }
+               panic!();
+       }
+}
diff --git a/fuzz/src/bin/invoice_deser_target.rs b/fuzz/src/bin/invoice_deser_target.rs
new file mode 100644 (file)
index 0000000..06dbbe3
--- /dev/null
@@ -0,0 +1,113 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+// This file is auto-generated by gen_target.sh based on target_template.txt
+// To modify it, modify target_template.txt and run gen_target.sh instead.
+
+#![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
+
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
+extern crate lightning_fuzz;
+use lightning_fuzz::invoice_deser::*;
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               invoice_deser_run(data.as_ptr(), data.len());
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       invoice_deser_run(data.as_ptr(), data.len());
+               });
+       }
+}
+
+#[cfg(feature = "libfuzzer_fuzz")]
+#[macro_use] extern crate libfuzzer_sys;
+#[cfg(feature = "libfuzzer_fuzz")]
+fuzz_target!(|data: &[u8]| {
+       invoice_deser_run(data.as_ptr(), data.len());
+});
+
+#[cfg(feature = "stdin_fuzz")]
+fn main() {
+       use std::io::Read;
+
+       let mut data = Vec::with_capacity(8192);
+       std::io::stdin().read_to_end(&mut data).unwrap();
+       invoice_deser_run(data.as_ptr(), data.len());
+}
+
+#[test]
+fn run_test_cases() {
+       use std::fs;
+       use std::io::Read;
+       use lightning_fuzz::utils::test_logger::StringBuffer;
+
+       use std::sync::{atomic, Arc};
+       {
+               let data: Vec<u8> = vec![0];
+               invoice_deser_run(data.as_ptr(), data.len());
+       }
+       let mut threads = Vec::new();
+       let threads_running = Arc::new(atomic::AtomicUsize::new(0));
+       if let Ok(tests) = fs::read_dir("test_cases/invoice_deser") {
+               for test in tests {
+                       let mut data: Vec<u8> = Vec::new();
+                       let path = test.unwrap().path();
+                       fs::File::open(&path).unwrap().read_to_end(&mut data).unwrap();
+                       threads_running.fetch_add(1, atomic::Ordering::AcqRel);
+
+                       let thread_count_ref = Arc::clone(&threads_running);
+                       let main_thread_ref = std::thread::current();
+                       threads.push((path.file_name().unwrap().to_str().unwrap().to_string(),
+                               std::thread::spawn(move || {
+                                       let string_logger = StringBuffer::new();
+
+                                       let panic_logger = string_logger.clone();
+                                       let res = if ::std::panic::catch_unwind(move || {
+                                               invoice_deser_test(&data, panic_logger);
+                                       }).is_err() {
+                                               Some(string_logger.into_string())
+                                       } else { None };
+                                       thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel);
+                                       main_thread_ref.unpark();
+                                       res
+                               })
+                       ));
+                       while threads_running.load(atomic::Ordering::Acquire) > 32 {
+                               std::thread::park();
+                       }
+               }
+       }
+       let mut failed_outputs = Vec::new();
+       for (test, thread) in threads.drain(..) {
+               if let Some(output) = thread.join().unwrap() {
+                       println!("\nOutput of {}:\n{}\n", test, output);
+                       failed_outputs.push(test);
+               }
+       }
+       if !failed_outputs.is_empty() {
+               println!("Test cases which failed: ");
+               for case in failed_outputs {
+                       println!("{}", case);
+               }
+               panic!();
+       }
+}
diff --git a/fuzz/src/bin/invoice_request_deser_target.rs b/fuzz/src/bin/invoice_request_deser_target.rs
new file mode 100644 (file)
index 0000000..97741ff
--- /dev/null
@@ -0,0 +1,113 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+// This file is auto-generated by gen_target.sh based on target_template.txt
+// To modify it, modify target_template.txt and run gen_target.sh instead.
+
+#![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
+
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
+extern crate lightning_fuzz;
+use lightning_fuzz::invoice_request_deser::*;
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               invoice_request_deser_run(data.as_ptr(), data.len());
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       invoice_request_deser_run(data.as_ptr(), data.len());
+               });
+       }
+}
+
+#[cfg(feature = "libfuzzer_fuzz")]
+#[macro_use] extern crate libfuzzer_sys;
+#[cfg(feature = "libfuzzer_fuzz")]
+fuzz_target!(|data: &[u8]| {
+       invoice_request_deser_run(data.as_ptr(), data.len());
+});
+
+#[cfg(feature = "stdin_fuzz")]
+fn main() {
+       use std::io::Read;
+
+       let mut data = Vec::with_capacity(8192);
+       std::io::stdin().read_to_end(&mut data).unwrap();
+       invoice_request_deser_run(data.as_ptr(), data.len());
+}
+
+#[test]
+fn run_test_cases() {
+       use std::fs;
+       use std::io::Read;
+       use lightning_fuzz::utils::test_logger::StringBuffer;
+
+       use std::sync::{atomic, Arc};
+       {
+               let data: Vec<u8> = vec![0];
+               invoice_request_deser_run(data.as_ptr(), data.len());
+       }
+       let mut threads = Vec::new();
+       let threads_running = Arc::new(atomic::AtomicUsize::new(0));
+       if let Ok(tests) = fs::read_dir("test_cases/invoice_request_deser") {
+               for test in tests {
+                       let mut data: Vec<u8> = Vec::new();
+                       let path = test.unwrap().path();
+                       fs::File::open(&path).unwrap().read_to_end(&mut data).unwrap();
+                       threads_running.fetch_add(1, atomic::Ordering::AcqRel);
+
+                       let thread_count_ref = Arc::clone(&threads_running);
+                       let main_thread_ref = std::thread::current();
+                       threads.push((path.file_name().unwrap().to_str().unwrap().to_string(),
+                               std::thread::spawn(move || {
+                                       let string_logger = StringBuffer::new();
+
+                                       let panic_logger = string_logger.clone();
+                                       let res = if ::std::panic::catch_unwind(move || {
+                                               invoice_request_deser_test(&data, panic_logger);
+                                       }).is_err() {
+                                               Some(string_logger.into_string())
+                                       } else { None };
+                                       thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel);
+                                       main_thread_ref.unpark();
+                                       res
+                               })
+                       ));
+                       while threads_running.load(atomic::Ordering::Acquire) > 32 {
+                               std::thread::park();
+                       }
+               }
+       }
+       let mut failed_outputs = Vec::new();
+       for (test, thread) in threads.drain(..) {
+               if let Some(output) = thread.join().unwrap() {
+                       println!("\nOutput of {}:\n{}\n", test, output);
+                       failed_outputs.push(test);
+               }
+       }
+       if !failed_outputs.is_empty() {
+               println!("Test cases which failed: ");
+               for case in failed_outputs {
+                       println!("{}", case);
+               }
+               panic!();
+       }
+}
diff --git a/fuzz/src/bin/msg_channel_details_target.rs b/fuzz/src/bin/msg_channel_details_target.rs
new file mode 100644 (file)
index 0000000..cb5021a
--- /dev/null
@@ -0,0 +1,113 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+// This file is auto-generated by gen_target.sh based on target_template.txt
+// To modify it, modify target_template.txt and run gen_target.sh instead.
+
+#![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
+
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
+extern crate lightning_fuzz;
+use lightning_fuzz::msg_targets::msg_channel_details::*;
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               msg_channel_details_run(data.as_ptr(), data.len());
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       msg_channel_details_run(data.as_ptr(), data.len());
+               });
+       }
+}
+
+#[cfg(feature = "libfuzzer_fuzz")]
+#[macro_use] extern crate libfuzzer_sys;
+#[cfg(feature = "libfuzzer_fuzz")]
+fuzz_target!(|data: &[u8]| {
+       msg_channel_details_run(data.as_ptr(), data.len());
+});
+
+#[cfg(feature = "stdin_fuzz")]
+fn main() {
+       use std::io::Read;
+
+       let mut data = Vec::with_capacity(8192);
+       std::io::stdin().read_to_end(&mut data).unwrap();
+       msg_channel_details_run(data.as_ptr(), data.len());
+}
+
+#[test]
+fn run_test_cases() {
+       use std::fs;
+       use std::io::Read;
+       use lightning_fuzz::utils::test_logger::StringBuffer;
+
+       use std::sync::{atomic, Arc};
+       {
+               let data: Vec<u8> = vec![0];
+               msg_channel_details_run(data.as_ptr(), data.len());
+       }
+       let mut threads = Vec::new();
+       let threads_running = Arc::new(atomic::AtomicUsize::new(0));
+       if let Ok(tests) = fs::read_dir("test_cases/msg_channel_details") {
+               for test in tests {
+                       let mut data: Vec<u8> = Vec::new();
+                       let path = test.unwrap().path();
+                       fs::File::open(&path).unwrap().read_to_end(&mut data).unwrap();
+                       threads_running.fetch_add(1, atomic::Ordering::AcqRel);
+
+                       let thread_count_ref = Arc::clone(&threads_running);
+                       let main_thread_ref = std::thread::current();
+                       threads.push((path.file_name().unwrap().to_str().unwrap().to_string(),
+                               std::thread::spawn(move || {
+                                       let string_logger = StringBuffer::new();
+
+                                       let panic_logger = string_logger.clone();
+                                       let res = if ::std::panic::catch_unwind(move || {
+                                               msg_channel_details_test(&data, panic_logger);
+                                       }).is_err() {
+                                               Some(string_logger.into_string())
+                                       } else { None };
+                                       thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel);
+                                       main_thread_ref.unpark();
+                                       res
+                               })
+                       ));
+                       while threads_running.load(atomic::Ordering::Acquire) > 32 {
+                               std::thread::park();
+                       }
+               }
+       }
+       let mut failed_outputs = Vec::new();
+       for (test, thread) in threads.drain(..) {
+               if let Some(output) = thread.join().unwrap() {
+                       println!("\nOutput of {}:\n{}\n", test, output);
+                       failed_outputs.push(test);
+               }
+       }
+       if !failed_outputs.is_empty() {
+               println!("Test cases which failed: ");
+               for case in failed_outputs {
+                       println!("{}", case);
+               }
+               panic!();
+       }
+}
diff --git a/fuzz/src/bin/offer_deser_target.rs b/fuzz/src/bin/offer_deser_target.rs
new file mode 100644 (file)
index 0000000..49563b1
--- /dev/null
@@ -0,0 +1,113 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+// This file is auto-generated by gen_target.sh based on target_template.txt
+// To modify it, modify target_template.txt and run gen_target.sh instead.
+
+#![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
+
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
+extern crate lightning_fuzz;
+use lightning_fuzz::offer_deser::*;
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               offer_deser_run(data.as_ptr(), data.len());
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       offer_deser_run(data.as_ptr(), data.len());
+               });
+       }
+}
+
+#[cfg(feature = "libfuzzer_fuzz")]
+#[macro_use] extern crate libfuzzer_sys;
+#[cfg(feature = "libfuzzer_fuzz")]
+fuzz_target!(|data: &[u8]| {
+       offer_deser_run(data.as_ptr(), data.len());
+});
+
+#[cfg(feature = "stdin_fuzz")]
+fn main() {
+       use std::io::Read;
+
+       let mut data = Vec::with_capacity(8192);
+       std::io::stdin().read_to_end(&mut data).unwrap();
+       offer_deser_run(data.as_ptr(), data.len());
+}
+
+#[test]
+fn run_test_cases() {
+       use std::fs;
+       use std::io::Read;
+       use lightning_fuzz::utils::test_logger::StringBuffer;
+
+       use std::sync::{atomic, Arc};
+       {
+               let data: Vec<u8> = vec![0];
+               offer_deser_run(data.as_ptr(), data.len());
+       }
+       let mut threads = Vec::new();
+       let threads_running = Arc::new(atomic::AtomicUsize::new(0));
+       if let Ok(tests) = fs::read_dir("test_cases/offer_deser") {
+               for test in tests {
+                       let mut data: Vec<u8> = Vec::new();
+                       let path = test.unwrap().path();
+                       fs::File::open(&path).unwrap().read_to_end(&mut data).unwrap();
+                       threads_running.fetch_add(1, atomic::Ordering::AcqRel);
+
+                       let thread_count_ref = Arc::clone(&threads_running);
+                       let main_thread_ref = std::thread::current();
+                       threads.push((path.file_name().unwrap().to_str().unwrap().to_string(),
+                               std::thread::spawn(move || {
+                                       let string_logger = StringBuffer::new();
+
+                                       let panic_logger = string_logger.clone();
+                                       let res = if ::std::panic::catch_unwind(move || {
+                                               offer_deser_test(&data, panic_logger);
+                                       }).is_err() {
+                                               Some(string_logger.into_string())
+                                       } else { None };
+                                       thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel);
+                                       main_thread_ref.unpark();
+                                       res
+                               })
+                       ));
+                       while threads_running.load(atomic::Ordering::Acquire) > 32 {
+                               std::thread::park();
+                       }
+               }
+       }
+       let mut failed_outputs = Vec::new();
+       for (test, thread) in threads.drain(..) {
+               if let Some(output) = thread.join().unwrap() {
+                       println!("\nOutput of {}:\n{}\n", test, output);
+                       failed_outputs.push(test);
+               }
+       }
+       if !failed_outputs.is_empty() {
+               println!("Test cases which failed: ");
+               for case in failed_outputs {
+                       println!("{}", case);
+               }
+               panic!();
+       }
+}
diff --git a/fuzz/src/bin/refund_deser_target.rs b/fuzz/src/bin/refund_deser_target.rs
new file mode 100644 (file)
index 0000000..c985778
--- /dev/null
@@ -0,0 +1,113 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+// This file is auto-generated by gen_target.sh based on target_template.txt
+// To modify it, modify target_template.txt and run gen_target.sh instead.
+
+#![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
+
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
+extern crate lightning_fuzz;
+use lightning_fuzz::refund_deser::*;
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               refund_deser_run(data.as_ptr(), data.len());
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       refund_deser_run(data.as_ptr(), data.len());
+               });
+       }
+}
+
+#[cfg(feature = "libfuzzer_fuzz")]
+#[macro_use] extern crate libfuzzer_sys;
+#[cfg(feature = "libfuzzer_fuzz")]
+fuzz_target!(|data: &[u8]| {
+       refund_deser_run(data.as_ptr(), data.len());
+});
+
+#[cfg(feature = "stdin_fuzz")]
+fn main() {
+       use std::io::Read;
+
+       let mut data = Vec::with_capacity(8192);
+       std::io::stdin().read_to_end(&mut data).unwrap();
+       refund_deser_run(data.as_ptr(), data.len());
+}
+
+#[test]
+fn run_test_cases() {
+       use std::fs;
+       use std::io::Read;
+       use lightning_fuzz::utils::test_logger::StringBuffer;
+
+       use std::sync::{atomic, Arc};
+       {
+               let data: Vec<u8> = vec![0];
+               refund_deser_run(data.as_ptr(), data.len());
+       }
+       let mut threads = Vec::new();
+       let threads_running = Arc::new(atomic::AtomicUsize::new(0));
+       if let Ok(tests) = fs::read_dir("test_cases/refund_deser") {
+               for test in tests {
+                       let mut data: Vec<u8> = Vec::new();
+                       let path = test.unwrap().path();
+                       fs::File::open(&path).unwrap().read_to_end(&mut data).unwrap();
+                       threads_running.fetch_add(1, atomic::Ordering::AcqRel);
+
+                       let thread_count_ref = Arc::clone(&threads_running);
+                       let main_thread_ref = std::thread::current();
+                       threads.push((path.file_name().unwrap().to_str().unwrap().to_string(),
+                               std::thread::spawn(move || {
+                                       let string_logger = StringBuffer::new();
+
+                                       let panic_logger = string_logger.clone();
+                                       let res = if ::std::panic::catch_unwind(move || {
+                                               refund_deser_test(&data, panic_logger);
+                                       }).is_err() {
+                                               Some(string_logger.into_string())
+                                       } else { None };
+                                       thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel);
+                                       main_thread_ref.unpark();
+                                       res
+                               })
+                       ));
+                       while threads_running.load(atomic::Ordering::Acquire) > 32 {
+                               std::thread::park();
+                       }
+               }
+       }
+       let mut failed_outputs = Vec::new();
+       for (test, thread) in threads.drain(..) {
+               if let Some(output) = thread.join().unwrap() {
+                       println!("\nOutput of {}:\n{}\n", test, output);
+                       failed_outputs.push(test);
+               }
+       }
+       if !failed_outputs.is_empty() {
+               println!("Test cases which failed: ");
+               for case in failed_outputs {
+                       println!("{}", case);
+               }
+               panic!();
+       }
+}
index e1bf9cb540d370972eab7ea9fc58732ef8f6b833..40106ffbb86d5a9e614aa05887546cd582217a70 100644 (file)
@@ -29,6 +29,7 @@ use bitcoin::network::constants::Network;
 
 use bitcoin::hashes::Hash as TraitImport;
 use bitcoin::hashes::sha256::Hash as Sha256;
+use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::{BlockHash, WPubkeyHash};
 
 use lightning::chain;
@@ -36,9 +37,9 @@ use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, chainmonitor, chan
 use lightning::chain::channelmonitor::{ChannelMonitor, MonitorEvent};
 use lightning::chain::transaction::OutPoint;
 use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
-use lightning::chain::keysinterface::{KeyMaterial, KeysInterface, InMemorySigner, Recipient, EntropySource, NodeSigner, SignerProvider};
+use lightning::chain::keysinterface::{KeyMaterial, InMemorySigner, Recipient, EntropySource, NodeSigner, SignerProvider};
 use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
-use lightning::ln::channelmanager::{self, ChainParameters, ChannelDetails, ChannelManager, PaymentSendFailure, ChannelManagerReadArgs, PaymentId};
+use lightning::ln::channelmanager::{ChainParameters, ChannelDetails, ChannelManager, PaymentSendFailure, ChannelManagerReadArgs, PaymentId};
 use lightning::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
 use lightning::ln::msgs::{self, CommitmentUpdate, ChannelMessageHandler, DecodeError, UpdateAddHTLC, Init};
 use lightning::ln::script::ShutdownScript;
@@ -54,14 +55,13 @@ use lightning::routing::router::{InFlightHtlcs, Route, RouteHop, RouteParameters
 use crate::utils::test_logger::{self, Output};
 use crate::utils::test_persister::TestPersister;
 
-use bitcoin::secp256k1::{PublicKey, SecretKey, Scalar};
+use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1};
 use bitcoin::secp256k1::ecdh::SharedSecret;
-use bitcoin::secp256k1::ecdsa::RecoverableSignature;
-use bitcoin::secp256k1::Secp256k1;
+use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
 
 use std::mem;
 use std::cmp::{self, Ordering};
-use std::collections::{HashSet, hash_map, HashMap};
+use hashbrown::{HashSet, hash_map, HashMap};
 use std::sync::{Arc,Mutex};
 use std::sync::atomic;
 use std::io::Cursor;
@@ -97,10 +97,6 @@ impl Router for FuzzRouter {
                        action: msgs::ErrorAction::IgnoreError
                })
        }
-       fn notify_payment_path_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
-       fn notify_payment_path_successful(&self, _path: &[&RouteHop]) {}
-       fn notify_payment_probe_successful(&self, _path: &[&RouteHop]) {}
-       fn notify_payment_probe_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
 }
 
 pub struct TestBroadcaster {}
@@ -152,15 +148,15 @@ impl chain::Watch<EnforcingSigner> for TestChainMonitor {
                self.chain_monitor.watch_channel(funding_txo, monitor)
        }
 
-       fn update_channel(&self, funding_txo: OutPoint, update: channelmonitor::ChannelMonitorUpdate) -> chain::ChannelMonitorUpdateStatus {
+       fn update_channel(&self, funding_txo: OutPoint, update: &channelmonitor::ChannelMonitorUpdate) -> chain::ChannelMonitorUpdateStatus {
                let mut map_lock = self.latest_monitors.lock().unwrap();
                let mut map_entry = match map_lock.entry(funding_txo) {
                        hash_map::Entry::Occupied(entry) => entry,
                        hash_map::Entry::Vacant(_) => panic!("Didn't have monitor on update call"),
                };
                let deserialized_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::
-                       read(&mut Cursor::new(&map_entry.get().1), &*self.keys).unwrap().1;
-               deserialized_monitor.update_monitor(&update, &&TestBroadcaster{}, &FuzzEstimator { ret_val: atomic::AtomicU32::new(253) }, &self.logger).unwrap();
+                       read(&mut Cursor::new(&map_entry.get().1), (&*self.keys, &*self.keys)).unwrap().1;
+               deserialized_monitor.update_monitor(update, &&TestBroadcaster{}, &FuzzEstimator { ret_val: atomic::AtomicU32::new(253) }, &self.logger).unwrap();
                let mut ser = VecWriter(Vec::new());
                deserialized_monitor.write(&mut ser).unwrap();
                map_entry.insert((update.update_id, ser.0));
@@ -174,7 +170,7 @@ impl chain::Watch<EnforcingSigner> for TestChainMonitor {
 }
 
 struct KeyProvider {
-       node_id: u8,
+       node_secret: SecretKey,
        rand_bytes_id: atomic::AtomicU32,
        enforcement_states: Mutex<HashMap<[u8;32], Arc<Mutex<EnforcementState>>>>,
 }
@@ -182,37 +178,45 @@ struct KeyProvider {
 impl EntropySource for KeyProvider {
        fn get_secure_random_bytes(&self) -> [u8; 32] {
                let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed);
-               let mut res = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, self.node_id];
+               let mut res = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, self.node_secret[31]];
                res[30-4..30].copy_from_slice(&id.to_le_bytes());
                res
        }
 }
 
 impl NodeSigner for KeyProvider {
-       fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> {
-               Ok(SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, self.node_id]).unwrap())
-       }
-
        fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
-               let secp_ctx = Secp256k1::signing_only();
-               Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
+               let node_secret = match recipient {
+                       Recipient::Node => Ok(&self.node_secret),
+                       Recipient::PhantomNode => Err(())
+               }?;
+               Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret))
        }
 
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
-               let mut node_secret = self.get_node_secret(recipient)?;
+               let mut node_secret = match recipient {
+                       Recipient::Node => Ok(self.node_secret.clone()),
+                       Recipient::PhantomNode => Err(())
+               }?;
                if let Some(tweak) = tweak {
-                       node_secret = node_secret.mul_tweak(tweak).unwrap();
+                       node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
                }
                Ok(SharedSecret::new(other_key, &node_secret))
        }
 
        fn get_inbound_payment_key_material(&self) -> KeyMaterial {
-               KeyMaterial([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, self.node_id])
+               KeyMaterial([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, self.node_secret[31]])
        }
 
        fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
                unreachable!()
        }
+
+       fn sign_gossip_message(&self, msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
+               let msg_hash = Message::from_slice(&Sha256dHash::hash(&msg.encode()[..])[..]).map_err(|_| ())?;
+               let secp_ctx = Secp256k1::signing_only();
+               Ok(secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
+       }
 }
 
 impl SignerProvider for KeyProvider {
@@ -228,13 +232,12 @@ impl SignerProvider for KeyProvider {
                let id = channel_keys_id[0];
                let keys = InMemorySigner::new(
                        &secp_ctx,
-                       self.get_node_secret(Recipient::Node).unwrap(),
-                       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, self.node_id]).unwrap(),
-                       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, self.node_id]).unwrap(),
-                       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, self.node_id]).unwrap(),
-                       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, self.node_id]).unwrap(),
-                       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, self.node_id]).unwrap(),
-                       [id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_id],
+                       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, self.node_secret[31]]).unwrap(),
+                       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, self.node_secret[31]]).unwrap(),
+                       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, self.node_secret[31]]).unwrap(),
+                       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, self.node_secret[31]]).unwrap(),
+                       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, self.node_secret[31]]).unwrap(),
+                       [id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_secret[31]],
                        channel_value_satoshis,
                        channel_keys_id,
                );
@@ -245,7 +248,7 @@ impl SignerProvider for KeyProvider {
        fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, DecodeError> {
                let mut reader = std::io::Cursor::new(buffer);
 
-               let inner: InMemorySigner = ReadableArgs::read(&mut reader, self.get_node_secret(Recipient::Node).unwrap())?;
+               let inner: InMemorySigner = Readable::read(&mut reader)?;
                let state = self.make_enforcement_state_cell(inner.commitment_seed);
 
                Ok(EnforcingSigner {
@@ -257,21 +260,19 @@ impl SignerProvider for KeyProvider {
 
        fn get_destination_script(&self) -> Script {
                let secp_ctx = Secp256k1::signing_only();
-               let channel_monitor_claim_key = SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, self.node_id]).unwrap();
+               let channel_monitor_claim_key = SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, self.node_secret[31]]).unwrap();
                let our_channel_monitor_claim_key_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize());
                Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script()
        }
 
        fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
                let secp_ctx = Secp256k1::signing_only();
-               let secret_key = SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, self.node_id]).unwrap();
+               let secret_key = SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, self.node_secret[31]]).unwrap();
                let pubkey_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &secret_key).serialize());
                ShutdownScript::new_p2wpkh(&pubkey_hash)
        }
 }
 
-impl KeysInterface for KeyProvider {}
-
 impl KeyProvider {
        fn make_enforcement_state_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<EnforcementState>> {
                let mut revoked_commitments = self.enforcement_states.lock().unwrap();
@@ -294,7 +295,7 @@ fn check_api_err(api_err: APIError) {
                        // all others. If you hit this panic, the list of acceptable errors
                        // is probably just stale and you should add new messages here.
                        match err.as_str() {
-                               "Peer for first hop currently disconnected/pending monitor update!" => {},
+                               "Peer for first hop currently disconnected" => {},
                                _ if err.starts_with("Cannot push more than their max accepted HTLCs ") => {},
                                _ if err.starts_with("Cannot send value that would put us over the max HTLC value in flight our peer will accept ") => {},
                                _ if err.starts_with("Cannot send value that would put our balance under counterparty-announced channel reserve value") => {},
@@ -328,14 +329,14 @@ fn check_payment_err(send_err: PaymentSendFailure) {
        }
 }
 
-type ChanMan<'a> = ChannelManager<Arc<TestChainMonitor>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, &'a FuzzRouter, Arc<dyn Logger>>;
+type ChanMan<'a> = ChannelManager<Arc<TestChainMonitor>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<FuzzEstimator>, &'a FuzzRouter, Arc<dyn Logger>>;
 
 #[inline]
 fn get_payment_secret_hash(dest: &ChanMan, payment_id: &mut u8) -> Option<(PaymentSecret, PaymentHash)> {
        let mut payment_hash;
        for _ in 0..256 {
                payment_hash = PaymentHash(Sha256::hash(&[*payment_id; 1]).into_inner());
-               if let Ok(payment_secret) = dest.create_inbound_payment_for_hash(payment_hash, None, 3600) {
+               if let Ok(payment_secret) = dest.create_inbound_payment_for_hash(payment_hash, None, 3600, None) {
                        return Some((payment_secret, payment_hash));
                }
                *payment_id = payment_id.wrapping_add(1);
@@ -353,9 +354,9 @@ fn send_payment(source: &ChanMan, dest: &ChanMan, dest_chan_id: u64, amt: u64, p
        if let Err(err) = source.send_payment(&Route {
                paths: vec![vec![RouteHop {
                        pubkey: dest.get_our_node_id(),
-                       node_features: channelmanager::provided_node_features(),
+                       node_features: dest.node_features(),
                        short_channel_id: dest_chan_id,
-                       channel_features: channelmanager::provided_channel_features(),
+                       channel_features: dest.channel_features(),
                        fee_msat: amt,
                        cltv_expiry_delta: 200,
                }]],
@@ -375,16 +376,16 @@ fn send_hop_payment(source: &ChanMan, middle: &ChanMan, middle_chan_id: u64, des
        if let Err(err) = source.send_payment(&Route {
                paths: vec![vec![RouteHop {
                        pubkey: middle.get_our_node_id(),
-                       node_features: channelmanager::provided_node_features(),
+                       node_features: middle.node_features(),
                        short_channel_id: middle_chan_id,
-                       channel_features: channelmanager::provided_channel_features(),
+                       channel_features: middle.channel_features(),
                        fee_msat: 50000,
                        cltv_expiry_delta: 100,
                },RouteHop {
                        pubkey: dest.get_our_node_id(),
-                       node_features: channelmanager::provided_node_features(),
+                       node_features: dest.node_features(),
                        short_channel_id: dest_chan_id,
-                       channel_features: channelmanager::provided_channel_features(),
+                       channel_features: dest.channel_features(),
                        fee_msat: amt,
                        cltv_expiry_delta: 200,
                }]],
@@ -404,7 +405,8 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
        macro_rules! make_node {
                ($node_id: expr, $fee_estimator: expr) => { {
                        let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone()));
-                       let keys_manager = Arc::new(KeyProvider { node_id: $node_id, rand_bytes_id: atomic::AtomicU32::new(0), enforcement_states: Mutex::new(HashMap::new()) });
+                       let node_secret = SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, $node_id]).unwrap();
+                       let keys_manager = Arc::new(KeyProvider { node_secret, rand_bytes_id: atomic::AtomicU32::new(0), enforcement_states: Mutex::new(HashMap::new()) });
                        let monitor = Arc::new(TestChainMonitor::new(broadcast.clone(), logger.clone(), $fee_estimator.clone(),
                                Arc::new(TestPersister {
                                        update_ret: Mutex::new(ChannelMonitorUpdateStatus::Completed)
@@ -416,9 +418,9 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                        let network = Network::Bitcoin;
                        let params = ChainParameters {
                                network,
-                               best_block: BestBlock::from_genesis(network),
+                               best_block: BestBlock::from_network(network),
                        };
-                       (ChannelManager::new($fee_estimator.clone(), monitor.clone(), broadcast.clone(), &router, Arc::clone(&logger), keys_manager.clone(), config, params),
+                       (ChannelManager::new($fee_estimator.clone(), monitor.clone(), broadcast.clone(), &router, Arc::clone(&logger), keys_manager.clone(), keys_manager.clone(), keys_manager.clone(), config, params),
                        monitor, keys_manager)
                } }
        }
@@ -439,7 +441,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                        let mut monitors = HashMap::new();
                        let mut old_monitors = $old_monitors.latest_monitors.lock().unwrap();
                        for (outpoint, (update_id, monitor_ser)) in old_monitors.drain() {
-                               monitors.insert(outpoint, <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(&monitor_ser), &*$keys_manager).expect("Failed to read monitor").1);
+                               monitors.insert(outpoint, <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(&monitor_ser), (&*$keys_manager, &*$keys_manager)).expect("Failed to read monitor").1);
                                chain_monitor.latest_monitors.lock().unwrap().insert(outpoint, (update_id, monitor_ser));
                        }
                        let mut monitor_refs = HashMap::new();
@@ -448,7 +450,9 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                        }
 
                        let read_args = ChannelManagerReadArgs {
-                               keys_manager,
+                               entropy_source: keys_manager.clone(),
+                               node_signer: keys_manager.clone(),
+                               signer_provider: keys_manager.clone(),
                                fee_estimator: $fee_estimator.clone(),
                                chain_monitor: chain_monitor.clone(),
                                tx_broadcaster: broadcast.clone(),
@@ -470,8 +474,8 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
        let mut channel_txn = Vec::new();
        macro_rules! make_channel {
                ($source: expr, $dest: expr, $chan_id: expr) => { {
-                       $source.peer_connected(&$dest.get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-                       $dest.peer_connected(&$source.get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+                       $source.peer_connected(&$dest.get_our_node_id(), &Init { features: $dest.init_features(), remote_network_address: None }, true).unwrap();
+                       $dest.peer_connected(&$source.get_our_node_id(), &Init { features: $source.init_features(), remote_network_address: None }, false).unwrap();
 
                        $source.create_channel($dest.get_our_node_id(), 100_000, 42, 0, None).unwrap();
                        let open_channel = {
@@ -482,7 +486,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                                } else { panic!("Wrong event type"); }
                        };
 
-                       $dest.handle_open_channel(&$source.get_our_node_id(), channelmanager::provided_init_features(), &open_channel);
+                       $dest.handle_open_channel(&$source.get_our_node_id(), &open_channel);
                        let accept_channel = {
                                let events = $dest.get_and_clear_pending_msg_events();
                                assert_eq!(events.len(), 1);
@@ -491,7 +495,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                                } else { panic!("Wrong event type"); }
                        };
 
-                       $source.handle_accept_channel(&$dest.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+                       $source.handle_accept_channel(&$dest.get_our_node_id(), &accept_channel);
                        let funding_output;
                        {
                                let events = $source.get_and_clear_pending_events();
@@ -910,6 +914,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                                                events::Event::PaymentClaimed { .. } => {},
                                                events::Event::PaymentPathSuccessful { .. } => {},
                                                events::Event::PaymentPathFailed { .. } => {},
+                                               events::Event::PaymentFailed { .. } => {},
                                                events::Event::ProbeSuccessful { .. } | events::Event::ProbeFailed { .. } => {
                                                        // Even though we don't explicitly send probes, because probes are
                                                        // detected based on hashing the payment hash+preimage, its rather
@@ -974,31 +979,31 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
 
                        0x0c => {
                                if !chan_a_disconnected {
-                                       nodes[0].peer_disconnected(&nodes[1].get_our_node_id(), false);
-                                       nodes[1].peer_disconnected(&nodes[0].get_our_node_id(), false);
+                                       nodes[0].peer_disconnected(&nodes[1].get_our_node_id());
+                                       nodes[1].peer_disconnected(&nodes[0].get_our_node_id());
                                        chan_a_disconnected = true;
                                        drain_msg_events_on_disconnect!(0);
                                }
                        },
                        0x0d => {
                                if !chan_b_disconnected {
-                                       nodes[1].peer_disconnected(&nodes[2].get_our_node_id(), false);
-                                       nodes[2].peer_disconnected(&nodes[1].get_our_node_id(), false);
+                                       nodes[1].peer_disconnected(&nodes[2].get_our_node_id());
+                                       nodes[2].peer_disconnected(&nodes[1].get_our_node_id());
                                        chan_b_disconnected = true;
                                        drain_msg_events_on_disconnect!(2);
                                }
                        },
                        0x0e => {
                                if chan_a_disconnected {
-                                       nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-                                       nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+                                       nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: nodes[1].init_features(), remote_network_address: None }, true).unwrap();
+                                       nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: nodes[0].init_features(), remote_network_address: None }, false).unwrap();
                                        chan_a_disconnected = false;
                                }
                        },
                        0x0f => {
                                if chan_b_disconnected {
-                                       nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-                                       nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+                                       nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: nodes[2].init_features(), remote_network_address: None }, true).unwrap();
+                                       nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: nodes[1].init_features(), remote_network_address: None }, false).unwrap();
                                        chan_b_disconnected = false;
                                }
                        },
@@ -1035,7 +1040,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
 
                        0x2c => {
                                if !chan_a_disconnected {
-                                       nodes[1].peer_disconnected(&nodes[0].get_our_node_id(), false);
+                                       nodes[1].peer_disconnected(&nodes[0].get_our_node_id());
                                        chan_a_disconnected = true;
                                        drain_msg_events_on_disconnect!(0);
                                }
@@ -1049,14 +1054,14 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                        },
                        0x2d => {
                                if !chan_a_disconnected {
-                                       nodes[0].peer_disconnected(&nodes[1].get_our_node_id(), false);
+                                       nodes[0].peer_disconnected(&nodes[1].get_our_node_id());
                                        chan_a_disconnected = true;
                                        nodes[0].get_and_clear_pending_msg_events();
                                        ab_events.clear();
                                        ba_events.clear();
                                }
                                if !chan_b_disconnected {
-                                       nodes[2].peer_disconnected(&nodes[1].get_our_node_id(), false);
+                                       nodes[2].peer_disconnected(&nodes[1].get_our_node_id());
                                        chan_b_disconnected = true;
                                        nodes[2].get_and_clear_pending_msg_events();
                                        bc_events.clear();
@@ -1068,7 +1073,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                        },
                        0x2e => {
                                if !chan_b_disconnected {
-                                       nodes[1].peer_disconnected(&nodes[2].get_our_node_id(), false);
+                                       nodes[1].peer_disconnected(&nodes[2].get_our_node_id());
                                        chan_b_disconnected = true;
                                        drain_msg_events_on_disconnect!(2);
                                }
@@ -1193,13 +1198,13 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
 
                                // Next, make sure peers are all connected to each other
                                if chan_a_disconnected {
-                                       nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-                                       nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+                                       nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: nodes[1].init_features(), remote_network_address: None }, true).unwrap();
+                                       nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: nodes[0].init_features(), remote_network_address: None }, false).unwrap();
                                        chan_a_disconnected = false;
                                }
                                if chan_b_disconnected {
-                                       nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-                                       nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+                                       nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: nodes[2].init_features(), remote_network_address: None }, true).unwrap();
+                                       nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: nodes[1].init_features(), remote_network_address: None }, false).unwrap();
                                        chan_b_disconnected = false;
                                }
 
index 8c8f4aedf7a438d2a6ecf7b0f9a2eb95d9c6877d..61744ace7c733419149455dc21ab70fe7e496b60 100644 (file)
@@ -22,10 +22,10 @@ impl Writer for VecWriter {
 
 #[inline]
 pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
-       if let Ok((latest_block_hash, monitor)) = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(data), &OnlyReadsKeysInterface {}) {
+       if let Ok((latest_block_hash, monitor)) = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(data), (&OnlyReadsKeysInterface {}, &OnlyReadsKeysInterface {})) {
                let mut w = VecWriter(Vec::new());
                monitor.write(&mut w).unwrap();
-               let deserialized_copy = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(&w.0), &OnlyReadsKeysInterface {}).unwrap();
+               let deserialized_copy = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(&w.0), (&OnlyReadsKeysInterface {}, &OnlyReadsKeysInterface {})).unwrap();
                assert!(latest_block_hash == deserialized_copy.0);
                assert!(monitor == deserialized_copy.1);
        }
index 2d9be101ef89faf2fdd9901292becec1f013e26b..05ae32e4ca0e080348955b51cc7d22dc3e71e66e 100644 (file)
@@ -26,6 +26,7 @@ use bitcoin::network::constants::Network;
 use bitcoin::hashes::Hash as TraitImport;
 use bitcoin::hashes::HashEngine as TraitImportEngine;
 use bitcoin::hashes::sha256::Hash as Sha256;
+use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash};
 
 use lightning::chain;
@@ -33,32 +34,32 @@ use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen};
 use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
 use lightning::chain::chainmonitor;
 use lightning::chain::transaction::OutPoint;
-use lightning::chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, KeysInterface, EntropySource, NodeSigner, SignerProvider};
+use lightning::chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider};
 use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
 use lightning::ln::channelmanager::{ChainParameters, ChannelDetails, ChannelManager, PaymentId};
 use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor,IgnoringMessageHandler};
 use lightning::ln::msgs::{self, DecodeError};
 use lightning::ln::script::ShutdownScript;
 use lightning::routing::gossip::{P2PGossipSync, NetworkGraph};
-use lightning::routing::router::{find_route, InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters, Router};
+use lightning::routing::utxo::UtxoLookup;
+use lightning::routing::router::{find_route, InFlightHtlcs, PaymentParameters, Route, RouteParameters, Router};
 use lightning::routing::scoring::FixedPenaltyScorer;
 use lightning::util::config::UserConfig;
 use lightning::util::errors::APIError;
 use lightning::util::events::Event;
 use lightning::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
 use lightning::util::logger::Logger;
-use lightning::util::ser::ReadableArgs;
+use lightning::util::ser::{Readable, Writeable};
 
 use crate::utils::test_logger;
 use crate::utils::test_persister::TestPersister;
 
-use bitcoin::secp256k1::{PublicKey, SecretKey, Scalar};
+use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1};
 use bitcoin::secp256k1::ecdh::SharedSecret;
-use bitcoin::secp256k1::ecdsa::RecoverableSignature;
-use bitcoin::secp256k1::Secp256k1;
+use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
 
 use std::cell::RefCell;
-use std::collections::{HashMap, hash_map};
+use hashbrown::{HashMap, hash_map};
 use std::convert::TryInto;
 use std::cmp;
 use std::sync::{Arc, Mutex};
@@ -139,10 +140,6 @@ impl Router for FuzzRouter {
                        action: msgs::ErrorAction::IgnoreError
                })
        }
-       fn notify_payment_path_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
-       fn notify_payment_path_successful(&self, _path: &[&RouteHop]) {}
-       fn notify_payment_probe_successful(&self, _path: &[&RouteHop]) {}
-       fn notify_payment_probe_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
 }
 
 struct TestBroadcaster {
@@ -182,8 +179,8 @@ impl<'a> std::hash::Hash for Peer<'a> {
 
 type ChannelMan<'a> = ChannelManager<
        Arc<chainmonitor::ChainMonitor<EnforcingSigner, Arc<dyn chain::Filter>, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<TestPersister>>>,
-       Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, &'a FuzzRouter, Arc<dyn Logger>>;
-type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan<'a>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn chain::Access>, Arc<dyn Logger>>>, IgnoringMessageHandler, Arc<dyn Logger>, IgnoringMessageHandler>;
+       Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<FuzzEstimator>, &'a FuzzRouter, Arc<dyn Logger>>;
+type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan<'a>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn UtxoLookup>, Arc<dyn Logger>>>, IgnoringMessageHandler, Arc<dyn Logger>, IgnoringMessageHandler, Arc<KeyProvider>>;
 
 struct MoneyLossDetector<'a> {
        manager: Arc<ChannelMan<'a>>,
@@ -293,19 +290,21 @@ impl EntropySource for KeyProvider {
 }
 
 impl NodeSigner for KeyProvider {
-       fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> {
-               Ok(self.node_secret.clone())
-       }
-
        fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
-               let secp_ctx = Secp256k1::signing_only();
-               Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
+               let node_secret = match recipient {
+                       Recipient::Node => Ok(&self.node_secret),
+                       Recipient::PhantomNode => Err(())
+               }?;
+               Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret))
        }
 
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
-               let mut node_secret = self.get_node_secret(recipient)?;
+               let mut node_secret = match recipient {
+                       Recipient::Node => Ok(self.node_secret.clone()),
+                       Recipient::PhantomNode => Err(())
+               }?;
                if let Some(tweak) = tweak {
-                       node_secret = node_secret.mul_tweak(tweak).unwrap();
+                       node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
                }
                Ok(SharedSecret::new(other_key, &node_secret))
        }
@@ -317,6 +316,12 @@ impl NodeSigner for KeyProvider {
        fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
                unreachable!()
        }
+
+       fn sign_gossip_message(&self, msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
+               let msg_hash = Message::from_slice(&Sha256dHash::hash(&msg.encode()[..])[..]).map_err(|_| ())?;
+               let secp_ctx = Secp256k1::signing_only();
+               Ok(secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
+       }
 }
 
 impl SignerProvider for KeyProvider {
@@ -335,7 +340,6 @@ impl SignerProvider for KeyProvider {
                EnforcingSigner::new_with_revoked(if inbound {
                        InMemorySigner::new(
                                &secp_ctx,
-                               self.node_secret.clone(),
                                SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ctr]).unwrap(),
                                SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, ctr]).unwrap(),
                                SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, ctr]).unwrap(),
@@ -348,7 +352,6 @@ impl SignerProvider for KeyProvider {
                } else {
                        InMemorySigner::new(
                                &secp_ctx,
-                               self.node_secret.clone(),
                                SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, ctr]).unwrap(),
                                SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, ctr]).unwrap(),
                                SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, ctr]).unwrap(),
@@ -362,7 +365,7 @@ impl SignerProvider for KeyProvider {
        }
 
        fn read_chan_signer(&self, mut data: &[u8]) -> Result<EnforcingSigner, DecodeError> {
-               let inner: InMemorySigner = ReadableArgs::read(&mut data, self.node_secret.clone())?;
+               let inner: InMemorySigner = Readable::read(&mut data)?;
                let state = Arc::new(Mutex::new(EnforcementState::new()));
 
                Ok(EnforcingSigner::new_with_revoked(
@@ -387,8 +390,6 @@ impl SignerProvider for KeyProvider {
        }
 }
 
-impl KeysInterface for KeyProvider {}
-
 #[inline]
 pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
        let input = Arc::new(InputData {
@@ -441,15 +442,15 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
        let network = Network::Bitcoin;
        let params = ChainParameters {
                network,
-               best_block: BestBlock::from_genesis(network),
+               best_block: BestBlock::from_network(network),
        };
-       let channelmanager = Arc::new(ChannelManager::new(fee_est.clone(), monitor.clone(), broadcast.clone(), &router, Arc::clone(&logger), keys_manager.clone(), config, params));
-       // Adding new calls to `KeysInterface::get_secure_random_bytes` during startup can change all the
+       let channelmanager = Arc::new(ChannelManager::new(fee_est.clone(), monitor.clone(), broadcast.clone(), &router, Arc::clone(&logger), keys_manager.clone(), keys_manager.clone(), keys_manager.clone(), config, params));
+       // Adding new calls to `EntropySource::get_secure_random_bytes` during startup can change all the
        // keys subsequently generated in this test. Rather than regenerating all the messages manually,
        // it's easier to just increment the counter here so the keys don't change.
        keys_manager.counter.fetch_sub(3, Ordering::AcqRel);
-       let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret(Recipient::Node).unwrap());
-       let network_graph = Arc::new(NetworkGraph::new(genesis_block(network).block_hash(), Arc::clone(&logger)));
+       let our_id = &keys_manager.get_node_id(Recipient::Node).unwrap();
+       let network_graph = Arc::new(NetworkGraph::new(network, Arc::clone(&logger)));
        let gossip_sync = Arc::new(P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger)));
        let scorer = FixedPenaltyScorer::with_penalty(0);
 
@@ -458,7 +459,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                chan_handler: channelmanager.clone(),
                route_handler: gossip_sync.clone(),
                onion_message_handler: IgnoringMessageHandler {},
-       }, our_network_key, 0, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0], Arc::clone(&logger), IgnoringMessageHandler{}));
+       }, 0, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0], Arc::clone(&logger), IgnoringMessageHandler{}, keys_manager.clone()));
 
        let mut should_forward = false;
        let mut payments_received: Vec<PaymentHash> = Vec::new();
@@ -508,11 +509,10 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                        },
                        4 => {
                                let final_value_msat = slice_to_be24(get_slice!(3)) as u64;
-                               let payment_params = PaymentParameters::from_node_id(get_pubkey!());
+                               let payment_params = PaymentParameters::from_node_id(get_pubkey!(), 42);
                                let params = RouteParameters {
                                        payment_params,
                                        final_value_msat,
-                                       final_cltv_expiry_delta: 42,
                                };
                                let random_seed_bytes: [u8; 32] = keys_manager.get_secure_random_bytes();
                                let route = match find_route(&our_id, &params, &network_graph, None, Arc::clone(&logger), &scorer, &random_seed_bytes) {
@@ -532,11 +532,10 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                        },
                        15 => {
                                let final_value_msat = slice_to_be24(get_slice!(3)) as u64;
-                               let payment_params = PaymentParameters::from_node_id(get_pubkey!());
+                               let payment_params = PaymentParameters::from_node_id(get_pubkey!(), 42);
                                let params = RouteParameters {
                                        payment_params,
                                        final_value_msat,
-                                       final_cltv_expiry_delta: 42,
                                };
                                let random_seed_bytes: [u8; 32] = keys_manager.get_secure_random_bytes();
                                let mut route = match find_route(&our_id, &params, &network_graph, None, Arc::clone(&logger), &scorer, &random_seed_bytes) {
@@ -601,7 +600,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                let payment_hash = PaymentHash(Sha256::from_engine(sha).into_inner());
                                // Note that this may fail - our hashes may collide and we'll end up trying to
                                // double-register the same payment_hash.
-                               let _ = channelmanager.create_inbound_payment_for_hash(payment_hash, None, 1);
+                               let _ = channelmanager.create_inbound_payment_for_hash(payment_hash, None, 1, None);
                        },
                        9 => {
                                for payment in payments_received.drain(..) {
@@ -633,9 +632,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                        if let Err(e) = channelmanager.funding_transaction_generated(&funding_generation.0, &funding_generation.1, tx.clone()) {
                                                // It's possible the channel has been closed in the mean time, but any other
                                                // failure may be a bug.
-                                               if let APIError::ChannelUnavailable { err } = e {
-                                                       assert_eq!(err, "No such channel");
-                                               } else { panic!(); }
+                                               if let APIError::ChannelUnavailable { .. } = e { } else { panic!(); }
                                        }
                                        pending_funding_signatures.insert(funding_output, tx);
                                }
diff --git a/fuzz/src/indexedmap.rs b/fuzz/src/indexedmap.rs
new file mode 100644 (file)
index 0000000..7cbb895
--- /dev/null
@@ -0,0 +1,161 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+use lightning::util::indexed_map::{IndexedMap, self};
+use std::collections::{BTreeMap, btree_map};
+use hashbrown::HashSet;
+
+use crate::utils::test_logger;
+
+use std::ops::{RangeBounds, Bound};
+
+struct ExclLowerInclUpper(u8, u8);
+impl RangeBounds<u8> for ExclLowerInclUpper {
+       fn start_bound(&self) -> Bound<&u8> { Bound::Excluded(&self.0) }
+       fn end_bound(&self) -> Bound<&u8> { Bound::Included(&self.1) }
+}
+struct ExclLowerExclUpper(u8, u8);
+impl RangeBounds<u8> for ExclLowerExclUpper {
+       fn start_bound(&self) -> Bound<&u8> { Bound::Excluded(&self.0) }
+       fn end_bound(&self) -> Bound<&u8> { Bound::Excluded(&self.1) }
+}
+
+fn check_eq(btree: &BTreeMap<u8, u8>, mut indexed: IndexedMap<u8, u8>) {
+       assert_eq!(btree.len(), indexed.len());
+       assert_eq!(btree.is_empty(), indexed.is_empty());
+
+       let mut btree_clone = btree.clone();
+       assert!(btree_clone == *btree);
+       let mut indexed_clone = indexed.clone();
+       assert!(indexed_clone == indexed);
+
+       for k in 0..=255 {
+               assert_eq!(btree.contains_key(&k), indexed.contains_key(&k));
+               assert_eq!(btree.get(&k), indexed.get(&k));
+
+               let btree_entry = btree_clone.entry(k);
+               let indexed_entry = indexed_clone.entry(k);
+               match btree_entry {
+                       btree_map::Entry::Occupied(mut bo) => {
+                               if let indexed_map::Entry::Occupied(mut io) = indexed_entry {
+                                       assert_eq!(bo.get(), io.get());
+                                       assert_eq!(bo.get_mut(), io.get_mut());
+                               } else { panic!(); }
+                       },
+                       btree_map::Entry::Vacant(_) => {
+                               if let indexed_map::Entry::Vacant(_) = indexed_entry {
+                               } else { panic!(); }
+                       }
+               }
+       }
+
+       const STRIDE: u8 = 16;
+       for range_type in 0..4 {
+               for k in 0..=255/STRIDE {
+                       let lower_bound = k * STRIDE;
+                       let upper_bound = lower_bound + (STRIDE - 1);
+                       macro_rules! range { ($map: expr) => {
+                               match range_type {
+                                       0 => $map.range(lower_bound..upper_bound),
+                                       1 => $map.range(lower_bound..=upper_bound),
+                                       2 => $map.range(ExclLowerInclUpper(lower_bound, upper_bound)),
+                                       3 => $map.range(ExclLowerExclUpper(lower_bound, upper_bound)),
+                                       _ => unreachable!(),
+                               }
+                       } }
+                       let mut btree_iter = range!(btree);
+                       let mut indexed_iter = range!(indexed);
+                       loop {
+                               let b_v = btree_iter.next();
+                               let i_v = indexed_iter.next();
+                               assert_eq!(b_v, i_v);
+                               if b_v.is_none() { break; }
+                       }
+               }
+       }
+
+       let mut key_set = HashSet::with_capacity(256);
+       for k in indexed.unordered_keys() {
+               assert!(key_set.insert(*k));
+               assert!(btree.contains_key(k));
+       }
+       assert_eq!(key_set.len(), btree.len());
+
+       key_set.clear();
+       for (k, v) in indexed.unordered_iter() {
+               assert!(key_set.insert(*k));
+               assert_eq!(btree.get(k).unwrap(), v);
+       }
+       assert_eq!(key_set.len(), btree.len());
+
+       key_set.clear();
+       for (k, v) in indexed_clone.unordered_iter_mut() {
+               assert!(key_set.insert(*k));
+               assert_eq!(btree.get(k).unwrap(), v);
+       }
+       assert_eq!(key_set.len(), btree.len());
+}
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       if data.len() % 2 != 0 { return; }
+       let mut btree = BTreeMap::new();
+       let mut indexed = IndexedMap::new();
+
+       // Read in k-v pairs from the input and insert them into the maps then check that the maps are
+       // equivalent in every way we can read them.
+       for tuple in data.windows(2) {
+               let prev_value_b = btree.insert(tuple[0], tuple[1]);
+               let prev_value_i = indexed.insert(tuple[0], tuple[1]);
+               assert_eq!(prev_value_b, prev_value_i);
+       }
+       check_eq(&btree, indexed.clone());
+
+       // Now, modify the maps in all the ways we have to do so, checking that the maps remain
+       // equivalent as we go.
+       for (k, v) in indexed.unordered_iter_mut() {
+               *v = *k;
+               *btree.get_mut(k).unwrap() = *k;
+       }
+       check_eq(&btree, indexed.clone());
+
+       for k in 0..=255 {
+               match btree.entry(k) {
+                       btree_map::Entry::Occupied(mut bo) => {
+                               if let indexed_map::Entry::Occupied(mut io) = indexed.entry(k) {
+                                       if k < 64 {
+                                               *io.get_mut() ^= 0xff;
+                                               *bo.get_mut() ^= 0xff;
+                                       } else if k < 128 {
+                                               *io.into_mut() ^= 0xff;
+                                               *bo.get_mut() ^= 0xff;
+                                       } else {
+                                               assert_eq!(bo.remove_entry(), io.remove_entry());
+                                       }
+                               } else { panic!(); }
+                       },
+                       btree_map::Entry::Vacant(bv) => {
+                               if let indexed_map::Entry::Vacant(iv) = indexed.entry(k) {
+                                       bv.insert(k);
+                                       iv.insert(k);
+                               } else { panic!(); }
+                       },
+               }
+       }
+       check_eq(&btree, indexed);
+}
+
+pub fn indexedmap_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
+       do_test(data);
+}
+
+#[no_mangle]
+pub extern "C" fn indexedmap_run(data: *const u8, datalen: usize) {
+       do_test(unsafe { std::slice::from_raw_parts(data, datalen) });
+}
diff --git a/fuzz/src/invoice_deser.rs b/fuzz/src/invoice_deser.rs
new file mode 100644 (file)
index 0000000..7b93fd3
--- /dev/null
@@ -0,0 +1,31 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+use crate::utils::test_logger;
+use lightning::offers::invoice::Invoice;
+use lightning::util::ser::Writeable;
+use std::convert::TryFrom;
+
+#[inline]
+pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
+       if let Ok(invoice) = Invoice::try_from(data.to_vec()) {
+               let mut bytes = Vec::with_capacity(data.len());
+               invoice.write(&mut bytes).unwrap();
+               assert_eq!(data, bytes);
+       }
+}
+
+pub fn invoice_deser_test<Out: test_logger::Output>(data: &[u8], out: Out) {
+       do_test(data, out);
+}
+
+#[no_mangle]
+pub extern "C" fn invoice_deser_run(data: *const u8, datalen: usize) {
+       do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {});
+}
diff --git a/fuzz/src/invoice_request_deser.rs b/fuzz/src/invoice_request_deser.rs
new file mode 100644 (file)
index 0000000..aa3045c
--- /dev/null
@@ -0,0 +1,112 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+use bitcoin::secp256k1::{KeyPair, Parity, PublicKey, Secp256k1, SecretKey, self};
+use crate::utils::test_logger;
+use core::convert::{Infallible, TryFrom};
+use lightning::chain::keysinterface::EntropySource;
+use lightning::ln::PaymentHash;
+use lightning::ln::features::BlindedHopFeatures;
+use lightning::offers::invoice::{BlindedPayInfo, UnsignedInvoice};
+use lightning::offers::invoice_request::InvoiceRequest;
+use lightning::offers::parse::SemanticError;
+use lightning::onion_message::BlindedPath;
+use lightning::util::ser::Writeable;
+
+#[inline]
+pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
+       if let Ok(invoice_request) = InvoiceRequest::try_from(data.to_vec()) {
+               let mut bytes = Vec::with_capacity(data.len());
+               invoice_request.write(&mut bytes).unwrap();
+               assert_eq!(data, bytes);
+
+               let secp_ctx = Secp256k1::new();
+               let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
+               let mut buffer = Vec::new();
+
+               if let Ok(unsigned_invoice) = build_response(&invoice_request, &secp_ctx) {
+                       let signing_pubkey = unsigned_invoice.signing_pubkey();
+                       let (x_only_pubkey, _) = keys.x_only_public_key();
+                       let odd_pubkey = x_only_pubkey.public_key(Parity::Odd);
+                       let even_pubkey = x_only_pubkey.public_key(Parity::Even);
+                       if signing_pubkey == odd_pubkey || signing_pubkey == even_pubkey {
+                               unsigned_invoice
+                                       .sign::<_, Infallible>(
+                                               |digest| Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys))
+                                       )
+                                       .unwrap()
+                                       .write(&mut buffer)
+                                       .unwrap();
+                       } else {
+                               unsigned_invoice
+                                       .sign::<_, Infallible>(
+                                               |digest| Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys))
+                                       )
+                                       .unwrap_err();
+                       }
+               }
+       }
+}
+
+struct Randomness;
+
+impl EntropySource for Randomness {
+       fn get_secure_random_bytes(&self) -> [u8; 32] { [42; 32] }
+}
+
+fn pubkey(byte: u8) -> PublicKey {
+       let secp_ctx = Secp256k1::new();
+       PublicKey::from_secret_key(&secp_ctx, &privkey(byte))
+}
+
+fn privkey(byte: u8) -> SecretKey {
+       SecretKey::from_slice(&[byte; 32]).unwrap()
+}
+
+fn build_response<'a, T: secp256k1::Signing + secp256k1::Verification>(
+       invoice_request: &'a InvoiceRequest, secp_ctx: &Secp256k1<T>
+) -> Result<UnsignedInvoice<'a>, SemanticError> {
+       let entropy_source = Randomness {};
+       let paths = vec![
+               BlindedPath::new(&[pubkey(43), pubkey(44), pubkey(42)], &entropy_source, secp_ctx).unwrap(),
+               BlindedPath::new(&[pubkey(45), pubkey(46), pubkey(42)], &entropy_source, secp_ctx).unwrap(),
+       ];
+
+       let payinfo = vec![
+               BlindedPayInfo {
+                       fee_base_msat: 1,
+                       fee_proportional_millionths: 1_000,
+                       cltv_expiry_delta: 42,
+                       htlc_minimum_msat: 100,
+                       htlc_maximum_msat: 1_000_000_000_000,
+                       features: BlindedHopFeatures::empty(),
+               },
+               BlindedPayInfo {
+                       fee_base_msat: 1,
+                       fee_proportional_millionths: 1_000,
+                       cltv_expiry_delta: 42,
+                       htlc_minimum_msat: 100,
+                       htlc_maximum_msat: 1_000_000_000_000,
+                       features: BlindedHopFeatures::empty(),
+               },
+       ];
+
+       let payment_paths = paths.into_iter().zip(payinfo.into_iter()).collect();
+       let payment_hash = PaymentHash([42; 32]);
+       invoice_request.respond_with(payment_paths, payment_hash)?.build()
+}
+
+pub fn invoice_request_deser_test<Out: test_logger::Output>(data: &[u8], out: Out) {
+       do_test(data, out);
+}
+
+#[no_mangle]
+pub extern "C" fn invoice_request_deser_run(data: *const u8, datalen: usize) {
+       do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {});
+}
index 2238a9702a9563a78e59ef8010f6e816f282b4b1..92142e5642313d436d86eddcdfee4e6c9fd25295 100644 (file)
@@ -14,12 +14,18 @@ extern crate hex;
 
 pub mod utils;
 
+pub mod bech32_parse;
 pub mod chanmon_deser;
 pub mod chanmon_consistency;
 pub mod full_stack;
+pub mod indexedmap;
+pub mod invoice_deser;
+pub mod invoice_request_deser;
+pub mod offer_deser;
 pub mod onion_message;
 pub mod peer_crypt;
 pub mod process_network_graph;
+pub mod refund_deser;
 pub mod router;
 pub mod zbase32;
 
diff --git a/fuzz/src/offer_deser.rs b/fuzz/src/offer_deser.rs
new file mode 100644 (file)
index 0000000..213742d
--- /dev/null
@@ -0,0 +1,69 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey};
+use crate::utils::test_logger;
+use core::convert::{Infallible, TryFrom};
+use lightning::offers::invoice_request::UnsignedInvoiceRequest;
+use lightning::offers::offer::{Amount, Offer, Quantity};
+use lightning::offers::parse::SemanticError;
+use lightning::util::ser::Writeable;
+
+#[inline]
+pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
+       if let Ok(offer) = Offer::try_from(data.to_vec()) {
+               let mut bytes = Vec::with_capacity(data.len());
+               offer.write(&mut bytes).unwrap();
+               assert_eq!(data, bytes);
+
+               let secp_ctx = Secp256k1::new();
+               let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
+               let pubkey = PublicKey::from(keys);
+               let mut buffer = Vec::new();
+
+               if let Ok(invoice_request) = build_response(&offer, pubkey) {
+                       invoice_request
+                               .sign::<_, Infallible>(
+                                       |digest| Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys))
+                               )
+                               .unwrap()
+                               .write(&mut buffer)
+                               .unwrap();
+               }
+       }
+}
+
+fn build_response<'a>(
+       offer: &'a Offer, pubkey: PublicKey
+) -> Result<UnsignedInvoiceRequest<'a>, SemanticError> {
+       let mut builder = offer.request_invoice(vec![42; 64], pubkey)?;
+
+       builder = match offer.amount() {
+               None => builder.amount_msats(1000).unwrap(),
+               Some(Amount::Bitcoin { amount_msats }) => builder.amount_msats(amount_msats + 1)?,
+               Some(Amount::Currency { .. }) => return Err(SemanticError::UnsupportedCurrency),
+       };
+
+       builder = match offer.supported_quantity() {
+               Quantity::Bounded(n) => builder.quantity(n.get()).unwrap(),
+               Quantity::Unbounded => builder.quantity(10).unwrap(),
+               Quantity::One => builder,
+       };
+
+       builder.build()
+}
+
+pub fn offer_deser_test<Out: test_logger::Output>(data: &[u8], out: Out) {
+       do_test(data, out);
+}
+
+#[no_mangle]
+pub extern "C" fn offer_deser_run(data: *const u8, datalen: usize) {
+       do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {});
+}
index 4841f1c3014b58959bcc80c57158f5653751b683..9bbf8b9cdffa5010e6463ae96d5de071b19d8285 100644 (file)
@@ -5,7 +5,7 @@ use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey};
 use bitcoin::secp256k1::ecdh::SharedSecret;
 use bitcoin::secp256k1::ecdsa::RecoverableSignature;
 
-use lightning::chain::keysinterface::{Recipient, KeyMaterial, KeysInterface, EntropySource, NodeSigner, SignerProvider};
+use lightning::chain::keysinterface::{Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider};
 use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
 use lightning::ln::script::ShutdownScript;
 use lightning::util::enforcing_trait_impls::EnforcingSigner;
@@ -30,7 +30,7 @@ pub fn do_test<L: Logger>(data: &[u8], logger: &L) {
                        counter: AtomicU64::new(0),
                };
                let custom_msg_handler = TestCustomMessageHandler {};
-               let onion_messenger = OnionMessenger::new(&keys_manager, logger, &custom_msg_handler);
+               let onion_messenger = OnionMessenger::new(&keys_manager, &keys_manager, logger, &custom_msg_handler);
                let mut pk = [2; 33]; pk[1] = 0xff;
                let peer_node_id_not_used = PublicKey::from_slice(&pk).unwrap();
                onion_messenger.handle_onion_message(&peer_node_id_not_used, &msg);
@@ -100,17 +100,19 @@ impl EntropySource for KeyProvider {
 }
 
 impl NodeSigner for KeyProvider {
-       fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> {
-               Ok(self.node_secret.clone())
-       }
-
        fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
-               let secp_ctx = Secp256k1::signing_only();
-               Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
+               let node_secret = match recipient {
+                       Recipient::Node => Ok(&self.node_secret),
+                       Recipient::PhantomNode => Err(())
+               }?;
+               Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret))
        }
 
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
-               let mut node_secret = self.get_node_secret(recipient)?;
+               let mut node_secret = match recipient {
+                       Recipient::Node => Ok(self.node_secret.clone()),
+                       Recipient::PhantomNode => Err(())
+               }?;
                if let Some(tweak) = tweak {
                        node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
                }
@@ -122,6 +124,10 @@ impl NodeSigner for KeyProvider {
        fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
                unreachable!()
        }
+
+       fn sign_gossip_message(&self, _msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<bitcoin::secp256k1::ecdsa::Signature, ()> {
+               unreachable!()
+       }
 }
 
 impl SignerProvider for KeyProvider {
@@ -140,8 +146,6 @@ impl SignerProvider for KeyProvider {
        fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!() }
 }
 
-impl KeysInterface for KeyProvider {}
-
 #[cfg(test)]
 mod tests {
        use lightning::util::logger::{Logger, Record};
index 15e9486a35e1c44e2a085db4bc862219bfb1b277..f6df392fcef5407623b6c0f0cfcf9b8690cdbc75 100644 (file)
@@ -8,6 +8,7 @@
 // licenses.
 
 use lightning::ln::peer_channel_encryptor::PeerChannelEncryptor;
+use lightning::util::test_utils::TestNodeSigner;
 
 use bitcoin::secp256k1::{Secp256k1, PublicKey, SecretKey};
 
@@ -41,6 +42,7 @@ pub fn do_test(data: &[u8]) {
                Ok(key) => key,
                Err(_) => return,
        };
+       let node_signer = TestNodeSigner::new(our_network_key);
        let ephemeral_key = match SecretKey::from_slice(get_slice!(32)) {
                Ok(key) => key,
                Err(_) => return,
@@ -53,15 +55,15 @@ pub fn do_test(data: &[u8]) {
                };
                let mut crypter = PeerChannelEncryptor::new_outbound(their_pubkey, ephemeral_key);
                crypter.get_act_one(&secp_ctx);
-               match crypter.process_act_two(get_slice!(50), &our_network_key, &secp_ctx) {
+               match crypter.process_act_two(get_slice!(50), &&node_signer) {
                        Ok(_) => {},
                        Err(_) => return,
                }
                assert!(crypter.is_ready_for_encryption());
                crypter
        } else {
-               let mut crypter = PeerChannelEncryptor::new_inbound(&our_network_key, &secp_ctx);
-               match crypter.process_act_one_with_keys(get_slice!(50), &our_network_key, ephemeral_key, &secp_ctx) {
+               let mut crypter = PeerChannelEncryptor::new_inbound(&&node_signer);
+               match crypter.process_act_one_with_keys(get_slice!(50), &&node_signer, ephemeral_key, &secp_ctx) {
                        Ok(_) => {},
                        Err(_) => return,
                }
index 6615811512cb55f9007f0948305aea0651707c32..b4c6a29e8a99f47744fdb9fd0caf2468c7604e57 100644 (file)
@@ -1,15 +1,13 @@
 // Imports that need to be added manually
 use lightning_rapid_gossip_sync::RapidGossipSync;
-use bitcoin::hashes::Hash as TraitImport;
 
 use crate::utils::test_logger;
 
 /// Actual fuzz test, method signature and name are fixed
 fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
-       let block_hash = bitcoin::BlockHash::all_zeros();
        let logger = test_logger::TestLogger::new("".to_owned(), out);
-       let network_graph = lightning::routing::gossip::NetworkGraph::new(block_hash, &logger);
-       let rapid_sync = RapidGossipSync::new(&network_graph);
+       let network_graph = lightning::routing::gossip::NetworkGraph::new(bitcoin::Network::Bitcoin, &logger);
+       let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
        let _ = rapid_sync.update_network_graph(data);
 }
 
diff --git a/fuzz/src/refund_deser.rs b/fuzz/src/refund_deser.rs
new file mode 100644 (file)
index 0000000..9adaa3e
--- /dev/null
@@ -0,0 +1,101 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey, self};
+use crate::utils::test_logger;
+use core::convert::{Infallible, TryFrom};
+use lightning::chain::keysinterface::EntropySource;
+use lightning::ln::PaymentHash;
+use lightning::ln::features::BlindedHopFeatures;
+use lightning::offers::invoice::{BlindedPayInfo, UnsignedInvoice};
+use lightning::offers::parse::SemanticError;
+use lightning::offers::refund::Refund;
+use lightning::onion_message::BlindedPath;
+use lightning::util::ser::Writeable;
+
+#[inline]
+pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
+       if let Ok(refund) = Refund::try_from(data.to_vec()) {
+               let mut bytes = Vec::with_capacity(data.len());
+               refund.write(&mut bytes).unwrap();
+               assert_eq!(data, bytes);
+
+               let secp_ctx = Secp256k1::new();
+               let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
+               let pubkey = PublicKey::from(keys);
+               let mut buffer = Vec::new();
+
+               if let Ok(invoice) = build_response(&refund, pubkey, &secp_ctx) {
+                       invoice
+                               .sign::<_, Infallible>(
+                                       |digest| Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys))
+                               )
+                               .unwrap()
+                               .write(&mut buffer)
+                               .unwrap();
+               }
+       }
+}
+
+struct Randomness;
+
+impl EntropySource for Randomness {
+       fn get_secure_random_bytes(&self) -> [u8; 32] { [42; 32] }
+}
+
+fn pubkey(byte: u8) -> PublicKey {
+       let secp_ctx = Secp256k1::new();
+       PublicKey::from_secret_key(&secp_ctx, &privkey(byte))
+}
+
+fn privkey(byte: u8) -> SecretKey {
+       SecretKey::from_slice(&[byte; 32]).unwrap()
+}
+
+fn build_response<'a, T: secp256k1::Signing + secp256k1::Verification>(
+       refund: &'a Refund, signing_pubkey: PublicKey, secp_ctx: &Secp256k1<T>
+) -> Result<UnsignedInvoice<'a>, SemanticError> {
+       let entropy_source = Randomness {};
+       let paths = vec![
+               BlindedPath::new(&[pubkey(43), pubkey(44), pubkey(42)], &entropy_source, secp_ctx).unwrap(),
+               BlindedPath::new(&[pubkey(45), pubkey(46), pubkey(42)], &entropy_source, secp_ctx).unwrap(),
+       ];
+
+       let payinfo = vec![
+               BlindedPayInfo {
+                       fee_base_msat: 1,
+                       fee_proportional_millionths: 1_000,
+                       cltv_expiry_delta: 42,
+                       htlc_minimum_msat: 100,
+                       htlc_maximum_msat: 1_000_000_000_000,
+                       features: BlindedHopFeatures::empty(),
+               },
+               BlindedPayInfo {
+                       fee_base_msat: 1,
+                       fee_proportional_millionths: 1_000,
+                       cltv_expiry_delta: 42,
+                       htlc_minimum_msat: 100,
+                       htlc_maximum_msat: 1_000_000_000_000,
+                       features: BlindedHopFeatures::empty(),
+               },
+       ];
+
+       let payment_paths = paths.into_iter().zip(payinfo.into_iter()).collect();
+       let payment_hash = PaymentHash([42; 32]);
+       refund.respond_with(payment_paths, payment_hash, signing_pubkey)?.build()
+}
+
+pub fn refund_deser_test<Out: test_logger::Output>(data: &[u8], out: Out) {
+       do_test(data, out);
+}
+
+#[no_mangle]
+pub extern "C" fn refund_deser_run(data: *const u8, datalen: usize) {
+       do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {});
+}
index 761f7bddc864706d39ebb44739f3dd2082cd365c..4c228cc731bc2d0981ad77c9a0e2ff444f243302 100644 (file)
@@ -11,24 +11,24 @@ use bitcoin::blockdata::script::Builder;
 use bitcoin::blockdata::transaction::TxOut;
 use bitcoin::hash_types::BlockHash;
 
-use lightning::chain;
 use lightning::chain::transaction::OutPoint;
 use lightning::ln::channelmanager::{self, ChannelDetails, ChannelCounterparty};
 use lightning::ln::msgs;
 use lightning::routing::gossip::{NetworkGraph, RoutingFees};
+use lightning::routing::utxo::{UtxoFuture, UtxoLookup, UtxoLookupError, UtxoResult};
 use lightning::routing::router::{find_route, PaymentParameters, RouteHint, RouteHintHop, RouteParameters};
 use lightning::routing::scoring::FixedPenaltyScorer;
+use lightning::util::config::UserConfig;
 use lightning::util::ser::Readable;
 
 use bitcoin::hashes::Hash;
 use bitcoin::secp256k1::PublicKey;
 use bitcoin::network::constants::Network;
-use bitcoin::blockdata::constants::genesis_block;
 
 use crate::utils::test_logger;
 
 use std::convert::TryInto;
-use std::collections::HashSet;
+use hashbrown::HashSet;
 use std::sync::Arc;
 use std::sync::atomic::{AtomicUsize, Ordering};
 
@@ -80,17 +80,36 @@ impl InputData {
        }
 }
 
-struct FuzzChainSource {
+struct FuzzChainSource<'a, 'b, Out: test_logger::Output> {
        input: Arc<InputData>,
+       net_graph: &'a NetworkGraph<&'b test_logger::TestLogger<Out>>,
 }
-impl chain::Access for FuzzChainSource {
-       fn get_utxo(&self, _genesis_hash: &BlockHash, _short_channel_id: u64) -> Result<TxOut, chain::AccessError> {
-               match self.input.get_slice(2) {
-                       Some(&[0, _]) => Err(chain::AccessError::UnknownChain),
-                       Some(&[1, _]) => Err(chain::AccessError::UnknownTx),
-                       Some(&[_, x]) => Ok(TxOut { value: 0, script_pubkey: Builder::new().push_int(x as i64).into_script().to_v0_p2wsh() }),
-                       None => Err(chain::AccessError::UnknownTx),
-                       _ => unreachable!(),
+impl<Out: test_logger::Output> UtxoLookup for FuzzChainSource<'_, '_, Out> {
+       fn get_utxo(&self, _genesis_hash: &BlockHash, _short_channel_id: u64) -> UtxoResult {
+               let input_slice = self.input.get_slice(2);
+               if input_slice.is_none() { return UtxoResult::Sync(Err(UtxoLookupError::UnknownTx)); }
+               let input_slice = input_slice.unwrap();
+               let txo_res = TxOut {
+                       value: if input_slice[0] % 2 == 0 { 1_000_000 } else { 1_000 },
+                       script_pubkey: Builder::new().push_int(input_slice[1] as i64).into_script().to_v0_p2wsh(),
+               };
+               match input_slice {
+                       &[0, _] => UtxoResult::Sync(Err(UtxoLookupError::UnknownChain)),
+                       &[1, _] => UtxoResult::Sync(Err(UtxoLookupError::UnknownTx)),
+                       &[2, _] => {
+                               let future = UtxoFuture::new();
+                               future.resolve_without_forwarding(self.net_graph, Ok(txo_res));
+                               UtxoResult::Async(future.clone())
+                       },
+                       &[3, _] => {
+                               let future = UtxoFuture::new();
+                               future.resolve_without_forwarding(self.net_graph, Err(UtxoLookupError::UnknownTx));
+                               UtxoResult::Async(future.clone())
+                       },
+                       &[4, _] => {
+                               UtxoResult::Async(UtxoFuture::new()) // the future will never resolve
+                       },
+                       &[..] => UtxoResult::Sync(Ok(txo_res)),
                }
        }
 }
@@ -148,6 +167,15 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                }
        }
 
+       macro_rules! get_pubkey_from_node_id {
+               ($node_id: expr ) => {
+                       match PublicKey::from_slice($node_id.as_slice()) {
+                               Ok(pk) => pk,
+                               Err(_) => return,
+                       }
+               }
+       }
+
        macro_rules! get_pubkey {
                () => {
                        match PublicKey::from_slice(get_slice!(33)) {
@@ -160,7 +188,11 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
        let logger = test_logger::TestLogger::new("".to_owned(), out);
 
        let our_pubkey = get_pubkey!();
-       let net_graph = NetworkGraph::new(genesis_block(Network::Bitcoin).header.block_hash(), &logger);
+       let net_graph = NetworkGraph::new(Network::Bitcoin, &logger);
+       let chain_source = FuzzChainSource {
+               input: Arc::clone(&input),
+               net_graph: &net_graph,
+       };
 
        let mut node_pks = HashSet::new();
        let mut scid = 42;
@@ -174,20 +206,21 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                        return;
                                }
                                let msg = decode_msg_with_len16!(msgs::UnsignedNodeAnnouncement, 288);
-                               node_pks.insert(msg.node_id);
+                               node_pks.insert(get_pubkey_from_node_id!(msg.node_id));
                                let _ = net_graph.update_node_from_unsigned_announcement(&msg);
                        },
                        1 => {
                                let msg = decode_msg_with_len16!(msgs::UnsignedChannelAnnouncement, 32+8+33*4);
-                               node_pks.insert(msg.node_id_1);
-                               node_pks.insert(msg.node_id_2);
-                               let _ = net_graph.update_channel_from_unsigned_announcement::<&FuzzChainSource>(&msg, &None);
+                               node_pks.insert(get_pubkey_from_node_id!(msg.node_id_1));
+                               node_pks.insert(get_pubkey_from_node_id!(msg.node_id_2));
+                               let _ = net_graph.update_channel_from_unsigned_announcement::
+                                       <&FuzzChainSource<'_, '_, Out>>(&msg, &None);
                        },
                        2 => {
                                let msg = decode_msg_with_len16!(msgs::UnsignedChannelAnnouncement, 32+8+33*4);
-                               node_pks.insert(msg.node_id_1);
-                               node_pks.insert(msg.node_id_2);
-                               let _ = net_graph.update_channel_from_unsigned_announcement(&msg, &Some(&FuzzChainSource { input: Arc::clone(&input) }));
+                               node_pks.insert(get_pubkey_from_node_id!(msg.node_id_1));
+                               node_pks.insert(get_pubkey_from_node_id!(msg.node_id_2));
+                               let _ = net_graph.update_channel_from_unsigned_announcement(&msg, &Some(&chain_source));
                        },
                        3 => {
                                let _ = net_graph.update_channel_unsigned(&decode_msg!(msgs::UnsignedChannelUpdate, 72));
@@ -210,7 +243,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                                                channel_id: [0; 32],
                                                                counterparty: ChannelCounterparty {
                                                                        node_id: *rnid,
-                                                                       features: channelmanager::provided_init_features(),
+                                                                       features: channelmanager::provided_init_features(&UserConfig::default()),
                                                                        unspendable_punishment_reserve: 0,
                                                                        forwarding_info: None,
                                                                        outbound_htlc_minimum_msat: None,
@@ -262,10 +295,12 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                let scorer = FixedPenaltyScorer::with_penalty(0);
                                let random_seed_bytes: [u8; 32] = [get_slice!(1)[0]; 32];
                                for target in node_pks.iter() {
+                                       let final_value_msat = slice_to_be64(get_slice!(8));
+                                       let final_cltv_expiry_delta = slice_to_be32(get_slice!(4));
                                        let route_params = RouteParameters {
-                                               payment_params: PaymentParameters::from_node_id(*target).with_route_hints(last_hops.clone()),
-                                               final_value_msat: slice_to_be64(get_slice!(8)),
-                                               final_cltv_expiry_delta: slice_to_be32(get_slice!(4)),
+                                               payment_params: PaymentParameters::from_node_id(*target, final_cltv_expiry_delta)
+                                                       .with_route_hints(last_hops.clone()),
+                                               final_value_msat,
                                        };
                                        let _ = find_route(&our_pubkey, &route_params, &net_graph,
                                                first_hops.map(|c| c.iter().collect::<Vec<_>>()).as_ref().map(|a| a.as_slice()),
index 44675fa787294b4a63144c9a2cddfacc4b9b33a6..e3635297adb037500adafebd98708025c99fa762 100644 (file)
@@ -14,7 +14,7 @@ impl chainmonitor::Persist<EnforcingSigner> for TestPersister {
                self.update_ret.lock().unwrap().clone()
        }
 
-       fn update_persisted_channel(&self, _funding_txo: OutPoint, _update: &Option<channelmonitor::ChannelMonitorUpdate>, _data: &channelmonitor::ChannelMonitor<EnforcingSigner>, _update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus {
+       fn update_persisted_channel(&self, _funding_txo: OutPoint, _update: Option<&channelmonitor::ChannelMonitorUpdate>, _data: &channelmonitor::ChannelMonitor<EnforcingSigner>, _update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus {
                self.update_ret.lock().unwrap().clone()
        }
 }
index cff3f9bdbb52dd87e5f2cfbd68525768e109963e..8f846c5e037e0e53edc9924f5643a7ebce94fb1f 100644 (file)
@@ -1,12 +1,18 @@
 #include <stdint.h>
+void bech32_parse_run(const unsigned char* data, size_t data_len);
 void chanmon_deser_run(const unsigned char* data, size_t data_len);
 void chanmon_consistency_run(const unsigned char* data, size_t data_len);
 void full_stack_run(const unsigned char* data, size_t data_len);
+void invoice_deser_run(const unsigned char* data, size_t data_len);
+void invoice_request_deser_run(const unsigned char* data, size_t data_len);
+void offer_deser_run(const unsigned char* data, size_t data_len);
 void onion_message_run(const unsigned char* data, size_t data_len);
 void peer_crypt_run(const unsigned char* data, size_t data_len);
 void process_network_graph_run(const unsigned char* data, size_t data_len);
+void refund_deser_run(const unsigned char* data, size_t data_len);
 void router_run(const unsigned char* data, size_t data_len);
 void zbase32_run(const unsigned char* data, size_t data_len);
+void indexedmap_run(const unsigned char* data, size_t data_len);
 void msg_accept_channel_run(const unsigned char* data, size_t data_len);
 void msg_announcement_signatures_run(const unsigned char* data, size_t data_len);
 void msg_channel_reestablish_run(const unsigned char* data, size_t data_len);
index 343408ea99cdee000e65ed6b7d37d9ea3fa9abe8..96ac33a917e344a7027fa270babebec1774d8639 100644 (file)
@@ -15,11 +15,14 @@ rustdoc-args = ["--cfg", "docsrs"]
 
 [features]
 futures = [ "futures-util" ]
+std = ["lightning/std", "lightning-rapid-gossip-sync/std"]
+
+default = ["std"]
 
 [dependencies]
-bitcoin = "0.29.0"
-lightning = { version = "0.0.113", path = "../lightning", features = ["std"] }
-lightning-rapid-gossip-sync = { version = "0.0.113", path = "../lightning-rapid-gossip-sync" }
+bitcoin = { version = "0.29.0", default-features = false }
+lightning = { version = "0.0.113", path = "../lightning", default-features = false }
+lightning-rapid-gossip-sync = { version = "0.0.113", path = "../lightning-rapid-gossip-sync", default-features = false }
 futures-util = { version = "0.3", default-features = false, features = ["async-await-macro"], optional = true }
 
 [dev-dependencies]
index 199295b9f0c92e5dd1139480ebeed419ee44a701..a6de0a62fb07583ae29741b87d209c0e66ee7c5d 100644 (file)
 
 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
 
+#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
+
+#[cfg(any(test, feature = "std"))]
+extern crate core;
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
 #[macro_use] extern crate lightning;
 extern crate lightning_rapid_gossip_sync;
 
 use lightning::chain;
 use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
 use lightning::chain::chainmonitor::{ChainMonitor, Persist};
-use lightning::chain::keysinterface::{KeysInterface, SignerProvider};
+use lightning::chain::keysinterface::{EntropySource, NodeSigner, SignerProvider};
 use lightning::ln::channelmanager::ChannelManager;
 use lightning::ln::msgs::{ChannelMessageHandler, OnionMessageHandler, RoutingMessageHandler};
 use lightning::ln::peer_handler::{CustomMessageHandler, PeerManager, SocketDescriptor};
 use lightning::routing::gossip::{NetworkGraph, P2PGossipSync};
+use lightning::routing::utxo::UtxoLookup;
 use lightning::routing::router::Router;
-use lightning::routing::scoring::WriteableScore;
-use lightning::util::events::{Event, EventHandler, EventsProvider};
+use lightning::routing::scoring::{Score, WriteableScore};
+use lightning::util::events::{Event, PathFailure};
+#[cfg(feature = "std")]
+use lightning::util::events::{EventHandler, EventsProvider};
 use lightning::util::logger::Logger;
 use lightning::util::persist::Persister;
 use lightning_rapid_gossip_sync::RapidGossipSync;
+
+use core::ops::Deref;
+use core::time::Duration;
+
+#[cfg(feature = "std")]
 use std::sync::Arc;
-use std::sync::atomic::{AtomicBool, Ordering};
-use std::thread;
-use std::thread::JoinHandle;
-use std::time::{Duration, Instant};
-use std::ops::Deref;
+#[cfg(feature = "std")]
+use core::sync::atomic::{AtomicBool, Ordering};
+#[cfg(feature = "std")]
+use std::thread::{self, JoinHandle};
+#[cfg(feature = "std")]
+use std::time::Instant;
 
 #[cfg(feature = "futures")]
-use futures_util::{select_biased, future::FutureExt};
+use futures_util::{select_biased, future::FutureExt, task};
+#[cfg(not(feature = "std"))]
+use alloc::vec::Vec;
 
 /// `BackgroundProcessor` takes care of tasks that (1) need to happen periodically to keep
 /// Rust-Lightning running properly, and (2) either can or should be run in the background. Its
@@ -62,6 +81,7 @@ use futures_util::{select_biased, future::FutureExt};
 ///
 /// [`ChannelMonitor`]: lightning::chain::channelmonitor::ChannelMonitor
 /// [`Event`]: lightning::util::events::Event
+#[cfg(feature = "std")]
 #[must_use = "BackgroundProcessor will immediately stop on drop. It should be stored until shutdown."]
 pub struct BackgroundProcessor {
        stop_thread: Arc<AtomicBool>,
@@ -98,13 +118,13 @@ const FIRST_NETWORK_PRUNE_TIMER: u64 = 1;
 
 /// Either [`P2PGossipSync`] or [`RapidGossipSync`].
 pub enum GossipSync<
-       P: Deref<Target = P2PGossipSync<G, A, L>>,
+       P: Deref<Target = P2PGossipSync<G, U, L>>,
        R: Deref<Target = RapidGossipSync<G, L>>,
        G: Deref<Target = NetworkGraph<L>>,
-       A: Deref,
+       U: Deref,
        L: Deref,
 >
-where A::Target: chain::Access, L::Target: Logger {
+where U::Target: UtxoLookup, L::Target: Logger {
        /// Gossip sync via the lightning peer-to-peer network as defined by BOLT 7.
        P2P(P),
        /// Rapid gossip sync from a trusted server.
@@ -114,13 +134,13 @@ where A::Target: chain::Access, L::Target: Logger {
 }
 
 impl<
-       P: Deref<Target = P2PGossipSync<G, A, L>>,
+       P: Deref<Target = P2PGossipSync<G, U, L>>,
        R: Deref<Target = RapidGossipSync<G, L>>,
        G: Deref<Target = NetworkGraph<L>>,
-       A: Deref,
+       U: Deref,
        L: Deref,
-> GossipSync<P, R, G, A, L>
-where A::Target: chain::Access, L::Target: Logger {
+> GossipSync<P, R, G, U, L>
+where U::Target: UtxoLookup, L::Target: Logger {
        fn network_graph(&self) -> Option<&G> {
                match self {
                        GossipSync::P2P(gossip_sync) => Some(gossip_sync.network_graph()),
@@ -145,10 +165,10 @@ where A::Target: chain::Access, L::Target: Logger {
 }
 
 /// (C-not exported) as the bindings concretize everything and have constructors for us
-impl<P: Deref<Target = P2PGossipSync<G, A, L>>, G: Deref<Target = NetworkGraph<L>>, A: Deref, L: Deref>
-       GossipSync<P, &RapidGossipSync<G, L>, G, A, L>
+impl<P: Deref<Target = P2PGossipSync<G, U, L>>, G: Deref<Target = NetworkGraph<L>>, U: Deref, L: Deref>
+       GossipSync<P, &RapidGossipSync<G, L>, G, U, L>
 where
-       A::Target: chain::Access,
+       U::Target: UtxoLookup,
        L::Target: Logger,
 {
        /// Initializes a new [`GossipSync::P2P`] variant.
@@ -160,10 +180,10 @@ where
 /// (C-not exported) as the bindings concretize everything and have constructors for us
 impl<'a, R: Deref<Target = RapidGossipSync<G, L>>, G: Deref<Target = NetworkGraph<L>>, L: Deref>
        GossipSync<
-               &P2PGossipSync<G, &'a (dyn chain::Access + Send + Sync), L>,
+               &P2PGossipSync<G, &'a (dyn UtxoLookup + Send + Sync), L>,
                R,
                G,
-               &'a (dyn chain::Access + Send + Sync),
+               &'a (dyn UtxoLookup + Send + Sync),
                L,
        >
 where
@@ -178,10 +198,10 @@ where
 /// (C-not exported) as the bindings concretize everything and have constructors for us
 impl<'a, L: Deref>
        GossipSync<
-               &P2PGossipSync<&'a NetworkGraph<L>, &'a (dyn chain::Access + Send + Sync), L>,
+               &P2PGossipSync<&'a NetworkGraph<L>, &'a (dyn UtxoLookup + Send + Sync), L>,
                &RapidGossipSync<&'a NetworkGraph<L>, L>,
                &'a NetworkGraph<L>,
-               &'a (dyn chain::Access + Send + Sync),
+               &'a (dyn UtxoLookup + Send + Sync),
                L,
        >
 where
@@ -196,10 +216,41 @@ where
 fn handle_network_graph_update<L: Deref>(
        network_graph: &NetworkGraph<L>, event: &Event
 ) where L::Target: Logger {
-       if let Event::PaymentPathFailed { ref network_update, .. } = event {
-               if let Some(network_update) = network_update {
-                       network_graph.handle_network_update(&network_update);
-               }
+       if let Event::PaymentPathFailed {
+               failure: PathFailure::OnPath { network_update: Some(ref upd) }, .. } = event
+       {
+               network_graph.handle_network_update(upd);
+       }
+}
+
+fn update_scorer<'a, S: 'static + Deref<Target = SC> + Send + Sync, SC: 'a + WriteableScore<'a>>(
+       scorer: &'a S, event: &Event
+) {
+       let mut score = scorer.lock();
+       match event {
+               Event::PaymentPathFailed { ref path, short_channel_id: Some(scid), .. } => {
+                       let path = path.iter().collect::<Vec<_>>();
+                       score.payment_path_failed(&path, *scid);
+               },
+               Event::PaymentPathFailed { ref path, payment_failed_permanently: true, .. } => {
+                       // Reached if the destination explicitly failed it back. We treat this as a successful probe
+                       // because the payment made it all the way to the destination with sufficient liquidity.
+                       let path = path.iter().collect::<Vec<_>>();
+                       score.probe_successful(&path);
+               },
+               Event::PaymentPathSuccessful { path, .. } => {
+                       let path = path.iter().collect::<Vec<_>>();
+                       score.payment_path_successful(&path);
+               },
+               Event::ProbeSuccessful { path, .. } => {
+                       let path = path.iter().collect::<Vec<_>>();
+                       score.probe_successful(&path);
+               },
+               Event::ProbeFailed { path, short_channel_id: Some(scid), .. } => {
+                       let path = path.iter().collect::<Vec<_>>();
+                       score.probe_failed(&path, *scid);
+               },
+               _ => {},
        }
 }
 
@@ -207,15 +258,15 @@ macro_rules! define_run_body {
        ($persister: ident, $chain_monitor: ident, $process_chain_monitor_events: expr,
         $channel_manager: ident, $process_channel_manager_events: expr,
         $gossip_sync: ident, $peer_manager: ident, $logger: ident, $scorer: ident,
-        $loop_exit_check: expr, $await: expr)
+        $loop_exit_check: expr, $await: expr, $get_timer: expr, $timer_elapsed: expr)
        => { {
                log_trace!($logger, "Calling ChannelManager's timer_tick_occurred on startup");
                $channel_manager.timer_tick_occurred();
 
-               let mut last_freshness_call = Instant::now();
-               let mut last_ping_call = Instant::now();
-               let mut last_prune_call = Instant::now();
-               let mut last_scorer_persist_call = Instant::now();
+               let mut last_freshness_call = $get_timer(FRESHNESS_TIMER);
+               let mut last_ping_call = $get_timer(PING_TIMER);
+               let mut last_prune_call = $get_timer(FIRST_NETWORK_PRUNE_TIMER);
+               let mut last_scorer_persist_call = $get_timer(SCORER_PERSIST_TIMER);
                let mut have_pruned = false;
 
                loop {
@@ -237,9 +288,9 @@ macro_rules! define_run_body {
 
                        // We wait up to 100ms, but track how long it takes to detect being put to sleep,
                        // see `await_start`'s use below.
-                       let await_start = Instant::now();
+                       let mut await_start = $get_timer(1);
                        let updates_available = $await;
-                       let await_time = await_start.elapsed();
+                       let await_slow = $timer_elapsed(&mut await_start, 1);
 
                        if updates_available {
                                log_trace!($logger, "Persisting ChannelManager...");
@@ -251,12 +302,12 @@ macro_rules! define_run_body {
                                log_trace!($logger, "Terminating background processor.");
                                break;
                        }
-                       if last_freshness_call.elapsed().as_secs() > FRESHNESS_TIMER {
+                       if $timer_elapsed(&mut last_freshness_call, FRESHNESS_TIMER) {
                                log_trace!($logger, "Calling ChannelManager's timer_tick_occurred");
                                $channel_manager.timer_tick_occurred();
-                               last_freshness_call = Instant::now();
+                               last_freshness_call = $get_timer(FRESHNESS_TIMER);
                        }
-                       if await_time > Duration::from_secs(1) {
+                       if await_slow {
                                // On various platforms, we may be starved of CPU cycles for several reasons.
                                // E.g. on iOS, if we've been in the background, we will be entirely paused.
                                // Similarly, if we're on a desktop platform and the device has been asleep, we
@@ -271,40 +322,46 @@ macro_rules! define_run_body {
                                // peers.
                                log_trace!($logger, "100ms sleep took more than a second, disconnecting peers.");
                                $peer_manager.disconnect_all_peers();
-                               last_ping_call = Instant::now();
-                       } else if last_ping_call.elapsed().as_secs() > PING_TIMER {
+                               last_ping_call = $get_timer(PING_TIMER);
+                       } else if $timer_elapsed(&mut last_ping_call, PING_TIMER) {
                                log_trace!($logger, "Calling PeerManager's timer_tick_occurred");
                                $peer_manager.timer_tick_occurred();
-                               last_ping_call = Instant::now();
+                               last_ping_call = $get_timer(PING_TIMER);
                        }
 
                        // Note that we want to run a graph prune once not long after startup before
                        // falling back to our usual hourly prunes. This avoids short-lived clients never
                        // pruning their network graph. We run once 60 seconds after startup before
                        // continuing our normal cadence.
-                       if last_prune_call.elapsed().as_secs() > if have_pruned { NETWORK_PRUNE_TIMER } else { FIRST_NETWORK_PRUNE_TIMER } {
+                       if $timer_elapsed(&mut last_prune_call, if have_pruned { NETWORK_PRUNE_TIMER } else { FIRST_NETWORK_PRUNE_TIMER }) {
                                // The network graph must not be pruned while rapid sync completion is pending
                                if let Some(network_graph) = $gossip_sync.prunable_network_graph() {
-                                       log_trace!($logger, "Pruning and persisting network graph.");
-                                       network_graph.remove_stale_channels_and_tracking();
+                                       #[cfg(feature = "std")] {
+                                               log_trace!($logger, "Pruning and persisting network graph.");
+                                               network_graph.remove_stale_channels_and_tracking();
+                                       }
+                                       #[cfg(not(feature = "std"))] {
+                                               log_warn!($logger, "Not pruning network graph, consider enabling `std` or doing so manually with remove_stale_channels_and_tracking_with_time.");
+                                               log_trace!($logger, "Persisting network graph.");
+                                       }
 
                                        if let Err(e) = $persister.persist_graph(network_graph) {
                                                log_error!($logger, "Error: Failed to persist network graph, check your disk and permissions {}", e)
                                        }
 
-                                       last_prune_call = Instant::now();
+                                       last_prune_call = $get_timer(NETWORK_PRUNE_TIMER);
                                        have_pruned = true;
                                }
                        }
 
-                       if last_scorer_persist_call.elapsed().as_secs() > SCORER_PERSIST_TIMER {
+                       if $timer_elapsed(&mut last_scorer_persist_call, SCORER_PERSIST_TIMER) {
                                if let Some(ref scorer) = $scorer {
                                        log_trace!($logger, "Persisting scorer");
                                        if let Err(e) = $persister.persist_scorer(&scorer) {
                                                log_error!($logger, "Error: Failed to persist scorer, check your disk and permissions {}", e)
                                        }
                                }
-                               last_scorer_persist_call = Instant::now();
+                               last_scorer_persist_call = $get_timer(SCORER_PERSIST_TIMER);
                        }
                }
 
@@ -334,14 +391,21 @@ macro_rules! define_run_body {
 /// future which outputs true, the loop will exit and this function's future will complete.
 ///
 /// See [`BackgroundProcessor::start`] for information on which actions this handles.
+///
+/// Requires the `futures` feature. Note that while this method is available without the `std`
+/// feature, doing so will skip calling [`NetworkGraph::remove_stale_channels_and_tracking`],
+/// you should call [`NetworkGraph::remove_stale_channels_and_tracking_with_time`] regularly
+/// manually instead.
 #[cfg(feature = "futures")]
 pub async fn process_events_async<
        'a,
-       CA: 'static + Deref + Send + Sync,
+       UL: 'static + Deref + Send + Sync,
        CF: 'static + Deref + Send + Sync,
        CW: 'static + Deref + Send + Sync,
        T: 'static + Deref + Send + Sync,
-       K: 'static + Deref + Send + Sync,
+       ES: 'static + Deref + Send + Sync,
+       NS: 'static + Deref + Send + Sync,
+       SP: 'static + Deref + Send + Sync,
        F: 'static + Deref + Send + Sync,
        R: 'static + Deref + Send + Sync,
        G: 'static + Deref<Target = NetworkGraph<L>> + Send + Sync,
@@ -354,45 +418,51 @@ pub async fn process_events_async<
        EventHandlerFuture: core::future::Future<Output = ()>,
        EventHandler: Fn(Event) -> EventHandlerFuture,
        PS: 'static + Deref + Send,
-       M: 'static + Deref<Target = ChainMonitor<<K::Target as SignerProvider>::Signer, CF, T, F, L, P>> + Send + Sync,
-       CM: 'static + Deref<Target = ChannelManager<CW, T, K, F, R, L>> + Send + Sync,
-       PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
+       M: 'static + Deref<Target = ChainMonitor<<SP::Target as SignerProvider>::Signer, CF, T, F, L, P>> + Send + Sync,
+       CM: 'static + Deref<Target = ChannelManager<CW, T, ES, NS, SP, F, R, L>> + Send + Sync,
+       PGS: 'static + Deref<Target = P2PGossipSync<G, UL, L>> + Send + Sync,
        RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
        UMH: 'static + Deref + Send + Sync,
-       PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH>> + Send + Sync,
+       PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH, NS>> + Send + Sync,
        S: 'static + Deref<Target = SC> + Send + Sync,
-       SC: WriteableScore<'a>,
-       SleepFuture: core::future::Future<Output = bool>,
+       SC: for<'b> WriteableScore<'b>,
+       SleepFuture: core::future::Future<Output = bool> + core::marker::Unpin,
        Sleeper: Fn(Duration) -> SleepFuture
 >(
        persister: PS, event_handler: EventHandler, chain_monitor: M, channel_manager: CM,
-       gossip_sync: GossipSync<PGS, RGS, G, CA, L>, peer_manager: PM, logger: L, scorer: Option<S>,
+       gossip_sync: GossipSync<PGS, RGS, G, UL, L>, peer_manager: PM, logger: L, scorer: Option<S>,
        sleeper: Sleeper,
-) -> Result<(), std::io::Error>
+) -> Result<(), lightning::io::Error>
 where
-       CA::Target: 'static + chain::Access,
+       UL::Target: 'static + UtxoLookup,
        CF::Target: 'static + chain::Filter,
-       CW::Target: 'static + chain::Watch<<K::Target as SignerProvider>::Signer>,
+       CW::Target: 'static + chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: 'static + BroadcasterInterface,
-       K::Target: 'static + KeysInterface,
+       ES::Target: 'static + EntropySource,
+       NS::Target: 'static + NodeSigner,
+       SP::Target: 'static + SignerProvider,
        F::Target: 'static + FeeEstimator,
        R::Target: 'static + Router,
        L::Target: 'static + Logger,
-       P::Target: 'static + Persist<<K::Target as SignerProvider>::Signer>,
+       P::Target: 'static + Persist<<SP::Target as SignerProvider>::Signer>,
        CMH::Target: 'static + ChannelMessageHandler,
        OMH::Target: 'static + OnionMessageHandler,
        RMH::Target: 'static + RoutingMessageHandler,
        UMH::Target: 'static + CustomMessageHandler,
-       PS::Target: 'static + Persister<'a, CW, T, K, F, R, L, SC>,
+       PS::Target: 'static + Persister<'a, CW, T, ES, NS, SP, F, R, L, SC>,
 {
        let mut should_break = true;
        let async_event_handler = |event| {
                let network_graph = gossip_sync.network_graph();
                let event_handler = &event_handler;
+               let scorer = &scorer;
                async move {
                        if let Some(network_graph) = network_graph {
                                handle_network_graph_update(network_graph, &event)
                        }
+                       if let Some(ref scorer) = scorer {
+                               update_scorer(scorer, &event);
+                       }
                        event_handler(event).await;
                }
        };
@@ -407,9 +477,15 @@ where
                                        false
                                }
                        }
+               }, |t| sleeper(Duration::from_secs(t)),
+               |fut: &mut SleepFuture, _| {
+                       let mut waker = task::noop_waker();
+                       let mut ctx = task::Context::from_waker(&mut waker);
+                       core::pin::Pin::new(fut).poll(&mut ctx).is_ready()
                })
 }
 
+#[cfg(feature = "std")]
 impl BackgroundProcessor {
        /// Start a background thread that takes care of responsibilities enumerated in the [top-level
        /// documentation].
@@ -457,11 +533,13 @@ impl BackgroundProcessor {
        /// [`NetworkGraph::write`]: lightning::routing::gossip::NetworkGraph#impl-Writeable
        pub fn start<
                'a,
-               CA: 'static + Deref + Send + Sync,
+               UL: 'static + Deref + Send + Sync,
                CF: 'static + Deref + Send + Sync,
                CW: 'static + Deref + Send + Sync,
                T: 'static + Deref + Send + Sync,
-               K: 'static + Deref + Send + Sync,
+               ES: 'static + Deref + Send + Sync,
+               NS: 'static + Deref + Send + Sync,
+               SP: 'static + Deref + Send + Sync,
                F: 'static + Deref + Send + Sync,
                R: 'static + Deref + Send + Sync,
                G: 'static + Deref<Target = NetworkGraph<L>> + Send + Sync,
@@ -473,33 +551,35 @@ impl BackgroundProcessor {
                RMH: 'static + Deref + Send + Sync,
                EH: 'static + EventHandler + Send,
                PS: 'static + Deref + Send,
-               M: 'static + Deref<Target = ChainMonitor<<K::Target as SignerProvider>::Signer, CF, T, F, L, P>> + Send + Sync,
-               CM: 'static + Deref<Target = ChannelManager<CW, T, K, F, R, L>> + Send + Sync,
-               PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
+               M: 'static + Deref<Target = ChainMonitor<<SP::Target as SignerProvider>::Signer, CF, T, F, L, P>> + Send + Sync,
+               CM: 'static + Deref<Target = ChannelManager<CW, T, ES, NS, SP, F, R, L>> + Send + Sync,
+               PGS: 'static + Deref<Target = P2PGossipSync<G, UL, L>> + Send + Sync,
                RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
                UMH: 'static + Deref + Send + Sync,
-               PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH>> + Send + Sync,
+               PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH, NS>> + Send + Sync,
                S: 'static + Deref<Target = SC> + Send + Sync,
-               SC: WriteableScore<'a>,
+               SC: for <'b> WriteableScore<'b>,
        >(
                persister: PS, event_handler: EH, chain_monitor: M, channel_manager: CM,
-               gossip_sync: GossipSync<PGS, RGS, G, CA, L>, peer_manager: PM, logger: L, scorer: Option<S>,
+               gossip_sync: GossipSync<PGS, RGS, G, UL, L>, peer_manager: PM, logger: L, scorer: Option<S>,
        ) -> Self
        where
-               CA::Target: 'static + chain::Access,
+               UL::Target: 'static + UtxoLookup,
                CF::Target: 'static + chain::Filter,
-               CW::Target: 'static + chain::Watch<<K::Target as SignerProvider>::Signer>,
+               CW::Target: 'static + chain::Watch<<SP::Target as SignerProvider>::Signer>,
                T::Target: 'static + BroadcasterInterface,
-               K::Target: 'static + KeysInterface,
+               ES::Target: 'static + EntropySource,
+               NS::Target: 'static + NodeSigner,
+               SP::Target: 'static + SignerProvider,
                F::Target: 'static + FeeEstimator,
                R::Target: 'static + Router,
                L::Target: 'static + Logger,
-               P::Target: 'static + Persist<<K::Target as SignerProvider>::Signer>,
+               P::Target: 'static + Persist<<SP::Target as SignerProvider>::Signer>,
                CMH::Target: 'static + ChannelMessageHandler,
                OMH::Target: 'static + OnionMessageHandler,
                RMH::Target: 'static + RoutingMessageHandler,
                UMH::Target: 'static + CustomMessageHandler,
-               PS::Target: 'static + Persister<'a, CW, T, K, F, R, L, SC>,
+               PS::Target: 'static + Persister<'a, CW, T, ES, NS, SP, F, R, L, SC>,
        {
                let stop_thread = Arc::new(AtomicBool::new(false));
                let stop_thread_clone = stop_thread.clone();
@@ -509,12 +589,16 @@ impl BackgroundProcessor {
                                if let Some(network_graph) = network_graph {
                                        handle_network_graph_update(network_graph, &event)
                                }
+                               if let Some(ref scorer) = scorer {
+                                       update_scorer(scorer, &event);
+                               }
                                event_handler.handle_event(event);
                        };
                        define_run_body!(persister, chain_monitor, chain_monitor.process_pending_events(&event_handler),
                                channel_manager, channel_manager.process_pending_events(&event_handler),
                                gossip_sync, peer_manager, logger, scorer, stop_thread.load(Ordering::Acquire),
-                               channel_manager.await_persistable_update_timeout(Duration::from_millis(100)))
+                               channel_manager.await_persistable_update_timeout(Duration::from_millis(100)),
+                               |_| Instant::now(), |time: &Instant, dur| time.elapsed().as_secs() > dur)
                });
                Self { stop_thread: stop_thread_clone, thread_handle: Some(handle) }
        }
@@ -560,38 +644,42 @@ impl BackgroundProcessor {
        }
 }
 
+#[cfg(feature = "std")]
 impl Drop for BackgroundProcessor {
        fn drop(&mut self) {
                self.stop_and_join_thread().unwrap();
        }
 }
 
-#[cfg(test)]
+#[cfg(all(feature = "std", test))]
 mod tests {
        use bitcoin::blockdata::block::BlockHeader;
        use bitcoin::blockdata::constants::genesis_block;
        use bitcoin::blockdata::locktime::PackedLockTime;
        use bitcoin::blockdata::transaction::{Transaction, TxOut};
        use bitcoin::network::constants::Network;
+       use bitcoin::secp256k1::{SecretKey, PublicKey, Secp256k1};
        use lightning::chain::{BestBlock, Confirm, chainmonitor};
        use lightning::chain::channelmonitor::ANTI_REORG_DELAY;
-       use lightning::chain::keysinterface::{InMemorySigner, Recipient, EntropySource, KeysInterface, KeysManager, NodeSigner};
+       use lightning::chain::keysinterface::{InMemorySigner, KeysManager};
        use lightning::chain::transaction::OutPoint;
        use lightning::get_event_msg;
-       use lightning::ln::channelmanager::{self, BREAKDOWN_TIMEOUT, ChainParameters, ChannelManager, SimpleArcChannelManager};
-       use lightning::ln::features::ChannelFeatures;
+       use lightning::ln::PaymentHash;
+       use lightning::ln::channelmanager;
+       use lightning::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChainParameters, MIN_CLTV_EXPIRY_DELTA, PaymentId};
+       use lightning::ln::features::{ChannelFeatures, NodeFeatures};
        use lightning::ln::msgs::{ChannelMessageHandler, Init};
        use lightning::ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler};
-       use lightning::routing::gossip::{NetworkGraph, P2PGossipSync};
-       use lightning::routing::router::DefaultRouter;
-       use lightning::routing::scoring::{ProbabilisticScoringParameters, ProbabilisticScorer};
+       use lightning::routing::gossip::{NetworkGraph, NodeId, P2PGossipSync};
+       use lightning::routing::router::{DefaultRouter, RouteHop};
+       use lightning::routing::scoring::{ChannelUsage, Score};
        use lightning::util::config::UserConfig;
-       use lightning::util::events::{Event, MessageSendEventsProvider, MessageSendEvent};
+       use lightning::util::events::{Event, PathFailure, MessageSendEventsProvider, MessageSendEvent};
        use lightning::util::ser::Writeable;
        use lightning::util::test_utils;
        use lightning::util::persist::KVStorePersister;
-       use lightning_invoice::payment::{InvoicePayer, Retry};
        use lightning_persister::FilesystemPersister;
+       use std::collections::VecDeque;
        use std::fs;
        use std::path::PathBuf;
        use std::sync::{Arc, Mutex};
@@ -614,23 +702,25 @@ mod tests {
                fn disconnect_socket(&mut self) {}
        }
 
+       type ChannelManager = channelmanager::ChannelManager<Arc<ChainMonitor>, Arc<test_utils::TestBroadcaster>, Arc<KeysManager>, Arc<KeysManager>, Arc<KeysManager>, Arc<test_utils::TestFeeEstimator>, Arc<DefaultRouter< Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestLogger>, Arc<Mutex<TestScorer>>>>, Arc<test_utils::TestLogger>>;
+
        type ChainMonitor = chainmonitor::ChainMonitor<InMemorySigner, Arc<test_utils::TestChainSource>, Arc<test_utils::TestBroadcaster>, Arc<test_utils::TestFeeEstimator>, Arc<test_utils::TestLogger>, Arc<FilesystemPersister>>;
 
        type PGS = Arc<P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>>;
        type RGS = Arc<RapidGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestLogger>>>;
 
        struct Node {
-               node: Arc<SimpleArcChannelManager<ChainMonitor, test_utils::TestBroadcaster, test_utils::TestFeeEstimator, test_utils::TestLogger>>,
+               node: Arc<ChannelManager>,
                p2p_gossip_sync: PGS,
                rapid_gossip_sync: RGS,
-               peer_manager: Arc<PeerManager<TestDescriptor, Arc<test_utils::TestChannelMessageHandler>, Arc<test_utils::TestRoutingMessageHandler>, IgnoringMessageHandler, Arc<test_utils::TestLogger>, IgnoringMessageHandler>>,
+               peer_manager: Arc<PeerManager<TestDescriptor, Arc<test_utils::TestChannelMessageHandler>, Arc<test_utils::TestRoutingMessageHandler>, IgnoringMessageHandler, Arc<test_utils::TestLogger>, IgnoringMessageHandler, Arc<KeysManager>>>,
                chain_monitor: Arc<ChainMonitor>,
                persister: Arc<FilesystemPersister>,
                tx_broadcaster: Arc<test_utils::TestBroadcaster>,
                network_graph: Arc<NetworkGraph<Arc<test_utils::TestLogger>>>,
                logger: Arc<test_utils::TestLogger>,
                best_block: BestBlock,
-               scorer: Arc<Mutex<ProbabilisticScorer<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestLogger>>>>,
+               scorer: Arc<Mutex<TestScorer>>,
        }
 
        impl Node {
@@ -716,6 +806,128 @@ mod tests {
                }
        }
 
+       struct TestScorer {
+               event_expectations: Option<VecDeque<TestResult>>,
+       }
+
+       #[derive(Debug)]
+       enum TestResult {
+               PaymentFailure { path: Vec<RouteHop>, short_channel_id: u64 },
+               PaymentSuccess { path: Vec<RouteHop> },
+               ProbeFailure { path: Vec<RouteHop> },
+               ProbeSuccess { path: Vec<RouteHop> },
+       }
+
+       impl TestScorer {
+               fn new() -> Self {
+                       Self { event_expectations: None }
+               }
+
+               fn expect(&mut self, expectation: TestResult) {
+                       self.event_expectations.get_or_insert_with(|| VecDeque::new()).push_back(expectation);
+               }
+       }
+
+       impl lightning::util::ser::Writeable for TestScorer {
+               fn write<W: lightning::util::ser::Writer>(&self, _: &mut W) -> Result<(), lightning::io::Error> { Ok(()) }
+       }
+
+       impl Score for TestScorer {
+               fn channel_penalty_msat(
+                       &self, _short_channel_id: u64, _source: &NodeId, _target: &NodeId, _usage: ChannelUsage
+               ) -> u64 { unimplemented!(); }
+
+               fn payment_path_failed(&mut self, actual_path: &[&RouteHop], actual_short_channel_id: u64) {
+                       if let Some(expectations) = &mut self.event_expectations {
+                               match expectations.pop_front().unwrap() {
+                                       TestResult::PaymentFailure { path, short_channel_id } => {
+                                               assert_eq!(actual_path, &path.iter().collect::<Vec<_>>()[..]);
+                                               assert_eq!(actual_short_channel_id, short_channel_id);
+                                       },
+                                       TestResult::PaymentSuccess { path } => {
+                                               panic!("Unexpected successful payment path: {:?}", path)
+                                       },
+                                       TestResult::ProbeFailure { path } => {
+                                               panic!("Unexpected probe failure: {:?}", path)
+                                       },
+                                       TestResult::ProbeSuccess { path } => {
+                                               panic!("Unexpected probe success: {:?}", path)
+                                       }
+                               }
+                       }
+               }
+
+               fn payment_path_successful(&mut self, actual_path: &[&RouteHop]) {
+                       if let Some(expectations) = &mut self.event_expectations {
+                               match expectations.pop_front().unwrap() {
+                                       TestResult::PaymentFailure { path, .. } => {
+                                               panic!("Unexpected payment path failure: {:?}", path)
+                                       },
+                                       TestResult::PaymentSuccess { path } => {
+                                               assert_eq!(actual_path, &path.iter().collect::<Vec<_>>()[..]);
+                                       },
+                                       TestResult::ProbeFailure { path } => {
+                                               panic!("Unexpected probe failure: {:?}", path)
+                                       },
+                                       TestResult::ProbeSuccess { path } => {
+                                               panic!("Unexpected probe success: {:?}", path)
+                                       }
+                               }
+                       }
+               }
+
+               fn probe_failed(&mut self, actual_path: &[&RouteHop], _: u64) {
+                       if let Some(expectations) = &mut self.event_expectations {
+                               match expectations.pop_front().unwrap() {
+                                       TestResult::PaymentFailure { path, .. } => {
+                                               panic!("Unexpected payment path failure: {:?}", path)
+                                       },
+                                       TestResult::PaymentSuccess { path } => {
+                                               panic!("Unexpected payment path success: {:?}", path)
+                                       },
+                                       TestResult::ProbeFailure { path } => {
+                                               assert_eq!(actual_path, &path.iter().collect::<Vec<_>>()[..]);
+                                       },
+                                       TestResult::ProbeSuccess { path } => {
+                                               panic!("Unexpected probe success: {:?}", path)
+                                       }
+                               }
+                       }
+               }
+               fn probe_successful(&mut self, actual_path: &[&RouteHop]) {
+                       if let Some(expectations) = &mut self.event_expectations {
+                               match expectations.pop_front().unwrap() {
+                                       TestResult::PaymentFailure { path, .. } => {
+                                               panic!("Unexpected payment path failure: {:?}", path)
+                                       },
+                                       TestResult::PaymentSuccess { path } => {
+                                               panic!("Unexpected payment path success: {:?}", path)
+                                       },
+                                       TestResult::ProbeFailure { path } => {
+                                               panic!("Unexpected probe failure: {:?}", path)
+                                       },
+                                       TestResult::ProbeSuccess { path } => {
+                                               assert_eq!(actual_path, &path.iter().collect::<Vec<_>>()[..]);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       impl Drop for TestScorer {
+               fn drop(&mut self) {
+                       if std::thread::panicking() {
+                               return;
+                       }
+
+                       if let Some(event_expectations) = &self.event_expectations {
+                               if !event_expectations.is_empty() {
+                                       panic!("Unsatisfied event expectations: {:?}", event_expectations);
+                               }
+                       }
+               }
+       }
+
        fn get_full_filepath(filepath: String, filename: String) -> String {
                let mut path = PathBuf::from(filepath);
                path.push(filename);
@@ -730,9 +942,8 @@ mod tests {
                        let logger = Arc::new(test_utils::TestLogger::with_id(format!("node {}", i)));
                        let network = Network::Testnet;
                        let genesis_block = genesis_block(network);
-                       let network_graph = Arc::new(NetworkGraph::new(genesis_block.header.block_hash(), logger.clone()));
-                       let params = ProbabilisticScoringParameters::default();
-                       let scorer = Arc::new(Mutex::new(ProbabilisticScorer::new(params, network_graph.clone(), logger.clone())));
+                       let network_graph = Arc::new(NetworkGraph::new(network, logger.clone()));
+                       let scorer = Arc::new(Mutex::new(TestScorer::new()));
                        let seed = [i as u8; 32];
                        let router = Arc::new(DefaultRouter::new(network_graph.clone(), logger.clone(), seed, scorer.clone()));
                        let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
@@ -740,21 +951,21 @@ mod tests {
                        let now = Duration::from_secs(genesis_block.header.time as u64);
                        let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_nanos()));
                        let chain_monitor = Arc::new(chainmonitor::ChainMonitor::new(Some(chain_source.clone()), tx_broadcaster.clone(), logger.clone(), fee_estimator.clone(), persister.clone()));
-                       let best_block = BestBlock::from_genesis(network);
+                       let best_block = BestBlock::from_network(network);
                        let params = ChainParameters { network, best_block };
-                       let manager = Arc::new(ChannelManager::new(fee_estimator.clone(), chain_monitor.clone(), tx_broadcaster.clone(), router.clone(), logger.clone(), keys_manager.clone(), UserConfig::default(), params));
+                       let manager = Arc::new(ChannelManager::new(fee_estimator.clone(), chain_monitor.clone(), tx_broadcaster.clone(), router.clone(), logger.clone(), keys_manager.clone(), keys_manager.clone(), keys_manager.clone(), UserConfig::default(), params));
                        let p2p_gossip_sync = Arc::new(P2PGossipSync::new(network_graph.clone(), Some(chain_source.clone()), logger.clone()));
-                       let rapid_gossip_sync = Arc::new(RapidGossipSync::new(network_graph.clone()));
+                       let rapid_gossip_sync = Arc::new(RapidGossipSync::new(network_graph.clone(), logger.clone()));
                        let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new()), onion_message_handler: IgnoringMessageHandler{}};
-                       let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(Recipient::Node).unwrap(), 0, &seed, logger.clone(), IgnoringMessageHandler{}));
+                       let peer_manager = Arc::new(PeerManager::new(msg_handler, 0, &seed, logger.clone(), IgnoringMessageHandler{}, keys_manager.clone()));
                        let node = Node { node: manager, p2p_gossip_sync, rapid_gossip_sync, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block, scorer };
                        nodes.push(node);
                }
 
                for i in 0..num_nodes {
                        for j in (i+1)..num_nodes {
-                               nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-                               nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+                               nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &Init { features: nodes[j].node.init_features(), remote_network_address: None }, true).unwrap();
+                               nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &Init { features: nodes[i].node.init_features(), remote_network_address: None }, false).unwrap();
                        }
                }
 
@@ -775,8 +986,8 @@ mod tests {
        macro_rules! begin_open_channel {
                ($node_a: expr, $node_b: expr, $channel_value: expr) => {{
                        $node_a.node.create_channel($node_b.node.get_our_node_id(), $channel_value, 100, 42, None).unwrap();
-                       $node_b.node.handle_open_channel(&$node_a.node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!($node_a, MessageSendEvent::SendOpenChannel, $node_b.node.get_our_node_id()));
-                       $node_a.node.handle_accept_channel(&$node_b.node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!($node_b, MessageSendEvent::SendAcceptChannel, $node_a.node.get_our_node_id()));
+                       $node_b.node.handle_open_channel(&$node_a.node.get_our_node_id(), &get_event_msg!($node_a, MessageSendEvent::SendOpenChannel, $node_b.node.get_our_node_id()));
+                       $node_a.node.handle_accept_channel(&$node_b.node.get_our_node_id(), &get_event_msg!($node_b, MessageSendEvent::SendAcceptChannel, $node_a.node.get_our_node_id()));
                }}
        }
 
@@ -1101,7 +1312,7 @@ mod tests {
                        0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 25, 0, 0,
                        0, 1, 0, 0, 0, 125, 255, 2, 68, 226, 0, 6, 11, 0, 1, 5, 0, 0, 0, 0, 29, 129, 25, 192,
                ];
-               nodes[0].rapid_gossip_sync.update_network_graph(&initialization_input[..]).unwrap();
+               nodes[0].rapid_gossip_sync.update_network_graph_no_std(&initialization_input[..], Some(1642291930)).unwrap();
 
                // this should have added two channels
                assert_eq!(network_graph.read_only().channels().len(), 3);
@@ -1117,18 +1328,120 @@ mod tests {
        }
 
        #[test]
-       fn test_invoice_payer() {
-               let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
-               let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let nodes = create_nodes(2, "test_invoice_payer".to_string());
+       fn test_payment_path_scoring() {
+               // Ensure that we update the scorer when relevant events are processed. In this case, we ensure
+               // that we update the scorer upon a payment path succeeding (note that the channel must be
+               // public or else we won't score it).
+               // Set up a background event handler for FundingGenerationReady events.
+               let (sender, receiver) = std::sync::mpsc::sync_channel(1);
+               let event_handler = move |event: Event| match event {
+                       Event::PaymentPathFailed { .. } => sender.send(event).unwrap(),
+                       Event::PaymentPathSuccessful { .. } => sender.send(event).unwrap(),
+                       Event::ProbeSuccessful { .. } => sender.send(event).unwrap(),
+                       Event::ProbeFailed { .. } => sender.send(event).unwrap(),
+                       _ => panic!("Unexpected event: {:?}", event),
+               };
 
-               // Initiate the background processors to watch each node.
+               let nodes = create_nodes(1, "test_payment_path_scoring".to_string());
                let data_dir = nodes[0].persister.get_data_dir();
-               let persister = Arc::new(Persister::new(data_dir));
-               let router = DefaultRouter::new(Arc::clone(&nodes[0].network_graph), Arc::clone(&nodes[0].logger), random_seed_bytes, Arc::clone(&nodes[0].scorer));
-               let invoice_payer = Arc::new(InvoicePayer::new(Arc::clone(&nodes[0].node), router, Arc::clone(&nodes[0].logger), |_: _| {}, Retry::Attempts(2)));
-               let event_handler = Arc::clone(&invoice_payer);
+               let persister = Arc::new(Persister::new(data_dir.clone()));
                let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].no_gossip_sync(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
+
+               let scored_scid = 4242;
+               let secp_ctx = Secp256k1::new();
+               let node_1_privkey = SecretKey::from_slice(&[42; 32]).unwrap();
+               let node_1_id = PublicKey::from_secret_key(&secp_ctx, &node_1_privkey);
+
+               let path = vec![RouteHop {
+                       pubkey: node_1_id,
+                       node_features: NodeFeatures::empty(),
+                       short_channel_id: scored_scid,
+                       channel_features: ChannelFeatures::empty(),
+                       fee_msat: 0,
+                       cltv_expiry_delta: MIN_CLTV_EXPIRY_DELTA as u32,
+               }];
+
+               nodes[0].scorer.lock().unwrap().expect(TestResult::PaymentFailure { path: path.clone(), short_channel_id: scored_scid });
+               nodes[0].node.push_pending_event(Event::PaymentPathFailed {
+                       payment_id: None,
+                       payment_hash: PaymentHash([42; 32]),
+                       payment_failed_permanently: false,
+                       failure: PathFailure::OnPath { network_update: None },
+                       path: path.clone(),
+                       short_channel_id: Some(scored_scid),
+                       retry: None,
+               });
+               let event = receiver
+                       .recv_timeout(Duration::from_secs(EVENT_DEADLINE))
+                       .expect("PaymentPathFailed not handled within deadline");
+               match event {
+                       Event::PaymentPathFailed { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+
+               // Ensure we'll score payments that were explicitly failed back by the destination as
+               // ProbeSuccess.
+               nodes[0].scorer.lock().unwrap().expect(TestResult::ProbeSuccess { path: path.clone() });
+               nodes[0].node.push_pending_event(Event::PaymentPathFailed {
+                       payment_id: None,
+                       payment_hash: PaymentHash([42; 32]),
+                       payment_failed_permanently: true,
+                       failure: PathFailure::OnPath { network_update: None },
+                       path: path.clone(),
+                       short_channel_id: None,
+                       retry: None,
+               });
+               let event = receiver
+                       .recv_timeout(Duration::from_secs(EVENT_DEADLINE))
+                       .expect("PaymentPathFailed not handled within deadline");
+               match event {
+                       Event::PaymentPathFailed { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+
+               nodes[0].scorer.lock().unwrap().expect(TestResult::PaymentSuccess { path: path.clone() });
+               nodes[0].node.push_pending_event(Event::PaymentPathSuccessful {
+                       payment_id: PaymentId([42; 32]),
+                       payment_hash: None,
+                       path: path.clone(),
+               });
+               let event = receiver
+                       .recv_timeout(Duration::from_secs(EVENT_DEADLINE))
+                       .expect("PaymentPathSuccessful not handled within deadline");
+               match event {
+                       Event::PaymentPathSuccessful { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+
+               nodes[0].scorer.lock().unwrap().expect(TestResult::ProbeSuccess { path: path.clone() });
+               nodes[0].node.push_pending_event(Event::ProbeSuccessful {
+                       payment_id: PaymentId([42; 32]),
+                       payment_hash: PaymentHash([42; 32]),
+                       path: path.clone(),
+               });
+               let event = receiver
+                       .recv_timeout(Duration::from_secs(EVENT_DEADLINE))
+                       .expect("ProbeSuccessful not handled within deadline");
+               match event {
+                       Event::ProbeSuccessful  { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+
+               nodes[0].scorer.lock().unwrap().expect(TestResult::ProbeFailure { path: path.clone() });
+               nodes[0].node.push_pending_event(Event::ProbeFailed {
+                       payment_id: PaymentId([42; 32]),
+                       payment_hash: PaymentHash([42; 32]),
+                       path: path.clone(),
+                       short_channel_id: Some(scored_scid),
+               });
+               let event = receiver
+                       .recv_timeout(Duration::from_secs(EVENT_DEADLINE))
+                       .expect("ProbeFailure not handled within deadline");
+               match event {
+                       Event::ProbeFailed { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+
                assert!(bg_processor.stop().is_ok());
        }
 }
index 8b185ff3babcb4e31f76bfb47260cf088c9ee11c..c605f5ef3a2ef4b3201cec0e7a979b1bda7b9ecc 100644 (file)
@@ -27,4 +27,5 @@ serde_json = { version = "1.0", optional = true }
 chunked_transfer = { version = "1.4", optional = true }
 
 [dev-dependencies]
+lightning = { version = "0.0.113", path = "../lightning", features = ["_test_utils"] }
 tokio = { version = "~1.14", features = [ "macros", "rt" ] }
index 23e4435a6f513a6e58ba8c428d32d6c031c46d35..2807bc877694c42b827d22a80cb2f17ce621edd0 100644 (file)
@@ -48,7 +48,7 @@ BlockSourceResult<ValidatedBlockHeader> where B::Target: BlockSource {
 /// use lightning::chain::chaininterface::BroadcasterInterface;
 /// use lightning::chain::chaininterface::FeeEstimator;
 /// use lightning::chain::keysinterface;
-/// use lightning::chain::keysinterface::KeysInterface;
+/// use lightning::chain::keysinterface::{EntropySource, NodeSigner, SignerProvider};
 /// use lightning::ln::channelmanager::{ChannelManager, ChannelManagerReadArgs};
 /// use lightning::routing::router::Router;
 /// use lightning::util::config::UserConfig;
@@ -61,18 +61,22 @@ BlockSourceResult<ValidatedBlockHeader> where B::Target: BlockSource {
 ///
 /// async fn init_sync<
 ///    B: BlockSource,
-///    K: KeysInterface,
+///    ES: EntropySource,
+///    NS: NodeSigner,
+///    SP: SignerProvider,
 ///    T: BroadcasterInterface,
 ///    F: FeeEstimator,
 ///    R: Router,
 ///    L: Logger,
 ///    C: chain::Filter,
-///    P: chainmonitor::Persist<K::Signer>,
+///    P: chainmonitor::Persist<SP::Signer>,
 /// >(
 ///    block_source: &B,
-///    chain_monitor: &ChainMonitor<K::Signer, &C, &T, &F, &L, &P>,
+///    chain_monitor: &ChainMonitor<SP::Signer, &C, &T, &F, &L, &P>,
 ///    config: UserConfig,
-///    keys_manager: &K,
+///    entropy_source: &ES,
+///    node_signer: &NS,
+///    signer_provider: &SP,
 ///    tx_broadcaster: &T,
 ///    fee_estimator: &F,
 ///    router: &R,
@@ -81,14 +85,16 @@ BlockSourceResult<ValidatedBlockHeader> where B::Target: BlockSource {
 /// ) {
 ///    // Read a serialized channel monitor paired with the block hash when it was persisted.
 ///    let serialized_monitor = "...";
-///    let (monitor_block_hash, mut monitor) = <(BlockHash, ChannelMonitor<K::Signer>)>::read(
-///            &mut Cursor::new(&serialized_monitor), keys_manager).unwrap();
+///    let (monitor_block_hash, mut monitor) = <(BlockHash, ChannelMonitor<SP::Signer>)>::read(
+///            &mut Cursor::new(&serialized_monitor), (entropy_source, signer_provider)).unwrap();
 ///
 ///    // Read the channel manager paired with the block hash when it was persisted.
 ///    let serialized_manager = "...";
 ///    let (manager_block_hash, mut manager) = {
 ///            let read_args = ChannelManagerReadArgs::new(
-///                    keys_manager,
+///                    entropy_source,
+///                    node_signer,
+///                    signer_provider,
 ///                    fee_estimator,
 ///                    chain_monitor,
 ///                    tx_broadcaster,
@@ -97,7 +103,7 @@ BlockSourceResult<ValidatedBlockHeader> where B::Target: BlockSource {
 ///                    config,
 ///                    vec![&mut monitor],
 ///            );
-///            <(BlockHash, ChannelManager<&ChainMonitor<K::Signer, &C, &T, &F, &L, &P>, &T, &K, &F, &R, &L>)>::read(
+///            <(BlockHash, ChannelManager<&ChainMonitor<SP::Signer, &C, &T, &F, &L, &P>, &T, &ES, &NS, &SP, &F, &R, &L>)>::read(
 ///                    &mut Cursor::new(&serialized_manager), read_args).unwrap()
 ///    };
 ///
index 189a68be0654dab1453ef459d3046d5d0001c17d..0a7c655147ff0c85faf1297a2830d95b1f5746ce 100644 (file)
@@ -132,6 +132,9 @@ impl BlockSourceError {
        }
 
        /// Converts the error into the underlying error.
+       ///
+       /// May contain an [`std::io::Error`] from the [`BlockSource`]. See implementations for further
+       /// details, if any.
        pub fn into_inner(self) -> Box<dyn std::error::Error + Send + Sync> {
                self.error
        }
index f04769560246f8537e1e022efa22c8b7a815eab4..e1dc43c8f28d65511c45ce32591ef9eb5b933e8b 100644 (file)
@@ -13,9 +13,31 @@ use serde_json;
 
 use std::convert::TryFrom;
 use std::convert::TryInto;
+use std::error::Error;
+use std::fmt;
 use std::sync::atomic::{AtomicUsize, Ordering};
 
+/// An error returned by the RPC server.
+#[derive(Debug)]
+pub struct RpcError {
+       /// The error code.
+       pub code: i64,
+       /// The error message.
+       pub message: String,
+}
+
+impl fmt::Display for RpcError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "RPC error {}: {}", self.code, self.message)
+    }
+}
+
+impl Error for RpcError {}
+
 /// A simple RPC client for calling methods using HTTP `POST`.
+///
+/// Implements [`BlockSource`] and may return an `Err` containing [`RpcError`]. See
+/// [`RpcClient::call_method`] for details.
 pub struct RpcClient {
        basic_auth: String,
        endpoint: HttpEndpoint,
@@ -38,6 +60,9 @@ impl RpcClient {
        }
 
        /// Calls a method with the response encoded in JSON format and interpreted as type `T`.
+       ///
+       /// When an `Err` is returned, [`std::io::Error::into_inner`] may contain an [`RpcError`] if
+       /// [`std::io::Error::kind`] is [`std::io::ErrorKind::Other`].
        pub async fn call_method<T>(&self, method: &str, params: &[serde_json::Value]) -> std::io::Result<T>
        where JsonResponse: TryFrom<Vec<u8>, Error = std::io::Error> + TryInto<T, Error = std::io::Error> {
                let host = format!("{}:{}", self.endpoint.host(), self.endpoint.port());
@@ -69,8 +94,11 @@ impl RpcClient {
                let error = &response["error"];
                if !error.is_null() {
                        // TODO: Examine error code for a more precise std::io::ErrorKind.
-                       let message = error["message"].as_str().unwrap_or("unknown error");
-                       return Err(std::io::Error::new(std::io::ErrorKind::Other, message));
+                       let rpc_error = RpcError { 
+                               code: error["code"].as_i64().unwrap_or(-1), 
+                               message: error["message"].as_str().unwrap_or("unknown error").to_string() 
+                       };
+                       return Err(std::io::Error::new(std::io::ErrorKind::Other, rpc_error));
                }
 
                let result = &mut response["result"];
@@ -163,7 +191,9 @@ mod tests {
                match client.call_method::<u64>("getblock", &[invalid_block_hash]).await {
                        Err(e) => {
                                assert_eq!(e.kind(), std::io::ErrorKind::Other);
-                               assert_eq!(e.get_ref().unwrap().to_string(), "invalid parameter");
+                               let rpc_error: Box<RpcError> = e.into_inner().unwrap().downcast().unwrap();
+                               assert_eq!(rpc_error.code, -8);
+                               assert_eq!(rpc_error.message, "invalid parameter");
                        },
                        Ok(_) => panic!("Expected error"),
                }
diff --git a/lightning-custom-message/Cargo.toml b/lightning-custom-message/Cargo.toml
new file mode 100644 (file)
index 0000000..657844c
--- /dev/null
@@ -0,0 +1,18 @@
+[package]
+name = "lightning-custom-message"
+version = "0.0.113"
+authors = ["Jeffrey Czyz"]
+license = "MIT OR Apache-2.0"
+repository = "http://github.com/lightningdevkit/rust-lightning"
+description = """
+Utilities for supporting custom peer-to-peer messages in LDK.
+"""
+edition = "2021"
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
+
+[dependencies]
+bitcoin = "0.29.0"
+lightning = { version = "0.0.113", path = "../lightning" }
diff --git a/lightning-custom-message/src/lib.rs b/lightning-custom-message/src/lib.rs
new file mode 100644 (file)
index 0000000..a6e4397
--- /dev/null
@@ -0,0 +1,310 @@
+//! Utilities for supporting custom peer-to-peer messages in LDK.
+//!
+//! [BOLT 1] specifies a custom message type range for use with experimental or application-specific
+//! messages. While a [`CustomMessageHandler`] can be defined to support more than one message type,
+//! defining such a handler requires a significant amount of boilerplate and can be error prone.
+//!
+//! This crate provides the [`composite_custom_message_handler`] macro for easily composing
+//! pre-defined custom message handlers into one handler. The resulting handler can be further
+//! composed with other custom message handlers using the same macro.
+//!
+//! The following example demonstrates defining a `FooBarHandler` to compose separate handlers for
+//! `Foo` and `Bar` messages, and further composing it with a handler for `Baz` messages.
+//!
+//!```
+//! # extern crate bitcoin;
+//! extern crate lightning;
+//! #[macro_use]
+//! extern crate lightning_custom_message;
+//!
+//! # use bitcoin::secp256k1::PublicKey;
+//! # use lightning::io;
+//! # use lightning::ln::msgs::{DecodeError, LightningError};
+//! use lightning::ln::peer_handler::CustomMessageHandler;
+//! use lightning::ln::wire::{CustomMessageReader, self};
+//! use lightning::util::ser::Writeable;
+//! # use lightning::util::ser::Writer;
+//!
+//! // Assume that `FooHandler` and `BarHandler` are defined in one crate and `BazHandler` is
+//! // defined in another crate, handling messages `Foo`, `Bar`, and `Baz`, respectively.
+//!
+//! #[derive(Debug)]
+//! pub struct Foo;
+//!
+//! macro_rules! foo_type_id {
+//!     () => { 32768 }
+//! }
+//!
+//! impl wire::Type for Foo {
+//!     fn type_id(&self) -> u16 { foo_type_id!() }
+//! }
+//! impl Writeable for Foo {
+//!     // ...
+//! #     fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
+//! #         unimplemented!()
+//! #     }
+//! }
+//!
+//! pub struct FooHandler;
+//!
+//! impl CustomMessageReader for FooHandler {
+//!     // ...
+//! #     type CustomMessage = Foo;
+//! #     fn read<R: io::Read>(
+//! #         &self, _message_type: u16, _buffer: &mut R
+//! #     ) -> Result<Option<Self::CustomMessage>, DecodeError> {
+//! #         unimplemented!()
+//! #     }
+//! }
+//! impl CustomMessageHandler for FooHandler {
+//!     // ...
+//! #     fn handle_custom_message(
+//! #         &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
+//! #     ) -> Result<(), LightningError> {
+//! #         unimplemented!()
+//! #     }
+//! #     fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
+//! #         unimplemented!()
+//! #     }
+//! }
+//!
+//! #[derive(Debug)]
+//! pub struct Bar;
+//!
+//! macro_rules! bar_type_id {
+//!     () => { 32769 }
+//! }
+//!
+//! impl wire::Type for Bar {
+//!     fn type_id(&self) -> u16 { bar_type_id!() }
+//! }
+//! impl Writeable for Bar {
+//!     // ...
+//! #     fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
+//! #         unimplemented!()
+//! #     }
+//! }
+//!
+//! pub struct BarHandler;
+//!
+//! impl CustomMessageReader for BarHandler {
+//!     // ...
+//! #     type CustomMessage = Bar;
+//! #     fn read<R: io::Read>(
+//! #         &self, _message_type: u16, _buffer: &mut R
+//! #     ) -> Result<Option<Self::CustomMessage>, DecodeError> {
+//! #         unimplemented!()
+//! #     }
+//! }
+//! impl CustomMessageHandler for BarHandler {
+//!     // ...
+//! #     fn handle_custom_message(
+//! #         &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
+//! #     ) -> Result<(), LightningError> {
+//! #         unimplemented!()
+//! #     }
+//! #     fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
+//! #         unimplemented!()
+//! #     }
+//! }
+//!
+//! #[derive(Debug)]
+//! pub struct Baz;
+//!
+//! macro_rules! baz_type_id {
+//!     () => { 32770 }
+//! }
+//!
+//! impl wire::Type for Baz {
+//!     fn type_id(&self) -> u16 { baz_type_id!() }
+//! }
+//! impl Writeable for Baz {
+//!     // ...
+//! #     fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
+//! #         unimplemented!()
+//! #     }
+//! }
+//!
+//! pub struct BazHandler;
+//!
+//! impl CustomMessageReader for BazHandler {
+//!     // ...
+//! #     type CustomMessage = Baz;
+//! #     fn read<R: io::Read>(
+//! #         &self, _message_type: u16, _buffer: &mut R
+//! #     ) -> Result<Option<Self::CustomMessage>, DecodeError> {
+//! #         unimplemented!()
+//! #     }
+//! }
+//! impl CustomMessageHandler for BazHandler {
+//!     // ...
+//! #     fn handle_custom_message(
+//! #         &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
+//! #     ) -> Result<(), LightningError> {
+//! #         unimplemented!()
+//! #     }
+//! #     fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
+//! #         unimplemented!()
+//! #     }
+//! }
+//!
+//! # fn main() {
+//! // The first crate may define a handler composing `FooHandler` and `BarHandler` and export the
+//! // corresponding message type ids as a macro to use in further composition.
+//!
+//! composite_custom_message_handler!(
+//!     pub struct FooBarHandler {
+//!         foo: FooHandler,
+//!         bar: BarHandler,
+//!     }
+//!
+//!     pub enum FooBarMessage {
+//!         Foo(foo_type_id!()),
+//!         Bar(bar_type_id!()),
+//!     }
+//! );
+//!
+//! #[macro_export]
+//! macro_rules! foo_bar_type_ids {
+//!     () => { foo_type_id!() | bar_type_id!() }
+//! }
+//!
+//! // Another crate can then define a handler further composing `FooBarHandler` with `BazHandler`
+//! // and similarly export the composition of message type ids as a macro.
+//!
+//! composite_custom_message_handler!(
+//!     pub struct FooBarBazHandler {
+//!         foo_bar: FooBarHandler,
+//!         baz: BazHandler,
+//!     }
+//!
+//!     pub enum FooBarBazMessage {
+//!         FooBar(foo_bar_type_ids!()),
+//!         Baz(baz_type_id!()),
+//!     }
+//! );
+//!
+//! #[macro_export]
+//! macro_rules! foo_bar_baz_type_ids {
+//!     () => { foo_bar_type_ids!() | baz_type_id!() }
+//! }
+//! # }
+//!```
+//!
+//! [BOLT 1]: https://github.com/lightning/bolts/blob/master/01-messaging.md
+//! [`CustomMessageHandler`]: crate::lightning::ln::peer_handler::CustomMessageHandler
+
+#![doc(test(no_crate_inject, attr(deny(warnings))))]
+
+pub extern crate bitcoin;
+pub extern crate lightning;
+
+/// Defines a composite type implementing [`CustomMessageHandler`] (and therefore also implementing
+/// [`CustomMessageReader`]), along with a corresponding enumerated custom message [`Type`], from
+/// one or more previously defined custom message handlers.
+///
+/// Useful for parameterizing [`PeerManager`] with custom message handling for one or more sets of
+/// custom messages. Message type ids may be given as a valid `match` pattern, including ranges,
+/// though using OR-ed literal patterns is preferred in order to catch unreachable code for
+/// conflicting handlers.
+///
+/// See [crate documentation] for example usage.
+///
+/// [`CustomMessageHandler`]: crate::lightning::ln::peer_handler::CustomMessageHandler
+/// [`CustomMessageReader`]: crate::lightning::ln::wire::CustomMessageReader
+/// [`Type`]: crate::lightning::ln::wire::Type
+/// [`PeerManager`]: crate::lightning::ln::peer_handler::PeerManager
+/// [crate documentation]: self
+#[macro_export]
+macro_rules! composite_custom_message_handler {
+       (
+               $handler_visibility:vis struct $handler:ident {
+                       $($field_visibility:vis $field:ident: $type:ty),* $(,)*
+               }
+
+               $message_visibility:vis enum $message:ident {
+                       $($variant:ident($pattern:pat)),* $(,)*
+               }
+       ) => {
+               #[allow(missing_docs)]
+               $handler_visibility struct $handler {
+                       $(
+                               $field_visibility $field: $type,
+                       )*
+               }
+
+               #[allow(missing_docs)]
+               #[derive(Debug)]
+               $message_visibility enum $message {
+                       $(
+                               $variant(<$type as $crate::lightning::ln::wire::CustomMessageReader>::CustomMessage),
+                       )*
+               }
+
+               impl $crate::lightning::ln::peer_handler::CustomMessageHandler for $handler {
+                       fn handle_custom_message(
+                               &self, msg: Self::CustomMessage, sender_node_id: &$crate::bitcoin::secp256k1::PublicKey
+                       ) -> Result<(), $crate::lightning::ln::msgs::LightningError> {
+                               match msg {
+                                       $(
+                                               $message::$variant(message) => {
+                                                       $crate::lightning::ln::peer_handler::CustomMessageHandler::handle_custom_message(
+                                                               &self.$field, message, sender_node_id
+                                                       )
+                                               },
+                                       )*
+                               }
+                       }
+
+                       fn get_and_clear_pending_msg(&self) -> Vec<($crate::bitcoin::secp256k1::PublicKey, Self::CustomMessage)> {
+                               vec![].into_iter()
+                                       $(
+                                               .chain(
+                                                       self.$field
+                                                               .get_and_clear_pending_msg()
+                                                               .into_iter()
+                                                               .map(|(pubkey, message)| (pubkey, $message::$variant(message)))
+                                               )
+                                       )*
+                                       .collect()
+                       }
+               }
+
+               impl $crate::lightning::ln::wire::CustomMessageReader for $handler {
+                       type CustomMessage = $message;
+                       fn read<R: $crate::lightning::io::Read>(
+                               &self, message_type: u16, buffer: &mut R
+                       ) -> Result<Option<Self::CustomMessage>, $crate::lightning::ln::msgs::DecodeError> {
+                               match message_type {
+                                       $(
+                                               $pattern => match <$type>::read(&self.$field, message_type, buffer)? {
+                                                       None => unreachable!(),
+                                                       Some(message) => Ok(Some($message::$variant(message))),
+                                               },
+                                       )*
+                                       _ => Ok(None),
+                               }
+                       }
+               }
+
+               impl $crate::lightning::ln::wire::Type for $message {
+                       fn type_id(&self) -> u16 {
+                               match self {
+                                       $(
+                                               Self::$variant(message) => message.type_id(),
+                                       )*
+                               }
+                       }
+               }
+
+               impl $crate::lightning::util::ser::Writeable for $message {
+                       fn write<W: $crate::lightning::util::ser::Writer>(&self, writer: &mut W) -> Result<(), $crate::lightning::io::Error> {
+                               match self {
+                                       $(
+                                               Self::$variant(message) => message.write(writer),
+                                       )*
+                               }
+                       }
+               }
+       }
+}
index 0759698b1603476b890198ebe14b99ce8948016c..92c1cb5c28f5385b5eb2f37c2cbbac62b58ac398 100644 (file)
@@ -22,7 +22,7 @@ use secp256k1;
 use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
 use secp256k1::PublicKey;
 
-use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiry, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
+use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
        SemanticError, PrivateRoute, ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawInvoice,
        constants, SignedRawInvoice, RawDataPart, InvoiceFeatures};
 
@@ -451,8 +451,8 @@ impl FromBase32 for TaggedField {
                                Ok(TaggedField::DescriptionHash(Sha256::from_base32(field_data)?)),
                        constants::TAG_EXPIRY_TIME =>
                                Ok(TaggedField::ExpiryTime(ExpiryTime::from_base32(field_data)?)),
-                       constants::TAG_MIN_FINAL_CLTV_EXPIRY =>
-                               Ok(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry::from_base32(field_data)?)),
+                       constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA =>
+                               Ok(TaggedField::MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta::from_base32(field_data)?)),
                        constants::TAG_FALLBACK =>
                                Ok(TaggedField::Fallback(Fallback::from_base32(field_data)?)),
                        constants::TAG_PRIVATE_ROUTE =>
@@ -523,13 +523,13 @@ impl FromBase32 for ExpiryTime {
        }
 }
 
-impl FromBase32 for MinFinalCltvExpiry {
+impl FromBase32 for MinFinalCltvExpiryDelta {
        type Err = ParseError;
 
-       fn from_base32(field_data: &[u5]) -> Result<MinFinalCltvExpiry, ParseError> {
+       fn from_base32(field_data: &[u5]) -> Result<MinFinalCltvExpiryDelta, ParseError> {
                let expiry = parse_int_be::<u64, u5>(field_data, 32);
                if let Some(expiry) = expiry {
-                       Ok(MinFinalCltvExpiry(expiry))
+                       Ok(MinFinalCltvExpiryDelta(expiry))
                } else {
                        Err(ParseError::IntegerOverflowError)
                }
@@ -840,14 +840,14 @@ mod test {
        }
 
        #[test]
-       fn test_parse_min_final_cltv_expiry() {
-               use crate::MinFinalCltvExpiry;
+       fn test_parse_min_final_cltv_expiry_delta() {
+               use crate::MinFinalCltvExpiryDelta;
                use bech32::FromBase32;
 
                let input = from_bech32("pr".as_bytes());
-               let expected = Ok(MinFinalCltvExpiry(35));
+               let expected = Ok(MinFinalCltvExpiryDelta(35));
 
-               assert_eq!(MinFinalCltvExpiry::from_base32(&input), expected);
+               assert_eq!(MinFinalCltvExpiryDelta::from_base32(&input), expected);
        }
 
        #[test]
index 4737173eef5da6e1f0ebdf16d8d235b536db4dce..17b6e2de2b6efe8582f9f78823289f306c9f4991 100644 (file)
@@ -154,11 +154,11 @@ pub const DEFAULT_EXPIRY_TIME: u64 = 3600;
 /// Default minimum final CLTV expiry as defined by [BOLT 11].
 ///
 /// Note that this is *not* the same value as rust-lightning's minimum CLTV expiry, which is
-/// provided in [`MIN_FINAL_CLTV_EXPIRY`].
+/// provided in [`MIN_FINAL_CLTV_EXPIRY_DELTA`].
 ///
 /// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
-/// [`MIN_FINAL_CLTV_EXPIRY`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY
-pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18;
+/// [`MIN_FINAL_CLTV_EXPIRY_DELTA`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA
+pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA: u64 = 18;
 
 /// Builder for `Invoice`s. It's the most convenient and advised way to use this library. It ensures
 /// that only a semantically and syntactically correct Invoice can be built using it.
@@ -199,7 +199,7 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18;
 ///    .payment_hash(payment_hash)
 ///    .payment_secret(payment_secret)
 ///    .current_timestamp()
-///    .min_final_cltv_expiry(144)
+///    .min_final_cltv_expiry_delta(144)
 ///    .build_signed(|hash| {
 ///            Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
 ///    })
@@ -297,7 +297,7 @@ pub struct RawInvoice {
 
 /// Data of the `RawInvoice` that is encoded in the human readable part
 ///
-/// (C-not exported) As we don't yet support Option<Enum>
+/// (C-not exported) As we don't yet support `Option<Enum>`
 #[derive(Eq, PartialEq, Debug, Clone, Hash)]
 pub struct RawHrp {
        /// The currency deferred from the 3rd and 4th character of the bech32 transaction
@@ -410,7 +410,7 @@ pub enum TaggedField {
        PayeePubKey(PayeePubKey),
        DescriptionHash(Sha256),
        ExpiryTime(ExpiryTime),
-       MinFinalCltvExpiry(MinFinalCltvExpiry),
+       MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta),
        Fallback(Fallback),
        PrivateRoute(PrivateRoute),
        PaymentSecret(PaymentSecret),
@@ -438,9 +438,9 @@ pub struct PayeePubKey(pub PublicKey);
 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
 pub struct ExpiryTime(Duration);
 
-/// `min_final_cltv_expiry` to use for the last HTLC in the route
+/// `min_final_cltv_expiry_delta` to use for the last HTLC in the route
 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
-pub struct MinFinalCltvExpiry(pub u64);
+pub struct MinFinalCltvExpiryDelta(pub u64);
 
 // TODO: better types instead onf byte arrays
 /// Fallback address in case no LN payment is possible
@@ -475,7 +475,7 @@ pub mod constants {
        pub const TAG_PAYEE_PUB_KEY: u8 = 19;
        pub const TAG_DESCRIPTION_HASH: u8 = 23;
        pub const TAG_EXPIRY_TIME: u8 = 6;
-       pub const TAG_MIN_FINAL_CLTV_EXPIRY: u8 = 24;
+       pub const TAG_MIN_FINAL_CLTV_EXPIRY_DELTA: u8 = 24;
        pub const TAG_FALLBACK: u8 = 9;
        pub const TAG_PRIVATE_ROUTE: u8 = 3;
        pub const TAG_PAYMENT_SECRET: u8 = 16;
@@ -654,9 +654,9 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
 }
 
 impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, T, tb::False, S> {
-       /// Sets `min_final_cltv_expiry`.
-       pub fn min_final_cltv_expiry(mut self, min_final_cltv_expiry: u64) -> InvoiceBuilder<D, H, T, tb::True, S> {
-               self.tagged_fields.push(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry(min_final_cltv_expiry)));
+       /// Sets `min_final_cltv_expiry_delta`.
+       pub fn min_final_cltv_expiry_delta(mut self, min_final_cltv_expiry_delta: u64) -> InvoiceBuilder<D, H, T, tb::True, S> {
+               self.tagged_fields.push(TaggedField::MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta(min_final_cltv_expiry_delta)));
                self.set_flags()
        }
 }
@@ -806,6 +806,7 @@ impl SignedRawInvoice {
 ///
 /// The following example would extract the first B.
 ///
+/// ```ignore
 /// enum Enum {
 ///    A(u8),
 ///    B(u16)
@@ -814,6 +815,7 @@ impl SignedRawInvoice {
 /// let elements = vec![Enum::A(1), Enum::A(2), Enum::B(3), Enum::A(4)];
 ///
 /// assert_eq!(find_extract!(elements.iter(), Enum::B(x), x), Some(3u16));
+/// ```
 macro_rules! find_extract {
        ($iter:expr, $enm:pat, $enm_var:ident) => {
                find_all_extract!($iter, $enm, $enm_var).next()
@@ -825,6 +827,7 @@ macro_rules! find_extract {
 ///
 /// The following example would extract all A.
 ///
+/// ```ignore
 /// enum Enum {
 ///    A(u8),
 ///    B(u16)
@@ -836,6 +839,7 @@ macro_rules! find_extract {
 ///    find_all_extract!(elements.iter(), Enum::A(x), x).collect::<Vec<u8>>(),
 ///    vec![1u8, 2u8, 4u8]
 /// );
+/// ```
 macro_rules! find_all_extract {
        ($iter:expr, $enm:pat, $enm_var:ident) => {
                $iter.filter_map(|tf| match *tf {
@@ -925,8 +929,8 @@ impl RawInvoice {
                find_extract!(self.known_tagged_fields(), TaggedField::ExpiryTime(ref x), x)
        }
 
-       pub fn min_final_cltv_expiry(&self) -> Option<&MinFinalCltvExpiry> {
-               find_extract!(self.known_tagged_fields(), TaggedField::MinFinalCltvExpiry(ref x), x)
+       pub fn min_final_cltv_expiry_delta(&self) -> Option<&MinFinalCltvExpiryDelta> {
+               find_extract!(self.known_tagged_fields(), TaggedField::MinFinalCltvExpiryDelta(ref x), x)
        }
 
        pub fn payment_secret(&self) -> Option<&PaymentSecret> {
@@ -1239,12 +1243,12 @@ impl Invoice {
                        .unwrap_or_else(|| Duration::new(u64::max_value(), 1_000_000_000 - 1)) < at_time
        }
 
-       /// Returns the invoice's `min_final_cltv_expiry` time, if present, otherwise
-       /// [`DEFAULT_MIN_FINAL_CLTV_EXPIRY`].
-       pub fn min_final_cltv_expiry(&self) -> u64 {
-               self.signed_invoice.min_final_cltv_expiry()
+       /// Returns the invoice's `min_final_cltv_expiry_delta` time, if present, otherwise
+       /// [`DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA`].
+       pub fn min_final_cltv_expiry_delta(&self) -> u64 {
+               self.signed_invoice.min_final_cltv_expiry_delta()
                        .map(|x| x.0)
-                       .unwrap_or(DEFAULT_MIN_FINAL_CLTV_EXPIRY)
+                       .unwrap_or(DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA)
        }
 
        /// Returns a list of all fallback addresses
@@ -1276,7 +1280,7 @@ impl Invoice {
                self.signed_invoice.amount_pico_btc().map(|v| v / 10)
        }
 
-       /// Returns the amount if specified in the invoice as pico <currency>.
+       /// Returns the amount if specified in the invoice as pico BTC.
        fn amount_pico_btc(&self) -> Option<u64> {
                self.signed_invoice.amount_pico_btc()
        }
@@ -1297,7 +1301,7 @@ impl TaggedField {
                        TaggedField::PayeePubKey(_) => constants::TAG_PAYEE_PUB_KEY,
                        TaggedField::DescriptionHash(_) => constants::TAG_DESCRIPTION_HASH,
                        TaggedField::ExpiryTime(_) => constants::TAG_EXPIRY_TIME,
-                       TaggedField::MinFinalCltvExpiry(_) => constants::TAG_MIN_FINAL_CLTV_EXPIRY,
+                       TaggedField::MinFinalCltvExpiryDelta(_) => constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA,
                        TaggedField::Fallback(_) => constants::TAG_FALLBACK,
                        TaggedField::PrivateRoute(_) => constants::TAG_PRIVATE_ROUTE,
                        TaggedField::PaymentSecret(_) => constants::TAG_PAYMENT_SECRET,
@@ -1444,6 +1448,11 @@ pub enum CreationError {
        ///
        /// [phantom invoices]: crate::utils::create_phantom_invoice
        MissingRouteHints,
+
+       /// The provided `min_final_cltv_expiry_delta` was less than [`MIN_FINAL_CLTV_EXPIRY_DELTA`].
+       ///
+       /// [`MIN_FINAL_CLTV_EXPIRY_DELTA`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA
+       MinFinalCltvExpiryDeltaTooShort,
 }
 
 impl Display for CreationError {
@@ -1454,6 +1463,8 @@ impl Display for CreationError {
                        CreationError::TimestampOutOfBounds => f.write_str("The Unix timestamp of the supplied date is less than zero or greater than 35-bits"),
                        CreationError::InvalidAmount => f.write_str("The supplied millisatoshi amount was greater than the total bitcoin supply"),
                        CreationError::MissingRouteHints => f.write_str("The invoice required route hints and they weren't provided"),
+                       CreationError::MinFinalCltvExpiryDeltaTooShort => f.write_str(
+                               "The supplied final CLTV expiry delta was less than LDK's `MIN_FINAL_CLTV_EXPIRY_DELTA`"),
                }
        }
 }
@@ -1800,7 +1811,7 @@ mod test {
                let builder = InvoiceBuilder::new(Currency::Bitcoin)
                        .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
                        .duration_since_epoch(Duration::from_secs(1234567))
-                       .min_final_cltv_expiry(144);
+                       .min_final_cltv_expiry_delta(144);
 
                let too_long_string = String::from_iter(
                        (0..1024).map(|_| '?')
@@ -1918,7 +1929,7 @@ mod test {
                        .duration_since_epoch(Duration::from_secs(1234567))
                        .payee_pub_key(public_key.clone())
                        .expiry_time(Duration::from_secs(54321))
-                       .min_final_cltv_expiry(144)
+                       .min_final_cltv_expiry_delta(144)
                        .fallback(Fallback::PubKeyHash([0;20]))
                        .private_route(route_1.clone())
                        .private_route(route_2.clone())
@@ -1944,7 +1955,7 @@ mod test {
                );
                assert_eq!(invoice.payee_pub_key(), Some(&public_key));
                assert_eq!(invoice.expiry_time(), Duration::from_secs(54321));
-               assert_eq!(invoice.min_final_cltv_expiry(), 144);
+               assert_eq!(invoice.min_final_cltv_expiry_delta(), 144);
                assert_eq!(invoice.fallbacks(), vec![&Fallback::PubKeyHash([0;20])]);
                assert_eq!(invoice.private_routes(), vec![&PrivateRoute(route_1), &PrivateRoute(route_2)]);
                assert_eq!(
@@ -1985,7 +1996,7 @@ mod test {
                        .unwrap();
                let invoice = Invoice::from_signed(signed_invoice).unwrap();
 
-               assert_eq!(invoice.min_final_cltv_expiry(), DEFAULT_MIN_FINAL_CLTV_EXPIRY);
+               assert_eq!(invoice.min_final_cltv_expiry_delta(), DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA);
                assert_eq!(invoice.expiry_time(), Duration::from_secs(DEFAULT_EXPIRY_TIME));
                assert!(!invoice.would_expire(Duration::from_secs(1234568)));
        }
index 9fb472d3b311fbc872bdab4d5c74455a4f4e6857..981fd2e6ba49225c0e41fb2923ee56e480aea0b7 100644 (file)
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
-//! A module for paying Lightning invoices and sending spontaneous payments.
-//!
-//! Defines an [`InvoicePayer`] utility for sending payments, parameterized by [`Payer`] and
-//! [`Router`] traits. Implementations of [`Payer`] provide the payer's node id, channels, and means
-//! to send a payment over a [`Route`]. Implementations of [`Router`] find a [`Route`] between payer
-//! and payee using information provided by the payer and from the payee's [`Invoice`], when
-//! applicable.
-//!
-//! [`InvoicePayer`] uses its [`Router`] parameterization for optionally notifying scorers upon
-//! receiving the [`Event::PaymentPathFailed`] and [`Event::PaymentPathSuccessful`] events.
-//! It also does the same for payment probe failure and success events using [`Event::ProbeFailed`]
-//! and [`Event::ProbeSuccessful`].
-//!
-//! [`InvoicePayer`] is capable of retrying failed payments. It accomplishes this by implementing
-//! [`EventHandler`] which decorates a user-provided handler. It will intercept any
-//! [`Event::PaymentPathFailed`] events and retry the failed paths for a fixed number of total
-//! attempts or until retry is no longer possible. In such a situation, [`InvoicePayer`] will pass
-//! along the events to the user-provided handler.
-//!
-//! # Example
-//!
-//! ```
-//! # extern crate lightning;
-//! # extern crate lightning_invoice;
-//! # extern crate secp256k1;
-//! #
-//! # use lightning::io;
-//! # use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
-//! # use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure};
-//! # use lightning::ln::msgs::LightningError;
-//! # use lightning::routing::gossip::NodeId;
-//! # use lightning::routing::router::{InFlightHtlcs, Route, RouteHop, RouteParameters, Router};
-//! # use lightning::routing::scoring::{ChannelUsage, Score};
-//! # use lightning::util::events::{Event, EventHandler, EventsProvider};
-//! # use lightning::util::logger::{Logger, Record};
-//! # use lightning::util::ser::{Writeable, Writer};
-//! # use lightning_invoice::Invoice;
-//! # use lightning_invoice::payment::{InvoicePayer, Payer, Retry};
-//! # use secp256k1::PublicKey;
-//! # use std::cell::RefCell;
-//! # use std::ops::Deref;
-//! #
-//! # struct FakeEventProvider {}
-//! # impl EventsProvider for FakeEventProvider {
-//! #     fn process_pending_events<H: Deref>(&self, handler: H) where H::Target: EventHandler {}
-//! # }
-//! #
-//! # struct FakePayer {}
-//! # impl Payer for FakePayer {
-//! #     fn node_id(&self) -> PublicKey { unimplemented!() }
-//! #     fn first_hops(&self) -> Vec<ChannelDetails> { unimplemented!() }
-//! #     fn send_payment(
-//! #         &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
-//! #         payment_id: PaymentId
-//! #     ) -> Result<(), PaymentSendFailure> { unimplemented!() }
-//! #     fn send_spontaneous_payment(
-//! #         &self, route: &Route, payment_preimage: PaymentPreimage, payment_id: PaymentId,
-//! #     ) -> Result<(), PaymentSendFailure> { unimplemented!() }
-//! #     fn retry_payment(
-//! #         &self, route: &Route, payment_id: PaymentId
-//! #     ) -> Result<(), PaymentSendFailure> { unimplemented!() }
-//! #     fn abandon_payment(&self, payment_id: PaymentId) { unimplemented!() }
-//! #     fn inflight_htlcs(&self) -> InFlightHtlcs { unimplemented!() }
-//! # }
-//! #
-//! # struct FakeRouter {}
-//! # impl Router for FakeRouter {
-//! #     fn find_route(
-//! #         &self, payer: &PublicKey, params: &RouteParameters,
-//! #         first_hops: Option<&[&ChannelDetails]>, _inflight_htlcs: &InFlightHtlcs
-//! #     ) -> Result<Route, LightningError> { unimplemented!() }
-//! #     fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) {  unimplemented!() }
-//! #     fn notify_payment_path_successful(&self, path: &[&RouteHop]) {  unimplemented!() }
-//! #     fn notify_payment_probe_successful(&self, path: &[&RouteHop]) {  unimplemented!() }
-//! #     fn notify_payment_probe_failed(&self, path: &[&RouteHop], short_channel_id: u64) { unimplemented!() }
-//! # }
-//! #
-//! # struct FakeScorer {}
-//! # impl Writeable for FakeScorer {
-//! #     fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> { unimplemented!(); }
-//! # }
-//! # impl Score for FakeScorer {
-//! #     fn channel_penalty_msat(
-//! #         &self, _short_channel_id: u64, _source: &NodeId, _target: &NodeId, _usage: ChannelUsage
-//! #     ) -> u64 { 0 }
-//! #     fn payment_path_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}
-//! #     fn payment_path_successful(&mut self, _path: &[&RouteHop]) {}
-//! #     fn probe_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}
-//! #     fn probe_successful(&mut self, _path: &[&RouteHop]) {}
-//! # }
-//! #
-//! # struct FakeLogger {}
-//! # impl Logger for FakeLogger {
-//! #     fn log(&self, record: &Record) { unimplemented!() }
-//! # }
-//! #
-//! # fn main() {
-//! let event_handler = |event: Event| {
-//!     match event {
-//!         Event::PaymentPathFailed { .. } => println!("payment failed after retries"),
-//!         Event::PaymentSent { .. } => println!("payment successful"),
-//!         _ => {},
-//!     }
-//! };
-//! # let payer = FakePayer {};
-//! # let router = FakeRouter {};
-//! # let scorer = RefCell::new(FakeScorer {});
-//! # let logger = FakeLogger {};
-//! let invoice_payer = InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-//!
-//! let invoice = "...";
-//! if let Ok(invoice) = invoice.parse::<Invoice>() {
-//!     invoice_payer.pay_invoice(&invoice).unwrap();
-//!
-//! # let event_provider = FakeEventProvider {};
-//!     loop {
-//!         event_provider.process_pending_events(&invoice_payer);
-//!     }
-//! }
-//! # }
-//! ```
-//!
-//! # Note
-//!
-//! The [`Route`] is computed before each payment attempt. Any updates affecting path finding such
-//! as updates to the network graph or changes to channel scores should be applied prior to
-//! retries, typically by way of composing [`EventHandler`]s accordingly.
+//! Convenient utilities for paying Lightning invoices and sending spontaneous payments.
 
 use crate::Invoice;
 
 use bitcoin_hashes::Hash;
-use bitcoin_hashes::sha256::Hash as Sha256;
 
-use crate::prelude::*;
-use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
-use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure};
-use lightning::ln::msgs::LightningError;
-use lightning::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteParameters, Router};
-use lightning::util::events::{Event, EventHandler};
+use lightning::chain;
+use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
+use lightning::chain::keysinterface::{NodeSigner, SignerProvider, EntropySource};
+use lightning::ln::{PaymentHash, PaymentSecret};
+use lightning::ln::channelmanager::{ChannelManager, PaymentId, Retry, RetryableSendFailure};
+use lightning::routing::router::{PaymentParameters, RouteParameters, Router};
 use lightning::util::logger::Logger;
-use crate::time_utils::Time;
-use crate::sync::Mutex;
 
-use secp256k1::PublicKey;
-
-use core::fmt;
-use core::fmt::{Debug, Display, Formatter};
-use core::future::Future;
+use core::fmt::Debug;
 use core::ops::Deref;
 use core::time::Duration;
-#[cfg(feature = "std")]
-use std::time::SystemTime;
 
-/// A utility for paying [`Invoice`]s and sending spontaneous payments.
+/// Pays the given [`Invoice`], retrying if needed based on [`Retry`].
 ///
-/// See [module-level documentation] for details.
+/// [`Invoice::payment_hash`] is used as the [`PaymentId`], which ensures idempotency as long
+/// as the payment is still pending. Once the payment completes or fails, you must ensure that
+/// a second payment with the same [`PaymentHash`] is never sent.
 ///
-/// [module-level documentation]: crate::payment
-pub type InvoicePayer<P, R, L, E> = InvoicePayerUsingTime::<P, R, L, E, ConfiguredTime>;
-
-#[cfg(not(feature = "no-std"))]
-type ConfiguredTime = std::time::Instant;
-#[cfg(feature = "no-std")]
-use crate::time_utils;
-#[cfg(feature = "no-std")]
-type ConfiguredTime = time_utils::Eternity;
-
-/// Sealed trait with a blanket implementation to allow both sync and async implementations of event
-/// handling to exist within the InvoicePayer.
-mod sealed {
-       pub trait BaseEventHandler {}
-       impl<T> BaseEventHandler for T {}
-}
-
-/// (C-not exported) generally all users should use the [`InvoicePayer`] type alias.
-pub struct InvoicePayerUsingTime<
-       P: Deref,
-       R: Router,
-       L: Deref,
-       E: sealed::BaseEventHandler,
-       T: Time
-> where
-       P::Target: Payer,
-       L::Target: Logger,
+/// If you wish to use a different payment idempotency token, see [`pay_invoice_with_id`].
+pub fn pay_invoice<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       invoice: &Invoice, retry_strategy: Retry,
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>
+) -> Result<PaymentId, PaymentError>
+where
+               M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+               T::Target: BroadcasterInterface,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               SP::Target: SignerProvider,
+               F::Target: FeeEstimator,
+               R::Target: Router,
+               L::Target: Logger,
 {
-       payer: P,
-       router: R,
-       logger: L,
-       event_handler: E,
-       /// Caches the overall attempts at making a payment, which is updated prior to retrying.
-       payment_cache: Mutex<HashMap<PaymentHash, PaymentAttempts<T>>>,
-       retry: Retry,
-}
-
-/// Storing minimal payment attempts information required for determining if a outbound payment can
-/// be retried.
-#[derive(Clone, Copy)]
-struct PaymentAttempts<T: Time> {
-       /// This count will be incremented only after the result of the attempt is known. When it's 0,
-       /// it means the result of the first attempt is now known yet.
-       count: usize,
-       /// This field is only used when retry is [`Retry::Timeout`] which is only build with feature std
-       first_attempted_at: T
+       let payment_id = PaymentId(invoice.payment_hash().into_inner());
+       pay_invoice_with_id(invoice, payment_id, retry_strategy, channelmanager)
+               .map(|()| payment_id)
 }
 
-impl<T: Time> PaymentAttempts<T> {
-       fn new() -> Self {
-               PaymentAttempts {
-                       count: 0,
-                       first_attempted_at: T::now()
-               }
-       }
+/// Pays the given [`Invoice`] with a custom idempotency key, retrying if needed based on [`Retry`].
+///
+/// Note that idempotency is only guaranteed as long as the payment is still pending. Once the
+/// payment completes or fails, no idempotency guarantees are made.
+///
+/// You should ensure that the [`Invoice::payment_hash`] is unique and the same [`PaymentHash`]
+/// has never been paid before.
+///
+/// See [`pay_invoice`] for a variant which uses the [`PaymentHash`] for the idempotency token.
+pub fn pay_invoice_with_id<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       invoice: &Invoice, payment_id: PaymentId, retry_strategy: Retry,
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>
+) -> Result<(), PaymentError>
+where
+               M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+               T::Target: BroadcasterInterface,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               SP::Target: SignerProvider,
+               F::Target: FeeEstimator,
+               R::Target: Router,
+               L::Target: Logger,
+{
+       let amt_msat = invoice.amount_milli_satoshis().ok_or(PaymentError::Invoice("amount missing"))?;
+       pay_invoice_using_amount(invoice, amt_msat, payment_id, retry_strategy, channelmanager)
 }
 
-impl<T: Time> Display for PaymentAttempts<T> {
-       fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
-               #[cfg(feature = "no-std")]
-               return write!( f, "attempts: {}", self.count);
-               #[cfg(not(feature = "no-std"))]
-               return write!(
-                       f,
-                       "attempts: {}, duration: {}s",
-                       self.count,
-                       T::now().duration_since(self.first_attempted_at).as_secs()
-               );
-       }
+/// Pays the given zero-value [`Invoice`] using the given amount, retrying if needed based on
+/// [`Retry`].
+///
+/// [`Invoice::payment_hash`] is used as the [`PaymentId`], which ensures idempotency as long
+/// as the payment is still pending. Once the payment completes or fails, you must ensure that
+/// a second payment with the same [`PaymentHash`] is never sent.
+///
+/// If you wish to use a different payment idempotency token, see
+/// [`pay_zero_value_invoice_with_id`].
+pub fn pay_zero_value_invoice<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       invoice: &Invoice, amount_msats: u64, retry_strategy: Retry,
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>
+) -> Result<PaymentId, PaymentError>
+where
+               M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+               T::Target: BroadcasterInterface,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               SP::Target: SignerProvider,
+               F::Target: FeeEstimator,
+               R::Target: Router,
+               L::Target: Logger,
+{
+       let payment_id = PaymentId(invoice.payment_hash().into_inner());
+       pay_zero_value_invoice_with_id(invoice, amount_msats, payment_id, retry_strategy,
+               channelmanager)
+               .map(|()| payment_id)
 }
 
-/// A trait defining behavior of an [`Invoice`] payer.
-///
-/// While the behavior of [`InvoicePayer`] provides idempotency of duplicate `send_*payment` calls
-/// with the same [`PaymentHash`], it is up to the `Payer` to provide idempotency across restarts.
+/// Pays the given zero-value [`Invoice`] using the given amount and custom idempotency key,
+/// , retrying if needed based on [`Retry`].
 ///
-/// [`ChannelManager`] provides idempotency for duplicate payments with the same [`PaymentId`].
+/// Note that idempotency is only guaranteed as long as the payment is still pending. Once the
+/// payment completes or fails, no idempotency guarantees are made.
 ///
-/// In order to trivially ensure idempotency for payments, the default `Payer` implementation
-/// reuses the [`PaymentHash`] bytes as the [`PaymentId`]. Custom implementations wishing to
-/// provide payment idempotency with a different idempotency key (i.e. [`PaymentId`]) should map
-/// the [`Invoice`] or spontaneous payment target pubkey to their own idempotency key.
+/// You should ensure that the [`Invoice::payment_hash`] is unique and the same [`PaymentHash`]
+/// has never been paid before.
 ///
-/// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
-pub trait Payer {
-       /// Returns the payer's node id.
-       fn node_id(&self) -> PublicKey;
-
-       /// Returns the payer's channels.
-       fn first_hops(&self) -> Vec<ChannelDetails>;
-
-       /// Sends a payment over the Lightning Network using the given [`Route`].
-       fn send_payment(
-               &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
-               payment_id: PaymentId
-       ) -> Result<(), PaymentSendFailure>;
-
-       /// Sends a spontaneous payment over the Lightning Network using the given [`Route`].
-       fn send_spontaneous_payment(
-               &self, route: &Route, payment_preimage: PaymentPreimage, payment_id: PaymentId
-       ) -> Result<(), PaymentSendFailure>;
-
-       /// Retries a failed payment path for the [`PaymentId`] using the given [`Route`].
-       fn retry_payment(&self, route: &Route, payment_id: PaymentId) -> Result<(), PaymentSendFailure>;
-
-       /// Signals that no further retries for the given payment will occur.
-       fn abandon_payment(&self, payment_id: PaymentId);
-
-       /// Construct an [`InFlightHtlcs`] containing information about currently used up liquidity
-       /// across payments.
-       fn inflight_htlcs(&self) -> InFlightHtlcs;
+/// See [`pay_zero_value_invoice`] for a variant which uses the [`PaymentHash`] for the
+/// idempotency token.
+pub fn pay_zero_value_invoice_with_id<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       invoice: &Invoice, amount_msats: u64, payment_id: PaymentId, retry_strategy: Retry,
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>
+) -> Result<(), PaymentError>
+where
+               M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+               T::Target: BroadcasterInterface,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               SP::Target: SignerProvider,
+               F::Target: FeeEstimator,
+               R::Target: Router,
+               L::Target: Logger,
+{
+       if invoice.amount_milli_satoshis().is_some() {
+               Err(PaymentError::Invoice("amount unexpected"))
+       } else {
+               pay_invoice_using_amount(invoice, amount_msats, payment_id, retry_strategy,
+                       channelmanager)
+       }
 }
 
-/// Strategies available to retry payment path failures for an [`Invoice`].
-///
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub enum Retry {
-       /// Max number of attempts to retry payment.
-       ///
-       /// Note that this is the number of *path* failures, not full payment retries. For multi-path
-       /// payments, if this is less than the total number of paths, we will never even retry all of the
-       /// payment's paths.
-       Attempts(usize),
-       #[cfg(feature = "std")]
-       /// Time elapsed before abandoning retries for a payment.
-       Timeout(Duration),
+fn pay_invoice_using_amount<P: Deref>(
+       invoice: &Invoice, amount_msats: u64, payment_id: PaymentId, retry_strategy: Retry,
+       payer: P
+) -> Result<(), PaymentError> where P::Target: Payer {
+       let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
+       let payment_secret = Some(invoice.payment_secret().clone());
+       let mut payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key(),
+               invoice.min_final_cltv_expiry_delta() as u32)
+               .with_expiry_time(expiry_time_from_unix_epoch(&invoice).as_secs())
+               .with_route_hints(invoice.route_hints());
+       if let Some(features) = invoice.features() {
+               payment_params = payment_params.with_features(features.clone());
+       }
+       let route_params = RouteParameters {
+               payment_params,
+               final_value_msat: amount_msats,
+       };
+
+       payer.send_payment(payment_hash, &payment_secret, payment_id, route_params, retry_strategy)
 }
 
-impl Retry {
-       fn is_retryable_now<T: Time>(&self, attempts: &PaymentAttempts<T>) -> bool {
-               match (self, attempts) {
-                       (Retry::Attempts(max_retry_count), PaymentAttempts { count, .. }) => {
-                               max_retry_count >= &count
-                       },
-                       #[cfg(feature = "std")]
-                       (Retry::Timeout(max_duration), PaymentAttempts { first_attempted_at, .. } ) =>
-                               *max_duration >= T::now().duration_since(*first_attempted_at),
-               }
-       }
+fn expiry_time_from_unix_epoch(invoice: &Invoice) -> Duration {
+       invoice.signed_invoice.raw_invoice.data.timestamp.0 + invoice.expiry_time()
 }
 
 /// An error that may occur when making a payment.
@@ -310,475 +170,115 @@ impl Retry {
 pub enum PaymentError {
        /// An error resulting from the provided [`Invoice`] or payment hash.
        Invoice(&'static str),
-       /// An error occurring when finding a route.
-       Routing(LightningError),
        /// An error occurring when sending a payment.
-       Sending(PaymentSendFailure),
+       Sending(RetryableSendFailure),
 }
 
-impl<P: Deref, R: Router, L: Deref, E: sealed::BaseEventHandler, T: Time>
-       InvoicePayerUsingTime<P, R, L, E, T>
-where
-       P::Target: Payer,
-       L::Target: Logger,
-{
-       /// Creates an invoice payer that retries failed payment paths.
-       ///
-       /// Will forward any [`Event::PaymentPathFailed`] events to the decorated `event_handler` once
-       /// `retry` has been exceeded for a given [`Invoice`].
-       pub fn new(
-               payer: P, router: R, logger: L, event_handler: E, retry: Retry
-       ) -> Self {
-               Self {
-                       payer,
-                       router,
-                       logger,
-                       event_handler,
-                       payment_cache: Mutex::new(HashMap::new()),
-                       retry,
-               }
-       }
-
-       /// Pays the given [`Invoice`], caching it for later use in case a retry is needed.
-       ///
-       /// [`Invoice::payment_hash`] is used as the [`PaymentId`], which ensures idempotency as long
-       /// as the payment is still pending. Once the payment completes or fails, you must ensure that
-       /// a second payment with the same [`PaymentHash`] is never sent.
-       ///
-       /// If you wish to use a different payment idempotency token, see
-       /// [`Self::pay_invoice_with_id`].
-       pub fn pay_invoice(&self, invoice: &Invoice) -> Result<PaymentId, PaymentError> {
-               let payment_id = PaymentId(invoice.payment_hash().into_inner());
-               self.pay_invoice_with_id(invoice, payment_id).map(|()| payment_id)
-       }
-
-       /// Pays the given [`Invoice`] with a custom idempotency key, caching the invoice for later use
-       /// in case a retry is needed.
-       ///
-       /// Note that idempotency is only guaranteed as long as the payment is still pending. Once the
-       /// payment completes or fails, no idempotency guarantees are made.
-       ///
-       /// You should ensure that the [`Invoice::payment_hash`] is unique and the same [`PaymentHash`]
-       /// has never been paid before.
-       ///
-       /// See [`Self::pay_invoice`] for a variant which uses the [`PaymentHash`] for the idempotency
-       /// token.
-       pub fn pay_invoice_with_id(&self, invoice: &Invoice, payment_id: PaymentId) -> Result<(), PaymentError> {
-               if invoice.amount_milli_satoshis().is_none() {
-                       Err(PaymentError::Invoice("amount missing"))
-               } else {
-                       self.pay_invoice_using_amount(invoice, None, payment_id)
-               }
-       }
-
-       /// Pays the given zero-value [`Invoice`] using the given amount, caching it for later use in
-       /// case a retry is needed.
-       ///
-       /// [`Invoice::payment_hash`] is used as the [`PaymentId`], which ensures idempotency as long
-       /// as the payment is still pending. Once the payment completes or fails, you must ensure that
-       /// a second payment with the same [`PaymentHash`] is never sent.
-       ///
-       /// If you wish to use a different payment idempotency token, see
-       /// [`Self::pay_zero_value_invoice_with_id`].
-       pub fn pay_zero_value_invoice(
-               &self, invoice: &Invoice, amount_msats: u64
-       ) -> Result<PaymentId, PaymentError> {
-               let payment_id = PaymentId(invoice.payment_hash().into_inner());
-               self.pay_zero_value_invoice_with_id(invoice, amount_msats, payment_id).map(|()| payment_id)
-       }
-
-       /// Pays the given zero-value [`Invoice`] using the given amount and custom idempotency key,
-       /// caching the invoice for later use in case a retry is needed.
-       ///
-       /// Note that idempotency is only guaranteed as long as the payment is still pending. Once the
-       /// payment completes or fails, no idempotency guarantees are made.
-       ///
-       /// You should ensure that the [`Invoice::payment_hash`] is unique and the same [`PaymentHash`]
-       /// has never been paid before.
-       ///
-       /// See [`Self::pay_zero_value_invoice`] for a variant which uses the [`PaymentHash`] for the
-       /// idempotency token.
-       pub fn pay_zero_value_invoice_with_id(
-               &self, invoice: &Invoice, amount_msats: u64, payment_id: PaymentId
-       ) -> Result<(), PaymentError> {
-               if invoice.amount_milli_satoshis().is_some() {
-                       Err(PaymentError::Invoice("amount unexpected"))
-               } else {
-                       self.pay_invoice_using_amount(invoice, Some(amount_msats), payment_id)
-               }
-       }
-
-       fn pay_invoice_using_amount(
-               &self, invoice: &Invoice, amount_msats: Option<u64>, payment_id: PaymentId
-       ) -> Result<(), PaymentError> {
-               debug_assert!(invoice.amount_milli_satoshis().is_some() ^ amount_msats.is_some());
-
-               let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
-               match self.payment_cache.lock().unwrap().entry(payment_hash) {
-                       hash_map::Entry::Occupied(_) => return Err(PaymentError::Invoice("payment pending")),
-                       hash_map::Entry::Vacant(entry) => entry.insert(PaymentAttempts::new()),
-               };
-
-               let payment_secret = Some(invoice.payment_secret().clone());
-               let mut payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key())
-                       .with_expiry_time(expiry_time_from_unix_epoch(&invoice).as_secs())
-                       .with_route_hints(invoice.route_hints());
-               if let Some(features) = invoice.features() {
-                       payment_params = payment_params.with_features(features.clone());
-               }
-               let route_params = RouteParameters {
-                       payment_params,
-                       final_value_msat: invoice.amount_milli_satoshis().or(amount_msats).unwrap(),
-                       final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
-               };
-
-               let send_payment = |route: &Route| {
-                       self.payer.send_payment(route, payment_hash, &payment_secret, payment_id)
-               };
-
-               self.pay_internal(&route_params, payment_hash, send_payment)
-                       .map_err(|e| { self.payment_cache.lock().unwrap().remove(&payment_hash); e })
-       }
-
-       /// Pays `pubkey` an amount using the hash of the given preimage, caching it for later use in
-       /// case a retry is needed.
-       ///
-       /// The hash of the [`PaymentPreimage`] is used as the [`PaymentId`], which ensures idempotency
-       /// as long as the payment is still pending. Once the payment completes or fails, you must
-       /// ensure that a second payment with the same [`PaymentPreimage`] is never sent.
-       pub fn pay_pubkey(
-               &self, pubkey: PublicKey, payment_preimage: PaymentPreimage, amount_msats: u64,
-               final_cltv_expiry_delta: u32
-       ) -> Result<PaymentId, PaymentError> {
-               let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
-               let payment_id = PaymentId(payment_hash.0);
-               self.do_pay_pubkey(pubkey, payment_preimage, payment_hash, payment_id, amount_msats,
-                               final_cltv_expiry_delta)
-                       .map(|()| payment_id)
-       }
-
-       /// Pays `pubkey` an amount using the hash of the given preimage and a custom idempotency key,
-       /// caching the invoice for later use in case a retry is needed.
-       ///
-       /// Note that idempotency is only guaranteed as long as the payment is still pending. Once the
-       /// payment completes or fails, no idempotency guarantees are made.
+/// A trait defining behavior of an [`Invoice`] payer.
+///
+/// Useful for unit testing internal methods.
+trait Payer {
+       /// Sends a payment over the Lightning Network using the given [`Route`].
        ///
-       /// You should ensure that the [`PaymentPreimage`] is unique and the corresponding
-       /// [`PaymentHash`] has never been paid before.
-       pub fn pay_pubkey_with_id(
-               &self, pubkey: PublicKey, payment_preimage: PaymentPreimage, payment_id: PaymentId,
-               amount_msats: u64, final_cltv_expiry_delta: u32
-       ) -> Result<(), PaymentError> {
-               let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
-               self.do_pay_pubkey(pubkey, payment_preimage, payment_hash, payment_id, amount_msats,
-                               final_cltv_expiry_delta)
-       }
+       /// [`Route`]: lightning::routing::router::Route
+       fn send_payment(
+               &self, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
+               payment_id: PaymentId, route_params: RouteParameters, retry_strategy: Retry
+       ) -> Result<(), PaymentError>;
+}
 
-       fn do_pay_pubkey(
-               &self, pubkey: PublicKey, payment_preimage: PaymentPreimage, payment_hash: PaymentHash,
-               payment_id: PaymentId, amount_msats: u64, final_cltv_expiry_delta: u32
+impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> Payer for ChannelManager<M, T, ES, NS, SP, F, R, L>
+where
+               M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+               T::Target: BroadcasterInterface,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               SP::Target: SignerProvider,
+               F::Target: FeeEstimator,
+               R::Target: Router,
+               L::Target: Logger,
+{
+       fn send_payment(
+               &self, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
+               payment_id: PaymentId, route_params: RouteParameters, retry_strategy: Retry
        ) -> Result<(), PaymentError> {
-               match self.payment_cache.lock().unwrap().entry(payment_hash) {
-                       hash_map::Entry::Occupied(_) => return Err(PaymentError::Invoice("payment pending")),
-                       hash_map::Entry::Vacant(entry) => entry.insert(PaymentAttempts::new()),
-               };
-
-               let route_params = RouteParameters {
-                       payment_params: PaymentParameters::for_keysend(pubkey),
-                       final_value_msat: amount_msats,
-                       final_cltv_expiry_delta,
-               };
-
-               let send_payment = |route: &Route| {
-                       self.payer.send_spontaneous_payment(route, payment_preimage, payment_id)
-               };
-               self.pay_internal(&route_params, payment_hash, send_payment)
-                       .map_err(|e| { self.payment_cache.lock().unwrap().remove(&payment_hash); e })
+               self.send_payment_with_retry(payment_hash, payment_secret, payment_id, route_params, retry_strategy)
+                       .map_err(|e| PaymentError::Sending(e))
        }
+}
 
-       fn pay_internal<F: FnOnce(&Route) -> Result<(), PaymentSendFailure> + Copy>(
-               &self, params: &RouteParameters, payment_hash: PaymentHash, send_payment: F,
-       ) -> Result<(), PaymentError> {
-               #[cfg(feature = "std")] {
-                       if has_expired(params) {
-                               log_trace!(self.logger, "Invoice expired prior to send for payment {}", log_bytes!(payment_hash.0));
-                               return Err(PaymentError::Invoice("Invoice expired prior to send"));
-                       }
-               }
-
-               let payer = self.payer.node_id();
-               let first_hops = self.payer.first_hops();
-               let inflight_htlcs = self.payer.inflight_htlcs();
-               let route = self.router.find_route(
-                       &payer, &params, Some(&first_hops.iter().collect::<Vec<_>>()), &inflight_htlcs
-               ).map_err(|e| PaymentError::Routing(e))?;
+#[cfg(test)]
+mod tests {
+       use super::*;
+       use crate::{InvoiceBuilder, Currency};
+       use bitcoin_hashes::sha256::Hash as Sha256;
+       use lightning::ln::PaymentPreimage;
+       use lightning::ln::functional_test_utils::*;
+       use secp256k1::{SecretKey, Secp256k1};
+       use std::collections::VecDeque;
+       use std::time::{SystemTime, Duration};
 
-               match send_payment(&route) {
-                       Ok(()) => Ok(()),
-                       Err(e) => match e {
-                               PaymentSendFailure::ParameterError(_) => Err(e),
-                               PaymentSendFailure::PathParameterError(_) => Err(e),
-                               PaymentSendFailure::DuplicatePayment => Err(e),
-                               PaymentSendFailure::AllFailedResendSafe(_) => {
-                                       let mut payment_cache = self.payment_cache.lock().unwrap();
-                                       let payment_attempts = payment_cache.get_mut(&payment_hash).unwrap();
-                                       payment_attempts.count += 1;
-                                       if self.retry.is_retryable_now(payment_attempts) {
-                                               core::mem::drop(payment_cache);
-                                               Ok(self.pay_internal(params, payment_hash, send_payment)?)
-                                       } else {
-                                               Err(e)
-                                       }
-                               },
-                               PaymentSendFailure::PartialFailure { failed_paths_retry, payment_id, .. } => {
-                                       if let Some(retry_data) = failed_paths_retry {
-                                               // Some paths were sent, even if we failed to send the full MPP value our
-                                               // recipient may misbehave and claim the funds, at which point we have to
-                                               // consider the payment sent, so return `Ok()` here, ignoring any retry
-                                               // errors.
-                                               let _ = self.retry_payment(payment_id, payment_hash, &retry_data);
-                                               Ok(())
-                                       } else {
-                                               // This may happen if we send a payment and some paths fail, but
-                                               // only due to a temporary monitor failure or the like, implying
-                                               // they're really in-flight, but we haven't sent the initial
-                                               // HTLC-Add messages yet.
-                                               Ok(())
-                                       }
-                               },
-                       },
-               }.map_err(|e| PaymentError::Sending(e))
+       struct TestPayer {
+               expectations: core::cell::RefCell<VecDeque<Amount>>,
        }
 
-       fn retry_payment(
-               &self, payment_id: PaymentId, payment_hash: PaymentHash, params: &RouteParameters
-       ) -> Result<(), ()> {
-               let attempts =
-                       *self.payment_cache.lock().unwrap().entry(payment_hash)
-                               .and_modify(|attempts| attempts.count += 1)
-                               .or_insert(PaymentAttempts {
-                                       count: 1,
-                                       first_attempted_at: T::now()
-                               });
-
-               if !self.retry.is_retryable_now(&attempts) {
-                       log_trace!(self.logger, "Payment {} exceeded maximum attempts; not retrying ({})", log_bytes!(payment_hash.0), attempts);
-                       return Err(());
-               }
-
-               #[cfg(feature = "std")] {
-                       if has_expired(params) {
-                               log_trace!(self.logger, "Invoice expired for payment {}; not retrying ({:})", log_bytes!(payment_hash.0), attempts);
-                               return Err(());
+       impl TestPayer {
+               fn new() -> Self {
+                       Self {
+                               expectations: core::cell::RefCell::new(VecDeque::new()),
                        }
                }
 
-               let payer = self.payer.node_id();
-               let first_hops = self.payer.first_hops();
-               let inflight_htlcs = self.payer.inflight_htlcs();
-
-               let route = self.router.find_route(
-                       &payer, &params, Some(&first_hops.iter().collect::<Vec<_>>()), &inflight_htlcs
-               );
-
-               if route.is_err() {
-                       log_trace!(self.logger, "Failed to find a route for payment {}; not retrying ({:})", log_bytes!(payment_hash.0), attempts);
-                       return Err(());
+               fn expect_send(self, value_msat: Amount) -> Self {
+                       self.expectations.borrow_mut().push_back(value_msat);
+                       self
                }
 
-               match self.payer.retry_payment(&route.as_ref().unwrap(), payment_id) {
-                       Ok(()) => Ok(()),
-                       Err(PaymentSendFailure::ParameterError(_)) |
-                       Err(PaymentSendFailure::PathParameterError(_)) => {
-                               log_trace!(self.logger, "Failed to retry for payment {} due to bogus route/payment data, not retrying.", log_bytes!(payment_hash.0));
-                               Err(())
-                       },
-                       Err(PaymentSendFailure::AllFailedResendSafe(_)) => {
-                               self.retry_payment(payment_id, payment_hash, params)
-                       },
-                       Err(PaymentSendFailure::DuplicatePayment) => {
-                               log_error!(self.logger, "Got a DuplicatePayment error when attempting to retry a payment, this shouldn't happen.");
-                               Err(())
+               fn check_value_msats(&self, actual_value_msats: Amount) {
+                       let expected_value_msats = self.expectations.borrow_mut().pop_front();
+                       if let Some(expected_value_msats) = expected_value_msats {
+                               assert_eq!(actual_value_msats, expected_value_msats);
+                       } else {
+                               panic!("Unexpected amount: {:?}", actual_value_msats);
                        }
-                       Err(PaymentSendFailure::PartialFailure { failed_paths_retry, .. }) => {
-                               if let Some(retry) = failed_paths_retry {
-                                       // Always return Ok for the same reason as noted in pay_internal.
-                                       let _ = self.retry_payment(payment_id, payment_hash, &retry);
-                               }
-                               Ok(())
-                       },
                }
        }
 
-       /// Removes the payment cached by the given payment hash.
-       ///
-       /// Should be called once a payment has failed or succeeded if not using [`InvoicePayer`] as an
-       /// [`EventHandler`]. Otherwise, calling this method is unnecessary.
-       pub fn remove_cached_payment(&self, payment_hash: &PaymentHash) {
-               self.payment_cache.lock().unwrap().remove(payment_hash);
-       }
-}
-
-fn expiry_time_from_unix_epoch(invoice: &Invoice) -> Duration {
-       invoice.signed_invoice.raw_invoice.data.timestamp.0 + invoice.expiry_time()
-}
-
-#[cfg(feature = "std")]
-fn has_expired(route_params: &RouteParameters) -> bool {
-       if let Some(expiry_time) = route_params.payment_params.expiry_time {
-               Invoice::is_expired_from_epoch(&SystemTime::UNIX_EPOCH, Duration::from_secs(expiry_time))
-       } else { false }
-}
-
-impl<P: Deref, R: Router, L: Deref, E: sealed::BaseEventHandler, T: Time>
-       InvoicePayerUsingTime<P, R, L, E, T>
-where
-       P::Target: Payer,
-       L::Target: Logger,
-{
-       /// Returns a bool indicating whether the processed event should be forwarded to a user-provided
-       /// event handler.
-       fn handle_event_internal(&self, event: &Event) -> bool {
-               match event {
-                       Event::PaymentPathFailed {
-                               payment_id, payment_hash, payment_failed_permanently, path, short_channel_id, retry, ..
-                       } => {
-                               if let Some(short_channel_id) = short_channel_id {
-                                       let path = path.iter().collect::<Vec<_>>();
-                                       self.router.notify_payment_path_failed(&path, *short_channel_id)
-                               }
+       #[derive(Clone, Debug, PartialEq, Eq)]
+       struct Amount(u64); // msat
 
-                               if payment_id.is_none() {
-                                       log_trace!(self.logger, "Payment {} has no id; not retrying", log_bytes!(payment_hash.0));
-                               } else if *payment_failed_permanently {
-                                       log_trace!(self.logger, "Payment {} rejected by destination; not retrying", log_bytes!(payment_hash.0));
-                                       self.payer.abandon_payment(payment_id.unwrap());
-                               } else if retry.is_none() {
-                                       log_trace!(self.logger, "Payment {} missing retry params; not retrying", log_bytes!(payment_hash.0));
-                                       self.payer.abandon_payment(payment_id.unwrap());
-                               } else if self.retry_payment(payment_id.unwrap(), *payment_hash, retry.as_ref().unwrap()).is_ok() {
-                                       // We retried at least somewhat, don't provide the PaymentPathFailed event to the user.
-                                       return false;
-                               } else {
-                                       self.payer.abandon_payment(payment_id.unwrap());
-                               }
-                       },
-                       Event::PaymentFailed { payment_hash, .. } => {
-                               self.remove_cached_payment(&payment_hash);
-                       },
-                       Event::PaymentPathSuccessful { path, .. } => {
-                               let path = path.iter().collect::<Vec<_>>();
-                               self.router.notify_payment_path_successful(&path);
-                       },
-                       Event::PaymentSent { payment_hash, .. } => {
-                               let mut payment_cache = self.payment_cache.lock().unwrap();
-                               let attempts = payment_cache
-                                       .remove(payment_hash)
-                                       .map_or(1, |attempts| attempts.count + 1);
-                               log_trace!(self.logger, "Payment {} succeeded (attempts: {})", log_bytes!(payment_hash.0), attempts);
-                       },
-                       Event::ProbeSuccessful { payment_hash, path, .. } => {
-                               log_trace!(self.logger, "Probe payment {} of {}msat was successful", log_bytes!(payment_hash.0), path.last().unwrap().fee_msat);
-                               let path = path.iter().collect::<Vec<_>>();
-                               self.router.notify_payment_probe_successful(&path);
-                       },
-                       Event::ProbeFailed { payment_hash, path, short_channel_id, .. } => {
-                               if let Some(short_channel_id) = short_channel_id {
-                                       log_trace!(self.logger, "Probe payment {} of {}msat failed at channel {}", log_bytes!(payment_hash.0), path.last().unwrap().fee_msat, *short_channel_id);
-                                       let path = path.iter().collect::<Vec<_>>();
-                                       self.router.notify_payment_probe_failed(&path, *short_channel_id);
-                               }
-                       },
-                       _ => {},
+       impl Payer for TestPayer {
+               fn send_payment(
+                       &self, _payment_hash: PaymentHash, _payment_secret: &Option<PaymentSecret>,
+                       _payment_id: PaymentId, route_params: RouteParameters, _retry_strategy: Retry
+               ) -> Result<(), PaymentError> {
+                       self.check_value_msats(Amount(route_params.final_value_msat));
+                       Ok(())
                }
-
-               // Delegate to the decorated event handler unless the payment is retried.
-               true
        }
-}
 
-impl<P: Deref, R: Router, L: Deref, E: EventHandler, T: Time>
-       EventHandler for InvoicePayerUsingTime<P, R, L, E, T>
-where
-       P::Target: Payer,
-       L::Target: Logger,
-{
-       fn handle_event(&self, event: Event) {
-               let should_forward = self.handle_event_internal(&event);
-               if should_forward {
-                       self.event_handler.handle_event(event)
-               }
-       }
-}
+       impl Drop for TestPayer {
+               fn drop(&mut self) {
+                       if std::thread::panicking() {
+                               return;
+                       }
 
-impl<P: Deref, R: Router, L: Deref, T: Time, F: Future, H: Fn(Event) -> F>
-       InvoicePayerUsingTime<P, R, L, H, T>
-where
-       P::Target: Payer,
-       L::Target: Logger,
-{
-       /// Intercepts events required by the [`InvoicePayer`] and forwards them to the underlying event
-       /// handler, if necessary, to handle them asynchronously.
-       pub async fn handle_event_async(&self, event: Event) {
-               let should_forward = self.handle_event_internal(&event);
-               if should_forward {
-                       (self.event_handler)(event).await;
+                       if !self.expectations.borrow().is_empty() {
+                               panic!("Unsatisfied payment expectations: {:?}", self.expectations.borrow());
+                       }
                }
        }
-}
-
-#[cfg(test)]
-mod tests {
-       use super::*;
-       use crate::{InvoiceBuilder, Currency};
-       use crate::utils::create_invoice_from_channelmanager_and_duration_since_epoch;
-       use bitcoin_hashes::sha256::Hash as Sha256;
-       use lightning::ln::PaymentPreimage;
-       use lightning::ln::channelmanager;
-       use lightning::ln::features::{ChannelFeatures, NodeFeatures};
-       use lightning::ln::functional_test_utils::*;
-       use lightning::ln::msgs::{ChannelMessageHandler, ErrorAction, LightningError};
-       use lightning::routing::gossip::{EffectiveCapacity, NodeId};
-       use lightning::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, Router, ScorerAccountingForInFlightHtlcs};
-       use lightning::routing::scoring::{ChannelUsage, LockableScore, Score};
-       use lightning::util::test_utils::TestLogger;
-       use lightning::util::errors::APIError;
-       use lightning::util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
-       use secp256k1::{SecretKey, PublicKey, Secp256k1};
-       use std::cell::RefCell;
-       use std::collections::VecDeque;
-       use std::ops::DerefMut;
-       use std::time::{SystemTime, Duration};
-       use crate::time_utils::tests::SinceEpoch;
-       use crate::DEFAULT_EXPIRY_TIME;
-
-       fn invoice(payment_preimage: PaymentPreimage) -> Invoice {
-               let payment_hash = Sha256::hash(&payment_preimage.0);
-               let private_key = SecretKey::from_slice(&[42; 32]).unwrap();
-
-               InvoiceBuilder::new(Currency::Bitcoin)
-                       .description("test".into())
-                       .payment_hash(payment_hash)
-                       .payment_secret(PaymentSecret([0; 32]))
-                       .duration_since_epoch(duration_since_epoch())
-                       .min_final_cltv_expiry(144)
-                       .amount_milli_satoshis(128)
-                       .build_signed(|hash| {
-                               Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
-                       })
-                       .unwrap()
-       }
 
        fn duration_since_epoch() -> Duration {
                #[cfg(feature = "std")]
-                       let duration_since_epoch =
+               let duration_since_epoch =
                        SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
                #[cfg(not(feature = "std"))]
-                       let duration_since_epoch = Duration::from_secs(1234567);
+               let duration_since_epoch = Duration::from_secs(1234567);
                duration_since_epoch
        }
 
-       fn zero_value_invoice(payment_preimage: PaymentPreimage) -> Invoice {
+       fn invoice(payment_preimage: PaymentPreimage) -> Invoice {
                let payment_hash = Sha256::hash(&payment_preimage.0);
                let private_key = SecretKey::from_slice(&[42; 32]).unwrap();
 
@@ -787,1523 +287,66 @@ mod tests {
                        .payment_hash(payment_hash)
                        .payment_secret(PaymentSecret([0; 32]))
                        .duration_since_epoch(duration_since_epoch())
-                       .min_final_cltv_expiry(144)
+                       .min_final_cltv_expiry_delta(144)
+                       .amount_milli_satoshis(128)
                        .build_signed(|hash| {
                                Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
                        })
                        .unwrap()
        }
 
-       #[cfg(feature = "std")]
-       fn expired_invoice(payment_preimage: PaymentPreimage) -> Invoice {
+       fn zero_value_invoice(payment_preimage: PaymentPreimage) -> Invoice {
                let payment_hash = Sha256::hash(&payment_preimage.0);
                let private_key = SecretKey::from_slice(&[42; 32]).unwrap();
-               let duration = duration_since_epoch()
-                       .checked_sub(Duration::from_secs(DEFAULT_EXPIRY_TIME * 2))
-                       .unwrap();
+
                InvoiceBuilder::new(Currency::Bitcoin)
                        .description("test".into())
                        .payment_hash(payment_hash)
                        .payment_secret(PaymentSecret([0; 32]))
-                       .duration_since_epoch(duration)
-                       .min_final_cltv_expiry(144)
-                       .amount_milli_satoshis(128)
+                       .duration_since_epoch(duration_since_epoch())
+                       .min_final_cltv_expiry_delta(144)
                        .build_signed(|hash| {
                                Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
                        })
-                       .unwrap()
-       }
-
-       fn pubkey() -> PublicKey {
-               PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap()
-       }
-
-       #[test]
-       fn pays_invoice_on_first_attempt() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new().expect_send(Amount::ForInvoice(final_value_msat));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(0));
-
-               let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               invoice_payer.handle_event(Event::PaymentSent {
-                       payment_id, payment_preimage, payment_hash, fee_paid_msat: None
-               });
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 1);
-       }
-
-       #[test]
-       fn pays_invoice_on_retry() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new()
-                       .expect_send(Amount::ForInvoice(final_value_msat))
-                       .expect_send(Amount::OnRetry(final_value_msat / 2));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash,
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path: TestRouter::path_for_value(final_value_msat),
-                       short_channel_id: None,
-                       retry: Some(TestRouter::retry_for_invoice(&invoice)),
-               };
-               invoice_payer.handle_event(event);
-               assert_eq!(*event_handled.borrow(), false);
-               assert_eq!(*payer.attempts.borrow(), 2);
-
-               invoice_payer.handle_event(Event::PaymentSent {
-                       payment_id, payment_preimage, payment_hash, fee_paid_msat: None
-               });
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 2);
-       }
-
-       #[test]
-       fn pays_invoice_on_partial_failure() {
-               let event_handler = |_: Event| { panic!() };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let retry = TestRouter::retry_for_invoice(&invoice);
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new()
-                       .fails_with_partial_failure(retry.clone(), OnAttempt(1), None)
-                       .fails_with_partial_failure(retry, OnAttempt(2), None)
-                       .expect_send(Amount::ForInvoice(final_value_msat))
-                       .expect_send(Amount::OnRetry(final_value_msat / 2))
-                       .expect_send(Amount::OnRetry(final_value_msat / 2));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               assert!(invoice_payer.pay_invoice(&invoice).is_ok());
-       }
-
-       #[test]
-       fn retries_payment_path_for_unknown_payment() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new()
-                       .expect_send(Amount::OnRetry(final_value_msat / 2))
-                       .expect_send(Amount::OnRetry(final_value_msat / 2));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               let payment_id = Some(PaymentId([1; 32]));
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash,
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path: TestRouter::path_for_value(final_value_msat),
-                       short_channel_id: None,
-                       retry: Some(TestRouter::retry_for_invoice(&invoice)),
-               };
-               invoice_payer.handle_event(event.clone());
-               assert_eq!(*event_handled.borrow(), false);
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               invoice_payer.handle_event(event.clone());
-               assert_eq!(*event_handled.borrow(), false);
-               assert_eq!(*payer.attempts.borrow(), 2);
-
-               invoice_payer.handle_event(Event::PaymentSent {
-                       payment_id, payment_preimage, payment_hash, fee_paid_msat: None
-               });
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 2);
+               .unwrap()
        }
 
        #[test]
-       fn fails_paying_invoice_after_max_retry_counts() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
+       fn pays_invoice() {
+               let payment_id = PaymentId([42; 32]);
                let payment_preimage = PaymentPreimage([1; 32]);
                let invoice = invoice(payment_preimage);
                let final_value_msat = invoice.amount_milli_satoshis().unwrap();
 
-               let payer = TestPayer::new()
-                       .expect_send(Amount::ForInvoice(final_value_msat))
-                       .expect_send(Amount::OnRetry(final_value_msat / 2))
-                       .expect_send(Amount::OnRetry(final_value_msat / 2));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: true,
-                       path: TestRouter::path_for_value(final_value_msat),
-                       short_channel_id: None,
-                       retry: Some(TestRouter::retry_for_invoice(&invoice)),
-               };
-               invoice_payer.handle_event(event);
-               assert_eq!(*event_handled.borrow(), false);
-               assert_eq!(*payer.attempts.borrow(), 2);
-
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path: TestRouter::path_for_value(final_value_msat / 2),
-                       short_channel_id: None,
-                       retry: Some(RouteParameters {
-                               final_value_msat: final_value_msat / 2, ..TestRouter::retry_for_invoice(&invoice)
-                       }),
-               };
-               invoice_payer.handle_event(event.clone());
-               assert_eq!(*event_handled.borrow(), false);
-               assert_eq!(*payer.attempts.borrow(), 3);
-
-               invoice_payer.handle_event(event.clone());
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 3);
+               let payer = TestPayer::new().expect_send(Amount(final_value_msat));
+               pay_invoice_using_amount(&invoice, final_value_msat, payment_id, Retry::Attempts(0), &payer).unwrap();
        }
 
-       #[cfg(feature = "std")]
        #[test]
-       fn fails_paying_invoice_after_max_retry_timeout() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
+       fn pays_zero_value_invoice() {
+               let payment_id = PaymentId([42; 32]);
                let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new()
-                       .expect_send(Amount::ForInvoice(final_value_msat))
-                       .expect_send(Amount::OnRetry(final_value_msat / 2));
-
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               type InvoicePayerUsingSinceEpoch <P, R, L, E> = InvoicePayerUsingTime::<P, R, L, E, SinceEpoch>;
-
-               let invoice_payer =
-                       InvoicePayerUsingSinceEpoch::new(&payer, router, &logger, event_handler, Retry::Timeout(Duration::from_secs(120)));
-
-               let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: true,
-                       path: TestRouter::path_for_value(final_value_msat),
-                       short_channel_id: None,
-                       retry: Some(TestRouter::retry_for_invoice(&invoice)),
-               };
-               invoice_payer.handle_event(event.clone());
-               assert_eq!(*event_handled.borrow(), false);
-               assert_eq!(*payer.attempts.borrow(), 2);
-
-               SinceEpoch::advance(Duration::from_secs(121));
+               let invoice = zero_value_invoice(payment_preimage);
+               let amt_msat = 10_000;
 
-               invoice_payer.handle_event(event.clone());
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 2);
+               let payer = TestPayer::new().expect_send(Amount(amt_msat));
+               pay_invoice_using_amount(&invoice, amt_msat, payment_id, Retry::Attempts(0), &payer).unwrap();
        }
 
        #[test]
-       fn fails_paying_invoice_with_missing_retry_params() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
+       fn fails_paying_zero_value_invoice_with_amount() {
+               let chanmon_cfgs = create_chanmon_cfgs(1);
+               let node_cfgs = create_node_cfgs(1, &chanmon_cfgs);
+               let node_chanmgrs = create_node_chanmgrs(1, &node_cfgs, &[None]);
+               let nodes = create_network(1, &node_cfgs, &node_chanmgrs);
 
                let payment_preimage = PaymentPreimage([1; 32]);
                let invoice = invoice(payment_preimage);
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new().expect_send(Amount::ForInvoice(final_value_msat));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
+               let amt_msat = 10_000;
 
-               let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path: vec![],
-                       short_channel_id: None,
-                       retry: None,
-               };
-               invoice_payer.handle_event(event);
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 1);
-       }
-
-       // Expiration is checked only in an std environment
-       #[cfg(feature = "std")]
-       #[test]
-       fn fails_paying_invoice_after_expiration() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payer = TestPayer::new();
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = expired_invoice(payment_preimage);
-               if let PaymentError::Invoice(msg) = invoice_payer.pay_invoice(&invoice).unwrap_err() {
-                       assert_eq!(msg, "Invoice expired prior to send");
-               } else { panic!("Expected Invoice Error"); }
-       }
-
-       // Expiration is checked only in an std environment
-       #[cfg(feature = "std")]
-       #[test]
-       fn fails_retrying_invoice_after_expiration() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new().expect_send(Amount::ForInvoice(final_value_msat));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router,  &logger, event_handler, Retry::Attempts(2));
-
-               let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               let mut retry_data = TestRouter::retry_for_invoice(&invoice);
-               retry_data.payment_params.expiry_time = Some(SystemTime::now()
-                       .checked_sub(Duration::from_secs(2)).unwrap()
-                       .duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs());
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path: vec![],
-                       short_channel_id: None,
-                       retry: Some(retry_data),
-               };
-               invoice_payer.handle_event(event);
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 1);
-       }
-
-       #[test]
-       fn fails_paying_invoice_after_retry_error() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new()
-                       .fails_on_attempt(2)
-                       .expect_send(Amount::ForInvoice(final_value_msat))
-                       .expect_send(Amount::OnRetry(final_value_msat / 2));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path: TestRouter::path_for_value(final_value_msat / 2),
-                       short_channel_id: None,
-                       retry: Some(TestRouter::retry_for_invoice(&invoice)),
-               };
-               invoice_payer.handle_event(event);
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 2);
-       }
-
-       #[test]
-       fn fails_paying_invoice_after_rejected_by_payee() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new().expect_send(Amount::ForInvoice(final_value_msat));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
-                       network_update: None,
-                       payment_failed_permanently: true,
-                       all_paths_failed: false,
-                       path: vec![],
-                       short_channel_id: None,
-                       retry: Some(TestRouter::retry_for_invoice(&invoice)),
-               };
-               invoice_payer.handle_event(event);
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 1);
-       }
-
-       #[test]
-       fn fails_repaying_invoice_with_pending_payment() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new()
-                       .expect_send(Amount::ForInvoice(final_value_msat))
-                       .expect_send(Amount::ForInvoice(final_value_msat));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(0));
-
-               let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
-
-               // Cannot repay an invoice pending payment.
-               match invoice_payer.pay_invoice(&invoice) {
-                       Err(PaymentError::Invoice("payment pending")) => {},
-                       Err(_) => panic!("unexpected error"),
-                       Ok(_) => panic!("expected invoice error"),
-               }
-
-               // Can repay an invoice once cleared from cache.
-               let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
-               invoice_payer.remove_cached_payment(&payment_hash);
-               assert!(invoice_payer.pay_invoice(&invoice).is_ok());
-
-               // Cannot retry paying an invoice if cleared from cache.
-               invoice_payer.remove_cached_payment(&payment_hash);
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash,
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path: vec![],
-                       short_channel_id: None,
-                       retry: Some(TestRouter::retry_for_invoice(&invoice)),
-               };
-               invoice_payer.handle_event(event);
-               assert_eq!(*event_handled.borrow(), true);
-       }
-
-       #[test]
-       fn fails_paying_invoice_with_routing_errors() {
-               let payer = TestPayer::new();
-               let router = FailingRouter {};
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, |_: Event| {}, Retry::Attempts(0));
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               match invoice_payer.pay_invoice(&invoice) {
-                       Err(PaymentError::Routing(_)) => {},
-                       Err(_) => panic!("unexpected error"),
-                       Ok(_) => panic!("expected routing error"),
-               }
-       }
-
-       #[test]
-       fn fails_paying_invoice_with_sending_errors() {
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new()
-                       .fails_on_attempt(1)
-                       .expect_send(Amount::ForInvoice(final_value_msat));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, |_: Event| {}, Retry::Attempts(0));
-
-               match invoice_payer.pay_invoice(&invoice) {
-                       Err(PaymentError::Sending(_)) => {},
-                       Err(_) => panic!("unexpected error"),
-                       Ok(_) => panic!("expected sending error"),
-               }
-       }
-
-       #[test]
-       fn pays_zero_value_invoice_using_amount() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = zero_value_invoice(payment_preimage);
-               let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
-               let final_value_msat = 100;
-
-               let payer = TestPayer::new().expect_send(Amount::ForInvoice(final_value_msat));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(0));
-
-               let payment_id =
-                       Some(invoice_payer.pay_zero_value_invoice(&invoice, final_value_msat).unwrap());
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               invoice_payer.handle_event(Event::PaymentSent {
-                       payment_id, payment_preimage, payment_hash, fee_paid_msat: None
-               });
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 1);
-       }
-
-       #[test]
-       fn fails_paying_zero_value_invoice_with_amount() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payer = TestPayer::new();
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router,  &logger, event_handler, Retry::Attempts(0));
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-
-               // Cannot repay an invoice pending payment.
-               match invoice_payer.pay_zero_value_invoice(&invoice, 100) {
+               match pay_zero_value_invoice(&invoice, amt_msat, Retry::Attempts(0), &nodes[0].node) {
                        Err(PaymentError::Invoice("amount unexpected")) => {},
-                       Err(_) => panic!("unexpected error"),
-                       Ok(_) => panic!("expected invoice error"),
-               }
-       }
-
-       #[test]
-       fn pays_pubkey_with_amount() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let pubkey = pubkey();
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
-               let final_value_msat = 100;
-               let final_cltv_expiry_delta = 42;
-
-               let payer = TestPayer::new()
-                       .expect_send(Amount::Spontaneous(final_value_msat))
-                       .expect_send(Amount::OnRetry(final_value_msat));
-               let router = TestRouter::new(TestScorer::new());
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               let payment_id = Some(invoice_payer.pay_pubkey(
-                               pubkey, payment_preimage, final_value_msat, final_cltv_expiry_delta
-                       ).unwrap());
-               assert_eq!(*payer.attempts.borrow(), 1);
-
-               let retry = RouteParameters {
-                       payment_params: PaymentParameters::for_keysend(pubkey),
-                       final_value_msat,
-                       final_cltv_expiry_delta,
-               };
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash,
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path: vec![],
-                       short_channel_id: None,
-                       retry: Some(retry),
-               };
-               invoice_payer.handle_event(event);
-               assert_eq!(*event_handled.borrow(), false);
-               assert_eq!(*payer.attempts.borrow(), 2);
-
-               invoice_payer.handle_event(Event::PaymentSent {
-                       payment_id, payment_preimage, payment_hash, fee_paid_msat: None
-               });
-               assert_eq!(*event_handled.borrow(), true);
-               assert_eq!(*payer.attempts.borrow(), 2);
-       }
-
-       #[test]
-       fn scores_failed_channel() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-               let path = TestRouter::path_for_value(final_value_msat);
-               let short_channel_id = Some(path[0].short_channel_id);
-
-               // Expect that scorer is given short_channel_id upon handling the event.
-               let payer = TestPayer::new()
-                       .expect_send(Amount::ForInvoice(final_value_msat))
-                       .expect_send(Amount::OnRetry(final_value_msat / 2));
-               let scorer = TestScorer::new().expect(TestResult::PaymentFailure {
-                       path: path.clone(), short_channel_id: path[0].short_channel_id,
-               });
-               let router = TestRouter::new(scorer);
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
-               let event = Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash,
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path,
-                       short_channel_id,
-                       retry: Some(TestRouter::retry_for_invoice(&invoice)),
-               };
-               invoice_payer.handle_event(event);
-       }
-
-       #[test]
-       fn scores_successful_channels() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let invoice = invoice(payment_preimage);
-               let payment_hash = Some(PaymentHash(invoice.payment_hash().clone().into_inner()));
-               let final_value_msat = invoice.amount_milli_satoshis().unwrap();
-               let route = TestRouter::route_for_value(final_value_msat);
-
-               // Expect that scorer is given short_channel_id upon handling the event.
-               let payer = TestPayer::new().expect_send(Amount::ForInvoice(final_value_msat));
-               let scorer = TestScorer::new()
-                       .expect(TestResult::PaymentSuccess { path: route.paths[0].clone() })
-                       .expect(TestResult::PaymentSuccess { path: route.paths[1].clone() });
-               let router = TestRouter::new(scorer);
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               let payment_id = invoice_payer.pay_invoice(&invoice).unwrap();
-               let event = Event::PaymentPathSuccessful {
-                       payment_id, payment_hash, path: route.paths[0].clone()
-               };
-               invoice_payer.handle_event(event);
-               let event = Event::PaymentPathSuccessful {
-                       payment_id, payment_hash, path: route.paths[1].clone()
-               };
-               invoice_payer.handle_event(event);
-       }
-
-       #[test]
-       fn considers_inflight_htlcs_between_invoice_payments() {
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let payment_invoice = invoice(payment_preimage);
-               let final_value_msat = payment_invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new()
-                       .expect_send(Amount::ForInvoice(final_value_msat))
-                       .expect_send(Amount::ForInvoice(final_value_msat));
-               let scorer = TestScorer::new()
-                       // 1st invoice, 1st path
-                       .expect_usage(ChannelUsage { amount_msat: 64, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 84, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 94, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       // 1st invoice, 2nd path
-                       .expect_usage(ChannelUsage { amount_msat: 64, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 74, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       // 2nd invoice, 1st path
-                       .expect_usage(ChannelUsage { amount_msat: 64, inflight_htlc_msat: 64, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 84, inflight_htlc_msat: 84, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 94, inflight_htlc_msat: 94, effective_capacity: EffectiveCapacity::Unknown } )
-                       // 2nd invoice, 2nd path
-                       .expect_usage(ChannelUsage { amount_msat: 64, inflight_htlc_msat: 64, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 74, inflight_htlc_msat: 74, effective_capacity: EffectiveCapacity::Unknown } );
-               let router = TestRouter::new(scorer);
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(0));
-
-               // Make first invoice payment.
-               invoice_payer.pay_invoice(&payment_invoice).unwrap();
-
-               // Let's pay a second invoice that will be using the same path. This should trigger the
-               // assertions that expect `ChannelUsage` values of the first invoice payment that is still
-               // in-flight.
-               let payment_preimage_2 = PaymentPreimage([2; 32]);
-               let payment_invoice_2 = invoice(payment_preimage_2);
-               invoice_payer.pay_invoice(&payment_invoice_2).unwrap();
-       }
-
-       #[test]
-       fn considers_inflight_htlcs_between_retries() {
-               // First, let's just send a payment through, but only make sure one of the path completes
-               let event_handled = core::cell::RefCell::new(false);
-               let event_handler = |_: Event| { *event_handled.borrow_mut() = true; };
-
-               let payment_preimage = PaymentPreimage([1; 32]);
-               let payment_invoice = invoice(payment_preimage);
-               let payment_hash = PaymentHash(payment_invoice.payment_hash().clone().into_inner());
-               let final_value_msat = payment_invoice.amount_milli_satoshis().unwrap();
-
-               let payer = TestPayer::new()
-                       .expect_send(Amount::ForInvoice(final_value_msat))
-                       .expect_send(Amount::OnRetry(final_value_msat / 2))
-                       .expect_send(Amount::OnRetry(final_value_msat / 4));
-               let final_value_msat = payment_invoice.amount_milli_satoshis().unwrap();
-               let scorer = TestScorer::new()
-                       // 1st invoice, 1st path
-                       .expect_usage(ChannelUsage { amount_msat: 64, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 84, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 94, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       // 1st invoice, 2nd path
-                       .expect_usage(ChannelUsage { amount_msat: 64, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 74, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       // Retry 1, 1st path
-                       .expect_usage(ChannelUsage { amount_msat: 32, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 52, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 62, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       // Retry 1, 2nd path
-                       .expect_usage(ChannelUsage { amount_msat: 32, inflight_htlc_msat: 64, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 42, inflight_htlc_msat: 64 + 10, effective_capacity: EffectiveCapacity::Unknown } )
-                       // Retry 2, 1st path
-                       .expect_usage(ChannelUsage { amount_msat: 16, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 36, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 46, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown } )
-                       // Retry 2, 2nd path
-                       .expect_usage(ChannelUsage { amount_msat: 16, inflight_htlc_msat: 64 + 32, effective_capacity: EffectiveCapacity::Unknown } )
-                       .expect_usage(ChannelUsage { amount_msat: 26, inflight_htlc_msat: 74 + 32 + 10, effective_capacity: EffectiveCapacity::Unknown } );
-               let router = TestRouter::new(scorer);
-               let logger = TestLogger::new();
-               let invoice_payer =
-                       InvoicePayer::new(&payer, router, &logger, event_handler, Retry::Attempts(2));
-
-               // Fail 1st path, leave 2nd path inflight
-               let payment_id = Some(invoice_payer.pay_invoice(&payment_invoice).unwrap());
-               invoice_payer.payer.fail_path(&TestRouter::path_for_value(final_value_msat));
-               invoice_payer.handle_event(Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash,
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path: TestRouter::path_for_value(final_value_msat),
-                       short_channel_id: None,
-                       retry: Some(TestRouter::retry_for_invoice(&payment_invoice)),
-               });
-
-               // Fails again the 1st path of our retry
-               invoice_payer.payer.fail_path(&TestRouter::path_for_value(final_value_msat / 2));
-               invoice_payer.handle_event(Event::PaymentPathFailed {
-                       payment_id,
-                       payment_hash,
-                       network_update: None,
-                       payment_failed_permanently: false,
-                       all_paths_failed: false,
-                       path: TestRouter::path_for_value(final_value_msat / 2),
-                       short_channel_id: None,
-                       retry: Some(RouteParameters {
-                               final_value_msat: final_value_msat / 4,
-                               ..TestRouter::retry_for_invoice(&payment_invoice)
-                       }),
-               });
-       }
-
-       struct TestRouter {
-               scorer: RefCell<TestScorer>,
-       }
-
-       impl TestRouter {
-               fn new(scorer: TestScorer) -> Self {
-                       TestRouter { scorer: RefCell::new(scorer) }
-               }
-
-               fn route_for_value(final_value_msat: u64) -> Route {
-                       Route {
-                               paths: vec![
-                                       vec![
-                                               RouteHop {
-                                                       pubkey: PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
-                                                       channel_features: ChannelFeatures::empty(),
-                                                       node_features: NodeFeatures::empty(),
-                                                       short_channel_id: 0,
-                                                       fee_msat: 10,
-                                                       cltv_expiry_delta: 0
-                                               },
-                                               RouteHop {
-                                                       pubkey: PublicKey::from_slice(&hex::decode("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap(),
-                                                       channel_features: ChannelFeatures::empty(),
-                                                       node_features: NodeFeatures::empty(),
-                                                       short_channel_id: 1,
-                                                       fee_msat: 20,
-                                                       cltv_expiry_delta: 0
-                                               },
-                                               RouteHop {
-                                                       pubkey: PublicKey::from_slice(&hex::decode("027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007").unwrap()[..]).unwrap(),
-                                                       channel_features: ChannelFeatures::empty(),
-                                                       node_features: NodeFeatures::empty(),
-                                                       short_channel_id: 2,
-                                                       fee_msat: final_value_msat / 2,
-                                                       cltv_expiry_delta: 0
-                                               },
-                                       ],
-                                       vec![
-                                               RouteHop {
-                                                       pubkey: PublicKey::from_slice(&hex::decode("029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255").unwrap()[..]).unwrap(),
-                                                       channel_features: ChannelFeatures::empty(),
-                                                       node_features: NodeFeatures::empty(),
-                                                       short_channel_id: 3,
-                                                       fee_msat: 10,
-                                                       cltv_expiry_delta: 144
-                                               },
-                                               RouteHop {
-                                                       pubkey: PublicKey::from_slice(&hex::decode("027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007").unwrap()[..]).unwrap(),
-                                                       channel_features: ChannelFeatures::empty(),
-                                                       node_features: NodeFeatures::empty(),
-                                                       short_channel_id: 4,
-                                                       fee_msat: final_value_msat / 2,
-                                                       cltv_expiry_delta: 144
-                                               }
-                                       ],
-                               ],
-                               payment_params: None,
-                       }
-               }
-
-               fn path_for_value(final_value_msat: u64) -> Vec<RouteHop> {
-                       TestRouter::route_for_value(final_value_msat).paths[0].clone()
-               }
-
-               fn retry_for_invoice(invoice: &Invoice) -> RouteParameters {
-                       let mut payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key())
-                               .with_expiry_time(expiry_time_from_unix_epoch(invoice).as_secs())
-                               .with_route_hints(invoice.route_hints());
-                       if let Some(features) = invoice.features() {
-                               payment_params = payment_params.with_features(features.clone());
-                       }
-                       let final_value_msat = invoice.amount_milli_satoshis().unwrap() / 2;
-                       RouteParameters {
-                               payment_params,
-                               final_value_msat,
-                               final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
-                       }
-               }
-       }
-
-       impl Router for TestRouter {
-               fn find_route(
-                       &self, payer: &PublicKey, route_params: &RouteParameters,
-                       _first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: &InFlightHtlcs
-               ) -> Result<Route, LightningError> {
-                       // Simulate calling the Scorer just as you would in find_route
-                       let route = Self::route_for_value(route_params.final_value_msat);
-                       let locked_scorer = self.scorer.lock();
-                       let scorer = ScorerAccountingForInFlightHtlcs::new(locked_scorer, inflight_htlcs);
-                       for path in route.paths {
-                               let mut aggregate_msat = 0u64;
-                               for (idx, hop) in path.iter().rev().enumerate() {
-                                       aggregate_msat += hop.fee_msat;
-                                       let usage = ChannelUsage {
-                                               amount_msat: aggregate_msat,
-                                               inflight_htlc_msat: 0,
-                                               effective_capacity: EffectiveCapacity::Unknown,
-                                       };
-
-                                       // Since the path is reversed, the last element in our iteration is the first
-                                       // hop.
-                                       if idx == path.len() - 1 {
-                                               scorer.channel_penalty_msat(hop.short_channel_id, &NodeId::from_pubkey(payer), &NodeId::from_pubkey(&hop.pubkey), usage);
-                                       } else {
-                                               scorer.channel_penalty_msat(hop.short_channel_id, &NodeId::from_pubkey(&path[idx + 1].pubkey), &NodeId::from_pubkey(&hop.pubkey), usage);
-                                       }
-                               }
-                       }
-
-                       Ok(Route {
-                               payment_params: Some(route_params.payment_params.clone()), ..Self::route_for_value(route_params.final_value_msat)
-                       })
-               }
-
-               fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) {
-                       self.scorer.lock().payment_path_failed(path, short_channel_id);
-               }
-
-               fn notify_payment_path_successful(&self, path: &[&RouteHop]) {
-                       self.scorer.lock().payment_path_successful(path);
-               }
-
-               fn notify_payment_probe_successful(&self, path: &[&RouteHop]) {
-                       self.scorer.lock().probe_successful(path);
-               }
-
-               fn notify_payment_probe_failed(&self, path: &[&RouteHop], short_channel_id: u64) {
-                       self.scorer.lock().probe_failed(path, short_channel_id);
-               }
-       }
-
-       struct FailingRouter;
-
-       impl Router for FailingRouter {
-               fn find_route(
-                       &self, _payer: &PublicKey, _params: &RouteParameters, _first_hops: Option<&[&ChannelDetails]>,
-                       _inflight_htlcs: &InFlightHtlcs,
-               ) -> Result<Route, LightningError> {
-                       Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError })
-               }
-
-               fn notify_payment_path_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
-
-               fn notify_payment_path_successful(&self, _path: &[&RouteHop]) {}
-
-               fn notify_payment_probe_successful(&self, _path: &[&RouteHop]) {}
-
-               fn notify_payment_probe_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
-       }
-
-       struct TestScorer {
-               event_expectations: Option<VecDeque<TestResult>>,
-               scorer_expectations: RefCell<Option<VecDeque<ChannelUsage>>>,
-       }
-
-       #[derive(Debug)]
-       enum TestResult {
-               PaymentFailure { path: Vec<RouteHop>, short_channel_id: u64 },
-               PaymentSuccess { path: Vec<RouteHop> },
-       }
-
-       impl TestScorer {
-               fn new() -> Self {
-                       Self {
-                               event_expectations: None,
-                               scorer_expectations: RefCell::new(None),
-                       }
-               }
-
-               fn expect(mut self, expectation: TestResult) -> Self {
-                       self.event_expectations.get_or_insert_with(|| VecDeque::new()).push_back(expectation);
-                       self
-               }
-
-               fn expect_usage(self, expectation: ChannelUsage) -> Self {
-                       self.scorer_expectations.borrow_mut().get_or_insert_with(|| VecDeque::new()).push_back(expectation);
-                       self
-               }
-       }
-
-       #[cfg(c_bindings)]
-       impl lightning::util::ser::Writeable for TestScorer {
-               fn write<W: lightning::util::ser::Writer>(&self, _: &mut W) -> Result<(), lightning::io::Error> { unreachable!(); }
-       }
-
-       impl Score for TestScorer {
-               fn channel_penalty_msat(
-                       &self, _short_channel_id: u64, _source: &NodeId, _target: &NodeId, usage: ChannelUsage
-               ) -> u64 {
-                       if let Some(scorer_expectations) = self.scorer_expectations.borrow_mut().as_mut() {
-                               match scorer_expectations.pop_front() {
-                                       Some(expectation) => {
-                                               assert_eq!(expectation.amount_msat, usage.amount_msat);
-                                               assert_eq!(expectation.inflight_htlc_msat, usage.inflight_htlc_msat);
-                                       },
-                                       None => {},
-                               }
-                       }
-                       0
-               }
-
-               fn payment_path_failed(&mut self, actual_path: &[&RouteHop], actual_short_channel_id: u64) {
-                       if let Some(expectations) = &mut self.event_expectations {
-                               match expectations.pop_front() {
-                                       Some(TestResult::PaymentFailure { path, short_channel_id }) => {
-                                               assert_eq!(actual_path, &path.iter().collect::<Vec<_>>()[..]);
-                                               assert_eq!(actual_short_channel_id, short_channel_id);
-                                       },
-                                       Some(TestResult::PaymentSuccess { path }) => {
-                                               panic!("Unexpected successful payment path: {:?}", path)
-                                       },
-                                       None => panic!("Unexpected notify_payment_path_failed call: {:?}", actual_path),
-                               }
-                       }
-               }
-
-               fn payment_path_successful(&mut self, actual_path: &[&RouteHop]) {
-                       if let Some(expectations) = &mut self.event_expectations {
-                               match expectations.pop_front() {
-                                       Some(TestResult::PaymentFailure { path, .. }) => {
-                                               panic!("Unexpected payment path failure: {:?}", path)
-                                       },
-                                       Some(TestResult::PaymentSuccess { path }) => {
-                                               assert_eq!(actual_path, &path.iter().collect::<Vec<_>>()[..]);
-                                       },
-                                       None => panic!("Unexpected notify_payment_path_successful call: {:?}", actual_path),
-                               }
-                       }
-               }
-
-               fn probe_failed(&mut self, actual_path: &[&RouteHop], _: u64) {
-                       if let Some(expectations) = &mut self.event_expectations {
-                               match expectations.pop_front() {
-                                       Some(TestResult::PaymentFailure { path, .. }) => {
-                                               panic!("Unexpected failed payment path: {:?}", path)
-                                       },
-                                       Some(TestResult::PaymentSuccess { path }) => {
-                                               panic!("Unexpected successful payment path: {:?}", path)
-                                       },
-                                       None => panic!("Unexpected notify_payment_path_failed call: {:?}", actual_path),
-                               }
-                       }
-               }
-               fn probe_successful(&mut self, actual_path: &[&RouteHop]) {
-                       if let Some(expectations) = &mut self.event_expectations {
-                               match expectations.pop_front() {
-                                       Some(TestResult::PaymentFailure { path, .. }) => {
-                                               panic!("Unexpected payment path failure: {:?}", path)
-                                       },
-                                       Some(TestResult::PaymentSuccess { path }) => {
-                                               panic!("Unexpected successful payment path: {:?}", path)
-                                       },
-                                       None => panic!("Unexpected notify_payment_path_successful call: {:?}", actual_path),
-                               }
-                       }
-               }
-       }
-
-       impl Drop for TestScorer {
-               fn drop(&mut self) {
-                       if std::thread::panicking() {
-                               return;
-                       }
-
-                       if let Some(event_expectations) = &self.event_expectations {
-                               if !event_expectations.is_empty() {
-                                       panic!("Unsatisfied event expectations: {:?}", event_expectations);
-                               }
-                       }
-
-                       if let Some(scorer_expectations) = self.scorer_expectations.borrow().as_ref() {
-                               if !scorer_expectations.is_empty() {
-                                       panic!("Unsatisfied scorer expectations: {:?}", scorer_expectations)
-                               }
-                       }
-               }
-       }
-
-       struct TestPayer {
-               expectations: core::cell::RefCell<VecDeque<Amount>>,
-               attempts: core::cell::RefCell<usize>,
-               failing_on_attempt: core::cell::RefCell<HashMap<usize, PaymentSendFailure>>,
-               inflight_htlcs_paths: core::cell::RefCell<Vec<Vec<RouteHop>>>,
-       }
-
-       #[derive(Clone, Debug, PartialEq, Eq)]
-       enum Amount {
-               ForInvoice(u64),
-               Spontaneous(u64),
-               OnRetry(u64),
-       }
-
-       struct OnAttempt(usize);
-
-       impl TestPayer {
-               fn new() -> Self {
-                       Self {
-                               expectations: core::cell::RefCell::new(VecDeque::new()),
-                               attempts: core::cell::RefCell::new(0),
-                               failing_on_attempt: core::cell::RefCell::new(HashMap::new()),
-                               inflight_htlcs_paths: core::cell::RefCell::new(Vec::new()),
-                       }
-               }
-
-               fn expect_send(self, value_msat: Amount) -> Self {
-                       self.expectations.borrow_mut().push_back(value_msat);
-                       self
-               }
-
-               fn fails_on_attempt(self, attempt: usize) -> Self {
-                       let failure = PaymentSendFailure::ParameterError(APIError::MonitorUpdateInProgress);
-                       self.fails_with(failure, OnAttempt(attempt))
-               }
-
-               fn fails_with_partial_failure(self, retry: RouteParameters, attempt: OnAttempt, results: Option<Vec<Result<(), APIError>>>) -> Self {
-                       self.fails_with(PaymentSendFailure::PartialFailure {
-                               results: results.unwrap_or(vec![]),
-                               failed_paths_retry: Some(retry),
-                               payment_id: PaymentId([1; 32]),
-                       }, attempt)
-               }
-
-               fn fails_with(self, failure: PaymentSendFailure, attempt: OnAttempt) -> Self {
-                       self.failing_on_attempt.borrow_mut().insert(attempt.0, failure);
-                       self
-               }
-
-               fn check_attempts(&self) -> Result<(), PaymentSendFailure> {
-                       let mut attempts = self.attempts.borrow_mut();
-                       *attempts += 1;
-
-                       match self.failing_on_attempt.borrow_mut().remove(&*attempts) {
-                               Some(failure) => Err(failure),
-                               None => Ok(())
-                       }
+                       _ => panic!()
                }
-
-               fn check_value_msats(&self, actual_value_msats: Amount) {
-                       let expected_value_msats = self.expectations.borrow_mut().pop_front();
-                       if let Some(expected_value_msats) = expected_value_msats {
-                               assert_eq!(actual_value_msats, expected_value_msats);
-                       } else {
-                               panic!("Unexpected amount: {:?}", actual_value_msats);
-                       }
-               }
-
-               fn track_inflight_htlcs(&self, route: &Route) {
-                       for path in &route.paths {
-                               self.inflight_htlcs_paths.borrow_mut().push(path.clone());
-                       }
-               }
-
-               fn fail_path(&self, path: &Vec<RouteHop>) {
-                       let path_idx = self.inflight_htlcs_paths.borrow().iter().position(|p| p == path);
-
-                       if let Some(idx) = path_idx {
-                               self.inflight_htlcs_paths.borrow_mut().swap_remove(idx);
-                       }
-               }
-       }
-
-       impl Drop for TestPayer {
-               fn drop(&mut self) {
-                       if std::thread::panicking() {
-                               return;
-                       }
-
-                       if !self.expectations.borrow().is_empty() {
-                               panic!("Unsatisfied payment expectations: {:?}", self.expectations.borrow());
-                       }
-               }
-       }
-
-       impl Payer for TestPayer {
-               fn node_id(&self) -> PublicKey {
-                       let secp_ctx = Secp256k1::new();
-                       PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap())
-               }
-
-               fn first_hops(&self) -> Vec<ChannelDetails> {
-                       Vec::new()
-               }
-
-               fn send_payment(
-                       &self, route: &Route, _payment_hash: PaymentHash,
-                       _payment_secret: &Option<PaymentSecret>, _payment_id: PaymentId,
-               ) -> Result<(), PaymentSendFailure> {
-                       self.check_value_msats(Amount::ForInvoice(route.get_total_amount()));
-                       self.track_inflight_htlcs(route);
-                       self.check_attempts()
-               }
-
-               fn send_spontaneous_payment(
-                       &self, route: &Route, _payment_preimage: PaymentPreimage, _payment_id: PaymentId,
-               ) -> Result<(), PaymentSendFailure> {
-                       self.check_value_msats(Amount::Spontaneous(route.get_total_amount()));
-                       self.check_attempts()
-               }
-
-               fn retry_payment(
-                       &self, route: &Route, _payment_id: PaymentId
-               ) -> Result<(), PaymentSendFailure> {
-                       self.check_value_msats(Amount::OnRetry(route.get_total_amount()));
-                       self.track_inflight_htlcs(route);
-                       self.check_attempts()
-               }
-
-               fn abandon_payment(&self, _payment_id: PaymentId) { }
-
-               fn inflight_htlcs(&self) -> InFlightHtlcs {
-                       let mut inflight_htlcs = InFlightHtlcs::new();
-                       for path in self.inflight_htlcs_paths.clone().into_inner() {
-                               inflight_htlcs.process_path(&path, self.node_id());
-                       }
-                       inflight_htlcs
-               }
-       }
-
-       // *** Full Featured Functional Tests with a Real ChannelManager ***
-       struct ManualRouter(RefCell<VecDeque<Result<Route, LightningError>>>);
-
-       impl Router for ManualRouter {
-               fn find_route(
-                       &self, _payer: &PublicKey, _params: &RouteParameters, _first_hops: Option<&[&ChannelDetails]>,
-                       _inflight_htlcs: &InFlightHtlcs
-               ) -> Result<Route, LightningError> {
-                       self.0.borrow_mut().pop_front().unwrap()
-               }
-
-               fn notify_payment_path_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
-
-               fn notify_payment_path_successful(&self, _path: &[&RouteHop]) {}
-
-               fn notify_payment_probe_successful(&self, _path: &[&RouteHop]) {}
-
-               fn notify_payment_probe_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
-       }
-       impl ManualRouter {
-               fn expect_find_route(&self, result: Result<Route, LightningError>) {
-                       self.0.borrow_mut().push_back(result);
-               }
-       }
-       impl Drop for ManualRouter {
-               fn drop(&mut self) {
-                       if std::thread::panicking() {
-                               return;
-                       }
-                       assert!(self.0.borrow_mut().is_empty());
-               }
-       }
-
-       #[test]
-       fn retry_multi_path_single_failed_payment() {
-               // Tests that we can/will retry after a single path of an MPP payment failed immediately
-               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, None]);
-               let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chans = nodes[0].node.list_usable_channels();
-               let mut route = Route {
-                       paths: vec![
-                               vec![RouteHop {
-                                       pubkey: nodes[1].node.get_our_node_id(),
-                                       node_features: channelmanager::provided_node_features(),
-                                       short_channel_id: chans[0].short_channel_id.unwrap(),
-                                       channel_features: channelmanager::provided_channel_features(),
-                                       fee_msat: 10_000,
-                                       cltv_expiry_delta: 100,
-                               }],
-                               vec![RouteHop {
-                                       pubkey: nodes[1].node.get_our_node_id(),
-                                       node_features: channelmanager::provided_node_features(),
-                                       short_channel_id: chans[1].short_channel_id.unwrap(),
-                                       channel_features: channelmanager::provided_channel_features(),
-                                       fee_msat: 100_000_001, // Our default max-HTLC-value is 10% of the channel value, which this is one more than
-                                       cltv_expiry_delta: 100,
-                               }],
-                       ],
-                       payment_params: Some(PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())),
-               };
-               let router = ManualRouter(RefCell::new(VecDeque::new()));
-               router.expect_find_route(Ok(route.clone()));
-               // On retry, split the payment across both channels.
-               route.paths[0][0].fee_msat = 50_000_001;
-               route.paths[1][0].fee_msat = 50_000_000;
-               router.expect_find_route(Ok(route.clone()));
-
-               let event_handler = |_: Event| { panic!(); };
-               let invoice_payer = InvoicePayer::new(nodes[0].node, router, nodes[0].logger, event_handler, Retry::Attempts(1));
-
-               assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(
-                       &nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::Bitcoin,
-                       Some(100_010_000), "Invoice".to_string(), duration_since_epoch(), 3600).unwrap())
-                       .is_ok());
-               let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
-               assert_eq!(htlc_msgs.len(), 2);
-               check_added_monitors!(nodes[0], 2);
-       }
-
-       #[test]
-       fn immediate_retry_on_failure() {
-               // Tests that we can/will retry immediately after a failure
-               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, None]);
-               let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chans = nodes[0].node.list_usable_channels();
-               let mut route = Route {
-                       paths: vec![
-                               vec![RouteHop {
-                                       pubkey: nodes[1].node.get_our_node_id(),
-                                       node_features: channelmanager::provided_node_features(),
-                                       short_channel_id: chans[0].short_channel_id.unwrap(),
-                                       channel_features: channelmanager::provided_channel_features(),
-                                       fee_msat: 100_000_001, // Our default max-HTLC-value is 10% of the channel value, which this is one more than
-                                       cltv_expiry_delta: 100,
-                               }],
-                       ],
-                       payment_params: Some(PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())),
-               };
-               let router = ManualRouter(RefCell::new(VecDeque::new()));
-               router.expect_find_route(Ok(route.clone()));
-               // On retry, split the payment across both channels.
-               route.paths.push(route.paths[0].clone());
-               route.paths[0][0].short_channel_id = chans[1].short_channel_id.unwrap();
-               route.paths[0][0].fee_msat = 50_000_000;
-               route.paths[1][0].fee_msat = 50_000_001;
-               router.expect_find_route(Ok(route.clone()));
-
-               let event_handler = |_: Event| { panic!(); };
-               let invoice_payer = InvoicePayer::new(nodes[0].node, router, nodes[0].logger, event_handler, Retry::Attempts(1));
-
-               assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(
-                       &nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::Bitcoin,
-                       Some(100_010_000), "Invoice".to_string(), duration_since_epoch(), 3600).unwrap())
-                       .is_ok());
-               let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
-               assert_eq!(htlc_msgs.len(), 2);
-               check_added_monitors!(nodes[0], 2);
-       }
-
-       #[test]
-       fn no_extra_retries_on_back_to_back_fail() {
-               // In a previous release, we had a race where we may exceed the payment retry count if we
-               // get two failures in a row with the second having `all_paths_failed` set.
-               // Generally, when we give up trying to retry a payment, we don't know for sure what the
-               // current state of the ChannelManager event queue is. Specifically, we cannot be sure that
-               // there are not multiple additional `PaymentPathFailed` or even `PaymentSent` events
-               // pending which we will see later. Thus, when we previously removed the retry tracking map
-               // entry after a `all_paths_failed` `PaymentPathFailed` event, we may have dropped the
-               // retry entry even though more events for the same payment were still pending. This led to
-               // us retrying a payment again even though we'd already given up on it.
-               //
-               // We now have a separate event - `PaymentFailed` which indicates no HTLCs remain and which
-               // is used to remove the payment retry counter entries instead. This tests for the specific
-               // excess-retry case while also testing `PaymentFailed` generation.
-
-               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, &[None, None, None]);
-               let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-
-               let chan_1_scid = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-               let chan_2_scid = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-
-               let mut route = Route {
-                       paths: vec![
-                               vec![RouteHop {
-                                       pubkey: nodes[1].node.get_our_node_id(),
-                                       node_features: channelmanager::provided_node_features(),
-                                       short_channel_id: chan_1_scid,
-                                       channel_features: channelmanager::provided_channel_features(),
-                                       fee_msat: 0,
-                                       cltv_expiry_delta: 100,
-                               }, RouteHop {
-                                       pubkey: nodes[2].node.get_our_node_id(),
-                                       node_features: channelmanager::provided_node_features(),
-                                       short_channel_id: chan_2_scid,
-                                       channel_features: channelmanager::provided_channel_features(),
-                                       fee_msat: 100_000_000,
-                                       cltv_expiry_delta: 100,
-                               }],
-                               vec![RouteHop {
-                                       pubkey: nodes[1].node.get_our_node_id(),
-                                       node_features: channelmanager::provided_node_features(),
-                                       short_channel_id: chan_1_scid,
-                                       channel_features: channelmanager::provided_channel_features(),
-                                       fee_msat: 0,
-                                       cltv_expiry_delta: 100,
-                               }, RouteHop {
-                                       pubkey: nodes[2].node.get_our_node_id(),
-                                       node_features: channelmanager::provided_node_features(),
-                                       short_channel_id: chan_2_scid,
-                                       channel_features: channelmanager::provided_channel_features(),
-                                       fee_msat: 100_000_000,
-                                       cltv_expiry_delta: 100,
-                               }]
-                       ],
-                       payment_params: Some(PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())),
-               };
-               let router = ManualRouter(RefCell::new(VecDeque::new()));
-               router.expect_find_route(Ok(route.clone()));
-               // On retry, we'll only be asked for one path
-               route.paths.remove(1);
-               router.expect_find_route(Ok(route.clone()));
-
-               let expected_events: RefCell<VecDeque<&dyn Fn(Event)>> = RefCell::new(VecDeque::new());
-               let event_handler = |event: Event| {
-                       let event_checker = expected_events.borrow_mut().pop_front().unwrap();
-                       event_checker(event);
-               };
-               let invoice_payer = InvoicePayer::new(nodes[0].node, router, nodes[0].logger, event_handler, Retry::Attempts(1));
-
-               assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(
-                       &nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::Bitcoin,
-                       Some(100_010_000), "Invoice".to_string(), duration_since_epoch(), 3600).unwrap())
-                       .is_ok());
-               let htlc_updates = SendEvent::from_node(&nodes[0]);
-               check_added_monitors!(nodes[0], 1);
-               assert_eq!(htlc_updates.msgs.len(), 1);
-
-               nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &htlc_updates.msgs[0]);
-               nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &htlc_updates.commitment_msg);
-               check_added_monitors!(nodes[1], 1);
-               let (bs_first_raa, bs_first_cs) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id());
-
-               nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_first_raa);
-               check_added_monitors!(nodes[0], 1);
-               let second_htlc_updates = SendEvent::from_node(&nodes[0]);
-
-               nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_first_cs);
-               check_added_monitors!(nodes[0], 1);
-               let as_first_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id());
-
-               nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &second_htlc_updates.msgs[0]);
-               nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &second_htlc_updates.commitment_msg);
-               check_added_monitors!(nodes[1], 1);
-               let bs_second_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
-
-               nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_first_raa);
-               check_added_monitors!(nodes[1], 1);
-               let bs_fail_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
-
-               nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_raa);
-               check_added_monitors!(nodes[0], 1);
-
-               nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_fail_update.update_fail_htlcs[0]);
-               nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_fail_update.commitment_signed);
-               check_added_monitors!(nodes[0], 1);
-               let (as_second_raa, as_third_cs) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
-
-               nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_second_raa);
-               check_added_monitors!(nodes[1], 1);
-               let bs_second_fail_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
-
-               nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_third_cs);
-               check_added_monitors!(nodes[1], 1);
-               let bs_third_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
-
-               nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_second_fail_update.update_fail_htlcs[0]);
-               nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_fail_update.commitment_signed);
-               check_added_monitors!(nodes[0], 1);
-
-               nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_third_raa);
-               check_added_monitors!(nodes[0], 1);
-               let (as_third_raa, as_fourth_cs) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
-
-               nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_third_raa);
-               check_added_monitors!(nodes[1], 1);
-               nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_fourth_cs);
-               check_added_monitors!(nodes[1], 1);
-               let bs_fourth_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
-
-               nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_fourth_raa);
-               check_added_monitors!(nodes[0], 1);
-
-               // At this point A has sent two HTLCs which both failed due to lack of fee. It now has two
-               // pending `PaymentPathFailed` events, one with `all_paths_failed` unset, and the second
-               // with it set. The first event will use up the only retry we are allowed, with the second
-               // `PaymentPathFailed` being passed up to the user (us, in this case). Previously, we'd
-               // treated this as "HTLC complete" and dropped the retry counter, causing us to retry again
-               // if the final HTLC failed.
-               expected_events.borrow_mut().push_back(&|ev: Event| {
-                       if let Event::PaymentPathFailed { payment_failed_permanently, all_paths_failed, .. } = ev {
-                               assert!(!payment_failed_permanently);
-                               assert!(all_paths_failed);
-                       } else { panic!("Unexpected event"); }
-               });
-               nodes[0].node.process_pending_events(&invoice_payer);
-               assert!(expected_events.borrow().is_empty());
-
-               let retry_htlc_updates = SendEvent::from_node(&nodes[0]);
-               check_added_monitors!(nodes[0], 1);
-
-               nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &retry_htlc_updates.msgs[0]);
-               commitment_signed_dance!(nodes[1], nodes[0], &retry_htlc_updates.commitment_msg, false, true);
-               let bs_fail_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
-               nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_fail_update.update_fail_htlcs[0]);
-               commitment_signed_dance!(nodes[0], nodes[1], &bs_fail_update.commitment_signed, false, true);
-
-               expected_events.borrow_mut().push_back(&|ev: Event| {
-                       if let Event::PaymentPathFailed { payment_failed_permanently, all_paths_failed, .. } = ev {
-                               assert!(!payment_failed_permanently);
-                               assert!(all_paths_failed);
-                       } else { panic!("Unexpected event"); }
-               });
-               expected_events.borrow_mut().push_back(&|ev: Event| {
-                       if let Event::PaymentFailed { .. } = ev {
-                       } else { panic!("Unexpected event"); }
-               });
-               nodes[0].node.process_pending_events(&invoice_payer);
-               assert!(expected_events.borrow().is_empty());
        }
 }
index 0bb1715e728c5ac53f50fb978f32e9105c5faa4d..f5742289118ba1e21382ad899770d9fb028831ce 100644 (file)
@@ -3,7 +3,7 @@ use core::fmt::{Display, Formatter};
 use bech32::{ToBase32, u5, WriteBase32, Base32Len};
 use crate::prelude::*;
 
-use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiry, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
+use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
        PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, constants, SignedRawInvoice, RawDataPart};
 
 /// Converts a stream of bytes written to it to base32. On finalization the according padding will
@@ -313,13 +313,13 @@ impl Base32Len for ExpiryTime {
        }
 }
 
-impl ToBase32 for MinFinalCltvExpiry {
+impl ToBase32 for MinFinalCltvExpiryDelta {
        fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
                writer.write(&encode_int_be_base32(self.0))
        }
 }
 
-impl Base32Len for MinFinalCltvExpiry {
+impl Base32Len for MinFinalCltvExpiryDelta {
        fn base32_len(&self) -> usize {
                encoded_int_be_base32_size(self.0)
        }
@@ -434,8 +434,8 @@ impl ToBase32 for TaggedField {
                        TaggedField::ExpiryTime(ref duration) => {
                                write_tagged_field(writer, constants::TAG_EXPIRY_TIME, duration)
                        },
-                       TaggedField::MinFinalCltvExpiry(ref expiry) => {
-                               write_tagged_field(writer, constants::TAG_MIN_FINAL_CLTV_EXPIRY, expiry)
+                       TaggedField::MinFinalCltvExpiryDelta(ref expiry) => {
+                               write_tagged_field(writer, constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA, expiry)
                        },
                        TaggedField::Fallback(ref fallback_address) => {
                                write_tagged_field(writer, constants::TAG_FALLBACK, fallback_address)
index 1f6dc619a560b42b8f928cc8e6096605615e8f6c..11a779b1028a8ddceb825cc833cceb57856d52f0 100644 (file)
@@ -1,27 +1,24 @@
 //! Convenient utilities to create an invoice.
 
 use crate::{CreationError, Currency, Invoice, InvoiceBuilder, SignOrCreationError};
-use crate::payment::Payer;
 
 use crate::{prelude::*, Description, InvoiceDescription, Sha256};
 use bech32::ToBase32;
 use bitcoin_hashes::Hash;
 use lightning::chain;
 use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
-use lightning::chain::keysinterface::{Recipient, KeysInterface, NodeSigner, SignerProvider};
-use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
-use lightning::ln::channelmanager::{ChannelDetails, ChannelManager, PaymentId, PaymentSendFailure, MIN_FINAL_CLTV_EXPIRY};
-#[cfg(feature = "std")]
+use lightning::chain::keysinterface::{Recipient, NodeSigner, SignerProvider, EntropySource};
+use lightning::ln::{PaymentHash, PaymentSecret};
+use lightning::ln::channelmanager::{ChannelDetails, ChannelManager, MIN_FINAL_CLTV_EXPIRY_DELTA};
 use lightning::ln::channelmanager::{PhantomRouteHints, MIN_CLTV_EXPIRY_DELTA};
 use lightning::ln::inbound_payment::{create, create_from_hash, ExpandedKey};
 use lightning::routing::gossip::RoutingFees;
-use lightning::routing::router::{InFlightHtlcs, Route, RouteHint, RouteHintHop, Router};
+use lightning::routing::router::{RouteHint, RouteHintHop, Router};
 use lightning::util::logger::Logger;
 use secp256k1::PublicKey;
 use core::ops::Deref;
 use core::time::Duration;
 
-#[cfg(feature = "std")]
 /// Utility to create an invoice that can be paid to one of multiple nodes, or a "phantom invoice."
 /// See [`PhantomKeysManager`] for more information on phantom node payments.
 ///
@@ -41,8 +38,15 @@ use core::time::Duration;
 ///
 /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
 /// in excess of the current time.
+/// 
+/// `duration_since_epoch` is the current time since epoch in seconds.
+///
+/// You can specify a custom `min_final_cltv_expiry_delta`, or let LDK default it to
+/// [`MIN_FINAL_CLTV_EXPIRY_DELTA`]. The provided expiry must be at least [`MIN_FINAL_CLTV_EXPIRY_DELTA`] - 3.
+/// Note that LDK will add a buffer of 3 blocks to the delta to allow for up to a few new block
+/// confirmations during routing.
 ///
-/// Note that the provided `keys_manager`'s `KeysInterface` implementation must support phantom
+/// Note that the provided `keys_manager`'s `NodeSigner` implementation must support phantom
 /// invoices in its `sign_invoice` implementation ([`PhantomKeysManager`] satisfies this
 /// requirement).
 ///
@@ -51,24 +55,28 @@ use core::time::Duration;
 /// [`ChannelManager::create_inbound_payment`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment
 /// [`ChannelManager::create_inbound_payment_for_hash`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
 /// [`PhantomRouteHints::channels`]: lightning::ln::channelmanager::PhantomRouteHints::channels
-pub fn create_phantom_invoice<K: Deref, L: Deref>(
+/// [`MIN_FINAL_CLTV_EXPIRY_DETLA`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA
+/// 
+/// This can be used in a `no_std` environment, where [`std::time::SystemTime`] is not
+/// available and the current time is supplied by the caller.
+pub fn create_phantom_invoice<ES: Deref, NS: Deref, L: Deref>(
        amt_msat: Option<u64>, payment_hash: Option<PaymentHash>, description: String,
-       invoice_expiry_delta_secs: u32, phantom_route_hints: Vec<PhantomRouteHints>, keys_manager: K,
-       logger: L, network: Currency,
+       invoice_expiry_delta_secs: u32, phantom_route_hints: Vec<PhantomRouteHints>, entropy_source: ES,
+       node_signer: NS, logger: L, network: Currency, min_final_cltv_expiry_delta: Option<u16>, duration_since_epoch: Duration,
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
        L::Target: Logger,
 {
        let description = Description::new(description).map_err(SignOrCreationError::CreationError)?;
        let description = InvoiceDescription::Direct(&description,);
-       _create_phantom_invoice::<K, L>(
+       _create_phantom_invoice::<ES, NS, L>(
                amt_msat, payment_hash, description, invoice_expiry_delta_secs, phantom_route_hints,
-               keys_manager, logger, network,
+               entropy_source, node_signer, logger, network, min_final_cltv_expiry_delta, duration_since_epoch,
        )
 }
 
-#[cfg(feature = "std")]
 /// Utility to create an invoice that can be paid to one of multiple nodes, or a "phantom invoice."
 /// See [`PhantomKeysManager`] for more information on phantom node payments.
 ///
@@ -90,8 +98,10 @@ where
 ///
 /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
 /// in excess of the current time.
+/// 
+/// `duration_since_epoch` is the current time since epoch in seconds.
 ///
-/// Note that the provided `keys_manager`'s `KeysInterface` implementation must support phantom
+/// Note that the provided `keys_manager`'s `NodeSigner` implementation must support phantom
 /// invoices in its `sign_invoice` implementation ([`PhantomKeysManager`] satisfies this
 /// requirement).
 ///
@@ -100,32 +110,36 @@ where
 /// [`ChannelManager::create_inbound_payment`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment
 /// [`ChannelManager::create_inbound_payment_for_hash`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
 /// [`PhantomRouteHints::channels`]: lightning::ln::channelmanager::PhantomRouteHints::channels
-pub fn create_phantom_invoice_with_description_hash<K: Deref, L: Deref>(
+/// 
+/// This can be used in a `no_std` environment, where [`std::time::SystemTime`] is not
+/// available and the current time is supplied by the caller.
+pub fn create_phantom_invoice_with_description_hash<ES: Deref, NS: Deref, L: Deref>(
        amt_msat: Option<u64>, payment_hash: Option<PaymentHash>, invoice_expiry_delta_secs: u32,
-       description_hash: Sha256, phantom_route_hints: Vec<PhantomRouteHints>, keys_manager: K,
-       logger: L, network: Currency
+       description_hash: Sha256, phantom_route_hints: Vec<PhantomRouteHints>, entropy_source: ES,
+       node_signer: NS, logger: L, network: Currency, min_final_cltv_expiry_delta: Option<u16>, duration_since_epoch: Duration,
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
        L::Target: Logger,
 {
-       _create_phantom_invoice::<K, L>(
+       _create_phantom_invoice::<ES, NS, L>(
                amt_msat, payment_hash, InvoiceDescription::Hash(&description_hash),
-               invoice_expiry_delta_secs, phantom_route_hints, keys_manager, logger, network,
+               invoice_expiry_delta_secs, phantom_route_hints, entropy_source, node_signer, logger, network,
+               min_final_cltv_expiry_delta, duration_since_epoch,
        )
 }
 
-#[cfg(feature = "std")]
-fn _create_phantom_invoice<K: Deref, L: Deref>(
+fn _create_phantom_invoice<ES: Deref, NS: Deref, L: Deref>(
        amt_msat: Option<u64>, payment_hash: Option<PaymentHash>, description: InvoiceDescription,
-       invoice_expiry_delta_secs: u32, phantom_route_hints: Vec<PhantomRouteHints>, keys_manager: K,
-       logger: L, network: Currency,
+       invoice_expiry_delta_secs: u32, phantom_route_hints: Vec<PhantomRouteHints>, entropy_source: ES,
+       node_signer: NS, logger: L, network: Currency, min_final_cltv_expiry_delta: Option<u16>, duration_since_epoch: Duration,
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
        L::Target: Logger,
 {
-       use std::time::{SystemTime, UNIX_EPOCH};
 
        if phantom_route_hints.len() == 0 {
                return Err(SignOrCreationError::CreationError(
@@ -133,6 +147,10 @@ where
                ));
        }
 
+       if min_final_cltv_expiry_delta.is_some() && min_final_cltv_expiry_delta.unwrap().saturating_add(3) < MIN_FINAL_CLTV_EXPIRY_DELTA {
+               return Err(SignOrCreationError::CreationError(CreationError::MinFinalCltvExpiryDeltaTooShort));
+       }
+
        let invoice = match description {
                InvoiceDescription::Direct(description) => {
                        InvoiceBuilder::new(network).description(description.0.clone())
@@ -141,17 +159,16 @@ where
        };
 
        // If we ever see performance here being too slow then we should probably take this ExpandedKey as a parameter instead.
-       let keys = ExpandedKey::new(&keys_manager.get_inbound_payment_key_material());
+       let keys = ExpandedKey::new(&node_signer.get_inbound_payment_key_material());
        let (payment_hash, payment_secret) = if let Some(payment_hash) = payment_hash {
                let payment_secret = create_from_hash(
                        &keys,
                        amt_msat,
                        payment_hash,
                        invoice_expiry_delta_secs,
-                       SystemTime::now()
-                               .duration_since(UNIX_EPOCH)
-                               .expect("Time must be > 1970")
+                       duration_since_epoch
                                .as_secs(),
+                       min_final_cltv_expiry_delta,
                )
                .map_err(|_| SignOrCreationError::CreationError(CreationError::InvalidAmount))?;
                (payment_hash, payment_secret)
@@ -160,11 +177,10 @@ where
                        &keys,
                        amt_msat,
                        invoice_expiry_delta_secs,
-                       &keys_manager,
-                       SystemTime::now()
-                               .duration_since(UNIX_EPOCH)
-                               .expect("Time must be > 1970")
+                       &entropy_source,
+                       duration_since_epoch
                                .as_secs(),
+                       min_final_cltv_expiry_delta,
                )
                .map_err(|_| SignOrCreationError::CreationError(CreationError::InvalidAmount))?
        };
@@ -173,10 +189,12 @@ where
                phantom_route_hints.len(), log_bytes!(payment_hash.0));
 
        let mut invoice = invoice
-               .current_timestamp()
+               .duration_since_epoch(duration_since_epoch)
                .payment_hash(Hash::from_slice(&payment_hash.0).unwrap())
                .payment_secret(payment_secret)
-               .min_final_cltv_expiry(MIN_FINAL_CLTV_EXPIRY.into())
+               .min_final_cltv_expiry_delta(
+                       // Add a buffer of 3 to the delta if present, otherwise use LDK's minimum.
+                       min_final_cltv_expiry_delta.map(|x| x.saturating_add(3)).unwrap_or(MIN_FINAL_CLTV_EXPIRY_DELTA).into())
                .expiry_time(Duration::from_secs(invoice_expiry_delta_secs.into()));
        if let Some(amt) = amt_msat {
                invoice = invoice.amount_milli_satoshis(amt);
@@ -216,7 +234,7 @@ where
        let hrp_str = raw_invoice.hrp.to_string();
        let hrp_bytes = hrp_str.as_bytes();
        let data_without_signature = raw_invoice.data.to_base32();
-       let signed_raw_invoice = raw_invoice.sign(|_| keys_manager.sign_invoice(hrp_bytes, &data_without_signature, Recipient::PhantomNode));
+       let signed_raw_invoice = raw_invoice.sign(|_| node_signer.sign_invoice(hrp_bytes, &data_without_signature, Recipient::PhantomNode));
        match signed_raw_invoice {
                Ok(inv) => Ok(Invoice::from_signed(inv).unwrap()),
                Err(e) => Err(SignOrCreationError::SignError(e))
@@ -232,14 +250,24 @@ where
 ///
 /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
 /// in excess of the current time.
-pub fn create_invoice_from_channelmanager<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>(
-       channelmanager: &ChannelManager<M, T, K, F, R, L>, keys_manager: K, logger: L,
-       network: Currency, amt_msat: Option<u64>, description: String, invoice_expiry_delta_secs: u32
+///
+/// You can specify a custom `min_final_cltv_expiry_delta`, or let LDK default it to
+/// [`MIN_FINAL_CLTV_EXPIRY_DELTA`]. The provided expiry must be at least [`MIN_FINAL_CLTV_EXPIRY_DELTA`].
+/// Note that LDK will add a buffer of 3 blocks to the delta to allow for up to a few new block
+/// confirmations during routing.
+///
+/// [`MIN_FINAL_CLTV_EXPIRY_DETLA`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA
+pub fn create_invoice_from_channelmanager<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>, node_signer: NS, logger: L,
+       network: Currency, amt_msat: Option<u64>, description: String, invoice_expiry_delta_secs: u32,
+       min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
@@ -248,8 +276,8 @@ where
        let duration = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)
                .expect("for the foreseeable future this shouldn't happen");
        create_invoice_from_channelmanager_and_duration_since_epoch(
-               channelmanager, keys_manager, logger, network, amt_msat, description, duration,
-               invoice_expiry_delta_secs
+               channelmanager, node_signer, logger, network, amt_msat,
+               description, duration, invoice_expiry_delta_secs, min_final_cltv_expiry_delta,
        )
 }
 
@@ -263,15 +291,24 @@ where
 ///
 /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
 /// in excess of the current time.
-pub fn create_invoice_from_channelmanager_with_description_hash<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>(
-       channelmanager: &ChannelManager<M, T, K, F, R, L>, keys_manager: K, logger: L,
+///
+/// You can specify a custom `min_final_cltv_expiry_delta`, or let LDK default it to
+/// [`MIN_FINAL_CLTV_EXPIRY_DELTA`]. The provided expiry must be at least [`MIN_FINAL_CLTV_EXPIRY_DELTA`].
+/// Note that LDK will add a buffer of 3 blocks to the delta to allow for up to a few new block
+/// confirmations during routing.
+///
+/// [`MIN_FINAL_CLTV_EXPIRY_DETLA`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA
+pub fn create_invoice_from_channelmanager_with_description_hash<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>, node_signer: NS, logger: L,
        network: Currency, amt_msat: Option<u64>, description_hash: Sha256,
-       invoice_expiry_delta_secs: u32
+       invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
@@ -283,119 +320,137 @@ where
                .expect("for the foreseeable future this shouldn't happen");
 
        create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch(
-               channelmanager, keys_manager, logger, network, amt_msat,
-               description_hash, duration, invoice_expiry_delta_secs
+               channelmanager, node_signer, logger, network, amt_msat,
+               description_hash, duration, invoice_expiry_delta_secs, min_final_cltv_expiry_delta,
        )
 }
 
 /// See [`create_invoice_from_channelmanager_with_description_hash`]
 /// This version can be used in a `no_std` environment, where [`std::time::SystemTime`] is not
 /// available and the current time is supplied by the caller.
-pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>(
-       channelmanager: &ChannelManager<M, T, K, F, R, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>, node_signer: NS, logger: L,
        network: Currency, amt_msat: Option<u64>, description_hash: Sha256,
-       duration_since_epoch: Duration, invoice_expiry_delta_secs: u32
+       duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Invoice, SignOrCreationError<()>>
                where
-                       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+                       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
                        T::Target: BroadcasterInterface,
-                       K::Target: KeysInterface,
+                       ES::Target: EntropySource,
+                       NS::Target: NodeSigner,
+                       SP::Target: SignerProvider,
                        F::Target: FeeEstimator,
                        R::Target: Router,
                        L::Target: Logger,
 {
        _create_invoice_from_channelmanager_and_duration_since_epoch(
-               channelmanager, keys_manager, logger, network, amt_msat,
+               channelmanager, node_signer, logger, network, amt_msat,
                InvoiceDescription::Hash(&description_hash),
-               duration_since_epoch, invoice_expiry_delta_secs
+               duration_since_epoch, invoice_expiry_delta_secs, min_final_cltv_expiry_delta,
        )
 }
 
 /// See [`create_invoice_from_channelmanager`]
 /// This version can be used in a `no_std` environment, where [`std::time::SystemTime`] is not
 /// available and the current time is supplied by the caller.
-pub fn create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>(
-       channelmanager: &ChannelManager<M, T, K, F, R, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>, node_signer: NS, logger: L,
        network: Currency, amt_msat: Option<u64>, description: String, duration_since_epoch: Duration,
-       invoice_expiry_delta_secs: u32
+       invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Invoice, SignOrCreationError<()>>
                where
-                       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+                       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
                        T::Target: BroadcasterInterface,
-                       K::Target: KeysInterface,
+                       ES::Target: EntropySource,
+                       NS::Target: NodeSigner,
+                       SP::Target: SignerProvider,
                        F::Target: FeeEstimator,
                        R::Target: Router,
                        L::Target: Logger,
 {
        _create_invoice_from_channelmanager_and_duration_since_epoch(
-               channelmanager, keys_manager, logger, network, amt_msat,
+               channelmanager, node_signer, logger, network, amt_msat,
                InvoiceDescription::Direct(
                        &Description::new(description).map_err(SignOrCreationError::CreationError)?,
                ),
-               duration_since_epoch, invoice_expiry_delta_secs
+               duration_since_epoch, invoice_expiry_delta_secs, min_final_cltv_expiry_delta,
        )
 }
 
-fn _create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>(
-       channelmanager: &ChannelManager<M, T, K, F, R, L>, keys_manager: K, logger: L,
+fn _create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>, node_signer: NS, logger: L,
        network: Currency, amt_msat: Option<u64>, description: InvoiceDescription,
-       duration_since_epoch: Duration, invoice_expiry_delta_secs: u32
+       duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Invoice, SignOrCreationError<()>>
                where
-                       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+                       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
                        T::Target: BroadcasterInterface,
-                       K::Target: KeysInterface,
+                       ES::Target: EntropySource,
+                       NS::Target: NodeSigner,
+                       SP::Target: SignerProvider,
                        F::Target: FeeEstimator,
                        R::Target: Router,
                        L::Target: Logger,
 {
+       if min_final_cltv_expiry_delta.is_some() && min_final_cltv_expiry_delta.unwrap().saturating_add(3) < MIN_FINAL_CLTV_EXPIRY_DELTA {
+               return Err(SignOrCreationError::CreationError(CreationError::MinFinalCltvExpiryDeltaTooShort));
+       }
+
        // `create_inbound_payment` only returns an error if the amount is greater than the total bitcoin
        // supply.
        let (payment_hash, payment_secret) = channelmanager
-               .create_inbound_payment(amt_msat, invoice_expiry_delta_secs)
+               .create_inbound_payment(amt_msat, invoice_expiry_delta_secs, min_final_cltv_expiry_delta)
                .map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))?;
        _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash(
-               channelmanager, keys_manager, logger, network, amt_msat, description, duration_since_epoch, invoice_expiry_delta_secs, payment_hash, payment_secret)
+               channelmanager, node_signer, logger, network, amt_msat, description, duration_since_epoch,
+               invoice_expiry_delta_secs, payment_hash, payment_secret, min_final_cltv_expiry_delta)
 }
 
 /// See [`create_invoice_from_channelmanager_and_duration_since_epoch`]
 /// This version allows for providing a custom [`PaymentHash`] for the invoice.
 /// This may be useful if you're building an on-chain swap or involving another protocol where
 /// the payment hash is also involved outside the scope of lightning.
-pub fn create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>(
-       channelmanager: &ChannelManager<M, T, K, F, R, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>, node_signer: NS, logger: L,
        network: Currency, amt_msat: Option<u64>, description: String, duration_since_epoch: Duration,
-       invoice_expiry_delta_secs: u32, payment_hash: PaymentHash
+       invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Invoice, SignOrCreationError<()>>
        where
-               M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+               M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
                T::Target: BroadcasterInterface,
-               K::Target: KeysInterface,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               SP::Target: SignerProvider,
                F::Target: FeeEstimator,
                R::Target: Router,
                L::Target: Logger,
 {
        let payment_secret = channelmanager
-               .create_inbound_payment_for_hash(payment_hash,amt_msat, invoice_expiry_delta_secs)
+               .create_inbound_payment_for_hash(payment_hash, amt_msat, invoice_expiry_delta_secs,
+                       min_final_cltv_expiry_delta)
                .map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))?;
        _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash(
-               channelmanager, keys_manager, logger, network, amt_msat,
+               channelmanager, node_signer, logger, network, amt_msat,
                InvoiceDescription::Direct(
                        &Description::new(description).map_err(SignOrCreationError::CreationError)?,
                ),
-               duration_since_epoch, invoice_expiry_delta_secs, payment_hash, payment_secret
+               duration_since_epoch, invoice_expiry_delta_secs, payment_hash, payment_secret,
+               min_final_cltv_expiry_delta,
        )
 }
 
-fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>(
-       channelmanager: &ChannelManager<M, T, K, F, R, L>, keys_manager: K, logger: L,
+fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, ES, NS, SP, F, R, L>, node_signer: NS, logger: L,
        network: Currency, amt_msat: Option<u64>, description: InvoiceDescription, duration_since_epoch: Duration,
-       invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, payment_secret: PaymentSecret
+       invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, payment_secret: PaymentSecret,
+       min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Invoice, SignOrCreationError<()>>
        where
-               M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+               M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
                T::Target: BroadcasterInterface,
-               K::Target: KeysInterface,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               SP::Target: SignerProvider,
                F::Target: FeeEstimator,
                R::Target: Router,
                L::Target: Logger,
@@ -403,6 +458,10 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has
        let our_node_pubkey = channelmanager.get_our_node_id();
        let channels = channelmanager.list_channels();
 
+       if min_final_cltv_expiry_delta.is_some() && min_final_cltv_expiry_delta.unwrap().saturating_add(3) < MIN_FINAL_CLTV_EXPIRY_DELTA {
+               return Err(SignOrCreationError::CreationError(CreationError::MinFinalCltvExpiryDeltaTooShort));
+       }
+
        log_trace!(logger, "Creating invoice with payment hash {}", log_bytes!(payment_hash.0));
 
        let invoice = match description {
@@ -418,7 +477,9 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has
                .payment_hash(Hash::from_slice(&payment_hash.0).unwrap())
                .payment_secret(payment_secret)
                .basic_mpp()
-               .min_final_cltv_expiry(MIN_FINAL_CLTV_EXPIRY.into())
+               .min_final_cltv_expiry_delta(
+                       // Add a buffer of 3 to the delta if present, otherwise use LDK's minimum.
+                       min_final_cltv_expiry_delta.map(|x| x.saturating_add(3)).unwrap_or(MIN_FINAL_CLTV_EXPIRY_DELTA).into())
                .expiry_time(Duration::from_secs(invoice_expiry_delta_secs.into()));
        if let Some(amt) = amt_msat {
                invoice = invoice.amount_milli_satoshis(amt);
@@ -436,7 +497,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has
        let hrp_str = raw_invoice.hrp.to_string();
        let hrp_bytes = hrp_str.as_bytes();
        let data_without_signature = raw_invoice.data.to_base32();
-       let signed_raw_invoice = raw_invoice.sign(|_| keys_manager.sign_invoice(hrp_bytes, &data_without_signature, Recipient::Node));
+       let signed_raw_invoice = raw_invoice.sign(|_| node_signer.sign_invoice(hrp_bytes, &data_without_signature, Recipient::Node));
        match signed_raw_invoice {
                Ok(inv) => Ok(Invoice::from_signed(inv).unwrap()),
                Err(e) => Err(SignOrCreationError::SignError(e))
@@ -572,65 +633,21 @@ fn filter_channels<L: Deref>(
                .collect::<Vec<RouteHint>>()
 }
 
-impl<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref> Payer for ChannelManager<M, T, K, F, R, L>
-where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
-       T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
-       F::Target: FeeEstimator,
-       R::Target: Router,
-       L::Target: Logger,
-{
-       fn node_id(&self) -> PublicKey {
-               self.get_our_node_id()
-       }
-
-       fn first_hops(&self) -> Vec<ChannelDetails> {
-               self.list_usable_channels()
-       }
-
-       fn send_payment(
-               &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
-               payment_id: PaymentId
-       ) -> Result<(), PaymentSendFailure> {
-               self.send_payment(route, payment_hash, payment_secret, payment_id)
-       }
-
-       fn send_spontaneous_payment(
-               &self, route: &Route, payment_preimage: PaymentPreimage, payment_id: PaymentId,
-       ) -> Result<(), PaymentSendFailure> {
-               self.send_spontaneous_payment(route, Some(payment_preimage), payment_id).map(|_| ())
-       }
-
-       fn retry_payment(
-               &self, route: &Route, payment_id: PaymentId
-       ) -> Result<(), PaymentSendFailure> {
-               self.retry_payment(route, payment_id)
-       }
-
-       fn abandon_payment(&self, payment_id: PaymentId) {
-               self.abandon_payment(payment_id)
-       }
-
-       fn inflight_htlcs(&self) -> InFlightHtlcs { self.compute_inflight_htlcs() }
-}
-
 #[cfg(test)]
 mod test {
        use core::time::Duration;
-       use crate::{Currency, Description, InvoiceDescription};
+       use crate::{Currency, Description, InvoiceDescription, SignOrCreationError, CreationError};
        use bitcoin_hashes::{Hash, sha256};
        use bitcoin_hashes::sha256::Hash as Sha256;
        use lightning::chain::keysinterface::{EntropySource, PhantomKeysManager};
        use lightning::ln::{PaymentPreimage, PaymentHash};
-       use lightning::ln::channelmanager::{self, PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY, PaymentId};
+       use lightning::ln::channelmanager::{PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY_DELTA, PaymentId};
        use lightning::ln::functional_test_utils::*;
        use lightning::ln::msgs::ChannelMessageHandler;
        use lightning::routing::router::{PaymentParameters, RouteParameters, find_route};
        use lightning::util::events::{MessageSendEvent, MessageSendEventsProvider, Event};
        use lightning::util::test_utils;
        use lightning::util::config::UserConfig;
-       use lightning::chain::keysinterface::KeysInterface;
        use crate::utils::create_invoice_from_channelmanager_and_duration_since_epoch;
        use std::collections::HashSet;
 
@@ -640,14 +657,15 @@ mod test {
                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);
-               create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
                let non_default_invoice_expiry_secs = 4200;
                let invoice = create_invoice_from_channelmanager_and_duration_since_epoch(
                        &nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
                        Some(10_000), "test".to_string(), Duration::from_secs(1234567),
-                       non_default_invoice_expiry_secs).unwrap();
+                       non_default_invoice_expiry_secs, None).unwrap();
                assert_eq!(invoice.amount_pico_btc(), Some(100_000));
-               assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
+               // If no `min_final_cltv_expiry_delta` is specified, then it should be `MIN_FINAL_CLTV_EXPIRY_DELTA`.
+               assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
                assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string())));
                assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
 
@@ -661,18 +679,18 @@ mod test {
                assert_eq!(invoice.route_hints()[0].0[0].htlc_minimum_msat, chan.inbound_htlc_minimum_msat);
                assert_eq!(invoice.route_hints()[0].0[0].htlc_maximum_msat, chan.inbound_htlc_maximum_msat);
 
-               let payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key())
+               let payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key(),
+                               invoice.min_final_cltv_expiry_delta() as u32)
                        .with_features(invoice.features().unwrap().clone())
                        .with_route_hints(invoice.route_hints());
                let route_params = RouteParameters {
                        payment_params,
                        final_value_msat: invoice.amount_milli_satoshis().unwrap(),
-                       final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
                };
                let first_hops = nodes[0].node.list_usable_channels();
                let network_graph = &node_cfgs[0].network_graph;
                let logger = test_utils::TestLogger::new();
-               let scorer = test_utils::TestScorer::with_penalty(0);
+               let scorer = test_utils::TestScorer::new();
                let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
                let route = find_route(
                        &nodes[0].node.get_our_node_id(), &route_params, &network_graph,
@@ -701,6 +719,44 @@ mod test {
                assert_eq!(events.len(), 2);
        }
 
+       fn do_create_invoice_min_final_cltv_delta(with_custom_delta: bool) {
+               let chanmon_cfgs = create_chanmon_cfgs(2);
+               let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+               let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+               let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+               let custom_min_final_cltv_expiry_delta = Some(50);
+
+               let invoice = crate::utils::create_invoice_from_channelmanager_and_duration_since_epoch(
+                       &nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
+                       Some(10_000), "".into(), Duration::from_secs(1234567), 3600,
+                       if with_custom_delta { custom_min_final_cltv_expiry_delta } else { None },
+               ).unwrap();
+               assert_eq!(invoice.min_final_cltv_expiry_delta(), if with_custom_delta {
+                       custom_min_final_cltv_expiry_delta.unwrap() + 3 /* Buffer */} else { MIN_FINAL_CLTV_EXPIRY_DELTA } as u64);
+       }
+
+       #[test]
+       fn test_create_invoice_custom_min_final_cltv_delta() {
+               do_create_invoice_min_final_cltv_delta(true);
+               do_create_invoice_min_final_cltv_delta(false);
+       }
+
+       #[test]
+       fn create_invoice_min_final_cltv_delta_equals_htlc_fail_buffer() {
+               let chanmon_cfgs = create_chanmon_cfgs(2);
+               let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+               let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+               let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+               let custom_min_final_cltv_expiry_delta = Some(21);
+
+               let invoice = crate::utils::create_invoice_from_channelmanager_and_duration_since_epoch(
+                       &nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
+                       Some(10_000), "".into(), Duration::from_secs(1234567), 3600,
+                       custom_min_final_cltv_expiry_delta,
+               ).unwrap();
+               assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
+       }
+
        #[test]
        fn test_create_invoice_with_description_hash() {
                let chanmon_cfgs = create_chanmon_cfgs(2);
@@ -710,10 +766,10 @@ mod test {
                let description_hash = crate::Sha256(Hash::hash("Testing description_hash".as_bytes()));
                let invoice = crate::utils::create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch(
                        &nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
-                       Some(10_000), description_hash, Duration::from_secs(1234567), 3600
+                       Some(10_000), description_hash, Duration::from_secs(1234567), 3600, None,
                ).unwrap();
                assert_eq!(invoice.amount_pico_btc(), Some(100_000));
-               assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
+               assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
                assert_eq!(invoice.description(), InvoiceDescription::Hash(&crate::Sha256(Sha256::hash("Testing description_hash".as_bytes()))));
        }
 
@@ -727,10 +783,10 @@ mod test {
                let invoice = crate::utils::create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash(
                        &nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
                        Some(10_000), "test".to_string(), Duration::from_secs(1234567), 3600,
-                       payment_hash
+                       payment_hash, None,
                ).unwrap();
                assert_eq!(invoice.amount_pico_btc(), Some(100_000));
-               assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
+               assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
                assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string())));
                assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&payment_hash.0[..]).unwrap());
        }
@@ -742,8 +798,8 @@ mod test {
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-               let chan_1_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_2_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 2, 0, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_1_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 100000, 10001);
+               let chan_2_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 2, 0, 100000, 10001);
 
                let mut scid_aliases = HashSet::new();
                scid_aliases.insert(chan_1_0.0.short_channel_id_alias.unwrap());
@@ -758,9 +814,9 @@ mod test {
                let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
                let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-               let _chan_1_0_low_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_1_0_high_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let _chan_1_0_medium_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let _chan_1_0_low_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 100_000, 0);
+               let chan_1_0_high_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 10_000_000, 0);
+               let _chan_1_0_medium_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 1_000_000, 0);
                let mut scid_aliases = HashSet::new();
                scid_aliases.insert(chan_1_0_high_inbound_capacity.0.short_channel_id_alias.unwrap());
                match_invoice_routes(Some(5000), &nodes[0], scid_aliases);
@@ -772,9 +828,9 @@ mod test {
                let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
                let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
-               let chan_a = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_b = create_unannounced_chan_between_nodes_with_value(&nodes, 2, 0, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let _chan_c = create_unannounced_chan_between_nodes_with_value(&nodes, 3, 0, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_a = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 10_000_000, 0);
+               let chan_b = create_unannounced_chan_between_nodes_with_value(&nodes, 2, 0, 10_000_000, 0);
+               let _chan_c = create_unannounced_chan_between_nodes_with_value(&nodes, 3, 0, 1_000_000, 0);
 
                // With all peers connected we should get all hints that have sufficient value
                let mut scid_aliases = HashSet::new();
@@ -785,13 +841,13 @@ mod test {
 
                // With only one sufficient-value peer connected we should only get its hint
                scid_aliases.remove(&chan_b.0.short_channel_id_alias.unwrap());
-               nodes[0].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false);
+               nodes[0].node.peer_disconnected(&nodes[2].node.get_our_node_id());
                match_invoice_routes(Some(1_000_000_000), &nodes[0], scid_aliases.clone());
 
                // If we don't have any sufficient-value peers connected we should get all hints with
                // sufficient value, even though there is a connected insufficient-value peer.
                scid_aliases.insert(chan_b.0.short_channel_id_alias.unwrap());
-               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
                match_invoice_routes(Some(1_000_000_000), &nodes[0], scid_aliases);
        }
 
@@ -801,7 +857,7 @@ mod test {
                let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-               let chan_1_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_1_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 100000, 10001);
 
                // Create an unannonced channel between `nodes[2]` and `nodes[0]`, for which the
                // `msgs::ChannelUpdate` is never handled for the node(s). As the `msgs::ChannelUpdate`
@@ -810,9 +866,9 @@ mod test {
                private_chan_cfg.channel_handshake_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(), channelmanager::provided_init_features(), &open_channel);
+               nodes[0].node.handle_open_channel(&nodes[2].node.get_our_node_id(), &open_channel);
                let accept_channel = get_event_msg!(nodes[0], MessageSendEvent::SendAcceptChannel, nodes[2].node.get_our_node_id());
-               nodes[2].node.handle_accept_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+               nodes[2].node.handle_accept_channel(&nodes[0].node.get_our_node_id(), &accept_channel);
 
                let tx = sign_funding_transaction(&nodes[2], &nodes[0], 1_000_000, temporary_channel_id);
 
@@ -843,9 +899,9 @@ mod test {
                let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-               let _chan_1_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let _chan_1_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 100000, 10001);
 
-               let chan_2_0 = create_announced_chan_between_nodes_with_value(&nodes, 2, 0, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_2_0 = create_announced_chan_between_nodes_with_value(&nodes, 2, 0, 100000, 10001);
                nodes[2].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_2_0.1);
                nodes[0].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan_2_0.0);
 
@@ -861,11 +917,11 @@ mod test {
                let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-               let chan_1_0 = create_announced_chan_between_nodes_with_value(&nodes, 1, 0, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_1_0 = create_announced_chan_between_nodes_with_value(&nodes, 1, 0, 100000, 10001);
                nodes[0].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &chan_1_0.0);
                nodes[1].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_1_0.1);
 
-               let chan_2_0 = create_announced_chan_between_nodes_with_value(&nodes, 2, 0, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_2_0 = create_announced_chan_between_nodes_with_value(&nodes, 2, 0, 100000, 10001);
                nodes[2].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_2_0.1);
                nodes[0].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan_2_0.0);
 
@@ -879,8 +935,8 @@ mod test {
                let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-               let chan_1_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_2_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 2, 0, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_1_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 0, 100_000, 0);
+               let chan_2_0 = create_unannounced_chan_between_nodes_with_value(&nodes, 2, 0, 1_000_000, 0);
 
                // As the invoice amt is 1 msat above chan_1_0's inbound capacity, it shouldn't be included
                let mut scid_aliases_99_000_001_msat = HashSet::new();
@@ -918,7 +974,7 @@ mod test {
                let invoice = create_invoice_from_channelmanager_and_duration_since_epoch(
                        &invoice_node.node, invoice_node.keys_manager, invoice_node.logger,
                        Currency::BitcoinTestnet, invoice_amt, "test".to_string(), Duration::from_secs(1234567),
-                       3600).unwrap();
+                       3600, None).unwrap();
                let hints = invoice.private_routes();
 
                for hint in hints {
@@ -946,10 +1002,10 @@ mod test {
                let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-               let chan_0_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_0_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
                nodes[0].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &chan_0_1.1);
                nodes[1].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_1.0);
-               let chan_0_2 = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_0_2 = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001);
                nodes[0].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan_0_2.1);
                nodes[2].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_2.0);
 
@@ -968,9 +1024,10 @@ mod test {
                let non_default_invoice_expiry_secs = 4200;
 
                let invoice =
-                       crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface, &test_utils::TestLogger>(
+                       crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestLogger>(
                                Some(payment_amt), payment_hash, "test".to_string(), non_default_invoice_expiry_secs,
-                               route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet
+                               route_hints, &nodes[1].keys_manager, &nodes[1].keys_manager, &nodes[1].logger,
+                               Currency::BitcoinTestnet, None, Duration::from_secs(1234567)
                        ).unwrap();
                let (payment_hash, payment_secret) = (PaymentHash(invoice.payment_hash().into_inner()), *invoice.payment_secret());
                let payment_preimage = if user_generated_pmt_hash {
@@ -979,24 +1036,24 @@ mod test {
                        nodes[1].node.get_payment_preimage(payment_hash, payment_secret).unwrap()
                };
 
-               assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
+               assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
                assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string())));
                assert_eq!(invoice.route_hints().len(), 2);
                assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
                assert!(!invoice.features().unwrap().supports_basic_mpp());
 
-               let payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key())
+               let payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key(),
+                               invoice.min_final_cltv_expiry_delta() as u32)
                        .with_features(invoice.features().unwrap().clone())
                        .with_route_hints(invoice.route_hints());
                let params = RouteParameters {
                        payment_params,
                        final_value_msat: invoice.amount_milli_satoshis().unwrap(),
-                       final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
                };
                let first_hops = nodes[0].node.list_usable_channels();
                let network_graph = &node_cfgs[0].network_graph;
                let logger = test_utils::TestLogger::new();
-               let scorer = test_utils::TestScorer::with_penalty(0);
+               let scorer = test_utils::TestScorer::new();
                let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
                let route = find_route(
                        &nodes[0].node.get_our_node_id(), &params, &network_graph,
@@ -1067,17 +1124,20 @@ mod test {
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-               create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
+               create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001);
 
                let payment_amt = 20_000;
-               let (payment_hash, _payment_secret) = nodes[1].node.create_inbound_payment(Some(payment_amt), 3600).unwrap();
+               let (payment_hash, _payment_secret) = nodes[1].node.create_inbound_payment(Some(payment_amt), 3600, None).unwrap();
                let route_hints = vec![
                        nodes[1].node.get_phantom_route_hints(),
                        nodes[2].node.get_phantom_route_hints(),
                ];
 
-               let invoice = crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface, &test_utils::TestLogger>(Some(payment_amt), Some(payment_hash), "test".to_string(), 3600, route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet).unwrap();
+               let invoice = crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface,
+                       &test_utils::TestKeysInterface, &test_utils::TestLogger>(Some(payment_amt), Some(payment_hash),
+                               "test".to_string(), 3600, route_hints, &nodes[1].keys_manager, &nodes[1].keys_manager,
+                               &nodes[1].logger, Currency::BitcoinTestnet, None, Duration::from_secs(1234567)).unwrap();
 
                let chan_0_1 = &nodes[1].node.list_usable_channels()[0];
                assert_eq!(invoice.route_hints()[0].0[0].htlc_minimum_msat, chan_0_1.inbound_htlc_minimum_msat);
@@ -1105,18 +1165,46 @@ mod test {
                let description_hash = crate::Sha256(Hash::hash("Description hash phantom invoice".as_bytes()));
                let non_default_invoice_expiry_secs = 4200;
                let invoice = crate::utils::create_phantom_invoice_with_description_hash::<
-                       &test_utils::TestKeysInterface, &test_utils::TestLogger,
+                       &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestLogger,
                >(
                        Some(payment_amt), None, non_default_invoice_expiry_secs, description_hash,
-                       route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet
+                       route_hints, &nodes[1].keys_manager, &nodes[1].keys_manager, &nodes[1].logger,
+                       Currency::BitcoinTestnet, None, Duration::from_secs(1234567),
                )
                .unwrap();
                assert_eq!(invoice.amount_pico_btc(), Some(200_000));
-               assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
+               assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
                assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
                assert_eq!(invoice.description(), InvoiceDescription::Hash(&crate::Sha256(Sha256::hash("Description hash phantom invoice".as_bytes()))));
        }
 
+       #[test]
+       #[cfg(feature = "std")]
+       fn create_phantom_invoice_with_custom_payment_hash_and_custom_min_final_cltv_delta() {
+               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, &[None, None, None]);
+               let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+               let payment_amt = 20_000;
+               let route_hints = vec![
+                       nodes[1].node.get_phantom_route_hints(),
+                       nodes[2].node.get_phantom_route_hints(),
+               ];
+               let user_payment_preimage = PaymentPreimage([1; 32]);
+               let payment_hash = Some(PaymentHash(Sha256::hash(&user_payment_preimage.0[..]).into_inner()));
+               let non_default_invoice_expiry_secs = 4200;
+               let min_final_cltv_expiry_delta = Some(100);
+               let duration_since_epoch = Duration::from_secs(1234567);
+               let invoice = crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface,
+                       &test_utils::TestKeysInterface, &test_utils::TestLogger>(Some(payment_amt), payment_hash,
+                               "".to_string(), non_default_invoice_expiry_secs, route_hints, &nodes[1].keys_manager, &nodes[1].keys_manager,
+                               &nodes[1].logger, Currency::BitcoinTestnet, min_final_cltv_expiry_delta, duration_since_epoch).unwrap();
+               assert_eq!(invoice.amount_pico_btc(), Some(200_000));
+               assert_eq!(invoice.min_final_cltv_expiry_delta(), (min_final_cltv_expiry_delta.unwrap() + 3) as u64);
+               assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
+       }
+
        #[test]
        #[cfg(feature = "std")]
        fn test_multi_node_hints_includes_single_channels_to_participating_nodes() {
@@ -1130,8 +1218,8 @@ mod test {
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-               let chan_0_1 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_0_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_0_1 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
+               let chan_0_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001);
 
                let mut scid_aliases = HashSet::new();
                scid_aliases.insert(chan_0_1.0.short_channel_id_alias.unwrap());
@@ -1159,9 +1247,9 @@ mod test {
                let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
                let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-               let chan_0_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_0_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 3, 1000000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_1_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 3, 3_000_000, 10005, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_0_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001);
+               let chan_0_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 3, 1000000, 10001);
+               let chan_1_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 3, 3_000_000, 10005);
 
                let mut scid_aliases = HashSet::new();
                scid_aliases.insert(chan_0_2.0.short_channel_id_alias.unwrap());
@@ -1190,8 +1278,8 @@ mod test {
                let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
                let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-               let chan_0_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_0_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 3, 1000000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_0_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001);
+               let chan_0_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 3, 1000000, 10001);
 
                // Create an unannonced channel between `nodes[1]` and `nodes[3]`, for which the
                // `msgs::ChannelUpdate` is never handled for the node(s). As the `msgs::ChannelUpdate`
@@ -1200,9 +1288,9 @@ mod test {
                private_chan_cfg.channel_handshake_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(), channelmanager::provided_init_features(), &open_channel);
+               nodes[3].node.handle_open_channel(&nodes[1].node.get_our_node_id(), &open_channel);
                let accept_channel = get_event_msg!(nodes[3], MessageSendEvent::SendAcceptChannel, nodes[1].node.get_our_node_id());
-               nodes[1].node.handle_accept_channel(&nodes[3].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+               nodes[1].node.handle_accept_channel(&nodes[3].node.get_our_node_id(), &accept_channel);
 
                let tx = sign_funding_transaction(&nodes[1], &nodes[3], 1_000_000, temporary_channel_id);
 
@@ -1248,9 +1336,9 @@ mod test {
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-               let chan_0_1 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_0_1 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
 
-               let chan_2_0 = create_announced_chan_between_nodes_with_value(&nodes, 2, 0, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_2_0 = create_announced_chan_between_nodes_with_value(&nodes, 2, 0, 100000, 10001);
                nodes[2].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_2_0.1);
                nodes[0].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan_2_0.0);
 
@@ -1281,12 +1369,12 @@ mod test {
                let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
                let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-               let chan_0_2 = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_0_2 = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001);
                nodes[0].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan_0_2.1);
                nodes[2].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_2.0);
-               let _chan_1_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let _chan_1_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 10001);
 
-               let chan_0_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 3, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_0_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 3, 100000, 10001);
 
                // Hints should include `chan_0_3` from as `nodes[3]` only have private channels, and no
                // channels for `nodes[2]` as it contains a mix of public and private channels.
@@ -1315,10 +1403,10 @@ mod test {
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-               let _chan_0_1_low_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_0_1_high_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let _chan_0_1_medium_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_0_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let _chan_0_1_low_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0);
+               let chan_0_1_high_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0);
+               let _chan_0_1_medium_inbound_capacity = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
+               let chan_0_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001);
 
                let mut scid_aliases = HashSet::new();
                scid_aliases.insert(chan_0_1_high_inbound_capacity.0.short_channel_id_alias.unwrap());
@@ -1346,9 +1434,9 @@ mod test {
                let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
                let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-               let chan_0_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_0_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 3, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let chan_1_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 3, 200_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan_0_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 1_000_000, 0);
+               let chan_0_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 0, 3, 100_000, 0);
+               let chan_1_3 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 3, 200_000, 0);
 
                // Since the invoice 1 msat above chan_0_3's inbound capacity, it should be filtered out.
                let mut scid_aliases_99_000_001_msat = HashSet::new();
@@ -1422,7 +1510,10 @@ mod test {
                        .map(|route_hint| route_hint.phantom_scid)
                        .collect::<HashSet<u64>>();
 
-               let invoice = crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface, &test_utils::TestLogger>(invoice_amt, None, "test".to_string(), 3600, phantom_route_hints, &invoice_node.keys_manager, &invoice_node.logger, Currency::BitcoinTestnet).unwrap();
+               let invoice = crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface,
+                       &test_utils::TestKeysInterface, &test_utils::TestLogger>(invoice_amt, None, "test".to_string(),
+                               3600, phantom_route_hints, &invoice_node.keys_manager, &invoice_node.keys_manager,
+                               &invoice_node.logger, Currency::BitcoinTestnet, None, Duration::from_secs(1234567)).unwrap();
 
                let invoice_hints = invoice.private_routes();
 
@@ -1445,4 +1536,20 @@ mod test {
                }
                assert!(chan_ids_to_match.is_empty(), "Unmatched short channel ids: {:?}", chan_ids_to_match);
        }
+
+       #[test]
+       fn test_create_invoice_fails_with_invalid_custom_min_final_cltv_expiry_delta() {
+               let chanmon_cfgs = create_chanmon_cfgs(2);
+               let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+               let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+               let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+               let result = crate::utils::create_invoice_from_channelmanager_and_duration_since_epoch(
+                       &nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
+                       Some(10_000), "Some description".into(), Duration::from_secs(1234567), 3600, Some(MIN_FINAL_CLTV_EXPIRY_DELTA - 4),
+               );
+               match result {
+                       Err(SignOrCreationError::CreationError(CreationError::MinFinalCltvExpiryDeltaTooShort)) => {},
+                       _ => panic!(),
+               }
+       }
 }
index ffac702ce1a99582f42ae75e2e26cf7af98f8f6d..272d9062a6e4c9a062e622c55f2ed568bbae5409 100644 (file)
@@ -246,7 +246,7 @@ fn get_test_tuples() -> Vec<(String, SignedRawInvoice, bool, bool)> {
                                        "462264ede7e14047e9b249da94fefc47f41f7d02ee9b091815a5506bc8abf75f"
                                ).unwrap())
                                .expiry_time(Duration::from_secs(604800))
-                               .min_final_cltv_expiry(10)
+                               .min_final_cltv_expiry_delta(10)
                                .description("Blockstream Store: 88.85 USD for Blockstream Ledger Nano S x 1, \"Back In My Day\" Sticker x 2, \"I Got Lightning Working\" Sticker x 2 and 1 more items".to_owned())
                                .private_route(RouteHint(vec![RouteHintHop {
                                        src_node_id: PublicKey::from_slice(&hex::decode(
index 07f9f313307c0cd493ab2e2e54b00489aba283c5..8a518638c5f789de307d1fa47cdc3f37422c61ac 100644 (file)
@@ -21,3 +21,4 @@ tokio = { version = "1.0", features = [ "io-util", "macros", "rt", "sync", "net"
 
 [dev-dependencies]
 tokio = { version = "~1.14", features = [ "io-util", "macros", "rt", "rt-multi-thread", "sync", "net", "time" ] }
+lightning = { version = "0.0.113", path = "../lightning", features = ["_test_utils"] }
index 7a7cc4bb0992f7589c6df480aa5cc1ff93b86007..81e6157c656f6e39e76525e33ca09e1b55870325 100644 (file)
 //! type TxBroadcaster = dyn lightning::chain::chaininterface::BroadcasterInterface + Send + Sync;
 //! type FeeEstimator = dyn lightning::chain::chaininterface::FeeEstimator + Send + Sync;
 //! type Logger = dyn lightning::util::logger::Logger + Send + Sync;
-//! type ChainAccess = dyn lightning::chain::Access + Send + Sync;
+//! type NodeSigner = dyn lightning::chain::keysinterface::NodeSigner + Send + Sync;
+//! type UtxoLookup = dyn lightning::routing::utxo::UtxoLookup + Send + Sync;
 //! type ChainFilter = dyn lightning::chain::Filter + Send + Sync;
 //! type DataPersister = dyn lightning::chain::chainmonitor::Persist<lightning::chain::keysinterface::InMemorySigner> + Send + Sync;
 //! type ChainMonitor = lightning::chain::chainmonitor::ChainMonitor<lightning::chain::keysinterface::InMemorySigner, Arc<ChainFilter>, Arc<TxBroadcaster>, Arc<FeeEstimator>, Arc<Logger>, Arc<DataPersister>>;
 //! type ChannelManager = Arc<lightning::ln::channelmanager::SimpleArcChannelManager<ChainMonitor, TxBroadcaster, FeeEstimator, Logger>>;
-//! type PeerManager = Arc<lightning::ln::peer_handler::SimpleArcPeerManager<lightning_net_tokio::SocketDescriptor, ChainMonitor, TxBroadcaster, FeeEstimator, ChainAccess, Logger>>;
+//! type PeerManager = Arc<lightning::ln::peer_handler::SimpleArcPeerManager<lightning_net_tokio::SocketDescriptor, ChainMonitor, TxBroadcaster, FeeEstimator, UtxoLookup, Logger>>;
 //!
 //! // Connect to node with pubkey their_node_id at addr:
 //! async fn connect_to_node(peer_manager: PeerManager, chain_monitor: Arc<ChainMonitor>, channel_manager: ChannelManager, their_node_id: PublicKey, addr: SocketAddr) {
@@ -80,6 +81,7 @@ use tokio::{io, time};
 use tokio::sync::mpsc;
 use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt};
 
+use lightning::chain::keysinterface::NodeSigner;
 use lightning::ln::peer_handler;
 use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait;
 use lightning::ln::peer_handler::CustomMessageHandler;
@@ -123,18 +125,24 @@ struct Connection {
        id: u64,
 }
 impl Connection {
-       async fn poll_event_process<CMH, RMH, OMH, L, UMH>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>>, mut event_receiver: mpsc::Receiver<()>) where
+       async fn poll_event_process<PM, CMH, RMH, OMH, L, UMH, NS>(
+               peer_manager: PM,
+               mut event_receiver: mpsc::Receiver<()>,
+       ) where
+                       PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync,
                        CMH: Deref + 'static + Send + Sync,
                        RMH: Deref + 'static + Send + Sync,
                        OMH: Deref + 'static + Send + Sync,
                        L: Deref + 'static + Send + Sync,
                        UMH: Deref + 'static + Send + Sync,
+                       NS: Deref + 'static + Send + Sync,
                        CMH::Target: ChannelMessageHandler + Send + Sync,
                        RMH::Target: RoutingMessageHandler + Send + Sync,
                        OMH::Target: OnionMessageHandler + Send + Sync,
                        L::Target: Logger + Send + Sync,
                        UMH::Target: CustomMessageHandler + Send + Sync,
-    {
+                       NS::Target: NodeSigner + Send + Sync,
+       {
                loop {
                        if event_receiver.recv().await.is_none() {
                                return;
@@ -143,24 +151,34 @@ impl Connection {
                }
        }
 
-       async fn schedule_read<CMH, RMH, OMH, L, UMH>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>>, us: Arc<Mutex<Self>>, mut reader: io::ReadHalf<TcpStream>, mut read_wake_receiver: mpsc::Receiver<()>, mut write_avail_receiver: mpsc::Receiver<()>) where
+       async fn schedule_read<PM, CMH, RMH, OMH, L, UMH, NS>(
+               peer_manager: PM,
+               us: Arc<Mutex<Self>>,
+               mut reader: io::ReadHalf<TcpStream>,
+               mut read_wake_receiver: mpsc::Receiver<()>,
+               mut write_avail_receiver: mpsc::Receiver<()>,
+       ) where
+                       PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
                        CMH: Deref + 'static + Send + Sync,
                        RMH: Deref + 'static + Send + Sync,
                        OMH: Deref + 'static + Send + Sync,
                        L: Deref + 'static + Send + Sync,
                        UMH: Deref + 'static + Send + Sync,
+                       NS: Deref + 'static + Send + Sync,
                        CMH::Target: ChannelMessageHandler + 'static + Send + Sync,
                        RMH::Target: RoutingMessageHandler + 'static + Send + Sync,
                        OMH::Target: OnionMessageHandler + 'static + Send + Sync,
                        L::Target: Logger + 'static + Send + Sync,
                        UMH::Target: CustomMessageHandler + 'static + Send + Sync,
-        {
+                       NS::Target: NodeSigner + 'static + Send + Sync,
+               {
                // Create a waker to wake up poll_event_process, above
                let (event_waker, event_receiver) = mpsc::channel(1);
-               tokio::spawn(Self::poll_event_process(Arc::clone(&peer_manager), event_receiver));
+               tokio::spawn(Self::poll_event_process(peer_manager.clone(), event_receiver));
 
-               // 8KB is nice and big but also should never cause any issues with stack overflowing.
-               let mut buf = [0; 8192];
+               // 4KiB is nice and big without handling too many messages all at once, giving other peers
+               // a chance to do some work.
+               let mut buf = [0; 4096];
 
                let mut our_descriptor = SocketDescriptor::new(us.clone());
                // An enum describing why we did/are disconnecting:
@@ -272,21 +290,27 @@ fn get_addr_from_stream(stream: &StdTcpStream) -> Option<NetAddress> {
 /// The returned future will complete when the peer is disconnected and associated handling
 /// futures are freed, though, because all processing futures are spawned with tokio::spawn, you do
 /// not need to poll the provided future in order to make progress.
-pub fn setup_inbound<CMH, RMH, OMH, L, UMH>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>>, stream: StdTcpStream) -> impl std::future::Future<Output=()> where
+pub fn setup_inbound<PM, CMH, RMH, OMH, L, UMH, NS>(
+       peer_manager: PM,
+       stream: StdTcpStream,
+) -> impl std::future::Future<Output=()> where
+               PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
                CMH: Deref + 'static + Send + Sync,
                RMH: Deref + 'static + Send + Sync,
                OMH: Deref + 'static + Send + Sync,
                L: Deref + 'static + Send + Sync,
                UMH: Deref + 'static + Send + Sync,
+               NS: Deref + 'static + Send + Sync,
                CMH::Target: ChannelMessageHandler + Send + Sync,
                RMH::Target: RoutingMessageHandler + Send + Sync,
                OMH::Target: OnionMessageHandler + Send + Sync,
                L::Target: Logger + Send + Sync,
                UMH::Target: CustomMessageHandler + Send + Sync,
+               NS::Target: NodeSigner + Send + Sync,
 {
        let remote_addr = get_addr_from_stream(&stream);
        let (reader, write_receiver, read_receiver, us) = Connection::new(stream);
-       #[cfg(debug_assertions)]
+       #[cfg(test)]
        let last_us = Arc::clone(&us);
 
        let handle_opt = if let Ok(_) = peer_manager.new_inbound_connection(SocketDescriptor::new(us.clone()), remote_addr) {
@@ -307,8 +331,8 @@ pub fn setup_inbound<CMH, RMH, OMH, L, UMH>(peer_manager: Arc<peer_handler::Peer
                                // socket shutdown(). Still, as a check during testing, to make sure tokio doesn't
                                // keep too many wakers around, this makes sense. The race should be rare (we do
                                // some work after shutdown()) and an error would be a major memory leak.
-                               #[cfg(debug_assertions)]
-                               assert!(Arc::try_unwrap(last_us).is_ok());
+                               #[cfg(test)]
+                               debug_assert!(Arc::try_unwrap(last_us).is_ok());
                        }
                }
        }
@@ -321,21 +345,28 @@ pub fn setup_inbound<CMH, RMH, OMH, L, UMH>(peer_manager: Arc<peer_handler::Peer
 /// The returned future will complete when the peer is disconnected and associated handling
 /// futures are freed, though, because all processing futures are spawned with tokio::spawn, you do
 /// not need to poll the provided future in order to make progress.
-pub fn setup_outbound<CMH, RMH, OMH, L, UMH>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>>, their_node_id: PublicKey, stream: StdTcpStream) -> impl std::future::Future<Output=()> where
+pub fn setup_outbound<PM, CMH, RMH, OMH, L, UMH, NS>(
+       peer_manager: PM,
+       their_node_id: PublicKey,
+       stream: StdTcpStream,
+) -> impl std::future::Future<Output=()> where
+               PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
                CMH: Deref + 'static + Send + Sync,
                RMH: Deref + 'static + Send + Sync,
                OMH: Deref + 'static + Send + Sync,
                L: Deref + 'static + Send + Sync,
                UMH: Deref + 'static + Send + Sync,
+               NS: Deref + 'static + Send + Sync,
                CMH::Target: ChannelMessageHandler + Send + Sync,
                RMH::Target: RoutingMessageHandler + Send + Sync,
                OMH::Target: OnionMessageHandler + Send + Sync,
                L::Target: Logger + Send + Sync,
                UMH::Target: CustomMessageHandler + Send + Sync,
+               NS::Target: NodeSigner + Send + Sync,
 {
        let remote_addr = get_addr_from_stream(&stream);
        let (reader, mut write_receiver, read_receiver, us) = Connection::new(stream);
-       #[cfg(debug_assertions)]
+       #[cfg(test)]
        let last_us = Arc::clone(&us);
        let handle_opt = if let Ok(initial_send) = peer_manager.new_outbound_connection(their_node_id, SocketDescriptor::new(us.clone()), remote_addr) {
                Some(tokio::spawn(async move {
@@ -381,8 +412,8 @@ pub fn setup_outbound<CMH, RMH, OMH, L, UMH>(peer_manager: Arc<peer_handler::Pee
                                // socket shutdown(). Still, as a check during testing, to make sure tokio doesn't
                                // keep too many wakers around, this makes sense. The race should be rare (we do
                                // some work after shutdown()) and an error would be a major memory leak.
-                               #[cfg(debug_assertions)]
-                               assert!(Arc::try_unwrap(last_us).is_ok());
+                               #[cfg(test)]
+                               debug_assert!(Arc::try_unwrap(last_us).is_ok());
                        }
                }
        }
@@ -399,17 +430,24 @@ pub fn setup_outbound<CMH, RMH, OMH, L, UMH>(peer_manager: Arc<peer_handler::Pee
 /// disconnected and associated handling futures are freed, though, because all processing in said
 /// futures are spawned with tokio::spawn, you do not need to poll the second future in order to
 /// make progress.
-pub async fn connect_outbound<CMH, RMH, OMH, L, UMH>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>>, their_node_id: PublicKey, addr: SocketAddr) -> Option<impl std::future::Future<Output=()>> where
+pub async fn connect_outbound<PM, CMH, RMH, OMH, L, UMH, NS>(
+       peer_manager: PM,
+       their_node_id: PublicKey,
+       addr: SocketAddr,
+) -> Option<impl std::future::Future<Output=()>> where
+               PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
                CMH: Deref + 'static + Send + Sync,
                RMH: Deref + 'static + Send + Sync,
                OMH: Deref + 'static + Send + Sync,
                L: Deref + 'static + Send + Sync,
                UMH: Deref + 'static + Send + Sync,
+               NS: Deref + 'static + Send + Sync,
                CMH::Target: ChannelMessageHandler + Send + Sync,
                RMH::Target: RoutingMessageHandler + Send + Sync,
                OMH::Target: OnionMessageHandler + Send + Sync,
                L::Target: Logger + Send + Sync,
                UMH::Target: CustomMessageHandler + Send + Sync,
+               NS::Target: NodeSigner + Send + Sync,
 {
        if let Ok(Ok(stream)) = time::timeout(Duration::from_secs(10), async { TcpStream::connect(&addr).await.map(|s| s.into_std().unwrap()) }).await {
                Some(setup_outbound(peer_manager, their_node_id, stream))
@@ -547,7 +585,9 @@ mod tests {
        use lightning::ln::msgs::*;
        use lightning::ln::peer_handler::{MessageHandler, PeerManager};
        use lightning::ln::features::NodeFeatures;
+       use lightning::routing::gossip::NodeId;
        use lightning::util::events::*;
+       use lightning::util::test_utils::TestNodeSigner;
        use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey};
 
        use tokio::sync::mpsc;
@@ -576,22 +616,23 @@ mod tests {
                fn handle_channel_announcement(&self, _msg: &ChannelAnnouncement) -> Result<bool, LightningError> { Ok(false) }
                fn handle_channel_update(&self, _msg: &ChannelUpdate) -> Result<bool, LightningError> { Ok(false) }
                fn get_next_channel_announcement(&self, _starting_point: u64) -> Option<(ChannelAnnouncement, Option<ChannelUpdate>, Option<ChannelUpdate>)> { None }
-               fn get_next_node_announcement(&self, _starting_point: Option<&PublicKey>) -> Option<NodeAnnouncement> { None }
-               fn peer_connected(&self, _their_node_id: &PublicKey, _init_msg: &Init) -> Result<(), ()> { Ok(()) }
+               fn get_next_node_announcement(&self, _starting_point: Option<&NodeId>) -> Option<NodeAnnouncement> { None }
+               fn peer_connected(&self, _their_node_id: &PublicKey, _init_msg: &Init, _inbound: bool) -> Result<(), ()> { Ok(()) }
                fn handle_reply_channel_range(&self, _their_node_id: &PublicKey, _msg: ReplyChannelRange) -> Result<(), LightningError> { Ok(()) }
                fn handle_reply_short_channel_ids_end(&self, _their_node_id: &PublicKey, _msg: ReplyShortChannelIdsEnd) -> Result<(), LightningError> { Ok(()) }
                fn handle_query_channel_range(&self, _their_node_id: &PublicKey, _msg: QueryChannelRange) -> Result<(), LightningError> { Ok(()) }
                fn handle_query_short_channel_ids(&self, _their_node_id: &PublicKey, _msg: QueryShortChannelIds) -> Result<(), LightningError> { Ok(()) }
                fn provided_node_features(&self) -> NodeFeatures { NodeFeatures::empty() }
                fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures { InitFeatures::empty() }
+               fn processing_queue_high(&self) -> bool { false }
        }
        impl ChannelMessageHandler for MsgHandler {
-               fn handle_open_channel(&self, _their_node_id: &PublicKey, _their_features: InitFeatures, _msg: &OpenChannel) {}
-               fn handle_accept_channel(&self, _their_node_id: &PublicKey, _their_features: InitFeatures, _msg: &AcceptChannel) {}
+               fn handle_open_channel(&self, _their_node_id: &PublicKey, _msg: &OpenChannel) {}
+               fn handle_accept_channel(&self, _their_node_id: &PublicKey, _msg: &AcceptChannel) {}
                fn handle_funding_created(&self, _their_node_id: &PublicKey, _msg: &FundingCreated) {}
                fn handle_funding_signed(&self, _their_node_id: &PublicKey, _msg: &FundingSigned) {}
                fn handle_channel_ready(&self, _their_node_id: &PublicKey, _msg: &ChannelReady) {}
-               fn handle_shutdown(&self, _their_node_id: &PublicKey, _their_features: &InitFeatures, _msg: &Shutdown) {}
+               fn handle_shutdown(&self, _their_node_id: &PublicKey, _msg: &Shutdown) {}
                fn handle_closing_signed(&self, _their_node_id: &PublicKey, _msg: &ClosingSigned) {}
                fn handle_update_add_htlc(&self, _their_node_id: &PublicKey, _msg: &UpdateAddHTLC) {}
                fn handle_update_fulfill_htlc(&self, _their_node_id: &PublicKey, _msg: &UpdateFulfillHTLC) {}
@@ -602,13 +643,13 @@ mod tests {
                fn handle_update_fee(&self, _their_node_id: &PublicKey, _msg: &UpdateFee) {}
                fn handle_announcement_signatures(&self, _their_node_id: &PublicKey, _msg: &AnnouncementSignatures) {}
                fn handle_channel_update(&self, _their_node_id: &PublicKey, _msg: &ChannelUpdate) {}
-               fn peer_disconnected(&self, their_node_id: &PublicKey, _no_connection_possible: bool) {
+               fn peer_disconnected(&self, their_node_id: &PublicKey) {
                        if *their_node_id == self.expected_pubkey {
                                self.disconnected_flag.store(true, Ordering::SeqCst);
                                self.pubkey_disconnected.clone().try_send(()).unwrap();
                        }
                }
-               fn peer_connected(&self, their_node_id: &PublicKey, _init_msg: &Init) -> Result<(), ()> {
+               fn peer_connected(&self, their_node_id: &PublicKey, _init_msg: &Init, _inbound: bool) -> Result<(), ()> {
                        if *their_node_id == self.expected_pubkey {
                                self.pubkey_connected.clone().try_send(()).unwrap();
                        }
@@ -663,7 +704,7 @@ mod tests {
                        chan_handler: Arc::clone(&a_handler),
                        route_handler: Arc::clone(&a_handler),
                        onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
-               }, a_key.clone(), 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
+               }, 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(a_key))));
 
                let (b_connected_sender, mut b_connected) = mpsc::channel(1);
                let (b_disconnected_sender, mut b_disconnected) = mpsc::channel(1);
@@ -678,7 +719,7 @@ mod tests {
                        chan_handler: Arc::clone(&b_handler),
                        route_handler: Arc::clone(&b_handler),
                        onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
-               }, b_key.clone(), 0, &[2; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
+               }, 0, &[2; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(b_key))));
 
                // We bind on localhost, hoping the environment is properly configured with a local
                // address. This may not always be the case in containers and the like, so if this test is
@@ -731,7 +772,7 @@ mod tests {
                        chan_handler: Arc::new(lightning::ln::peer_handler::ErroringMessageHandler::new()),
                        onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
                        route_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
-               }, a_key, 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
+               }, 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(a_key))));
 
                // Make two connections, one for an inbound and one for an outbound connection
                let conn_a = {
index 2653b251c3b3a7d6c16b2f4107a5c1b6fa62630f..aaa3ef73d6c6f0e40f51a4c3684d0b4e1ced054b 100644 (file)
@@ -20,7 +20,7 @@ extern crate libc;
 use bitcoin::hash_types::{BlockHash, Txid};
 use bitcoin::hashes::hex::FromHex;
 use lightning::chain::channelmonitor::ChannelMonitor;
-use lightning::chain::keysinterface::{KeysInterface, SignerProvider};
+use lightning::chain::keysinterface::{EntropySource, SignerProvider};
 use lightning::util::ser::{ReadableArgs, Writeable};
 use lightning::util::persist::KVStorePersister;
 use std::fs;
@@ -48,7 +48,7 @@ impl FilesystemPersister {
        /// Initialize a new FilesystemPersister and set the path to the individual channels'
        /// files.
        pub fn new(path_to_channel_data: String) -> Self {
-               return Self {
+               Self {
                        path_to_channel_data,
                }
        }
@@ -59,10 +59,12 @@ impl FilesystemPersister {
        }
 
        /// Read `ChannelMonitor`s from disk.
-       pub fn read_channelmonitors<K: Deref> (
-               &self, keys_manager: K
-       ) -> Result<Vec<(BlockHash, ChannelMonitor<<K::Target as SignerProvider>::Signer>)>, std::io::Error>
-               where K::Target: KeysInterface + Sized,
+       pub fn read_channelmonitors<ES: Deref, SP: Deref> (
+               &self, entropy_source: ES, signer_provider: SP
+       ) -> std::io::Result<Vec<(BlockHash, ChannelMonitor<<SP::Target as SignerProvider>::Signer>)>>
+               where
+                       ES::Target: EntropySource + Sized,
+                       SP::Target: SignerProvider + Sized
        {
                let mut path = PathBuf::from(&self.path_to_channel_data);
                path.push("monitors");
@@ -70,45 +72,44 @@ impl FilesystemPersister {
                        return Ok(Vec::new());
                }
                let mut res = Vec::new();
-               for file_option in fs::read_dir(path).unwrap() {
+               for file_option in fs::read_dir(path)? {
                        let file = file_option.unwrap();
                        let owned_file_name = file.file_name();
-                       let filename = owned_file_name.to_str();
-                       if !filename.is_some() || !filename.unwrap().is_ascii() || filename.unwrap().len() < 65 {
+                       let filename = owned_file_name.to_str()
+                               .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::InvalidData,
+                                       "File name is not a valid utf8 string"))?;
+                       if !filename.is_ascii() || filename.len() < 65 {
                                return Err(std::io::Error::new(
                                        std::io::ErrorKind::InvalidData,
                                        "Invalid ChannelMonitor file name",
                                ));
                        }
-                       if filename.unwrap().ends_with(".tmp") {
+                       if filename.ends_with(".tmp") {
                                // If we were in the middle of committing an new update and crashed, it should be
                                // safe to ignore the update - we should never have returned to the caller and
                                // irrevocably committed to the new state in any way.
                                continue;
                        }
 
-                       let txid = Txid::from_hex(filename.unwrap().split_at(64).0);
-                       if txid.is_err() {
-                               return Err(std::io::Error::new(
+                       let txid = Txid::from_hex(filename.split_at(64).0)
+                               .map_err(|_| std::io::Error::new(
                                        std::io::ErrorKind::InvalidData,
                                        "Invalid tx ID in filename",
-                               ));
-                       }
+                               ))?;
 
-                       let index = filename.unwrap().split_at(65).1.parse();
-                       if index.is_err() {
-                               return Err(std::io::Error::new(
+                       let index = filename.split_at(65).1.parse()
+                               .map_err(|_| std::io::Error::new(
                                        std::io::ErrorKind::InvalidData,
                                        "Invalid tx index in filename",
-                               ));
-                       }
+                               ))?;
 
                        let contents = fs::read(&file.path())?;
                        let mut buffer = Cursor::new(&contents);
-                       match <(BlockHash, ChannelMonitor<<K::Target as SignerProvider>::Signer>)>::read(&mut buffer, &*keys_manager) {
+                       match <(BlockHash, ChannelMonitor<<SP::Target as SignerProvider>::Signer>)>::read(&mut buffer, (&*entropy_source, &*signer_provider)) {
                                Ok((blockhash, channel_monitor)) => {
-                                       if channel_monitor.get_funding_txo().0.txid != txid.unwrap() || channel_monitor.get_funding_txo().0.index != index.unwrap() {
-                                               return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "ChannelMonitor was stored in the wrong file"));
+                                       if channel_monitor.get_funding_txo().0.txid != txid || channel_monitor.get_funding_txo().0.index != index {
+                                               return Err(std::io::Error::new(std::io::ErrorKind::InvalidData,
+                                                                              "ChannelMonitor was stored in the wrong file"));
                                        }
                                        res.push((blockhash, channel_monitor));
                                }
@@ -142,7 +143,6 @@ mod tests {
        use lightning::chain::chainmonitor::Persist;
        use lightning::chain::transaction::OutPoint;
        use lightning::{check_closed_broadcast, check_closed_event, check_added_monitors};
-       use lightning::ln::channelmanager;
        use lightning::ln::functional_test_utils::*;
        use lightning::util::events::{ClosureReason, MessageSendEventsProvider};
        use lightning::util::test_utils;
@@ -165,6 +165,27 @@ mod tests {
                }
        }
 
+       #[test]
+       fn test_if_monitors_is_not_dir() {
+               let persister = FilesystemPersister::new("test_monitors_is_not_dir".to_string());
+
+               fs::create_dir_all(&persister.path_to_channel_data).unwrap();
+               let mut path = std::path::PathBuf::from(&persister.path_to_channel_data);
+               path.push("monitors");
+               fs::File::create(path).unwrap();
+
+               let chanmon_cfgs = create_chanmon_cfgs(1);
+               let mut node_cfgs = create_node_cfgs(1, &chanmon_cfgs);
+               let chain_mon_0 = test_utils::TestChainMonitor::new(Some(&chanmon_cfgs[0].chain_source), &chanmon_cfgs[0].tx_broadcaster, &chanmon_cfgs[0].logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
+               node_cfgs[0].chain_monitor = chain_mon_0;
+               let node_chanmgrs = create_node_chanmgrs(1, &node_cfgs, &[None]);
+               let nodes = create_network(1, &node_cfgs, &node_chanmgrs);
+
+               // Check that read_channelmonitors() returns error if monitors/ is not a
+               // directory.
+               assert!(persister.read_channelmonitors(nodes[0].keys_manager, nodes[0].keys_manager).is_err());
+       }
+
        // Integration-test the FilesystemPersister. Test relaying a few payments
        // and check that the persisted data is updated the appropriate number of
        // times.
@@ -184,20 +205,20 @@ mod tests {
 
                // Check that the persisted channel data is empty before any channels are
                // open.
-               let mut persisted_chan_data_0 = persister_0.read_channelmonitors(nodes[0].keys_manager).unwrap();
+               let mut persisted_chan_data_0 = persister_0.read_channelmonitors(nodes[0].keys_manager, nodes[0].keys_manager).unwrap();
                assert_eq!(persisted_chan_data_0.len(), 0);
-               let mut persisted_chan_data_1 = persister_1.read_channelmonitors(nodes[1].keys_manager).unwrap();
+               let mut persisted_chan_data_1 = persister_1.read_channelmonitors(nodes[1].keys_manager, nodes[1].keys_manager).unwrap();
                assert_eq!(persisted_chan_data_1.len(), 0);
 
                // Helper to make sure the channel is on the expected update ID.
                macro_rules! check_persisted_data {
                        ($expected_update_id: expr) => {
-                               persisted_chan_data_0 = persister_0.read_channelmonitors(nodes[0].keys_manager).unwrap();
+                               persisted_chan_data_0 = persister_0.read_channelmonitors(nodes[0].keys_manager, nodes[0].keys_manager).unwrap();
                                assert_eq!(persisted_chan_data_0.len(), 1);
                                for (_, mon) in persisted_chan_data_0.iter() {
                                        assert_eq!(mon.get_latest_update_id(), $expected_update_id);
                                }
-                               persisted_chan_data_1 = persister_1.read_channelmonitors(nodes[1].keys_manager).unwrap();
+                               persisted_chan_data_1 = persister_1.read_channelmonitors(nodes[1].keys_manager, nodes[1].keys_manager).unwrap();
                                assert_eq!(persisted_chan_data_1.len(), 1);
                                for (_, mon) in persisted_chan_data_1.iter() {
                                        assert_eq!(mon.get_latest_update_id(), $expected_update_id);
@@ -206,7 +227,7 @@ mod tests {
                }
 
                // Create some initial channel and check that a channel was persisted.
-               let _ = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let _ = create_announced_chan_between_nodes(&nodes, 0, 1);
                check_persisted_data!(0);
 
                // Send a few payments and make sure the monitors are updated to the latest.
@@ -250,7 +271,7 @@ mod tests {
                let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
                let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-               let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
                nodes[1].node.force_close_broadcasting_latest_txn(&chan.2, &nodes[0].node.get_our_node_id()).unwrap();
                check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed);
                let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap();
@@ -289,7 +310,7 @@ mod tests {
                let mut node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
                let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-               let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
                nodes[1].node.force_close_broadcasting_latest_txn(&chan.2, &nodes[0].node.get_our_node_id()).unwrap();
                check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed);
                let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap();
index 06ce7eb2075574df38c2b9cbf44813235e1fba1c..af235b1c4224d990f2a1d71881ab23e659d61e28 100644 (file)
@@ -53,9 +53,8 @@
 //! # }
 //! # let logger = FakeLogger {};
 //!
-//! let block_hash = genesis_block(Network::Bitcoin).header.block_hash();
-//! let network_graph = NetworkGraph::new(block_hash, &logger);
-//! let rapid_sync = RapidGossipSync::new(&network_graph);
+//! let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
+//! let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
 //! let snapshot_contents: &[u8] = &[0; 0];
 //! let new_last_sync_timestamp_result = rapid_sync.update_network_graph(snapshot_contents);
 //! ```
@@ -95,14 +94,16 @@ mod processing;
 pub struct RapidGossipSync<NG: Deref<Target=NetworkGraph<L>>, L: Deref>
 where L::Target: Logger {
        network_graph: NG,
+       logger: L,
        is_initial_sync_complete: AtomicBool
 }
 
 impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L::Target: Logger {
        /// Instantiate a new [`RapidGossipSync`] instance.
-       pub fn new(network_graph: NG) -> Self {
+       pub fn new(network_graph: NG, logger: L) -> Self {
                Self {
                        network_graph,
+                       logger,
                        is_initial_sync_complete: AtomicBool::new(false)
                }
        }
@@ -126,14 +127,22 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
        /// Update network graph from binary data.
        /// Returns the last sync timestamp to be used the next time rapid sync data is queried.
        ///
-       /// `network_graph`: network graph to be updated
-       ///
        /// `update_data`: `&[u8]` binary stream that comprises the update data
        pub fn update_network_graph(&self, update_data: &[u8]) -> Result<u32, GraphSyncError> {
                let mut read_cursor = io::Cursor::new(update_data);
                self.update_network_graph_from_byte_stream(&mut read_cursor)
        }
 
+       /// Update network graph from binary data.
+       /// Returns the last sync timestamp to be used the next time rapid sync data is queried.
+       ///
+       /// `update_data`: `&[u8]` binary stream that comprises the update data
+       /// `current_time_unix`: `Option<u64>` optional current timestamp to verify data age
+       pub fn update_network_graph_no_std(&self, update_data: &[u8], current_time_unix: Option<u64>) -> Result<u32, GraphSyncError> {
+               let mut read_cursor = io::Cursor::new(update_data);
+               self.update_network_graph_from_byte_stream_no_std(&mut read_cursor, current_time_unix)
+       }
+
        /// Gets a reference to the underlying [`NetworkGraph`] which was provided in
        /// [`RapidGossipSync::new`].
        ///
@@ -153,7 +162,6 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
 mod tests {
        use std::fs;
 
-       use bitcoin::blockdata::constants::genesis_block;
        use bitcoin::Network;
 
        use lightning::ln::msgs::DecodeError;
@@ -217,13 +225,12 @@ mod tests {
                let sync_test = FileSyncTest::new(tmp_directory, &valid_response);
                let graph_sync_test_file = sync_test.get_test_file_path();
 
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
-               let network_graph = NetworkGraph::new(block_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
 
                assert_eq!(network_graph.read_only().channels().len(), 0);
 
-               let rapid_sync = RapidGossipSync::new(&network_graph);
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
                let sync_result = rapid_sync.sync_network_graph_with_file_path(&graph_sync_test_file);
 
                if sync_result.is_err() {
@@ -250,13 +257,12 @@ mod tests {
 
        #[test]
        fn measure_native_read_from_file() {
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
-               let network_graph = NetworkGraph::new(block_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
 
                assert_eq!(network_graph.read_only().channels().len(), 0);
 
-               let rapid_sync = RapidGossipSync::new(&network_graph);
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
                let start = std::time::Instant::now();
                let sync_result = rapid_sync
                        .sync_network_graph_with_file_path("./res/full_graph.lngossip");
@@ -282,7 +288,6 @@ mod tests {
 pub mod bench {
        use test::Bencher;
 
-       use bitcoin::blockdata::constants::genesis_block;
        use bitcoin::Network;
 
        use lightning::ln::msgs::DecodeError;
@@ -293,11 +298,10 @@ pub mod bench {
 
        #[bench]
        fn bench_reading_full_graph_from_file(b: &mut Bencher) {
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
                b.iter(|| {
-                       let network_graph = NetworkGraph::new(block_hash, &logger);
-                       let rapid_sync = RapidGossipSync::new(&network_graph);
+                       let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
+                       let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
                        let sync_result = rapid_sync.sync_network_graph_with_file_path("./res/full_graph.lngossip");
                        if let Err(crate::error::GraphSyncError::DecodeError(DecodeError::Io(io_error))) = &sync_result {
                                let error_string = format!("Input file lightning-rapid-gossip-sync/res/full_graph.lngossip is missing! Download it from https://bitcoin.ninja/ldk-compressed_graph-bc08df7542-2022-05-05.bin\n\n{:?}", io_error);
index 3e001ec45c4be1aa7becbaa6da9f9158f3d217fa..8d36dfe38844f75d189e4c27896b3f3a4d3e4891 100644 (file)
@@ -10,12 +10,16 @@ use lightning::ln::msgs::{
 };
 use lightning::routing::gossip::NetworkGraph;
 use lightning::util::logger::Logger;
+use lightning::{log_warn, log_trace, log_given_level};
 use lightning::util::ser::{BigSize, Readable};
 use lightning::io;
 
 use crate::error::GraphSyncError;
 use crate::RapidGossipSync;
 
+#[cfg(all(feature = "std", not(test)))]
+use std::time::{SystemTime, UNIX_EPOCH};
+
 #[cfg(not(feature = "std"))]
 use alloc::{vec::Vec, borrow::ToOwned};
 
@@ -29,10 +33,30 @@ const GOSSIP_PREFIX: [u8; 4] = [76, 68, 75, 1];
 /// avoid malicious updates being able to trigger excessive memory allocation.
 const MAX_INITIAL_NODE_ID_VECTOR_CAPACITY: u32 = 50_000;
 
+/// We disallow gossip data that's more than two weeks old, per BOLT 7's
+/// suggestion.
+const STALE_RGS_UPDATE_AGE_LIMIT_SECS: u64 = 60 * 60 * 24 * 14;
+
 impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L::Target: Logger {
        pub(crate) fn update_network_graph_from_byte_stream<R: io::Read>(
+               &self,
+               read_cursor: &mut R,
+       ) -> Result<u32, GraphSyncError> {
+               #[allow(unused_mut, unused_assignments)]
+               let mut current_time_unix = None;
+               #[cfg(all(feature = "std", not(test)))]
+               {
+                       // Note that many tests rely on being able to set arbitrarily old timestamps, thus we
+                       // disable this check during tests!
+                       current_time_unix = Some(SystemTime::now().duration_since(UNIX_EPOCH).expect("Time must be > 1970").as_secs());
+               }
+               self.update_network_graph_from_byte_stream_no_std(read_cursor, current_time_unix)
+       }
+
+       pub(crate) fn update_network_graph_from_byte_stream_no_std<R: io::Read>(
                &self,
                mut read_cursor: &mut R,
+               current_time_unix: Option<u64>
        ) -> Result<u32, GraphSyncError> {
                let mut prefix = [0u8; 4];
                read_cursor.read_exact(&mut prefix)?;
@@ -43,6 +67,13 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
 
                let chain_hash: BlockHash = Readable::read(read_cursor)?;
                let latest_seen_timestamp: u32 = Readable::read(read_cursor)?;
+
+               if let Some(time) = current_time_unix {
+                       if (latest_seen_timestamp as u64) < time.saturating_sub(STALE_RGS_UPDATE_AGE_LIMIT_SECS) {
+                               return Err(LightningError{err: "Rapid Gossip Sync data is more than two weeks old".to_owned(), action: ErrorAction::IgnoreError}.into());
+                       }
+               }
+
                // backdate the applied timestamp by a week
                let backdated_timestamp = latest_seen_timestamp.saturating_sub(24 * 3600 * 7);
 
@@ -90,6 +121,7 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
                                if let ErrorAction::IgnoreDuplicateGossip = lightning_error.action {
                                        // everything is fine, just a duplicate channel announcement
                                } else {
+                                       log_warn!(self.logger, "Failed to process channel announcement: {:?}", lightning_error);
                                        return Err(lightning_error.into());
                                }
                        }
@@ -139,24 +171,19 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
                        if (channel_flags & 0b_1000_0000) != 0 {
                                // incremental update, field flags will indicate mutated values
                                let read_only_network_graph = network_graph.read_only();
-                               if let Some(channel) = read_only_network_graph
-                                       .channels()
-                                       .get(&short_channel_id) {
-
-                                       let directional_info = channel
-                                               .get_directional_info(channel_flags)
-                                               .ok_or(LightningError {
-                                                       err: "Couldn't find previous directional data for update".to_owned(),
-                                                       action: ErrorAction::IgnoreError,
-                                               })?;
-
+                               if let Some(directional_info) =
+                                       read_only_network_graph.channels().get(&short_channel_id)
+                                       .and_then(|channel| channel.get_directional_info(channel_flags))
+                               {
                                        synthetic_update.cltv_expiry_delta = directional_info.cltv_expiry_delta;
                                        synthetic_update.htlc_minimum_msat = directional_info.htlc_minimum_msat;
                                        synthetic_update.htlc_maximum_msat = directional_info.htlc_maximum_msat;
                                        synthetic_update.fee_base_msat = directional_info.fees.base_msat;
                                        synthetic_update.fee_proportional_millionths = directional_info.fees.proportional_millionths;
-
                                } else {
+                                       log_trace!(self.logger,
+                                               "Skipping application of channel update for chan {} with flags {} as original data is missing.",
+                                               short_channel_id, channel_flags);
                                        skip_update_for_unknown_channel = true;
                                }
                        };
@@ -193,7 +220,9 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
                        match network_graph.update_channel_unsigned(&synthetic_update) {
                                Ok(_) => {},
                                Err(LightningError { action: ErrorAction::IgnoreDuplicateGossip, .. }) => {},
-                               Err(LightningError { action: ErrorAction::IgnoreAndLog(_), .. }) => {},
+                               Err(LightningError { action: ErrorAction::IgnoreAndLog(level), err }) => {
+                                       log_given_level!(self.logger, level, "Failed to apply channel update: {:?}", err);
+                               },
                                Err(LightningError { action: ErrorAction::IgnoreError, .. }) => {},
                                Err(e) => return Err(e.into()),
                        }
@@ -207,7 +236,6 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
 
 #[cfg(test)]
 mod tests {
-       use bitcoin::blockdata::constants::genesis_block;
        use bitcoin::Network;
 
        use lightning::ln::msgs::DecodeError;
@@ -215,13 +243,32 @@ mod tests {
        use lightning::util::test_utils::TestLogger;
 
        use crate::error::GraphSyncError;
+       use crate::processing::STALE_RGS_UPDATE_AGE_LIMIT_SECS;
        use crate::RapidGossipSync;
 
+       const VALID_RGS_BINARY: [u8; 300] = [
+               76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
+               79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
+               0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
+               187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
+               157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
+               88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
+               204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
+               181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
+               110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
+               76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
+               226, 0, 6, 11, 0, 1, 2, 3, 0, 0, 0, 4, 0, 40, 0, 0, 0, 0, 0, 0, 3, 232, 0, 0, 3, 232,
+               0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
+               0, 0, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 2, 224, 0, 0, 0, 0, 58, 85, 116, 216, 0, 29, 0,
+               0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
+               0, 0, 1,
+       ];
+       const VALID_BINARY_TIMESTAMP: u64 = 1642291930;
+
        #[test]
        fn network_graph_fails_to_update_from_clipped_input() {
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
-               let network_graph = NetworkGraph::new(block_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
 
                let example_input = vec![
                        76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
@@ -239,7 +286,7 @@ mod tests {
                        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1, 24, 0,
                        0, 3, 232, 0, 0, 0,
                ];
-               let rapid_sync = RapidGossipSync::new(&network_graph);
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
                let update_result = rapid_sync.update_network_graph(&example_input[..]);
                assert!(update_result.is_err());
                if let Err(GraphSyncError::DecodeError(DecodeError::ShortRead)) = update_result {
@@ -259,13 +306,12 @@ mod tests {
                        68, 226, 0, 6, 11, 0, 1, 128,
                ];
 
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
-               let network_graph = NetworkGraph::new(block_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
 
                assert_eq!(network_graph.read_only().channels().len(), 0);
 
-               let rapid_sync = RapidGossipSync::new(&network_graph);
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
                let update_result = rapid_sync.update_network_graph(&incremental_update_input[..]);
                assert!(update_result.is_ok());
        }
@@ -288,23 +334,13 @@ mod tests {
                        2, 68, 226, 0, 6, 11, 0, 1, 128,
                ];
 
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
-               let network_graph = NetworkGraph::new(block_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
 
                assert_eq!(network_graph.read_only().channels().len(), 0);
 
-               let rapid_sync = RapidGossipSync::new(&network_graph);
-               let update_result = rapid_sync.update_network_graph(&announced_update_input[..]);
-               assert!(update_result.is_err());
-               if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
-                       assert_eq!(
-                               lightning_error.err,
-                               "Couldn't find previous directional data for update"
-                       );
-               } else {
-                       panic!("Unexpected update result: {:?}", update_result)
-               }
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
+               rapid_sync.update_network_graph(&announced_update_input[..]).unwrap();
        }
 
        #[test]
@@ -325,13 +361,12 @@ mod tests {
                        0, 1, 0, 0, 0, 125, 255, 2, 68, 226, 0, 6, 11, 0, 1, 5, 0, 0, 0, 0, 29, 129, 25, 192,
                ];
 
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
-               let network_graph = NetworkGraph::new(block_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
 
                assert_eq!(network_graph.read_only().channels().len(), 0);
 
-               let rapid_sync = RapidGossipSync::new(&network_graph);
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
                let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
                if initialization_result.is_err() {
                        panic!(
@@ -360,16 +395,7 @@ mod tests {
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 136, 0, 0, 0, 221, 255, 2,
                        68, 226, 0, 6, 11, 0, 1, 128,
                ];
-               let update_result = rapid_sync.update_network_graph(&opposite_direction_incremental_update_input[..]);
-               assert!(update_result.is_err());
-               if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
-                       assert_eq!(
-                               lightning_error.err,
-                               "Couldn't find previous directional data for update"
-                       );
-               } else {
-                       panic!("Unexpected update result: {:?}", update_result)
-               }
+               rapid_sync.update_network_graph(&opposite_direction_incremental_update_input[..]).unwrap();
        }
 
        #[test]
@@ -392,13 +418,12 @@ mod tests {
                        25, 192,
                ];
 
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
-               let network_graph = NetworkGraph::new(block_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
 
                assert_eq!(network_graph.read_only().channels().len(), 0);
 
-               let rapid_sync = RapidGossipSync::new(&network_graph);
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
                let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
                assert!(initialization_result.is_ok());
 
@@ -452,13 +477,12 @@ mod tests {
                        25, 192,
                ];
 
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
-               let network_graph = NetworkGraph::new(block_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
 
                assert_eq!(network_graph.read_only().channels().len(), 0);
 
-               let rapid_sync = RapidGossipSync::new(&network_graph);
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
                let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
                assert!(initialization_result.is_ok());
 
@@ -478,32 +502,13 @@ mod tests {
 
        #[test]
        fn full_update_succeeds() {
-               let valid_input = vec![
-                       76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
-                       79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
-                       0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
-                       187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
-                       157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
-                       88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
-                       204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
-                       181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
-                       110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
-                       76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
-                       226, 0, 6, 11, 0, 1, 2, 3, 0, 0, 0, 4, 0, 40, 0, 0, 0, 0, 0, 0, 3, 232, 0, 0, 3, 232,
-                       0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
-                       0, 0, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 2, 224, 0, 0, 0, 0, 58, 85, 116, 216, 0, 29, 0,
-                       0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
-                       0, 0, 1,
-               ];
-
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
-               let network_graph = NetworkGraph::new(block_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
 
                assert_eq!(network_graph.read_only().channels().len(), 0);
 
-               let rapid_sync = RapidGossipSync::new(&network_graph);
-               let update_result = rapid_sync.update_network_graph(&valid_input[..]);
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
+               let update_result = rapid_sync.update_network_graph(&VALID_RGS_BINARY);
                if update_result.is_err() {
                        panic!("Unexpected update result: {:?}", update_result)
                }
@@ -526,6 +531,56 @@ mod tests {
                assert!(after.contains("783241506229452801"));
        }
 
+       #[test]
+       fn full_update_succeeds_at_the_beginning_of_the_unix_era() {
+               let logger = TestLogger::new();
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
+
+               assert_eq!(network_graph.read_only().channels().len(), 0);
+
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
+               // this is mostly for checking uint underflow issues before the fuzzer does
+               let update_result = rapid_sync.update_network_graph_no_std(&VALID_RGS_BINARY, Some(0));
+               assert!(update_result.is_ok());
+               assert_eq!(network_graph.read_only().channels().len(), 2);
+       }
+
+       #[test]
+       fn timestamp_edge_cases_are_handled_correctly() {
+               // this is the timestamp encoded in the binary data of valid_input below
+               let logger = TestLogger::new();
+
+               let latest_succeeding_time = VALID_BINARY_TIMESTAMP + STALE_RGS_UPDATE_AGE_LIMIT_SECS;
+               let earliest_failing_time = latest_succeeding_time + 1;
+
+               {
+                       let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
+                       assert_eq!(network_graph.read_only().channels().len(), 0);
+
+                       let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
+                       let update_result = rapid_sync.update_network_graph_no_std(&VALID_RGS_BINARY, Some(latest_succeeding_time));
+                       assert!(update_result.is_ok());
+                       assert_eq!(network_graph.read_only().channels().len(), 2);
+               }
+
+               {
+                       let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
+                       assert_eq!(network_graph.read_only().channels().len(), 0);
+
+                       let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
+                       let update_result = rapid_sync.update_network_graph_no_std(&VALID_RGS_BINARY, Some(earliest_failing_time));
+                       assert!(update_result.is_err());
+                       if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
+                               assert_eq!(
+                                       lightning_error.err,
+                                       "Rapid Gossip Sync data is more than two weeks old"
+                               );
+                       } else {
+                               panic!("Unexpected update result: {:?}", update_result)
+                       }
+               }
+       }
+
        #[test]
        pub fn update_fails_with_unknown_version() {
                let unknown_version_input = vec![
@@ -546,10 +601,9 @@ mod tests {
                        0, 0, 1,
                ];
 
-               let block_hash = genesis_block(Network::Bitcoin).block_hash();
                let logger = TestLogger::new();
-               let network_graph = NetworkGraph::new(block_hash, &logger);
-               let rapid_sync = RapidGossipSync::new(&network_graph);
+               let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
                let update_result = rapid_sync.update_network_graph(&unknown_version_input[..]);
 
                assert!(update_result.is_err());
diff --git a/lightning-transaction-sync/Cargo.toml b/lightning-transaction-sync/Cargo.toml
new file mode 100644 (file)
index 0000000..9dfce6c
--- /dev/null
@@ -0,0 +1,34 @@
+[package]
+name = "lightning-transaction-sync"
+version = "0.0.113"
+authors = ["Elias Rohrer"]
+license = "MIT OR Apache-2.0"
+repository = "http://github.com/lightningdevkit/rust-lightning"
+description = """
+Utilities for syncing LDK via the transaction-based `Confirm` interface.
+"""
+edition = "2018"
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
+
+[features]
+default = []
+esplora-async = ["async-interface", "esplora-client/async", "futures"]
+esplora-blocking = ["esplora-client/blocking"]
+async-interface = []
+
+[dependencies]
+lightning = { version = "0.0.113", path = "../lightning", default-features = false }
+bitcoin = { version = "0.29.0", default-features = false }
+bdk-macros = "0.6"
+futures = { version = "0.3", optional = true }
+esplora-client = { version = "0.3.0", default-features = false, optional = true }
+
+[dev-dependencies]
+lightning = { version = "0.0.113", path = "../lightning", features = ["std"] }
+electrsd = { version = "0.22.0", features = ["legacy", "esplora_a33e97e1", "bitcoind_23_0"] }
+electrum-client = "0.12.0"
+once_cell = "1.16.0"
+tokio = { version = "1.14.0", features = ["full"] }
diff --git a/lightning-transaction-sync/src/common.rs b/lightning-transaction-sync/src/common.rs
new file mode 100644 (file)
index 0000000..a6ee61e
--- /dev/null
@@ -0,0 +1,75 @@
+use lightning::chain::WatchedOutput;
+use bitcoin::{Txid, BlockHash, Transaction, BlockHeader, OutPoint};
+
+use std::collections::{HashSet, HashMap};
+
+
+// Represents the current state.
+pub(crate) struct SyncState {
+       // Transactions that were previously processed, but must not be forgotten
+       // yet since they still need to be monitored for confirmation on-chain.
+       pub watched_transactions: HashSet<Txid>,
+       // Outputs that were previously processed, but must not be forgotten yet as
+       // as we still need to monitor any spends on-chain.
+       pub watched_outputs: HashMap<OutPoint, WatchedOutput>,
+       // The tip hash observed during our last sync.
+       pub last_sync_hash: Option<BlockHash>,
+       // Indicates whether we need to resync, e.g., after encountering an error.
+       pub pending_sync: bool,
+}
+
+impl SyncState {
+       pub fn new() -> Self {
+               Self {
+                       watched_transactions: HashSet::new(),
+                       watched_outputs: HashMap::new(),
+                       last_sync_hash: None,
+                       pending_sync: false,
+               }
+       }
+}
+
+
+// A queue that is to be filled by `Filter` and drained during the next syncing round.
+pub(crate) struct FilterQueue {
+       // Transactions that were registered via the `Filter` interface and have to be processed.
+       pub transactions: HashSet<Txid>,
+       // Outputs that were registered via the `Filter` interface and have to be processed.
+       pub outputs: HashMap<OutPoint, WatchedOutput>,
+}
+
+impl FilterQueue {
+       pub fn new() -> Self {
+               Self {
+                       transactions: HashSet::new(),
+                       outputs: HashMap::new(),
+               }
+       }
+
+       // Processes the transaction and output queues and adds them to the given [`SyncState`].
+       //
+       // Returns `true` if new items had been registered.
+       pub fn process_queues(&mut self, sync_state: &mut SyncState) -> bool {
+               let mut pending_registrations = false;
+
+               if !self.transactions.is_empty() {
+                       pending_registrations = true;
+
+                       sync_state.watched_transactions.extend(self.transactions.drain());
+               }
+
+               if !self.outputs.is_empty() {
+                       pending_registrations = true;
+
+                       sync_state.watched_outputs.extend(self.outputs.drain());
+               }
+               pending_registrations
+       }
+}
+
+pub(crate) struct ConfirmedTx {
+       pub tx: Transaction,
+       pub block_header: BlockHeader,
+       pub block_height: u32,
+       pub pos: usize,
+}
diff --git a/lightning-transaction-sync/src/error.rs b/lightning-transaction-sync/src/error.rs
new file mode 100644 (file)
index 0000000..73d9de7
--- /dev/null
@@ -0,0 +1,63 @@
+use std::fmt;
+
+#[derive(Debug)]
+/// An error that possibly needs to be handled by the user.
+pub enum TxSyncError {
+       /// A transaction sync failed and needs to be retried eventually.
+       Failed,
+}
+
+impl std::error::Error for TxSyncError {}
+
+impl fmt::Display for TxSyncError {
+       fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+               match *self {
+                       Self::Failed => write!(f, "Failed to conduct transaction sync."),
+               }
+       }
+}
+
+#[derive(Debug)]
+#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+pub(crate) enum InternalError {
+       /// A transaction sync failed and needs to be retried eventually.
+       Failed,
+       /// An inconsistency was encountered during transaction sync.
+       Inconsistency,
+}
+
+#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+impl fmt::Display for InternalError {
+       fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+               match *self {
+                       Self::Failed => write!(f, "Failed to conduct transaction sync."),
+                       Self::Inconsistency => {
+                               write!(f, "Encountered an inconsistency during transaction sync.")
+                       }
+               }
+       }
+}
+
+#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+impl std::error::Error for InternalError {}
+
+#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+impl From<esplora_client::Error> for TxSyncError {
+       fn from(_e: esplora_client::Error) -> Self {
+               Self::Failed
+       }
+}
+
+#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+impl From<esplora_client::Error> for InternalError {
+       fn from(_e: esplora_client::Error) -> Self {
+               Self::Failed
+       }
+}
+
+#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+impl From<InternalError> for TxSyncError {
+       fn from(_e: InternalError) -> Self {
+               Self::Failed
+       }
+}
diff --git a/lightning-transaction-sync/src/esplora.rs b/lightning-transaction-sync/src/esplora.rs
new file mode 100644 (file)
index 0000000..807ef80
--- /dev/null
@@ -0,0 +1,383 @@
+use crate::error::{TxSyncError, InternalError};
+use crate::common::{SyncState, FilterQueue, ConfirmedTx};
+
+use lightning::util::logger::Logger;
+use lightning::{log_error, log_given_level, log_info, log_internal, log_debug, log_trace};
+use lightning::chain::WatchedOutput;
+use lightning::chain::{Confirm, Filter};
+
+use bitcoin::{BlockHash, Script, Txid};
+
+use esplora_client::Builder;
+#[cfg(feature = "async-interface")]
+use esplora_client::r#async::AsyncClient;
+#[cfg(not(feature = "async-interface"))]
+use esplora_client::blocking::BlockingClient;
+
+use std::collections::HashSet;
+use core::ops::Deref;
+
+/// Synchronizes LDK with a given [`Esplora`] server.
+///
+/// Needs to be registered with a [`ChainMonitor`] via the [`Filter`] interface to be informed of
+/// transactions and outputs to monitor for on-chain confirmation, unconfirmation, and
+/// reconfirmation.
+///
+/// Note that registration via [`Filter`] needs to happen before any calls to
+/// [`Watch::watch_channel`] to ensure we get notified of the items to monitor.
+///
+/// This uses and exposes either a blocking or async client variant dependent on whether the
+/// `esplora-blocking` or the `esplora-async` feature is enabled.
+///
+/// [`Esplora`]: https://github.com/Blockstream/electrs
+/// [`ChainMonitor`]: lightning::chain::chainmonitor::ChainMonitor
+/// [`Watch::watch_channel`]: lightning::chain::Watch::watch_channel
+/// [`Filter`]: lightning::chain::Filter
+pub struct EsploraSyncClient<L: Deref>
+where
+       L::Target: Logger,
+{
+       sync_state: MutexType<SyncState>,
+       queue: std::sync::Mutex<FilterQueue>,
+       client: EsploraClientType,
+       logger: L,
+}
+
+impl<L: Deref> EsploraSyncClient<L>
+where
+       L::Target: Logger,
+{
+       /// Returns a new [`EsploraSyncClient`] object.
+       pub fn new(server_url: String, logger: L) -> Self {
+               let builder = Builder::new(&server_url);
+               #[cfg(not(feature = "async-interface"))]
+               let client = builder.build_blocking().unwrap();
+               #[cfg(feature = "async-interface")]
+               let client = builder.build_async().unwrap();
+
+               EsploraSyncClient::from_client(client, logger)
+       }
+
+       /// Returns a new [`EsploraSyncClient`] object using the given Esplora client.
+       pub fn from_client(client: EsploraClientType, logger: L) -> Self {
+               let sync_state = MutexType::new(SyncState::new());
+               let queue = std::sync::Mutex::new(FilterQueue::new());
+               Self {
+                       sync_state,
+                       queue,
+                       client,
+                       logger,
+               }
+       }
+
+       /// Synchronizes the given `confirmables` via their [`Confirm`] interface implementations. This
+       /// method should be called regularly to keep LDK up-to-date with current chain data.
+       ///
+       /// For example, instances of [`ChannelManager`] and [`ChainMonitor`] can be informed about the
+       /// newest on-chain activity related to the items previously registered via the [`Filter`]
+       /// interface.
+       ///
+       /// [`Confirm`]: lightning::chain::Confirm
+       /// [`ChainMonitor`]: lightning::chain::chainmonitor::ChainMonitor
+       /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
+       /// [`Filter`]: lightning::chain::Filter
+       #[maybe_async]
+       pub fn sync(&self, confirmables: Vec<&(dyn Confirm + Sync + Send)>) -> Result<(), TxSyncError> {
+               // This lock makes sure we're syncing once at a time.
+               #[cfg(not(feature = "async-interface"))]
+               let mut sync_state = self.sync_state.lock().unwrap();
+               #[cfg(feature = "async-interface")]
+               let mut sync_state = self.sync_state.lock().await;
+
+               log_info!(self.logger, "Starting transaction sync.");
+
+               let mut tip_hash = maybe_await!(self.client.get_tip_hash())?;
+
+               loop {
+                       let pending_registrations = self.queue.lock().unwrap().process_queues(&mut sync_state);
+                       let tip_is_new = Some(tip_hash) != sync_state.last_sync_hash;
+
+                       // We loop until any registered transactions have been processed at least once, or the
+                       // tip hasn't been updated during the last iteration.
+                       if !sync_state.pending_sync && !pending_registrations && !tip_is_new {
+                               // Nothing to do.
+                               break;
+                       } else {
+                               // Update the known tip to the newest one.
+                               if tip_is_new {
+                                       // First check for any unconfirmed transactions and act on it immediately.
+                                       match maybe_await!(self.get_unconfirmed_transactions(&confirmables)) {
+                                               Ok(unconfirmed_txs) => {
+                                                       // Double-check the tip hash. If it changed, a reorg happened since
+                                                       // we started syncing and we need to restart last-minute.
+                                                       let check_tip_hash = maybe_await!(self.client.get_tip_hash())?;
+                                                       if check_tip_hash != tip_hash {
+                                                               tip_hash = check_tip_hash;
+                                                               continue;
+                                                       }
+
+                                                       self.sync_unconfirmed_transactions(&mut sync_state, &confirmables, unconfirmed_txs);
+                                               },
+                                               Err(err) => {
+                                                       // (Semi-)permanent failure, retry later.
+                                                       log_error!(self.logger, "Failed during transaction sync, aborting.");
+                                                       sync_state.pending_sync = true;
+                                                       return Err(TxSyncError::from(err));
+                                               }
+                                       }
+
+                                       match maybe_await!(self.sync_best_block_updated(&confirmables, &tip_hash)) {
+                                               Ok(()) => {}
+                                               Err(InternalError::Inconsistency) => {
+                                                       // Immediately restart syncing when we encounter any inconsistencies.
+                                                       log_debug!(self.logger, "Encountered inconsistency during transaction sync, restarting.");
+                                                       sync_state.pending_sync = true;
+                                                       continue;
+                                               }
+                                               Err(err) => {
+                                                       // (Semi-)permanent failure, retry later.
+                                                       sync_state.pending_sync = true;
+                                                       return Err(TxSyncError::from(err));
+                                               }
+                                       }
+                               }
+
+                               match maybe_await!(self.get_confirmed_transactions(&sync_state)) {
+                                       Ok(confirmed_txs) => {
+                                               // Double-check the tip hash. If it changed, a reorg happened since
+                                               // we started syncing and we need to restart last-minute.
+                                               let check_tip_hash = maybe_await!(self.client.get_tip_hash())?;
+                                               if check_tip_hash != tip_hash {
+                                                       tip_hash = check_tip_hash;
+                                                       continue;
+                                               }
+
+                                               self.sync_confirmed_transactions(
+                                                       &mut sync_state,
+                                                       &confirmables,
+                                                       confirmed_txs,
+                                               );
+                                       }
+                                       Err(InternalError::Inconsistency) => {
+                                               // Immediately restart syncing when we encounter any inconsistencies.
+                                               log_debug!(self.logger, "Encountered inconsistency during transaction sync, restarting.");
+                                               sync_state.pending_sync = true;
+                                               continue;
+                                       }
+                                       Err(err) => {
+                                               // (Semi-)permanent failure, retry later.
+                                               log_error!(self.logger, "Failed during transaction sync, aborting.");
+                                               sync_state.pending_sync = true;
+                                               return Err(TxSyncError::from(err));
+                                       }
+                               }
+                               sync_state.last_sync_hash = Some(tip_hash);
+                               sync_state.pending_sync = false;
+                       }
+               }
+               log_info!(self.logger, "Finished transaction sync.");
+               Ok(())
+       }
+
+       #[maybe_async]
+       fn sync_best_block_updated(
+               &self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>, tip_hash: &BlockHash,
+       ) -> Result<(), InternalError> {
+
+               // Inform the interface of the new block.
+               let tip_header = maybe_await!(self.client.get_header_by_hash(tip_hash))?;
+               let tip_status = maybe_await!(self.client.get_block_status(&tip_hash))?;
+               if tip_status.in_best_chain {
+                       if let Some(tip_height) = tip_status.height {
+                               for c in confirmables {
+                                       c.best_block_updated(&tip_header, tip_height);
+                               }
+                       }
+               } else {
+                       return Err(InternalError::Inconsistency);
+               }
+               Ok(())
+       }
+
+       fn sync_confirmed_transactions(
+               &self, sync_state: &mut SyncState, confirmables: &Vec<&(dyn Confirm + Sync + Send)>, confirmed_txs: Vec<ConfirmedTx>,
+       ) {
+               for ctx in confirmed_txs {
+                       for c in confirmables {
+                               c.transactions_confirmed(
+                                       &ctx.block_header,
+                                       &[(ctx.pos, &ctx.tx)],
+                                       ctx.block_height,
+                               );
+                       }
+
+                       sync_state.watched_transactions.remove(&ctx.tx.txid());
+
+                       for input in &ctx.tx.input {
+                               sync_state.watched_outputs.remove(&input.previous_output);
+                       }
+               }
+       }
+
+       #[maybe_async]
+       fn get_confirmed_transactions(
+               &self, sync_state: &SyncState,
+       ) -> Result<Vec<ConfirmedTx>, InternalError> {
+
+               // First, check the confirmation status of registered transactions as well as the
+               // status of dependent transactions of registered outputs.
+
+               let mut confirmed_txs = Vec::new();
+
+               for txid in &sync_state.watched_transactions {
+                       if let Some(confirmed_tx) = maybe_await!(self.get_confirmed_tx(&txid, None, None))? {
+                               confirmed_txs.push(confirmed_tx);
+                       }
+               }
+
+               for (_, output) in &sync_state.watched_outputs {
+                       if let Some(output_status) = maybe_await!(self.client
+                               .get_output_status(&output.outpoint.txid, output.outpoint.index as u64))?
+                       {
+                               if let Some(spending_txid) = output_status.txid {
+                                       if let Some(spending_tx_status) = output_status.status {
+                                               if let Some(confirmed_tx) = maybe_await!(self
+                                                       .get_confirmed_tx(
+                                                               &spending_txid,
+                                                               spending_tx_status.block_hash,
+                                                               spending_tx_status.block_height,
+                                                       ))?
+                                               {
+                                                       confirmed_txs.push(confirmed_tx);
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               // Sort all confirmed transactions first by block height, then by in-block
+               // position, and finally feed them to the interface in order.
+               confirmed_txs.sort_unstable_by(|tx1, tx2| {
+                       tx1.block_height.cmp(&tx2.block_height).then_with(|| tx1.pos.cmp(&tx2.pos))
+               });
+
+               Ok(confirmed_txs)
+       }
+
+       #[maybe_async]
+       fn get_confirmed_tx(
+               &self, txid: &Txid, expected_block_hash: Option<BlockHash>, known_block_height: Option<u32>,
+       ) -> Result<Option<ConfirmedTx>, InternalError> {
+               if let Some(merkle_block) = maybe_await!(self.client.get_merkle_block(&txid))? {
+                       let block_header = merkle_block.header;
+                       let block_hash = block_header.block_hash();
+                       if let Some(expected_block_hash) = expected_block_hash {
+                               if expected_block_hash != block_hash {
+                                       log_trace!(self.logger, "Inconsistency: Tx {} expected in block {}, but is confirmed in {}", txid, expected_block_hash, block_hash);
+                                       return Err(InternalError::Inconsistency);
+                               }
+                       }
+
+                       let mut matches = Vec::new();
+                       let mut indexes = Vec::new();
+                       let _ = merkle_block.txn.extract_matches(&mut matches, &mut indexes);
+                       if indexes.len() != 1 || matches.len() != 1 || matches[0] != *txid {
+                               log_error!(self.logger, "Retrieved Merkle block for txid {} doesn't match expectations. This should not happen. Please verify server integrity.", txid);
+                               return Err(InternalError::Failed);
+                       }
+
+                       let pos = *indexes.get(0).ok_or(InternalError::Failed)? as usize;
+                       if let Some(tx) = maybe_await!(self.client.get_tx(&txid))? {
+                               if let Some(block_height) = known_block_height {
+                                       // We can take a shortcut here if a previous call already gave us the height.
+                                       return Ok(Some(ConfirmedTx { tx, block_header, pos, block_height }));
+                               }
+
+                               let block_status = maybe_await!(self.client.get_block_status(&block_hash))?;
+                               if let Some(block_height) = block_status.height {
+                                       return Ok(Some(ConfirmedTx { tx, block_header, pos, block_height }));
+                               } else {
+                                       // If any previously-confirmed block suddenly is no longer confirmed, we found
+                                       // an inconsistency and should start over.
+                                       log_trace!(self.logger, "Inconsistency: Tx {} was unconfirmed during syncing.", txid);
+                                       return Err(InternalError::Inconsistency);
+                               }
+                       }
+               }
+               Ok(None)
+       }
+
+       #[maybe_async]
+       fn get_unconfirmed_transactions(
+               &self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>,
+       ) -> Result<Vec<Txid>, InternalError> {
+               // Query the interface for relevant txids and check whether the relevant blocks are still
+               // in the best chain, mark them unconfirmed otherwise
+               let relevant_txids = confirmables
+                       .iter()
+                       .flat_map(|c| c.get_relevant_txids())
+                       .collect::<HashSet<(Txid, Option<BlockHash>)>>();
+
+               let mut unconfirmed_txs = Vec::new();
+
+               for (txid, block_hash_opt) in relevant_txids {
+                       if let Some(block_hash) = block_hash_opt {
+                               let block_status = maybe_await!(self.client.get_block_status(&block_hash))?;
+                               if block_status.in_best_chain {
+                                       // Skip if the block in question is still confirmed.
+                                       continue;
+                               }
+
+                               unconfirmed_txs.push(txid);
+                       } else {
+                               log_error!(self.logger, "Untracked confirmation of funding transaction. Please ensure none of your channels had been created with LDK prior to version 0.0.113!");
+                               panic!("Untracked confirmation of funding transaction. Please ensure none of your channels had been created with LDK prior to version 0.0.113!");
+                       }
+               }
+               Ok(unconfirmed_txs)
+       }
+
+       fn sync_unconfirmed_transactions(
+               &self, sync_state: &mut SyncState, confirmables: &Vec<&(dyn Confirm + Sync + Send)>, unconfirmed_txs: Vec<Txid>,
+       ) {
+               for txid in unconfirmed_txs {
+                       for c in confirmables {
+                               c.transaction_unconfirmed(&txid);
+                       }
+
+                       sync_state.watched_transactions.insert(txid);
+               }
+       }
+
+       /// Returns a reference to the underlying esplora client.
+       pub fn client(&self) -> &EsploraClientType {
+               &self.client
+       }
+}
+
+#[cfg(feature = "async-interface")]
+type MutexType<I> = futures::lock::Mutex<I>;
+#[cfg(not(feature = "async-interface"))]
+type MutexType<I> = std::sync::Mutex<I>;
+
+// The underlying client type.
+#[cfg(feature = "async-interface")]
+type EsploraClientType = AsyncClient;
+#[cfg(not(feature = "async-interface"))]
+type EsploraClientType = BlockingClient;
+
+
+impl<L: Deref> Filter for EsploraSyncClient<L>
+where
+       L::Target: Logger,
+{
+       fn register_tx(&self, txid: &Txid, _script_pubkey: &Script) {
+               let mut locked_queue = self.queue.lock().unwrap();
+               locked_queue.transactions.insert(*txid);
+       }
+
+       fn register_output(&self, output: WatchedOutput) {
+               let mut locked_queue = self.queue.lock().unwrap();
+               locked_queue.outputs.insert(output.outpoint.into_bitcoin_outpoint(), output);
+       }
+}
diff --git a/lightning-transaction-sync/src/lib.rs b/lightning-transaction-sync/src/lib.rs
new file mode 100644 (file)
index 0000000..791490d
--- /dev/null
@@ -0,0 +1,82 @@
+//! Provides utilities for syncing LDK via the transaction-based [`Confirm`] interface.
+//!
+//! The provided synchronization clients need to be registered with a [`ChainMonitor`] via the
+//! [`Filter`] interface. Then, the respective `fn sync` needs to be called with the [`Confirm`]
+//! implementations to be synchronized, i.e., usually instances of [`ChannelManager`] and
+//! [`ChainMonitor`].
+//!
+//! ## Features and Backend Support
+//!
+//!- `esplora_blocking` enables syncing against an Esplora backend based on a blocking client.
+//!- `esplora_async` enables syncing against an Esplora backend based on an async client.
+//!
+//! ## Version Compatibility
+//!
+//! Currently this crate is compatible with nodes that were created with LDK version 0.0.113 and above.
+//!
+//! ## Usage Example:
+//!
+//! ```ignore
+//! let tx_sync = Arc::new(EsploraSyncClient::new(
+//!    esplora_server_url,
+//!    Arc::clone(&some_logger),
+//! ));
+//!
+//! let chain_monitor = Arc::new(ChainMonitor::new(
+//!    Some(Arc::clone(&tx_sync)),
+//!    Arc::clone(&some_broadcaster),
+//!    Arc::clone(&some_logger),
+//!    Arc::clone(&some_fee_estimator),
+//!    Arc::clone(&some_persister),
+//! ));
+//!
+//! let channel_manager = Arc::new(ChannelManager::new(
+//!    Arc::clone(&some_fee_estimator),
+//!    Arc::clone(&chain_monitor),
+//!    Arc::clone(&some_broadcaster),
+//!    Arc::clone(&some_router),
+//!    Arc::clone(&some_logger),
+//!    Arc::clone(&some_entropy_source),
+//!    Arc::clone(&some_node_signer),
+//!    Arc::clone(&some_signer_provider),
+//!    user_config,
+//!    chain_params,
+//! ));
+//!
+//! let confirmables = vec![
+//!    &*channel_manager as &(dyn Confirm + Sync + Send),
+//!    &*chain_monitor as &(dyn Confirm + Sync + Send),
+//! ];
+//!
+//! tx_sync.sync(confirmables).unwrap();
+//! ```
+//!
+//! [`Confirm`]: lightning::chain::Confirm
+//! [`Filter`]: lightning::chain::Filter
+//! [`ChainMonitor`]: lightning::chain::chainmonitor::ChainMonitor
+//! [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
+
+// Prefix these with `rustdoc::` when we update our MSRV to be >= 1.52 to remove warnings.
+#![deny(broken_intra_doc_links)]
+#![deny(private_intra_doc_links)]
+
+#![deny(missing_docs)]
+#![deny(unsafe_code)]
+
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+#[macro_use]
+extern crate bdk_macros;
+
+#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+mod esplora;
+
+#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+mod common;
+
+mod error;
+pub use error::TxSyncError;
+
+#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+pub use esplora::EsploraSyncClient;
diff --git a/lightning-transaction-sync/tests/integration_tests.rs b/lightning-transaction-sync/tests/integration_tests.rs
new file mode 100644 (file)
index 0000000..276aeab
--- /dev/null
@@ -0,0 +1,350 @@
+#![cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
+use lightning_transaction_sync::EsploraSyncClient;
+use lightning::chain::{Confirm, Filter};
+use lightning::chain::transaction::TransactionData;
+use lightning::util::logger::{Logger, Record};
+
+use electrsd::{bitcoind, bitcoind::BitcoinD, ElectrsD};
+use bitcoin::{Amount, Txid, BlockHash, BlockHeader};
+use bitcoin::blockdata::constants::genesis_block;
+use bitcoin::network::constants::Network;
+use electrsd::bitcoind::bitcoincore_rpc::bitcoincore_rpc_json::AddressType;
+use bitcoind::bitcoincore_rpc::RpcApi;
+use electrum_client::ElectrumApi;
+
+use once_cell::sync::OnceCell;
+
+use std::env;
+use std::sync::Mutex;
+use std::time::Duration;
+use std::collections::{HashMap, HashSet};
+
+static BITCOIND: OnceCell<BitcoinD> = OnceCell::new();
+static ELECTRSD: OnceCell<ElectrsD> = OnceCell::new();
+static PREMINE: OnceCell<()> = OnceCell::new();
+static MINER_LOCK: OnceCell<Mutex<()>> = OnceCell::new();
+
+fn get_bitcoind() -> &'static BitcoinD {
+       BITCOIND.get_or_init(|| {
+               let bitcoind_exe =
+                       env::var("BITCOIND_EXE").ok().or_else(|| bitcoind::downloaded_exe_path().ok()).expect(
+                               "you need to provide an env var BITCOIND_EXE or specify a bitcoind version feature",
+                               );
+               let mut conf = bitcoind::Conf::default();
+               conf.network = "regtest";
+               let bitcoind = BitcoinD::with_conf(bitcoind_exe, &conf).unwrap();
+               std::thread::sleep(Duration::from_secs(1));
+               bitcoind
+       })
+}
+
+fn get_electrsd() -> &'static ElectrsD {
+       ELECTRSD.get_or_init(|| {
+               let bitcoind = get_bitcoind();
+               let electrs_exe =
+                       env::var("ELECTRS_EXE").ok().or_else(electrsd::downloaded_exe_path).expect(
+                               "you need to provide env var ELECTRS_EXE or specify an electrsd version feature",
+                       );
+               let mut conf = electrsd::Conf::default();
+               conf.http_enabled = true;
+               conf.network = "regtest";
+               let electrsd = ElectrsD::with_conf(electrs_exe, &bitcoind, &conf).unwrap();
+               std::thread::sleep(Duration::from_secs(1));
+               electrsd
+       })
+}
+
+fn generate_blocks_and_wait(num: usize) {
+       let miner_lock = MINER_LOCK.get_or_init(|| Mutex::new(()));
+       let _miner = miner_lock.lock().unwrap();
+       let cur_height = get_bitcoind().client.get_block_count().expect("failed to get current block height");
+       let address = get_bitcoind().client.get_new_address(Some("test"), Some(AddressType::Legacy)).expect("failed to get new address");
+       // TODO: expect this Result once the WouldBlock issue is resolved upstream.
+       let _block_hashes_res = get_bitcoind().client.generate_to_address(num as u64, &address);
+       wait_for_block(cur_height as usize + num);
+}
+
+fn wait_for_block(min_height: usize) {
+       let mut header = match get_electrsd().client.block_headers_subscribe() {
+               Ok(header) => header,
+               Err(_) => {
+                       // While subscribing should succeed the first time around, we ran into some cases where
+                       // it didn't. Since we can't proceed without subscribing, we try again after a delay
+                       // and panic if it still fails.
+                       std::thread::sleep(Duration::from_secs(1));
+                       get_electrsd().client.block_headers_subscribe().expect("failed to subscribe to block headers")
+               }
+       };
+
+       loop {
+               if header.height >= min_height {
+                       break;
+               }
+               header = exponential_backoff_poll(|| {
+                       get_electrsd().trigger().expect("failed to trigger electrsd");
+                       get_electrsd().client.ping().expect("failed to ping electrsd");
+                       get_electrsd().client.block_headers_pop().expect("failed to pop block header")
+               });
+       }
+}
+
+fn exponential_backoff_poll<T, F>(mut poll: F) -> T
+where
+       F: FnMut() -> Option<T>,
+{
+       let mut delay = Duration::from_millis(64);
+       let mut tries = 0;
+       loop {
+               match poll() {
+                       Some(data) => break data,
+                       None if delay.as_millis() < 512 => {
+                               delay = delay.mul_f32(2.0);
+                               tries += 1;
+                       }
+                       None if tries == 10 => panic!("Exceeded our maximum wait time."),
+                       None => tries += 1,
+               }
+
+               std::thread::sleep(delay);
+       }
+}
+
+fn premine() {
+       PREMINE.get_or_init(|| {
+               generate_blocks_and_wait(101);
+       });
+}
+
+#[derive(Debug)]
+enum TestConfirmableEvent {
+       Confirmed(Txid, BlockHash, u32),
+       Unconfirmed(Txid),
+       BestBlockUpdated(BlockHash, u32),
+}
+
+struct TestConfirmable {
+       pub confirmed_txs: Mutex<HashMap<Txid, (BlockHash, u32)>>,
+       pub unconfirmed_txs: Mutex<HashSet<Txid>>,
+       pub best_block: Mutex<(BlockHash, u32)>,
+       pub events: Mutex<Vec<TestConfirmableEvent>>,
+}
+
+impl TestConfirmable {
+       pub fn new() -> Self {
+               let genesis_hash = genesis_block(Network::Regtest).block_hash();
+               Self {
+                       confirmed_txs: Mutex::new(HashMap::new()),
+                       unconfirmed_txs: Mutex::new(HashSet::new()),
+                       best_block: Mutex::new((genesis_hash, 0)),
+                       events: Mutex::new(Vec::new()),
+               }
+       }
+}
+
+impl Confirm for TestConfirmable {
+       fn transactions_confirmed(&self, header: &BlockHeader, txdata: &TransactionData<'_>, height: u32) {
+               for (_, tx) in txdata {
+                       let txid = tx.txid();
+                       let block_hash = header.block_hash();
+                       self.confirmed_txs.lock().unwrap().insert(txid, (block_hash, height));
+                       self.unconfirmed_txs.lock().unwrap().remove(&txid);
+                       self.events.lock().unwrap().push(TestConfirmableEvent::Confirmed(txid, block_hash, height));
+               }
+       }
+
+       fn transaction_unconfirmed(&self, txid: &Txid) {
+               self.unconfirmed_txs.lock().unwrap().insert(*txid);
+               self.confirmed_txs.lock().unwrap().remove(txid);
+               self.events.lock().unwrap().push(TestConfirmableEvent::Unconfirmed(*txid));
+       }
+
+       fn best_block_updated(&self, header: &BlockHeader, height: u32) {
+               let block_hash = header.block_hash();
+               *self.best_block.lock().unwrap() = (block_hash, height);
+               self.events.lock().unwrap().push(TestConfirmableEvent::BestBlockUpdated(block_hash, height));
+       }
+
+       fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)> {
+               self.confirmed_txs.lock().unwrap().iter().map(|(&txid, (hash, _))| (txid, Some(*hash))).collect::<Vec<_>>()
+       }
+}
+
+pub struct TestLogger {}
+
+impl Logger for TestLogger {
+       fn log(&self, record: &Record) {
+               println!("{} -- {}",
+                               record.level,
+                               record.args);
+       }
+}
+
+#[test]
+#[cfg(feature = "esplora-blocking")]
+fn test_esplora_syncs() {
+       premine();
+       let mut logger = TestLogger {};
+       let esplora_url = format!("http://{}", get_electrsd().esplora_url.as_ref().unwrap());
+       let tx_sync = EsploraSyncClient::new(esplora_url, &mut logger);
+       let confirmable = TestConfirmable::new();
+
+       // Check we pick up on new best blocks
+       let expected_height = 0u32;
+       assert_eq!(confirmable.best_block.lock().unwrap().1, expected_height);
+
+       tx_sync.sync(vec![&confirmable]).unwrap();
+
+       let expected_height = get_bitcoind().client.get_block_count().unwrap() as u32;
+       assert_eq!(confirmable.best_block.lock().unwrap().1, expected_height);
+
+       let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
+       assert_eq!(events.len(), 1);
+
+       // Check registered confirmed transactions are marked confirmed
+       let new_address = get_bitcoind().client.get_new_address(Some("test"), Some(AddressType::Legacy)).unwrap();
+       let txid = get_bitcoind().client.send_to_address(&new_address, Amount::from_sat(5000), None, None, None, None, None, None).unwrap();
+       tx_sync.register_tx(&txid, &new_address.script_pubkey());
+
+       tx_sync.sync(vec![&confirmable]).unwrap();
+
+       let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
+       assert_eq!(events.len(), 0);
+       assert!(confirmable.confirmed_txs.lock().unwrap().is_empty());
+       assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
+
+       generate_blocks_and_wait(1);
+       tx_sync.sync(vec![&confirmable]).unwrap();
+
+       let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
+       assert_eq!(events.len(), 2);
+       assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&txid));
+       assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
+
+       // Check previously confirmed transactions are marked unconfirmed when they are reorged.
+       let best_block_hash = get_bitcoind().client.get_best_block_hash().unwrap();
+       get_bitcoind().client.invalidate_block(&best_block_hash).unwrap();
+
+       // We're getting back to the previous height with a new tip, but best block shouldn't change.
+       generate_blocks_and_wait(1);
+       assert_ne!(get_bitcoind().client.get_best_block_hash().unwrap(), best_block_hash);
+       tx_sync.sync(vec![&confirmable]).unwrap();
+       let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
+       assert_eq!(events.len(), 0);
+
+       // Now we're surpassing previous height, getting new tip.
+       generate_blocks_and_wait(1);
+       assert_ne!(get_bitcoind().client.get_best_block_hash().unwrap(), best_block_hash);
+       tx_sync.sync(vec![&confirmable]).unwrap();
+
+       // Transaction still confirmed but under new tip.
+       assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&txid));
+       assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
+
+       // Check we got unconfirmed, then reconfirmed in the meantime.
+       let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
+       assert_eq!(events.len(), 3);
+
+       match events[0] {
+               TestConfirmableEvent::Unconfirmed(t) => {
+                       assert_eq!(t, txid);
+               },
+               _ => panic!("Unexpected event"),
+       }
+
+       match events[1] {
+               TestConfirmableEvent::BestBlockUpdated(..) => {},
+               _ => panic!("Unexpected event"),
+       }
+
+       match events[2] {
+               TestConfirmableEvent::Confirmed(t, _, _) => {
+                       assert_eq!(t, txid);
+               },
+               _ => panic!("Unexpected event"),
+       }
+}
+
+#[tokio::test]
+#[cfg(feature = "esplora-async")]
+async fn test_esplora_syncs() {
+       premine();
+       let mut logger = TestLogger {};
+       let esplora_url = format!("http://{}", get_electrsd().esplora_url.as_ref().unwrap());
+       let tx_sync = EsploraSyncClient::new(esplora_url, &mut logger);
+       let confirmable = TestConfirmable::new();
+
+       // Check we pick up on new best blocks
+       let expected_height = 0u32;
+       assert_eq!(confirmable.best_block.lock().unwrap().1, expected_height);
+
+       tx_sync.sync(vec![&confirmable]).await.unwrap();
+
+       let expected_height = get_bitcoind().client.get_block_count().unwrap() as u32;
+       assert_eq!(confirmable.best_block.lock().unwrap().1, expected_height);
+
+       let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
+       assert_eq!(events.len(), 1);
+
+       // Check registered confirmed transactions are marked confirmed
+       let new_address = get_bitcoind().client.get_new_address(Some("test"), Some(AddressType::Legacy)).unwrap();
+       let txid = get_bitcoind().client.send_to_address(&new_address, Amount::from_sat(5000), None, None, None, None, None, None).unwrap();
+       tx_sync.register_tx(&txid, &new_address.script_pubkey());
+
+       tx_sync.sync(vec![&confirmable]).await.unwrap();
+
+       let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
+       assert_eq!(events.len(), 0);
+       assert!(confirmable.confirmed_txs.lock().unwrap().is_empty());
+       assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
+
+       generate_blocks_and_wait(1);
+       tx_sync.sync(vec![&confirmable]).await.unwrap();
+
+       let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
+       assert_eq!(events.len(), 2);
+       assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&txid));
+       assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
+
+       // Check previously confirmed transactions are marked unconfirmed when they are reorged.
+       let best_block_hash = get_bitcoind().client.get_best_block_hash().unwrap();
+       get_bitcoind().client.invalidate_block(&best_block_hash).unwrap();
+
+       // We're getting back to the previous height with a new tip, but best block shouldn't change.
+       generate_blocks_and_wait(1);
+       assert_ne!(get_bitcoind().client.get_best_block_hash().unwrap(), best_block_hash);
+       tx_sync.sync(vec![&confirmable]).await.unwrap();
+       let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
+       assert_eq!(events.len(), 0);
+
+       // Now we're surpassing previous height, getting new tip.
+       generate_blocks_and_wait(1);
+       assert_ne!(get_bitcoind().client.get_best_block_hash().unwrap(), best_block_hash);
+       tx_sync.sync(vec![&confirmable]).await.unwrap();
+
+       // Transaction still confirmed but under new tip.
+       assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&txid));
+       assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
+
+       // Check we got unconfirmed, then reconfirmed in the meantime.
+       let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
+       assert_eq!(events.len(), 3);
+
+       match events[0] {
+               TestConfirmableEvent::Unconfirmed(t) => {
+                       assert_eq!(t, txid);
+               },
+               _ => panic!("Unexpected event"),
+       }
+
+       match events[1] {
+               TestConfirmableEvent::BestBlockUpdated(..) => {},
+               _ => panic!("Unexpected event"),
+       }
+
+       match events[2] {
+               TestConfirmableEvent::Confirmed(t, _, _) => {
+                       assert_eq!(t, txid);
+               },
+               _ => panic!("Unexpected event"),
+       }
+}
index 1a446249105c8772ead4b9f1c1167d3ea160219a..e923a94bb6d3e7afb5f37376b6de132225821d21 100644 (file)
@@ -25,7 +25,7 @@ pub trait BroadcasterInterface {
 
 /// An enum that represents the speed at which we want a transaction to confirm used for feerate
 /// estimation.
-#[derive(Clone, Copy, Hash, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
 pub enum ConfirmationTarget {
        /// We are happy with this transaction confirming slowly when feerate drops some.
        Background,
index 8dba235f2127fd98faf400fa3b83978047b11bdd..9a74f891b1e985b371f2640ccf23f7c992e626ec 100644 (file)
@@ -31,7 +31,7 @@ use crate::chain::{ChannelMonitorUpdateStatus, Filter, WatchedOutput};
 use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
 use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, Balance, MonitorEvent, TransactionOutputs, LATENCY_GRACE_PERIOD_BLOCKS};
 use crate::chain::transaction::{OutPoint, TransactionData};
-use crate::chain::keysinterface::Sign;
+use crate::chain::keysinterface::WriteableEcdsaChannelSigner;
 use crate::util::atomic_counter::AtomicCounter;
 use crate::util::logger::Logger;
 use crate::util::errors::APIError;
@@ -68,7 +68,7 @@ impl MonitorUpdateId {
        pub(crate) fn from_monitor_update(update: &ChannelMonitorUpdate) -> Self {
                Self { contents: UpdateOrigin::OffChain(update.update_id) }
        }
-       pub(crate) fn from_new_monitor<ChannelSigner: Sign>(monitor: &ChannelMonitor<ChannelSigner>) -> Self {
+       pub(crate) fn from_new_monitor<ChannelSigner: WriteableEcdsaChannelSigner>(monitor: &ChannelMonitor<ChannelSigner>) -> Self {
                Self { contents: UpdateOrigin::OffChain(monitor.get_latest_update_id()) }
        }
 }
@@ -93,7 +93,7 @@ impl MonitorUpdateId {
 ///    [`ChannelMonitorUpdateStatus::PermanentFailure`], in which case the channel will likely be
 ///    closed without broadcasting the latest state. See
 ///    [`ChannelMonitorUpdateStatus::PermanentFailure`] for more details.
-pub trait Persist<ChannelSigner: Sign> {
+pub trait Persist<ChannelSigner: WriteableEcdsaChannelSigner> {
        /// Persist a new channel's data in response to a [`chain::Watch::watch_channel`] call. This is
        /// called by [`ChannelManager`] for new channels, or may be called directly, e.g. on startup.
        ///
@@ -144,10 +144,10 @@ pub trait Persist<ChannelSigner: Sign> {
        /// [`ChannelMonitorUpdateStatus`] for requirements when returning errors.
        ///
        /// [`Writeable::write`]: crate::util::ser::Writeable::write
-       fn update_persisted_channel(&self, channel_id: OutPoint, update: &Option<ChannelMonitorUpdate>, data: &ChannelMonitor<ChannelSigner>, update_id: MonitorUpdateId) -> ChannelMonitorUpdateStatus;
+       fn update_persisted_channel(&self, channel_id: OutPoint, update: Option<&ChannelMonitorUpdate>, data: &ChannelMonitor<ChannelSigner>, update_id: MonitorUpdateId) -> ChannelMonitorUpdateStatus;
 }
 
-struct MonitorHolder<ChannelSigner: Sign> {
+struct MonitorHolder<ChannelSigner: WriteableEcdsaChannelSigner> {
        monitor: ChannelMonitor<ChannelSigner>,
        /// The full set of pending monitor updates for this Channel.
        ///
@@ -182,7 +182,7 @@ struct MonitorHolder<ChannelSigner: Sign> {
        last_chain_persist_height: AtomicUsize,
 }
 
-impl<ChannelSigner: Sign> MonitorHolder<ChannelSigner> {
+impl<ChannelSigner: WriteableEcdsaChannelSigner> MonitorHolder<ChannelSigner> {
        fn has_pending_offchain_updates(&self, pending_monitor_updates_lock: &MutexGuard<Vec<MonitorUpdateId>>) -> bool {
                pending_monitor_updates_lock.iter().any(|update_id|
                        if let UpdateOrigin::OffChain(_) = update_id.contents { true } else { false })
@@ -197,12 +197,12 @@ impl<ChannelSigner: Sign> MonitorHolder<ChannelSigner> {
 ///
 /// Note that this holds a mutex in [`ChainMonitor`] and may block other events until it is
 /// released.
-pub struct LockedChannelMonitor<'a, ChannelSigner: Sign> {
+pub struct LockedChannelMonitor<'a, ChannelSigner: WriteableEcdsaChannelSigner> {
        lock: RwLockReadGuard<'a, HashMap<OutPoint, MonitorHolder<ChannelSigner>>>,
        funding_txo: OutPoint,
 }
 
-impl<ChannelSigner: Sign> Deref for LockedChannelMonitor<'_, ChannelSigner> {
+impl<ChannelSigner: WriteableEcdsaChannelSigner> Deref for LockedChannelMonitor<'_, ChannelSigner> {
        type Target = ChannelMonitor<ChannelSigner>;
        fn deref(&self) -> &ChannelMonitor<ChannelSigner> {
                &self.lock.get(&self.funding_txo).expect("Checked at construction").monitor
@@ -218,7 +218,7 @@ impl<ChannelSigner: Sign> Deref for LockedChannelMonitor<'_, ChannelSigner> {
 ///
 /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
 /// [module-level documentation]: crate::chain::chainmonitor
-pub struct ChainMonitor<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
+pub struct ChainMonitor<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
        where C::Target: chain::Filter,
         T::Target: BroadcasterInterface,
         F::Target: FeeEstimator,
@@ -242,7 +242,7 @@ pub struct ChainMonitor<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: De
        highest_chain_height: AtomicUsize,
 }
 
-impl<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> ChainMonitor<ChannelSigner, C, T, F, L, P>
+impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> ChainMonitor<ChannelSigner, C, T, F, L, P>
 where C::Target: chain::Filter,
            T::Target: BroadcasterInterface,
            F::Target: FeeEstimator,
@@ -294,7 +294,7 @@ where C::Target: chain::Filter,
                                }
 
                                log_trace!(self.logger, "Syncing Channel Monitor for channel {}", log_funding_info!(monitor));
-                               match self.persister.update_persisted_channel(*funding_outpoint, &None, monitor, update_id) {
+                               match self.persister.update_persisted_channel(*funding_outpoint, None, monitor, update_id) {
                                        ChannelMonitorUpdateStatus::Completed =>
                                                log_trace!(self.logger, "Finished syncing Channel Monitor for channel {}", log_funding_info!(monitor)),
                                        ChannelMonitorUpdateStatus::PermanentFailure => {
@@ -516,7 +516,7 @@ where C::Target: chain::Filter,
        }
 }
 
-impl<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
+impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
 chain::Listen for ChainMonitor<ChannelSigner, C, T, F, L, P>
 where
        C::Target: chain::Filter,
@@ -543,7 +543,7 @@ where
        }
 }
 
-impl<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
+impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
 chain::Confirm for ChainMonitor<ChannelSigner, C, T, F, L, P>
 where
        C::Target: chain::Filter,
@@ -592,7 +592,7 @@ where
        }
 }
 
-impl<ChannelSigner: Sign, C: Deref , T: Deref , F: Deref , L: Deref , P: Deref >
+impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref , T: Deref , F: Deref , L: Deref , P: Deref >
 chain::Watch<ChannelSigner> for ChainMonitor<ChannelSigner, C, T, F, L, P>
 where C::Target: chain::Filter,
            T::Target: BroadcasterInterface,
@@ -646,7 +646,7 @@ where C::Target: chain::Filter,
 
        /// Note that we persist the given `ChannelMonitor` update while holding the
        /// `ChainMonitor` monitors lock.
-       fn update_channel(&self, funding_txo: OutPoint, update: ChannelMonitorUpdate) -> ChannelMonitorUpdateStatus {
+       fn update_channel(&self, funding_txo: OutPoint, update: &ChannelMonitorUpdate) -> ChannelMonitorUpdateStatus {
                // Update the monitor that watches the channel referred to by the given outpoint.
                let monitors = self.monitors.read().unwrap();
                match monitors.get(&funding_txo) {
@@ -664,15 +664,15 @@ where C::Target: chain::Filter,
                        Some(monitor_state) => {
                                let monitor = &monitor_state.monitor;
                                log_trace!(self.logger, "Updating ChannelMonitor for channel {}", log_funding_info!(monitor));
-                               let update_res = monitor.update_monitor(&update, &self.broadcaster, &*self.fee_estimator, &self.logger);
+                               let update_res = monitor.update_monitor(update, &self.broadcaster, &*self.fee_estimator, &self.logger);
                                if update_res.is_err() {
                                        log_error!(self.logger, "Failed to update ChannelMonitor for channel {}.", log_funding_info!(monitor));
                                }
                                // Even if updating the monitor returns an error, the monitor's state will
                                // still be changed. So, persist the updated monitor despite the error.
-                               let update_id = MonitorUpdateId::from_monitor_update(&update);
+                               let update_id = MonitorUpdateId::from_monitor_update(update);
                                let mut pending_monitor_updates = monitor_state.pending_monitor_updates.lock().unwrap();
-                               let persist_res = self.persister.update_persisted_channel(funding_txo, &Some(update), monitor, update_id);
+                               let persist_res = self.persister.update_persisted_channel(funding_txo, Some(update), monitor, update_id);
                                match persist_res {
                                        ChannelMonitorUpdateStatus::InProgress => {
                                                pending_monitor_updates.push(update_id);
@@ -735,7 +735,7 @@ where C::Target: chain::Filter,
        }
 }
 
-impl<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> events::EventsProvider for ChainMonitor<ChannelSigner, C, T, F, L, P>
+impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> events::EventsProvider for ChainMonitor<ChannelSigner, C, T, F, L, P>
        where C::Target: chain::Filter,
              T::Target: BroadcasterInterface,
              F::Target: FeeEstimator,
@@ -792,11 +792,11 @@ mod tests {
        use crate::{get_htlc_update_msgs, get_local_commitment_txn, get_revoke_commit_msgs, get_route_and_payment_hash, unwrap_send_err};
        use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Watch};
        use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS;
-       use crate::ln::channelmanager::{self, PaymentSendFailure, PaymentId};
+       use crate::ln::channelmanager::{PaymentSendFailure, PaymentId};
        use crate::ln::functional_test_utils::*;
        use crate::ln::msgs::ChannelMessageHandler;
        use crate::util::errors::APIError;
-       use crate::util::events::{ClosureReason, MessageSendEvent, MessageSendEventsProvider};
+       use crate::util::events::{Event, ClosureReason, MessageSendEvent, MessageSendEventsProvider};
 
        #[test]
        fn test_async_ooo_offchain_updates() {
@@ -807,7 +807,7 @@ mod tests {
                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);
-               create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes(&nodes, 0, 1);
 
                // Route two payments to be claimed at the same time.
                let (payment_preimage_1, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
@@ -819,10 +819,8 @@ mod tests {
 
                nodes[1].node.claim_funds(payment_preimage_1);
                check_added_monitors!(nodes[1], 1);
-               expect_payment_claimed!(nodes[1], payment_hash_1, 1_000_000);
                nodes[1].node.claim_funds(payment_preimage_2);
                check_added_monitors!(nodes[1], 1);
-               expect_payment_claimed!(nodes[1], payment_hash_2, 1_000_000);
 
                let persistences = chanmon_cfgs[1].persister.offchain_monitor_updates.lock().unwrap().clone();
                assert_eq!(persistences.len(), 1);
@@ -850,8 +848,24 @@ mod tests {
                        .find(|(txo, _)| txo == funding_txo).unwrap().1.contains(&next_update));
                assert!(nodes[1].chain_monitor.release_pending_monitor_events().is_empty());
                assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
+               assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
                nodes[1].chain_monitor.chain_monitor.channel_monitor_updated(*funding_txo, update_iter.next().unwrap().clone()).unwrap();
 
+               let claim_events = nodes[1].node.get_and_clear_pending_events();
+               assert_eq!(claim_events.len(), 2);
+               match claim_events[0] {
+                       Event::PaymentClaimed { ref payment_hash, amount_msat: 1_000_000, .. } => {
+                               assert_eq!(payment_hash_1, *payment_hash);
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+               match claim_events[1] {
+                       Event::PaymentClaimed { ref payment_hash, amount_msat: 1_000_000, .. } => {
+                               assert_eq!(payment_hash_2, *payment_hash);
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+
                // Now manually walk the commitment signed dance - because we claimed two payments
                // back-to-back it doesn't fit into the neat walk commitment_signed_dance does.
 
@@ -897,8 +911,7 @@ mod tests {
                let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
                let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-               let channel = create_announced_chan_between_nodes(
-                       &nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
 
                // Get a route for later and rebalance the channel somewhat
                send_payment(&nodes[0], &[&nodes[1]], 10_000_000);
@@ -974,7 +987,7 @@ mod tests {
                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);
-               create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes(&nodes, 0, 1);
 
                chanmon_cfgs[0].persister.chain_sync_monitor_persistences.lock().unwrap().clear();
                chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
index db17810599d66e4d472d96ec96af76f1ced407f3..cd18ffad12d385747da26ee6e7222f9dc457b5f3 100644 (file)
@@ -37,19 +37,19 @@ use crate::ln::{PaymentHash, PaymentPreimage};
 use crate::ln::msgs::DecodeError;
 use crate::ln::chan_utils;
 use crate::ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCClaim, ChannelTransactionParameters, HolderCommitmentTransaction};
-use crate::ln::channelmanager::HTLCSource;
+use crate::ln::channelmanager::{HTLCSource, SentHTLCId};
 use crate::chain;
 use crate::chain::{BestBlock, WatchedOutput};
 use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
 use crate::chain::transaction::{OutPoint, TransactionData};
-use crate::chain::keysinterface::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, Sign, KeysInterface};
+use crate::chain::keysinterface::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource};
 #[cfg(anchors)]
 use crate::chain::onchaintx::ClaimEvent;
 use crate::chain::onchaintx::OnchainTxHandler;
 use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
 use crate::chain::Filter;
 use crate::util::logger::Logger;
-use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48, OptionDeserWrapper};
+use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, UpgradableRequired, Writer, Writeable, U48};
 use crate::util::byte_utils;
 use crate::util::events::Event;
 #[cfg(anchors)]
@@ -60,7 +60,7 @@ use core::{cmp, mem};
 use crate::io::{self, Error};
 use core::convert::TryInto;
 use core::ops::Deref;
-use crate::sync::Mutex;
+use crate::sync::{Mutex, LockTestExt};
 
 /// An update generated by the underlying channel itself which contains some new information the
 /// [`ChannelMonitor`] should be made aware of.
@@ -314,8 +314,8 @@ impl Readable for CounterpartyCommitmentParameters {
                                }
                        }
 
-                       let mut counterparty_delayed_payment_base_key = OptionDeserWrapper(None);
-                       let mut counterparty_htlc_base_key = OptionDeserWrapper(None);
+                       let mut counterparty_delayed_payment_base_key = RequiredWrapper(None);
+                       let mut counterparty_htlc_base_key = RequiredWrapper(None);
                        let mut on_counterparty_tx_csv: u16 = 0;
                        read_tlv_fields!(r, {
                                (0, counterparty_delayed_payment_base_key, required),
@@ -454,19 +454,15 @@ impl MaybeReadable for OnchainEventEntry {
                let mut transaction = None;
                let mut block_hash = None;
                let mut height = 0;
-               let mut event = None;
+               let mut event = UpgradableRequired(None);
                read_tlv_fields!(reader, {
                        (0, txid, required),
                        (1, transaction, option),
                        (2, height, required),
                        (3, block_hash, option),
-                       (4, event, ignorable),
+                       (4, event, upgradable_required),
                });
-               if let Some(ev) = event {
-                       Ok(Some(Self { txid, transaction, height, block_hash, event: ev }))
-               } else {
-                       Ok(None)
-               }
+               Ok(Some(Self { txid, transaction, height, block_hash, event: _init_tlv_based_struct_field!(event, upgradable_required) }))
        }
 }
 
@@ -498,6 +494,7 @@ pub(crate) enum ChannelMonitorUpdateStep {
        LatestHolderCommitmentTXInfo {
                commitment_tx: HolderCommitmentTransaction,
                htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
+               claimed_htlcs: Vec<(SentHTLCId, PaymentPreimage)>,
        },
        LatestCounterpartyCommitmentTXInfo {
                commitment_txid: Txid,
@@ -540,6 +537,7 @@ impl ChannelMonitorUpdateStep {
 impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
        (0, LatestHolderCommitmentTXInfo) => {
                (0, commitment_tx, required),
+               (1, claimed_htlcs, vec_type),
                (2, htlc_outputs, vec_type),
        },
        (1, LatestCounterpartyCommitmentTXInfo) => {
@@ -706,14 +704,15 @@ impl Readable for IrrevocablyResolvedHTLC {
 /// the "reorg path" (ie disconnecting blocks until you find a common ancestor from both the
 /// returned block hash and the the current chain and then reconnecting blocks to get to the
 /// best chain) upon deserializing the object!
-pub struct ChannelMonitor<Signer: Sign> {
+pub struct ChannelMonitor<Signer: WriteableEcdsaChannelSigner> {
        #[cfg(test)]
        pub(crate) inner: Mutex<ChannelMonitorImpl<Signer>>,
        #[cfg(not(test))]
        inner: Mutex<ChannelMonitorImpl<Signer>>,
 }
 
-pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
+#[derive(PartialEq)]
+pub(crate) struct ChannelMonitorImpl<Signer: WriteableEcdsaChannelSigner> {
        latest_update_id: u64,
        commitment_transaction_number_obscure_factor: u64,
 
@@ -753,6 +752,8 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
        /// Serialized to disk but should generally not be sent to Watchtowers.
        counterparty_hash_commitment_number: HashMap<PaymentHash, u64>,
 
+       counterparty_fulfilled_htlcs: HashMap<SentHTLCId, PaymentPreimage>,
+
        // We store two holder commitment transactions to avoid any race conditions where we may update
        // some monitors (potentially on watchtowers) but then fail to update others, resulting in the
        // various monitors for one channel being out of sync, and us broadcasting a holder
@@ -847,72 +848,24 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
 
        /// The node_id of our counterparty
        counterparty_node_id: Option<PublicKey>,
-
-       secp_ctx: Secp256k1<secp256k1::All>, //TODO: dedup this a bit...
 }
 
 /// Transaction outputs to watch for on-chain spends.
 pub type TransactionOutputs = (Txid, Vec<(u32, TxOut)>);
 
-#[cfg(any(test, fuzzing, feature = "_test_utils"))]
-/// Used only in testing and fuzzing to check serialization roundtrips don't change the underlying
-/// object
-impl<Signer: Sign> PartialEq for ChannelMonitor<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> PartialEq for ChannelMonitor<Signer> where Signer: PartialEq {
        fn eq(&self, other: &Self) -> bool {
-               let inner = self.inner.lock().unwrap();
-               let other = other.inner.lock().unwrap();
-               inner.eq(&other)
-       }
-}
-
-#[cfg(any(test, fuzzing, feature = "_test_utils"))]
-/// Used only in testing and fuzzing to check serialization roundtrips don't change the underlying
-/// object
-impl<Signer: Sign> PartialEq for ChannelMonitorImpl<Signer> {
-       fn eq(&self, other: &Self) -> bool {
-               if self.latest_update_id != other.latest_update_id ||
-                       self.commitment_transaction_number_obscure_factor != other.commitment_transaction_number_obscure_factor ||
-                       self.destination_script != other.destination_script ||
-                       self.broadcasted_holder_revokable_script != other.broadcasted_holder_revokable_script ||
-                       self.counterparty_payment_script != other.counterparty_payment_script ||
-                       self.channel_keys_id != other.channel_keys_id ||
-                       self.holder_revocation_basepoint != other.holder_revocation_basepoint ||
-                       self.funding_info != other.funding_info ||
-                       self.current_counterparty_commitment_txid != other.current_counterparty_commitment_txid ||
-                       self.prev_counterparty_commitment_txid != other.prev_counterparty_commitment_txid ||
-                       self.counterparty_commitment_params != other.counterparty_commitment_params ||
-                       self.funding_redeemscript != other.funding_redeemscript ||
-                       self.channel_value_satoshis != other.channel_value_satoshis ||
-                       self.their_cur_per_commitment_points != other.their_cur_per_commitment_points ||
-                       self.on_holder_tx_csv != other.on_holder_tx_csv ||
-                       self.commitment_secrets != other.commitment_secrets ||
-                       self.counterparty_claimable_outpoints != other.counterparty_claimable_outpoints ||
-                       self.counterparty_commitment_txn_on_chain != other.counterparty_commitment_txn_on_chain ||
-                       self.counterparty_hash_commitment_number != other.counterparty_hash_commitment_number ||
-                       self.prev_holder_signed_commitment_tx != other.prev_holder_signed_commitment_tx ||
-                       self.current_counterparty_commitment_number != other.current_counterparty_commitment_number ||
-                       self.current_holder_commitment_number != other.current_holder_commitment_number ||
-                       self.current_holder_commitment_tx != other.current_holder_commitment_tx ||
-                       self.payment_preimages != other.payment_preimages ||
-                       self.pending_monitor_events != other.pending_monitor_events ||
-                       self.pending_events.len() != other.pending_events.len() || // We trust events to round-trip properly
-                       self.onchain_events_awaiting_threshold_conf != other.onchain_events_awaiting_threshold_conf ||
-                       self.outputs_to_watch != other.outputs_to_watch ||
-                       self.lockdown_from_offchain != other.lockdown_from_offchain ||
-                       self.holder_tx_signed != other.holder_tx_signed ||
-                       self.funding_spend_seen != other.funding_spend_seen ||
-                       self.funding_spend_confirmed != other.funding_spend_confirmed ||
-                       self.confirmed_commitment_tx_counterparty_output != other.confirmed_commitment_tx_counterparty_output ||
-                       self.htlcs_resolved_on_chain != other.htlcs_resolved_on_chain
-               {
-                       false
-               } else {
-                       true
-               }
+               // We need some kind of total lockorder. Absent a better idea, we sort by position in
+               // memory and take locks in that order (assuming that we can't move within memory while a
+               // lock is held).
+               let ord = ((self as *const _) as usize) < ((other as *const _) as usize);
+               let a = if ord { self.inner.unsafe_well_ordered_double_lock_self() } else { other.inner.unsafe_well_ordered_double_lock_self() };
+               let b = if ord { other.inner.unsafe_well_ordered_double_lock_self() } else { self.inner.unsafe_well_ordered_double_lock_self() };
+               a.eq(&b)
        }
 }
 
-impl<Signer: Sign> Writeable for ChannelMonitor<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitor<Signer> {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
                self.inner.lock().unwrap().write(writer)
        }
@@ -922,7 +875,7 @@ impl<Signer: Sign> Writeable for ChannelMonitor<Signer> {
 const SERIALIZATION_VERSION: u8 = 1;
 const MIN_SERIALIZATION_VERSION: u8 = 1;
 
-impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
                write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
 
@@ -1084,13 +1037,14 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                        (9, self.counterparty_node_id, option),
                        (11, self.confirmed_commitment_tx_counterparty_output, option),
                        (13, self.spendable_txids_confirmed, vec_type),
+                       (15, self.counterparty_fulfilled_htlcs, required),
                });
 
                Ok(())
        }
 }
 
-impl<Signer: Sign> ChannelMonitor<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
        /// For lockorder enforcement purposes, we need to have a single site which constructs the
        /// `inner` mutex, otherwise cases where we lock two monitors at the same time (eg in our
        /// PartialEq implementation) we may decide a lockorder violation has occurred.
@@ -1140,7 +1094,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
 
                let onchain_tx_handler =
                        OnchainTxHandler::new(destination_script.clone(), keys,
-                       channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx.clone());
+                       channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx);
 
                let mut outputs_to_watch = HashMap::new();
                outputs_to_watch.insert(funding_info.0.txid, vec![(funding_info.0.index as u32, funding_info.1.clone())]);
@@ -1171,6 +1125,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                        counterparty_claimable_outpoints: HashMap::new(),
                        counterparty_commitment_txn_on_chain: HashMap::new(),
                        counterparty_hash_commitment_number: HashMap::new(),
+                       counterparty_fulfilled_htlcs: HashMap::new(),
 
                        prev_holder_signed_commitment_tx: None,
                        current_holder_commitment_tx: holder_commitment_tx,
@@ -1196,8 +1151,6 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
 
                        best_block,
                        counterparty_node_id: Some(counterparty_node_id),
-
-                       secp_ctx,
                })
        }
 
@@ -1227,7 +1180,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                &self, holder_commitment_tx: HolderCommitmentTransaction,
                htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
        ) -> Result<(), ()> {
-               self.inner.lock().unwrap().provide_latest_holder_commitment_tx(holder_commitment_tx, htlc_outputs).map_err(|_| ())
+               self.inner.lock().unwrap().provide_latest_holder_commitment_tx(holder_commitment_tx, htlc_outputs, &Vec::new()).map_err(|_| ())
        }
 
        /// This is used to provide payment preimage(s) out-of-band during startup without updating the
@@ -1521,7 +1474,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
        }
 }
 
-impl<Signer: Sign> ChannelMonitorImpl<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
        /// Helper for get_claimable_balances which does the work for an individual HTLC, generating up
        /// to one `Balance` for the HTLC.
        fn get_htlc_balance(&self, htlc: &HTLCOutputInCommitment, holder_commitment: bool,
@@ -1684,7 +1637,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        }
 }
 
-impl<Signer: Sign> ChannelMonitor<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
        /// Gets the balances in this channel which are either claimable by us if we were to
        /// force-close the channel now or which are claimable on-chain (possibly awaiting
        /// confirmation).
@@ -1863,9 +1816,10 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
        /// `ChannelMonitor`. This is used to determine if an HTLC was removed from the channel prior
        /// to the `ChannelManager` having been persisted.
        ///
-       /// This is similar to [`Self::get_pending_outbound_htlcs`] except it includes HTLCs which were
-       /// resolved by this `ChannelMonitor`.
-       pub(crate) fn get_all_current_outbound_htlcs(&self) -> HashMap<HTLCSource, HTLCOutputInCommitment> {
+       /// This is similar to [`Self::get_pending_or_resolved_outbound_htlcs`] except it includes
+       /// HTLCs which were resolved on-chain (i.e. where the final HTLC resolution was done by an
+       /// event from this `ChannelMonitor`).
+       pub(crate) fn get_all_current_outbound_htlcs(&self) -> HashMap<HTLCSource, (HTLCOutputInCommitment, Option<PaymentPreimage>)> {
                let mut res = HashMap::new();
                // Just examine the available counterparty commitment transactions. See docs on
                // `fail_unbroadcast_htlcs`, below, for justification.
@@ -1875,7 +1829,8 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                                if let Some(ref latest_outpoints) = us.counterparty_claimable_outpoints.get($txid) {
                                        for &(ref htlc, ref source_option) in latest_outpoints.iter() {
                                                if let &Some(ref source) = source_option {
-                                                       res.insert((**source).clone(), htlc.clone());
+                                                       res.insert((**source).clone(), (htlc.clone(),
+                                                               us.counterparty_fulfilled_htlcs.get(&SentHTLCId::from_source(source)).cloned()));
                                                }
                                        }
                                }
@@ -1890,9 +1845,14 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                res
        }
 
-       /// Gets the set of outbound HTLCs which are pending resolution in this channel.
+       /// Gets the set of outbound HTLCs which are pending resolution in this channel or which were
+       /// resolved with a preimage from our counterparty.
+       ///
        /// This is used to reconstruct pending outbound payments on restart in the ChannelManager.
-       pub(crate) fn get_pending_outbound_htlcs(&self) -> HashMap<HTLCSource, HTLCOutputInCommitment> {
+       ///
+       /// Currently, the preimage is unused, however if it is present in the relevant internal state
+       /// an HTLC is always included even if it has been resolved.
+       pub(crate) fn get_pending_or_resolved_outbound_htlcs(&self) -> HashMap<HTLCSource, (HTLCOutputInCommitment, Option<PaymentPreimage>)> {
                let us = self.inner.lock().unwrap();
                // We're only concerned with the confirmation count of HTLC transactions, and don't
                // actually care how many confirmations a commitment transaction may or may not have. Thus,
@@ -1940,8 +1900,10 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                                                                Some(commitment_tx_output_idx) == htlc.transaction_output_index
                                                        } else { false }
                                                });
-                                               if !htlc_update_confd {
-                                                       res.insert(source.clone(), htlc.clone());
+                                               let counterparty_resolved_preimage_opt =
+                                                       us.counterparty_fulfilled_htlcs.get(&SentHTLCId::from_source(source)).cloned();
+                                               if !htlc_update_confd || counterparty_resolved_preimage_opt.is_some() {
+                                                       res.insert(source.clone(), (htlc.clone(), counterparty_resolved_preimage_opt));
                                                }
                                        }
                                }
@@ -2023,6 +1985,9 @@ macro_rules! fail_unbroadcast_htlcs {
                                                                }
                                                        }
                                                        if matched_htlc { continue; }
+                                                       if $self.counterparty_fulfilled_htlcs.get(&SentHTLCId::from_source(source)).is_some() {
+                                                               continue;
+                                                       }
                                                        $self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
                                                                if entry.height != $commitment_tx_conf_height { return true; }
                                                                match entry.event {
@@ -2082,7 +2047,7 @@ pub fn deliberately_bogus_accepted_htlc_witness() -> Vec<Vec<u8>> {
        vec![Vec::new(), Vec::new(), Vec::new(), Vec::new(), deliberately_bogus_accepted_htlc_witness_program().into()].into()
 }
 
-impl<Signer: Sign> ChannelMonitorImpl<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
        /// Inserts a revocation secret into this channel monitor. Prunes old preimages if neither
        /// needed by holder commitment transactions HTCLs nor by counterparty ones. Unless we haven't already seen
        /// counterparty commitment transaction's secret, they are de facto pruned (we can use revocation key).
@@ -2094,8 +2059,23 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                // Prune HTLCs from the previous counterparty commitment tx so we don't generate failure/fulfill
                // events for now-revoked/fulfilled HTLCs.
                if let Some(txid) = self.prev_counterparty_commitment_txid.take() {
-                       for &mut (_, ref mut source) in self.counterparty_claimable_outpoints.get_mut(&txid).unwrap() {
-                               *source = None;
+                       if self.current_counterparty_commitment_txid.unwrap() != txid {
+                               let cur_claimables = self.counterparty_claimable_outpoints.get(
+                                       &self.current_counterparty_commitment_txid.unwrap()).unwrap();
+                               for (_, ref source_opt) in self.counterparty_claimable_outpoints.get(&txid).unwrap() {
+                                       if let Some(source) = source_opt {
+                                               if !cur_claimables.iter()
+                                                       .any(|(_, cur_source_opt)| cur_source_opt == source_opt)
+                                               {
+                                                       self.counterparty_fulfilled_htlcs.remove(&SentHTLCId::from_source(source));
+                                               }
+                                       }
+                               }
+                               for &mut (_, ref mut source_opt) in self.counterparty_claimable_outpoints.get_mut(&txid).unwrap() {
+                                       *source_opt = None;
+                               }
+                       } else {
+                               assert!(cfg!(fuzzing), "Commitment txids are unique outside of fuzzing, where hashes can collide");
                        }
                }
 
@@ -2180,28 +2160,37 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        /// is important that any clones of this channel monitor (including remote clones) by kept
        /// up-to-date as our holder commitment transaction is updated.
        /// Panics if set_on_holder_tx_csv has never been called.
-       fn provide_latest_holder_commitment_tx(&mut self, holder_commitment_tx: HolderCommitmentTransaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>) -> Result<(), &'static str> {
-               // block for Rust 1.34 compat
-               let mut new_holder_commitment_tx = {
-                       let trusted_tx = holder_commitment_tx.trust();
-                       let txid = trusted_tx.txid();
-                       let tx_keys = trusted_tx.keys();
-                       self.current_holder_commitment_number = trusted_tx.commitment_number();
-                       HolderSignedTx {
-                               txid,
-                               revocation_key: tx_keys.revocation_key,
-                               a_htlc_key: tx_keys.broadcaster_htlc_key,
-                               b_htlc_key: tx_keys.countersignatory_htlc_key,
-                               delayed_payment_key: tx_keys.broadcaster_delayed_payment_key,
-                               per_commitment_point: tx_keys.per_commitment_point,
-                               htlc_outputs,
-                               to_self_value_sat: holder_commitment_tx.to_broadcaster_value_sat(),
-                               feerate_per_kw: trusted_tx.feerate_per_kw(),
-                       }
+       fn provide_latest_holder_commitment_tx(&mut self, holder_commitment_tx: HolderCommitmentTransaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>, claimed_htlcs: &[(SentHTLCId, PaymentPreimage)]) -> Result<(), &'static str> {
+               let trusted_tx = holder_commitment_tx.trust();
+               let txid = trusted_tx.txid();
+               let tx_keys = trusted_tx.keys();
+               self.current_holder_commitment_number = trusted_tx.commitment_number();
+               let mut new_holder_commitment_tx = HolderSignedTx {
+                       txid,
+                       revocation_key: tx_keys.revocation_key,
+                       a_htlc_key: tx_keys.broadcaster_htlc_key,
+                       b_htlc_key: tx_keys.countersignatory_htlc_key,
+                       delayed_payment_key: tx_keys.broadcaster_delayed_payment_key,
+                       per_commitment_point: tx_keys.per_commitment_point,
+                       htlc_outputs,
+                       to_self_value_sat: holder_commitment_tx.to_broadcaster_value_sat(),
+                       feerate_per_kw: trusted_tx.feerate_per_kw(),
                };
                self.onchain_tx_handler.provide_latest_holder_tx(holder_commitment_tx);
                mem::swap(&mut new_holder_commitment_tx, &mut self.current_holder_commitment_tx);
                self.prev_holder_signed_commitment_tx = Some(new_holder_commitment_tx);
+               for (claimed_htlc_id, claimed_preimage) in claimed_htlcs {
+                       #[cfg(debug_assertions)] {
+                               let cur_counterparty_htlcs = self.counterparty_claimable_outpoints.get(
+                                               &self.current_counterparty_commitment_txid.unwrap()).unwrap();
+                               assert!(cur_counterparty_htlcs.iter().any(|(_, source_opt)| {
+                                       if let Some(source) = source_opt {
+                                               SentHTLCId::from_source(source) == *claimed_htlc_id
+                                       } else { false }
+                               }));
+                       }
+                       self.counterparty_fulfilled_htlcs.insert(*claimed_htlc_id, *claimed_preimage);
+               }
                if self.holder_tx_signed {
                        return Err("Latest holder commitment signed has already been signed, update is rejected");
                }
@@ -2296,10 +2285,10 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&*fee_estimator);
                for update in updates.updates.iter() {
                        match update {
-                               ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs } => {
+                               ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, claimed_htlcs } => {
                                        log_trace!(logger, "Updating ChannelMonitor with latest holder commitment transaction info");
                                        if self.lockdown_from_offchain { panic!(); }
-                                       if let Err(e) = self.provide_latest_holder_commitment_tx(commitment_tx.clone(), htlc_outputs.clone()) {
+                                       if let Err(e) = self.provide_latest_holder_commitment_tx(commitment_tx.clone(), htlc_outputs.clone(), &claimed_htlcs) {
                                                log_error!(logger, "Providing latest holder commitment transaction failed/was refused:");
                                                log_error!(logger, "    {}", e);
                                                ret = Err(());
@@ -2512,9 +2501,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                if commitment_number >= self.get_min_seen_secret() {
                        let secret = self.get_secret(commitment_number).unwrap();
                        let per_commitment_key = ignore_error!(SecretKey::from_slice(&secret));
-                       let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
-                       let revocation_pubkey = chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
-                       let delayed_key = chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.counterparty_commitment_params.counterparty_delayed_payment_base_key);
+                       let per_commitment_point = PublicKey::from_secret_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_key);
+                       let revocation_pubkey = chan_utils::derive_public_revocation_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
+                       let delayed_key = chan_utils::derive_public_key(&self.onchain_tx_handler.secp_ctx, &PublicKey::from_secret_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_key), &self.counterparty_commitment_params.counterparty_delayed_payment_base_key);
 
                        let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.counterparty_commitment_params.on_counterparty_tx_csv, &delayed_key);
                        let revokeable_p2wsh = revokeable_redeemscript.to_v0_p2wsh();
@@ -2627,8 +2616,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
 
                if let Some(transaction) = tx {
                        let revocation_pubkey = chan_utils::derive_public_revocation_key(
-                               &self.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
-                       let delayed_key = chan_utils::derive_public_key(&self.secp_ctx,
+                               &self.onchain_tx_handler.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
+                       let delayed_key = chan_utils::derive_public_key(&self.onchain_tx_handler.secp_ctx,
                                &per_commitment_point,
                                &self.counterparty_commitment_params.counterparty_delayed_payment_base_key);
                        let revokeable_p2wsh = chan_utils::get_revokeable_redeemscript(&revocation_pubkey,
@@ -2685,7 +2674,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                        Ok(key) => key,
                        Err(_) => return (Vec::new(), None)
                };
-               let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
+               let per_commitment_point = PublicKey::from_secret_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_key);
 
                let htlc_txid = tx.txid();
                let mut claimable_outpoints = vec![];
@@ -3664,7 +3653,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        }
 }
 
-impl<Signer: Sign, T: Deref, F: Deref, L: Deref> chain::Listen for (ChannelMonitor<Signer>, T, F, L)
+impl<Signer: WriteableEcdsaChannelSigner, T: Deref, F: Deref, L: Deref> chain::Listen for (ChannelMonitor<Signer>, T, F, L)
 where
        T::Target: BroadcasterInterface,
        F::Target: FeeEstimator,
@@ -3679,7 +3668,7 @@ where
        }
 }
 
-impl<Signer: Sign, T: Deref, F: Deref, L: Deref> chain::Confirm for (ChannelMonitor<Signer>, T, F, L)
+impl<Signer: WriteableEcdsaChannelSigner, T: Deref, F: Deref, L: Deref> chain::Confirm for (ChannelMonitor<Signer>, T, F, L)
 where
        T::Target: BroadcasterInterface,
        F::Target: FeeEstimator,
@@ -3704,9 +3693,9 @@ where
 
 const MAX_ALLOC_SIZE: usize = 64*1024;
 
-impl<'a, K: KeysInterface> ReadableArgs<&'a K>
-               for (BlockHash, ChannelMonitor<K::Signer>) {
-       fn read<R: io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
+impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP)>
+               for (BlockHash, ChannelMonitor<SP::Signer>) {
+       fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP)) -> Result<Self, DecodeError> {
                macro_rules! unwrap_obj {
                        ($key: expr) => {
                                match $key {
@@ -3716,6 +3705,8 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
                        }
                }
 
+               let (entropy_source, signer_provider) = args;
+
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                let latest_update_id: u64 = Readable::read(reader)?;
@@ -3889,8 +3880,8 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
                                return Err(DecodeError::InvalidValue);
                        }
                }
-               let onchain_tx_handler: OnchainTxHandler<K::Signer> = ReadableArgs::read(
-                       reader, (keys_manager, channel_value_satoshis, channel_keys_id)
+               let onchain_tx_handler: OnchainTxHandler<SP::Signer> = ReadableArgs::read(
+                       reader, (entropy_source, signer_provider, channel_value_satoshis, channel_keys_id)
                )?;
 
                let lockdown_from_offchain = Readable::read(reader)?;
@@ -3919,6 +3910,7 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
                let mut counterparty_node_id = None;
                let mut confirmed_commitment_tx_counterparty_output = None;
                let mut spendable_txids_confirmed = Some(Vec::new());
+               let mut counterparty_fulfilled_htlcs = Some(HashMap::new());
                read_tlv_fields!(reader, {
                        (1, funding_spend_confirmed, option),
                        (3, htlcs_resolved_on_chain, vec_type),
@@ -3927,11 +3919,9 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
                        (9, counterparty_node_id, option),
                        (11, confirmed_commitment_tx_counterparty_output, option),
                        (13, spendable_txids_confirmed, vec_type),
+                       (15, counterparty_fulfilled_htlcs, option),
                });
 
-               let mut secp_ctx = Secp256k1::new();
-               secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
-
                Ok((best_block.block_hash(), ChannelMonitor::from_impl(ChannelMonitorImpl {
                        latest_update_id,
                        commitment_transaction_number_obscure_factor,
@@ -3958,6 +3948,7 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
                        counterparty_claimable_outpoints,
                        counterparty_commitment_txn_on_chain,
                        counterparty_hash_commitment_number,
+                       counterparty_fulfilled_htlcs: counterparty_fulfilled_htlcs.unwrap(),
 
                        prev_holder_signed_commitment_tx,
                        current_holder_commitment_tx,
@@ -3983,8 +3974,6 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
 
                        best_block,
                        counterparty_node_id,
-
-                       secp_ctx,
                })))
        }
 }
@@ -4019,7 +4008,7 @@ mod tests {
        use crate::ln::{PaymentPreimage, PaymentHash};
        use crate::ln::chan_utils;
        use crate::ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
-       use crate::ln::channelmanager::{self, PaymentSendFailure, PaymentId};
+       use crate::ln::channelmanager::{PaymentSendFailure, PaymentId};
        use crate::ln::functional_test_utils::*;
        use crate::ln::script::ShutdownScript;
        use crate::util::errors::APIError;
@@ -4047,10 +4036,8 @@ mod tests {
                let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-               let channel = create_announced_chan_between_nodes(
-                       &nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               create_announced_chan_between_nodes(
-                       &nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
+               create_announced_chan_between_nodes(&nodes, 1, 2);
 
                // Rebalance somewhat
                send_payment(&nodes[0], &[&nodes[1]], 10_000_000);
@@ -4079,7 +4066,7 @@ mod tests {
 
                let (_, pre_update_monitor) = <(BlockHash, ChannelMonitor<InMemorySigner>)>::read(
                                                &mut io::Cursor::new(&get_monitor!(nodes[1], channel.2).encode()),
-                                               &nodes[1].keys_manager.backing).unwrap();
+                                               (&nodes[1].keys_manager.backing, &nodes[1].keys_manager.backing)).unwrap();
 
                // If the ChannelManager tries to update the channel, however, the ChainMonitor will pass
                // the update through to the ChannelMonitor which will refuse it (as the channel is closed).
@@ -4128,11 +4115,13 @@ mod tests {
        fn test_prune_preimages() {
                let secp_ctx = Secp256k1::new();
                let logger = Arc::new(TestLogger::new());
-               let broadcaster = Arc::new(TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))});
+               let broadcaster = Arc::new(TestBroadcaster {
+                       txn_broadcasted: Mutex::new(Vec::new()),
+                       blocks: Arc::new(Mutex::new(Vec::new()))
+               });
                let fee_estimator = TestFeeEstimator { sat_per_kw: Mutex::new(253) };
 
                let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
-               let dummy_tx = Transaction { version: 0, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() };
 
                let mut preimages = Vec::new();
                {
@@ -4185,7 +4174,6 @@ mod tests {
                        SecretKey::from_slice(&[41; 32]).unwrap(),
                        SecretKey::from_slice(&[41; 32]).unwrap(),
                        SecretKey::from_slice(&[41; 32]).unwrap(),
-                       SecretKey::from_slice(&[41; 32]).unwrap(),
                        [41; 32],
                        0,
                        [0; 32],
@@ -4214,7 +4202,7 @@ mod tests {
                // Prune with one old state and a holder commitment tx holding a few overlaps with the
                // old state.
                let shutdown_pubkey = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
-               let best_block = BestBlock::from_genesis(Network::Testnet);
+               let best_block = BestBlock::from_network(Network::Testnet);
                let monitor = ChannelMonitor::new(Secp256k1::new(), keys,
                                                  Some(ShutdownScript::new_p2wpkh_from_pubkey(shutdown_pubkey).into_inner()), 0, &Script::new(),
                                                  (OutPoint { txid: Txid::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()),
@@ -4223,11 +4211,10 @@ mod tests {
                                                  HolderCommitmentTransaction::dummy(), best_block, dummy_key);
 
                monitor.provide_latest_holder_commitment_tx(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..10])).unwrap();
-               let dummy_txid = dummy_tx.txid();
-               monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key, &logger);
-               monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key, &logger);
-               monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key, &logger);
-               monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key, &logger);
+               monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"1").into_inner()),
+                       preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key, &logger);
+               monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"2").into_inner()),
+                       preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key, &logger);
                for &(ref preimage, ref hash) in preimages.iter() {
                        let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_estimator);
                        monitor.provide_payment_preimage(hash, preimage, &broadcaster, &bounded_fee_estimator, &logger);
@@ -4241,6 +4228,9 @@ mod tests {
                test_preimages_exist!(&preimages[0..10], monitor);
                test_preimages_exist!(&preimages[15..20], monitor);
 
+               monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"3").into_inner()),
+                       preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key, &logger);
+
                // Now provide a further secret, pruning preimages 15-17
                secret[0..32].clone_from_slice(&hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
                monitor.provide_secret(281474976710654, secret.clone()).unwrap();
@@ -4248,6 +4238,9 @@ mod tests {
                test_preimages_exist!(&preimages[0..10], monitor);
                test_preimages_exist!(&preimages[17..20], monitor);
 
+               monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"4").into_inner()),
+                       preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key, &logger);
+
                // Now update holder commitment tx info, pruning only element 18 as we still care about the
                // previous commitment tx's preimages too
                monitor.provide_latest_holder_commitment_tx(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..5])).unwrap();
index 16075cdac4b2375b989abd28c7eec105af610c79..21331fff435e601a255a6944c04a8fff820db0bc 100644 (file)
@@ -21,7 +21,6 @@ use bitcoin::util::sighash;
 
 use bitcoin::bech32::u5;
 use bitcoin::hashes::{Hash, HashEngine};
-use bitcoin::hashes::sha256::HashEngine as Sha256State;
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::WPubkeyHash;
@@ -34,14 +33,14 @@ use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
 
 use crate::util::transaction_utils;
 use crate::util::crypto::{hkdf_extract_expand_twice, sign};
-use crate::util::ser::{Writeable, Writer, Readable, ReadableArgs};
+use crate::util::ser::{Writeable, Writer, Readable};
 #[cfg(anchors)]
 use crate::util::events::HTLCDescriptor;
 use crate::chain::transaction::OutPoint;
 use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
 use crate::ln::{chan_utils, PaymentPreimage};
 use crate::ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
-use crate::ln::msgs::UnsignedChannelAnnouncement;
+use crate::ln::msgs::{UnsignedChannelAnnouncement, UnsignedGossipMessage};
 use crate::ln::script::ShutdownScript;
 
 use crate::prelude::*;
@@ -49,6 +48,8 @@ use core::convert::TryInto;
 use core::sync::atomic::{AtomicUsize, Ordering};
 use crate::io::{self, Error};
 use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
+use crate::util::atomic_counter::AtomicCounter;
+use crate::util::chacha20::ChaCha20;
 use crate::util::invoice::construct_invoice_preimage;
 
 /// Used as initial key material, to be expanded into multiple secret keys (but not to be used
@@ -75,7 +76,7 @@ pub struct DelayedPaymentOutputDescriptor {
        /// The revocation point specific to the commitment transaction which was broadcast. Used to
        /// derive the witnessScript for this output.
        pub revocation_pubkey: PublicKey,
-       /// Arbitrary identification information returned by a call to [`BaseSign::channel_keys_id`].
+       /// Arbitrary identification information returned by a call to [`ChannelSigner::channel_keys_id`].
        /// This may be useful in re-deriving keys used in the channel to spend the output.
        pub channel_keys_id: [u8; 32],
        /// The value of the channel which this output originated from, possibly indirectly.
@@ -107,7 +108,7 @@ pub struct StaticPaymentOutputDescriptor {
        pub outpoint: OutPoint,
        /// The output which is referenced by the given outpoint.
        pub output: TxOut,
-       /// Arbitrary identification information returned by a call to [`BaseSign::channel_keys_id`].
+       /// Arbitrary identification information returned by a call to [`ChannelSigner::channel_keys_id`].
        /// This may be useful in re-deriving keys used in the channel to spend the output.
        pub channel_keys_id: [u8; 32],
        /// The value of the channel which this transactions spends.
@@ -137,7 +138,7 @@ impl_writeable_tlv_based!(StaticPaymentOutputDescriptor, {
 /// [`SpendableOutputs`]: crate::util::events::Event::SpendableOutputs
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum SpendableOutputDescriptor {
-       /// An output to a script which was provided via [`KeysInterface`] directly, either from
+       /// An output to a script which was provided via [`SignerProvider`] directly, either from
        /// [`get_destination_script`] or [`get_shutdown_scriptpubkey`], thus you should already
        /// know how to spend it. No secret keys are provided as LDK was never given any key.
        /// These may include outputs from a transaction punishing our counterparty or claiming an HTLC
@@ -172,15 +173,15 @@ pub enum SpendableOutputDescriptor {
        ///
        /// To derive the delayed payment key which is used to sign this input, you must pass the
        /// holder [`InMemorySigner::delayed_payment_base_key`] (i.e., the private key which corresponds to the
-       /// [`ChannelPublicKeys::delayed_payment_basepoint`] in [`BaseSign::pubkeys`]) and the provided
+       /// [`ChannelPublicKeys::delayed_payment_basepoint`] in [`ChannelSigner::pubkeys`]) and the provided
        /// [`DelayedPaymentOutputDescriptor::per_commitment_point`] to [`chan_utils::derive_private_key`]. The public key can be
        /// generated without the secret key using [`chan_utils::derive_public_key`] and only the
-       /// [`ChannelPublicKeys::delayed_payment_basepoint`] which appears in [`BaseSign::pubkeys`].
+       /// [`ChannelPublicKeys::delayed_payment_basepoint`] which appears in [`ChannelSigner::pubkeys`].
        ///
        /// To derive the [`DelayedPaymentOutputDescriptor::revocation_pubkey`] provided here (which is
        /// used in the witness script generation), you must pass the counterparty
        /// [`ChannelPublicKeys::revocation_basepoint`] (which appears in the call to
-       /// [`BaseSign::provide_channel_parameters`]) and the provided
+       /// [`ChannelSigner::provide_channel_parameters`]) and the provided
        /// [`DelayedPaymentOutputDescriptor::per_commitment_point`] to
        /// [`chan_utils::derive_public_revocation_key`].
        ///
@@ -191,7 +192,7 @@ pub enum SpendableOutputDescriptor {
        /// [`chan_utils::get_revokeable_redeemscript`].
        DelayedPaymentOutput(DelayedPaymentOutputDescriptor),
        /// An output to a P2WPKH, spendable exclusively by our payment key (i.e., the private key
-       /// which corresponds to the `payment_point` in [`BaseSign::pubkeys`]). The witness
+       /// which corresponds to the `payment_point` in [`ChannelSigner::pubkeys`]). The witness
        /// in the spending input is, thus, simply:
        /// ```bitcoin
        /// <BIP 143 signature> <payment key>
@@ -212,18 +213,14 @@ impl_writeable_tlv_based_enum!(SpendableOutputDescriptor,
        (2, StaticPaymentOutput),
 );
 
-/// A trait to sign Lightning channel transactions as described in
-/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
-///
-/// Signing services could be implemented on a hardware wallet and should implement signing
-/// policies in order to be secure. Please refer to the [VLS Policy
-/// Controls](https://gitlab.com/lightning-signer/validating-lightning-signer/-/blob/main/docs/policy-controls.md)
-/// for an example of such policies.
-pub trait BaseSign {
+/// A trait to handle Lightning channel key material without concretizing the channel type or
+/// the signature mechanism.
+pub trait ChannelSigner {
        /// Gets the per-commitment point for a specific commitment number
        ///
        /// Note that the commitment number starts at `(1 << 48) - 1` and counts backwards.
        fn get_per_commitment_point(&self, idx: u64, secp_ctx: &Secp256k1<secp256k1::All>) -> PublicKey;
+
        /// Gets the commitment secret for a specific commitment number as part of the revocation process
        ///
        /// An external signer implementation should error here if the commitment was already signed
@@ -234,6 +231,7 @@ pub trait BaseSign {
        /// Note that the commitment number starts at `(1 << 48) - 1` and counts backwards.
        // TODO: return a Result so we can signal a validation error
        fn release_commitment_secret(&self, idx: u64) -> [u8; 32];
+
        /// Validate the counterparty's signatures on the holder commitment transaction and HTLCs.
        ///
        /// This is required in order for the signer to make sure that releasing a commitment
@@ -249,12 +247,35 @@ pub trait BaseSign {
        /// irrelevant or duplicate preimages.
        fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction,
                preimages: Vec<PaymentPreimage>) -> Result<(), ()>;
+
        /// Returns the holder's channel public keys and basepoints.
        fn pubkeys(&self) -> &ChannelPublicKeys;
+
        /// Returns an arbitrary identifier describing the set of keys which are provided back to you in
        /// some [`SpendableOutputDescriptor`] types. This should be sufficient to identify this
-       /// [`BaseSign`] object uniquely and lookup or re-derive its keys.
+       /// [`EcdsaChannelSigner`] object uniquely and lookup or re-derive its keys.
        fn channel_keys_id(&self) -> [u8; 32];
+
+       /// Set the counterparty static channel data, including basepoints,
+       /// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint.
+       ///
+       /// This data is static, and will never change for a channel once set. For a given [`ChannelSigner`]
+       /// instance, LDK will call this method exactly once - either immediately after construction
+       /// (not including if done via [`SignerProvider::read_chan_signer`]) or when the funding
+       /// information has been generated.
+       ///
+       /// channel_parameters.is_populated() MUST be true.
+       fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
+}
+
+/// A trait to sign Lightning channel transactions as described in
+/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
+///
+/// Signing services could be implemented on a hardware wallet and should implement signing
+/// policies in order to be secure. Please refer to the [VLS Policy
+/// Controls](https://gitlab.com/lightning-signer/validating-lightning-signer/-/blob/main/docs/policy-controls.md)
+/// for an example of such policies.
+pub trait EcdsaChannelSigner: ChannelSigner {
        /// Create a signature for a counterparty's commitment transaction and associated HTLC transactions.
        ///
        /// Note that if signing fails or is rejected, the channel will be force-closed.
@@ -383,27 +404,18 @@ pub trait BaseSign {
        fn sign_holder_anchor_input(
                &self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
        ) -> Result<Signature, ()>;
-       /// Signs a channel announcement message with our funding key and our node secret key (aka
-       /// node_id or network_key), proving it comes from one of the channel participants.
+       /// Signs a channel announcement message with our funding key proving it comes from one of the
+       /// channel participants.
        ///
-       /// The first returned signature should be from our node secret key, the second from our
-       /// funding key.
+       /// Channel announcements also require a signature from each node's network key. Our node
+       /// signature is computed through [`NodeSigner::sign_gossip_message`].
        ///
        /// Note that if this fails or is rejected, the channel will not be publicly announced and
        /// our counterparty may (though likely will not) close the channel on us for violating the
        /// protocol.
-       fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
-               -> Result<(Signature, Signature), ()>;
-       /// Set the counterparty static channel data, including basepoints,
-       /// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint.
-       ///
-       /// This data is static, and will never change for a channel once set. For a given [`BaseSign`]
-       /// instance, LDK will call this method exactly once - either immediately after construction
-       /// (not including if done via [`SignerProvider::read_chan_signer`]) or when the funding
-       /// information has been generated.
-       ///
-       /// channel_parameters.is_populated() MUST be true.
-       fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
+       fn sign_channel_announcement_with_funding_key(
+               &self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
+       ) -> Result<Signature, ()>;
 }
 
 /// A writeable signer.
@@ -413,7 +425,7 @@ pub trait BaseSign {
 ///
 /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
 /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
-pub trait Sign: BaseSign + Writeable {}
+pub trait WriteableEcdsaChannelSigner: EcdsaChannelSigner + Writeable {}
 
 /// Specifies the recipient of an invoice.
 ///
@@ -438,16 +450,6 @@ pub trait EntropySource {
 
 /// A trait that can handle cryptographic operations at the scope level of a node.
 pub trait NodeSigner {
-       /// Get node secret key based on the provided [`Recipient`].
-       ///
-       /// The `node_id`/`network_key` is the public key that corresponds to this secret key.
-       ///
-       /// This method must return the same value each time it is called with a given [`Recipient`]
-       /// parameter.
-       ///
-       /// Errors if the [`Recipient`] variant is not supported by the implementation.
-       fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()>;
-
        /// Get secret key material as bytes for use in encrypting and decrypting inbound payment data.
        ///
        /// If the implementor of this trait supports [phantom node payments], then every node that is
@@ -462,24 +464,22 @@ pub trait NodeSigner {
        /// [phantom node payments]: PhantomKeysManager
        fn get_inbound_payment_key_material(&self) -> KeyMaterial;
 
-       /// Get node id based on the provided [`Recipient`]. This public key corresponds to the secret in
-       /// [`get_node_secret`].
+       /// Get node id based on the provided [`Recipient`].
        ///
        /// This method must return the same value each time it is called with a given [`Recipient`]
        /// parameter.
        ///
        /// Errors if the [`Recipient`] variant is not supported by the implementation.
-       ///
-       /// [`get_node_secret`]: Self::get_node_secret
        fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()>;
 
-       /// Gets the ECDH shared secret of our [`node secret`] and `other_key`, multiplying by `tweak` if
+       /// Gets the ECDH shared secret of our node secret and `other_key`, multiplying by `tweak` if
        /// one is provided. Note that this tweak can be applied to `other_key` instead of our node
        /// secret, though this is less efficient.
        ///
-       /// Errors if the [`Recipient`] variant is not supported by the implementation.
+       /// Note that if this fails while attempting to forward an HTLC, LDK will panic. The error
+       /// should be resolved to allow LDK to resume forwarding HTLCs.
        ///
-       /// [`node secret`]: Self::get_node_secret
+       /// Errors if the [`Recipient`] variant is not supported by the implementation.
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()>;
 
        /// Sign an invoice.
@@ -494,12 +494,20 @@ pub trait NodeSigner {
        ///
        /// Errors if the [`Recipient`] variant is not supported by the implementation.
        fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()>;
+
+       /// Sign a gossip message.
+       ///
+       /// Note that if this fails, LDK may panic and the message will not be broadcast to the network
+       /// or a possible channel counterparty. If LDK panics, the error should be resolved to allow the
+       /// message to be broadcast, as otherwise it may prevent one from receiving funds over the
+       /// corresponding channel.
+       fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()>;
 }
 
 /// A trait that can return signer instances for individual channels.
 pub trait SignerProvider {
-       /// A type which implements [`Sign`] which will be returned by [`Self::derive_channel_signer`].
-       type Signer : Sign;
+       /// A type which implements [`WriteableEcdsaChannelSigner`] which will be returned by [`Self::derive_channel_signer`].
+       type Signer : WriteableEcdsaChannelSigner;
 
        /// Generates a unique `channel_keys_id` that can be used to obtain a [`Self::Signer`] through
        /// [`SignerProvider::derive_channel_signer`]. The `user_channel_id` is provided to allow
@@ -514,12 +522,12 @@ pub trait SignerProvider {
        /// To derive a new `Signer`, a fresh `channel_keys_id` should be obtained through
        /// [`SignerProvider::generate_channel_keys_id`]. Otherwise, an existing `Signer` can be
        /// re-derived from its `channel_keys_id`, which can be obtained through its trait method
-       /// [`BaseSign::channel_keys_id`].
+       /// [`ChannelSigner::channel_keys_id`].
        fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::Signer;
 
-       /// Reads a [`Signer`] for this [`KeysInterface`] from the given input stream.
+       /// Reads a [`Signer`] for this [`SignerProvider`] from the given input stream.
        /// This is only called during deserialization of other objects which contain
-       /// [`Sign`]-implementing objects (i.e., [`ChannelMonitor`]s and [`ChannelManager`]s).
+       /// [`WriteableEcdsaChannelSigner`]-implementing objects (i.e., [`ChannelMonitor`]s and [`ChannelManager`]s).
        /// The bytes are exactly those which `<Self::Signer as Writeable>::write()` writes, and
        /// contain no versioning scheme. You may wish to include your own version prefix and ensure
        /// you've read all of the provided bytes to ensure no corruption occurred.
@@ -545,11 +553,8 @@ pub trait SignerProvider {
        fn get_shutdown_scriptpubkey(&self) -> ShutdownScript;
 }
 
-/// A trait to describe an object which can get user secrets and key material.
-pub trait KeysInterface: EntropySource + NodeSigner + SignerProvider {}
-
 #[derive(Clone)]
-/// A simple implementation of [`Sign`] that just keeps the private keys in memory.
+/// A simple implementation of [`WriteableEcdsaChannelSigner`] that just keeps the private keys in memory.
 ///
 /// This implementation performs no policy checks and is insufficient by itself as
 /// a secure external signer.
@@ -569,8 +574,6 @@ pub struct InMemorySigner {
        pub commitment_seed: [u8; 32],
        /// Holder public keys and basepoints.
        pub(crate) holder_channel_pubkeys: ChannelPublicKeys,
-       /// Private key of our node secret, used for signing channel announcements.
-       node_secret: SecretKey,
        /// Counterparty public keys and counterparty/holder `selected_contest_delay`, populated on channel acceptance.
        channel_parameters: Option<ChannelTransactionParameters>,
        /// The total value of this channel.
@@ -583,7 +586,6 @@ impl InMemorySigner {
        /// Creates a new [`InMemorySigner`].
        pub fn new<C: Signing>(
                secp_ctx: &Secp256k1<C>,
-               node_secret: SecretKey,
                funding_key: SecretKey,
                revocation_base_key: SecretKey,
                payment_key: SecretKey,
@@ -604,7 +606,6 @@ impl InMemorySigner {
                        delayed_payment_base_key,
                        htlc_base_key,
                        commitment_seed,
-                       node_secret,
                        channel_value_satoshis,
                        holder_channel_pubkeys,
                        channel_parameters: None,
@@ -630,38 +631,38 @@ impl InMemorySigner {
 
        /// Returns the counterparty's pubkeys.
        ///
-       /// Will panic if [`BaseSign::provide_channel_parameters`] has not been called before.
+       /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
        pub fn counterparty_pubkeys(&self) -> &ChannelPublicKeys { &self.get_channel_parameters().counterparty_parameters.as_ref().unwrap().pubkeys }
        /// Returns the `contest_delay` value specified by our counterparty and applied on holder-broadcastable
        /// transactions, i.e., the amount of time that we have to wait to recover our funds if we
        /// broadcast a transaction.
        ///
-       /// Will panic if [`BaseSign::provide_channel_parameters`] has not been called before.
+       /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
        pub fn counterparty_selected_contest_delay(&self) -> u16 { self.get_channel_parameters().counterparty_parameters.as_ref().unwrap().selected_contest_delay }
        /// Returns the `contest_delay` value specified by us and applied on transactions broadcastable
        /// by our counterparty, i.e., the amount of time that they have to wait to recover their funds
        /// if they broadcast a transaction.
        ///
-       /// Will panic if [`BaseSign::provide_channel_parameters`] has not been called before.
+       /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
        pub fn holder_selected_contest_delay(&self) -> u16 { self.get_channel_parameters().holder_selected_contest_delay }
        /// Returns whether the holder is the initiator.
        ///
-       /// Will panic if [`BaseSign::provide_channel_parameters`] has not been called before.
+       /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
        pub fn is_outbound(&self) -> bool { self.get_channel_parameters().is_outbound_from_holder }
        /// Funding outpoint
        ///
-       /// Will panic if [`BaseSign::provide_channel_parameters`] has not been called before.
+       /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
        pub fn funding_outpoint(&self) -> &OutPoint { self.get_channel_parameters().funding_outpoint.as_ref().unwrap() }
        /// Returns a [`ChannelTransactionParameters`] for this channel, to be used when verifying or
        /// building transactions.
        ///
-       /// Will panic if [`BaseSign::provide_channel_parameters`] has not been called before.
+       /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
        pub fn get_channel_parameters(&self) -> &ChannelTransactionParameters {
                self.channel_parameters.as_ref().unwrap()
        }
        /// Returns whether anchors should be used.
        ///
-       /// Will panic if [`BaseSign::provide_channel_parameters`] has not been called before.
+       /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
        pub fn opt_anchors(&self) -> bool {
                self.get_channel_parameters().opt_anchors.is_some()
        }
@@ -735,7 +736,7 @@ impl InMemorySigner {
        }
 }
 
-impl BaseSign for InMemorySigner {
+impl ChannelSigner for InMemorySigner {
        fn get_per_commitment_point(&self, idx: u64, secp_ctx: &Secp256k1<secp256k1::All>) -> PublicKey {
                let commitment_secret = SecretKey::from_slice(&chan_utils::build_commitment_secret(&self.commitment_seed, idx)).unwrap();
                PublicKey::from_secret_key(secp_ctx, &commitment_secret)
@@ -753,6 +754,18 @@ impl BaseSign for InMemorySigner {
 
        fn channel_keys_id(&self) -> [u8; 32] { self.channel_keys_id }
 
+       fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
+               assert!(self.channel_parameters.is_none() || self.channel_parameters.as_ref().unwrap() == channel_parameters);
+               if self.channel_parameters.is_some() {
+                       // The channel parameters were already set and they match, return early.
+                       return;
+               }
+               assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated");
+               self.channel_parameters = Some(channel_parameters.clone());
+       }
+}
+
+impl EcdsaChannelSigner for InMemorySigner {
        fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, _preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
                let trusted_tx = commitment_tx.trust();
                let keys = trusted_tx.keys();
@@ -875,20 +888,11 @@ impl BaseSign for InMemorySigner {
                Ok(sign(secp_ctx, &hash_to_message!(&sighash[..]), &self.funding_key))
        }
 
-       fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
-       -> Result<(Signature, Signature), ()> {
+       fn sign_channel_announcement_with_funding_key(
+               &self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
+       ) -> Result<Signature, ()> {
                let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
-               Ok((sign(secp_ctx, &msghash, &self.node_secret), sign(secp_ctx, &msghash, &self.funding_key)))
-       }
-
-       fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
-               assert!(self.channel_parameters.is_none() || self.channel_parameters.as_ref().unwrap() == channel_parameters);
-               if self.channel_parameters.is_some() {
-                       // The channel parameters were already set and they match, return early.
-                       return;
-               }
-               assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated");
-               self.channel_parameters = Some(channel_parameters.clone());
+               Ok(sign(secp_ctx, &msghash, &self.funding_key))
        }
 }
 
@@ -896,7 +900,7 @@ const SERIALIZATION_VERSION: u8 = 1;
 
 const MIN_SERIALIZATION_VERSION: u8 = 1;
 
-impl Sign for InMemorySigner {}
+impl WriteableEcdsaChannelSigner for InMemorySigner {}
 
 impl Writeable for InMemorySigner {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
@@ -918,8 +922,8 @@ impl Writeable for InMemorySigner {
        }
 }
 
-impl ReadableArgs<SecretKey> for InMemorySigner {
-       fn read<R: io::Read>(reader: &mut R, node_secret: SecretKey) -> Result<Self, DecodeError> {
+impl Readable for InMemorySigner {
+       fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                let funding_key = Readable::read(reader)?;
@@ -944,7 +948,6 @@ impl ReadableArgs<SecretKey> for InMemorySigner {
                        payment_key,
                        delayed_payment_base_key,
                        htlc_base_key,
-                       node_secret,
                        commitment_seed,
                        channel_value_satoshis,
                        holder_channel_pubkeys,
@@ -954,8 +957,8 @@ impl ReadableArgs<SecretKey> for InMemorySigner {
        }
 }
 
-/// Simple [`KeysInterface`] implementation that takes a 32-byte seed for use as a BIP 32 extended
-/// key and derives keys from that.
+/// Simple implementation of [`EntropySource`], [`NodeSigner`], and [`SignerProvider`] that takes a
+/// 32-byte seed for use as a BIP 32 extended key and derives keys from that.
 ///
 /// Your `node_id` is seed/0'.
 /// Unilateral closes may use seed/1'.
@@ -977,9 +980,8 @@ pub struct KeysManager {
        channel_master_key: ExtendedPrivKey,
        channel_child_index: AtomicUsize,
 
-       rand_bytes_master_key: ExtendedPrivKey,
-       rand_bytes_child_index: AtomicUsize,
-       rand_bytes_unique_start: Sha256State,
+       rand_bytes_unique_start: [u8; 32],
+       rand_bytes_index: AtomicCounter,
 
        seed: [u8; 32],
        starting_time_secs: u64,
@@ -1025,15 +1027,16 @@ impl KeysManager {
                                        Err(_) => panic!("Your RNG is busted"),
                                };
                                let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3).unwrap()).expect("Your RNG is busted");
-                               let rand_bytes_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4).unwrap()).expect("Your RNG is busted");
                                let inbound_payment_key: SecretKey = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(5).unwrap()).expect("Your RNG is busted").private_key;
                                let mut inbound_pmt_key_bytes = [0; 32];
                                inbound_pmt_key_bytes.copy_from_slice(&inbound_payment_key[..]);
 
-                               let mut rand_bytes_unique_start = Sha256::engine();
-                               rand_bytes_unique_start.input(&starting_time_secs.to_be_bytes());
-                               rand_bytes_unique_start.input(&starting_time_nanos.to_be_bytes());
-                               rand_bytes_unique_start.input(seed);
+                               let mut rand_bytes_engine = Sha256::engine();
+                               rand_bytes_engine.input(&starting_time_secs.to_be_bytes());
+                               rand_bytes_engine.input(&starting_time_nanos.to_be_bytes());
+                               rand_bytes_engine.input(seed);
+                               rand_bytes_engine.input(b"LDK PRNG Seed");
+                               let rand_bytes_unique_start = Sha256::from_engine(rand_bytes_engine).into_inner();
 
                                let mut res = KeysManager {
                                        secp_ctx,
@@ -1047,9 +1050,8 @@ impl KeysManager {
                                        channel_master_key,
                                        channel_child_index: AtomicUsize::new(0),
 
-                                       rand_bytes_master_key,
-                                       rand_bytes_child_index: AtomicUsize::new(0),
                                        rand_bytes_unique_start,
+                                       rand_bytes_index: AtomicCounter::new(),
 
                                        seed: *seed,
                                        starting_time_secs,
@@ -1062,7 +1064,13 @@ impl KeysManager {
                        Err(_) => panic!("Your rng is busted"),
                }
        }
-       /// Derive an old [`Sign`] containing per-channel secrets based on a key derivation parameters.
+
+       /// Gets the "node_id" secret key used to sign gossip announcements, decode onion data, etc.
+       pub fn get_node_secret_key(&self) -> SecretKey {
+               self.node_secret
+       }
+
+       /// Derive an old [`WriteableEcdsaChannelSigner`] containing per-channel secrets based on a key derivation parameters.
        pub fn derive_channel_keys(&self, channel_value_satoshis: u64, params: &[u8; 32]) -> InMemorySigner {
                let chan_id = u64::from_be_bytes(params[0..8].try_into().unwrap());
                let mut unique_start = Sha256::engine();
@@ -1102,7 +1110,6 @@ impl KeysManager {
 
                InMemorySigner::new(
                        &self.secp_ctx,
-                       self.node_secret,
                        funding_key,
                        revocation_base_key,
                        payment_key,
@@ -1247,25 +1254,14 @@ impl KeysManager {
 
 impl EntropySource for KeysManager {
        fn get_secure_random_bytes(&self) -> [u8; 32] {
-               let mut sha = self.rand_bytes_unique_start.clone();
-
-               let child_ix = self.rand_bytes_child_index.fetch_add(1, Ordering::AcqRel);
-               let child_privkey = self.rand_bytes_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
-               sha.input(&child_privkey.private_key[..]);
-
-               sha.input(b"Unique Secure Random Bytes Salt");
-               Sha256::from_engine(sha).into_inner()
+               let index = self.rand_bytes_index.get_increment();
+               let mut nonce = [0u8; 16];
+               nonce[..8].copy_from_slice(&index.to_be_bytes());
+               ChaCha20::get_single_block(&self.rand_bytes_unique_start, &nonce)
        }
 }
 
 impl NodeSigner for KeysManager {
-       fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
-               match recipient {
-                       Recipient::Node => Ok(self.node_secret.clone()),
-                       Recipient::PhantomNode => Err(())
-               }
-       }
-
        fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
                match recipient {
                        Recipient::Node => Ok(self.node_id.clone()),
@@ -1274,7 +1270,10 @@ impl NodeSigner for KeysManager {
        }
 
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
-               let mut node_secret = self.get_node_secret(recipient)?;
+               let mut node_secret = match recipient {
+                       Recipient::Node => Ok(self.node_secret.clone()),
+                       Recipient::PhantomNode => Err(())
+               }?;
                if let Some(tweak) = tweak {
                        node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
                }
@@ -1288,10 +1287,15 @@ impl NodeSigner for KeysManager {
        fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
                let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
                let secret = match recipient {
-                       Recipient::Node => self.get_node_secret(Recipient::Node)?,
-                       Recipient::PhantomNode => return Err(()),
-               };
-               Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
+                       Recipient::Node => Ok(&self.node_secret),
+                       Recipient::PhantomNode => Err(())
+               }?;
+               Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
+       }
+
+       fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
+               let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
+               Ok(sign(&self.secp_ctx, &msg_hash, &self.node_secret))
        }
 }
 
@@ -1319,7 +1323,7 @@ impl SignerProvider for KeysManager {
        }
 
        fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
-               InMemorySigner::read(&mut io::Cursor::new(reader), self.node_secret.clone())
+               InMemorySigner::read(&mut io::Cursor::new(reader))
        }
 
        fn get_destination_script(&self) -> Script {
@@ -1331,8 +1335,6 @@ impl SignerProvider for KeysManager {
        }
 }
 
-impl KeysInterface for KeysManager {}
-
 /// Similar to [`KeysManager`], but allows the node using this struct to receive phantom node
 /// payments.
 ///
@@ -1368,13 +1370,6 @@ impl EntropySource for PhantomKeysManager {
 }
 
 impl NodeSigner for PhantomKeysManager {
-       fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
-               match recipient {
-                       Recipient::Node => self.inner.get_node_secret(Recipient::Node),
-                       Recipient::PhantomNode => Ok(self.phantom_secret.clone()),
-               }
-       }
-
        fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
                match recipient {
                        Recipient::Node => self.inner.get_node_id(Recipient::Node),
@@ -1383,7 +1378,10 @@ impl NodeSigner for PhantomKeysManager {
        }
 
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
-               let mut node_secret = self.get_node_secret(recipient)?;
+               let mut node_secret = match recipient {
+                       Recipient::Node => self.inner.node_secret.clone(),
+                       Recipient::PhantomNode => self.phantom_secret.clone(),
+               };
                if let Some(tweak) = tweak {
                        node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
                }
@@ -1396,8 +1394,15 @@ impl NodeSigner for PhantomKeysManager {
 
        fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
                let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
-               let secret = self.get_node_secret(recipient)?;
-               Ok(self.inner.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
+               let secret = match recipient {
+                       Recipient::Node => &self.inner.node_secret,
+                       Recipient::PhantomNode => &self.phantom_secret,
+               };
+               Ok(self.inner.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
+       }
+
+       fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
+               self.inner.sign_gossip_message(msg)
        }
 }
 
@@ -1425,8 +1430,6 @@ impl SignerProvider for PhantomKeysManager {
        }
 }
 
-impl KeysInterface for PhantomKeysManager {}
-
 impl PhantomKeysManager {
        /// Constructs a [`PhantomKeysManager`] given a 32-byte seed and an additional `cross_node_seed`
        /// that is shared across all nodes that intend to participate in [phantom node payments]
@@ -1461,10 +1464,76 @@ impl PhantomKeysManager {
        pub fn derive_channel_keys(&self, channel_value_satoshis: u64, params: &[u8; 32]) -> InMemorySigner {
                self.inner.derive_channel_keys(channel_value_satoshis, params)
        }
+
+       /// Gets the "node_id" secret key used to sign gossip announcements, decode onion data, etc.
+       pub fn get_node_secret_key(&self) -> SecretKey {
+               self.inner.get_node_secret_key()
+       }
+
+       /// Gets the "node_id" secret key of the phantom node used to sign invoices, decode the
+       /// last-hop onion data, etc.
+       pub fn get_phantom_node_secret_key(&self) -> SecretKey {
+               self.phantom_secret
+       }
 }
 
-// Ensure that BaseSign can have a vtable
+// Ensure that EcdsaChannelSigner can have a vtable
 #[test]
 pub fn dyn_sign() {
-       let _signer: Box<dyn BaseSign>;
+       let _signer: Box<dyn EcdsaChannelSigner>;
+}
+
+#[cfg(all(test, feature = "_bench_unstable", not(feature = "no-std")))]
+mod benches {
+       use std::sync::{Arc, mpsc};
+       use std::sync::mpsc::TryRecvError;
+       use std::thread;
+       use std::time::Duration;
+       use bitcoin::blockdata::constants::genesis_block;
+       use bitcoin::Network;
+       use crate::chain::keysinterface::{EntropySource, KeysManager};
+
+       use test::Bencher;
+
+       #[bench]
+       fn bench_get_secure_random_bytes(bench: &mut Bencher) {
+               let seed = [0u8; 32];
+               let now = Duration::from_secs(genesis_block(Network::Testnet).header.time as u64);
+               let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_micros()));
+
+               let mut handles = Vec::new();
+               let mut stops = Vec::new();
+               for _ in 1..5 {
+                       let keys_manager_clone = Arc::clone(&keys_manager);
+                       let (stop_sender, stop_receiver) = mpsc::channel();
+                       let handle = thread::spawn(move || {
+                               loop {
+                                       keys_manager_clone.get_secure_random_bytes();
+                                       match stop_receiver.try_recv() {
+                                               Ok(_) | Err(TryRecvError::Disconnected) => {
+                                                       println!("Terminating.");
+                                                       break;
+                                               }
+                                               Err(TryRecvError::Empty) => {}
+                                       }
+                               }
+                       });
+                       handles.push(handle);
+                       stops.push(stop_sender);
+               }
+
+               bench.iter(|| {
+                       for _ in 1..100 {
+                               keys_manager.get_secure_random_bytes();
+                       }
+               });
+
+               for stop in stops {
+                       let _ = stop.send(());
+               }
+               for handle in handles {
+                       handle.join().unwrap();
+               }
+       }
+
 }
index 43add75950d6a50c3c07c5a07e525fd7154bf216..a6ed856ae4a0091124e68b78f928f7fb1c41650e 100644 (file)
 use bitcoin::blockdata::block::{Block, BlockHeader};
 use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::blockdata::script::Script;
-use bitcoin::blockdata::transaction::TxOut;
 use bitcoin::hash_types::{BlockHash, Txid};
 use bitcoin::network::constants::Network;
 use bitcoin::secp256k1::PublicKey;
 
 use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, MonitorEvent};
-use crate::chain::keysinterface::Sign;
+use crate::chain::keysinterface::WriteableEcdsaChannelSigner;
 use crate::chain::transaction::{OutPoint, TransactionData};
 
 use crate::prelude::*;
@@ -41,7 +40,7 @@ pub struct BestBlock {
 impl BestBlock {
        /// Constructs a `BestBlock` that represents the genesis block at height 0 of the given
        /// network.
-       pub fn from_genesis(network: Network) -> Self {
+       pub fn from_network(network: Network) -> Self {
                BestBlock {
                        block_hash: genesis_block(network).header.block_hash(),
                        height: 0,
@@ -60,26 +59,6 @@ impl BestBlock {
        pub fn height(&self) -> u32 { self.height }
 }
 
-/// An error when accessing the chain via [`Access`].
-#[derive(Clone, Debug)]
-pub enum AccessError {
-       /// The requested chain is unknown.
-       UnknownChain,
-
-       /// The requested transaction doesn't exist or hasn't confirmed.
-       UnknownTx,
-}
-
-/// The `Access` trait defines behavior for accessing chain data and state, such as blocks and
-/// UTXOs.
-pub trait Access {
-       /// Returns the transaction output of a funding transaction encoded by [`short_channel_id`].
-       /// Returns an error if `genesis_hash` is for a different chain or if such a transaction output
-       /// is unknown.
-       ///
-       /// [`short_channel_id`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#definition-of-short_channel_id
-       fn get_utxo(&self, genesis_hash: &BlockHash, short_channel_id: u64) -> Result<TxOut, AccessError>;
-}
 
 /// The `Listen` trait is used to notify when blocks have been connected or disconnected from the
 /// chain.
@@ -176,6 +155,9 @@ pub trait Confirm {
        /// Returns transactions that must be monitored for reorganization out of the chain along
        /// with the hash of the block as part of which it had been previously confirmed.
        ///
+       /// Note that the returned `Option<BlockHash>` might be `None` for channels created with LDK
+       /// 0.0.112 and prior, in which case you need to manually track previous confirmations.
+       ///
        /// Will include any transactions passed to [`transactions_confirmed`] that have insufficient
        /// confirmations to be safe from a chain reorganization. Will not include any transactions
        /// passed to [`transaction_unconfirmed`], unless later reconfirmed.
@@ -291,7 +273,7 @@ pub enum ChannelMonitorUpdateStatus {
 /// multiple instances.
 ///
 /// [`PermanentFailure`]: ChannelMonitorUpdateStatus::PermanentFailure
-pub trait Watch<ChannelSigner: Sign> {
+pub trait Watch<ChannelSigner: WriteableEcdsaChannelSigner> {
        /// Watches a channel identified by `funding_txo` using `monitor`.
        ///
        /// Implementations are responsible for watching the chain for the funding transaction along
@@ -312,7 +294,7 @@ pub trait Watch<ChannelSigner: Sign> {
        /// [`ChannelMonitorUpdateStatus`] for invariants around returning an error.
        ///
        /// [`update_monitor`]: channelmonitor::ChannelMonitor::update_monitor
-       fn update_channel(&self, funding_txo: OutPoint, update: ChannelMonitorUpdate) -> ChannelMonitorUpdateStatus;
+       fn update_channel(&self, funding_txo: OutPoint, update: &ChannelMonitorUpdate) -> ChannelMonitorUpdateStatus;
 
        /// Returns any monitor events since the last call. Subsequent calls must only return new
        /// events.
index 9bfe6fa9af21b1547e5aa8bf2183062cde66f4cd..d3ca02ca7a555114970976fc06dabbe408747b99 100644 (file)
@@ -21,7 +21,7 @@ use bitcoin::hash_types::{Txid, BlockHash};
 use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
 use bitcoin::secp256k1;
 
-use crate::chain::keysinterface::BaseSign;
+use crate::chain::keysinterface::{ChannelSigner, EntropySource, SignerProvider};
 use crate::ln::msgs::DecodeError;
 use crate::ln::PaymentPreimage;
 #[cfg(anchors)]
@@ -31,12 +31,12 @@ use crate::ln::chan_utils::{ChannelTransactionParameters, HolderCommitmentTransa
 use crate::chain::chaininterface::ConfirmationTarget;
 use crate::chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
 use crate::chain::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER};
-use crate::chain::keysinterface::{Sign, KeysInterface};
+use crate::chain::keysinterface::WriteableEcdsaChannelSigner;
 #[cfg(anchors)]
 use crate::chain::package::PackageSolvingData;
 use crate::chain::package::PackageTemplate;
 use crate::util::logger::Logger;
-use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, VecWriter};
+use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable, VecWriter};
 
 use crate::io;
 use crate::prelude::*;
@@ -106,18 +106,14 @@ impl MaybeReadable for OnchainEventEntry {
                let mut txid = Txid::all_zeros();
                let mut height = 0;
                let mut block_hash = None;
-               let mut event = None;
+               let mut event = UpgradableRequired(None);
                read_tlv_fields!(reader, {
                        (0, txid, required),
                        (1, block_hash, option),
                        (2, height, required),
-                       (4, event, ignorable),
+                       (4, event, upgradable_required),
                });
-               if let Some(ev) = event {
-                       Ok(Some(Self { txid, height, block_hash, event: ev }))
-               } else {
-                       Ok(None)
-               }
+               Ok(Some(Self { txid, height, block_hash, event: _init_tlv_based_struct_field!(event, upgradable_required) }))
        }
 }
 
@@ -219,7 +215,8 @@ type PackageID = [u8; 32];
 
 /// OnchainTxHandler receives claiming requests, aggregates them if it's sound, broadcast and
 /// do RBF bumping if possible.
-pub struct OnchainTxHandler<ChannelSigner: Sign> {
+#[derive(PartialEq)]
+pub struct OnchainTxHandler<ChannelSigner: WriteableEcdsaChannelSigner> {
        destination_script: Script,
        holder_commitment: HolderCommitmentTransaction,
        // holder_htlc_sigs and prev_holder_htlc_sigs are in the order as they appear in the commitment
@@ -271,7 +268,7 @@ pub struct OnchainTxHandler<ChannelSigner: Sign> {
 const SERIALIZATION_VERSION: u8 = 1;
 const MIN_SERIALIZATION_VERSION: u8 = 1;
 
-impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
+impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
        pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
 
@@ -322,11 +319,12 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
        }
 }
 
-impl<'a, K: KeysInterface> ReadableArgs<(&'a K, u64, [u8; 32])> for OnchainTxHandler<K::Signer> {
-       fn read<R: io::Read>(reader: &mut R, args: (&'a K, u64, [u8; 32])) -> Result<Self, DecodeError> {
-               let keys_manager = args.0;
-               let channel_value_satoshis = args.1;
-               let channel_keys_id = args.2;
+impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler<SP::Signer> {
+       fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result<Self, DecodeError> {
+               let entropy_source = args.0;
+               let signer_provider = args.1;
+               let channel_value_satoshis = args.2;
+               let channel_keys_id = args.3;
 
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
@@ -352,7 +350,7 @@ impl<'a, K: KeysInterface> ReadableArgs<(&'a K, u64, [u8; 32])> for OnchainTxHan
                        bytes_read += bytes_to_read;
                }
 
-               let mut signer = keys_manager.derive_channel_signer(channel_value_satoshis, channel_keys_id);
+               let mut signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id);
                signer.provide_channel_parameters(&channel_parameters);
 
                let pending_claim_requests_len: u64 = Readable::read(reader)?;
@@ -393,7 +391,7 @@ impl<'a, K: KeysInterface> ReadableArgs<(&'a K, u64, [u8; 32])> for OnchainTxHan
                read_tlv_fields!(reader, {});
 
                let mut secp_ctx = Secp256k1::new();
-               secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
+               secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
 
                Ok(OnchainTxHandler {
                        destination_script,
@@ -414,7 +412,7 @@ impl<'a, K: KeysInterface> ReadableArgs<(&'a K, u64, [u8; 32])> for OnchainTxHan
        }
 }
 
-impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
+impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
        pub(crate) fn new(destination_script: Script, signer: ChannelSigner, channel_parameters: ChannelTransactionParameters, holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>) -> Self {
                OnchainTxHandler {
                        destination_script,
@@ -475,8 +473,8 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                // remove it once it reaches the confirmation threshold, or to generate a new claim if the
                // transaction is reorged out.
                let mut all_inputs_have_confirmed_spend = true;
-               for outpoint in &request_outpoints {
-                       if let Some(first_claim_txid_height) = self.claimable_outpoints.get(outpoint) {
+               for outpoint in request_outpoints.iter() {
+                       if let Some(first_claim_txid_height) = self.claimable_outpoints.get(*outpoint) {
                                // We check for outpoint spends within claims individually rather than as a set
                                // since requests can have outpoints split off.
                                if !self.onchain_events_awaiting_threshold_conf.iter()
@@ -810,7 +808,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                                                        for outpoint in request.outpoints() {
                                                                log_debug!(logger, "Removing claim tracking for {} due to maturation of claim package {}.",
                                                                        outpoint, log_bytes!(package_id));
-                                                               self.claimable_outpoints.remove(&outpoint);
+                                                               self.claimable_outpoints.remove(outpoint);
                                                                #[cfg(anchors)]
                                                                self.pending_claim_events.remove(&package_id);
                                                        }
@@ -819,7 +817,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                                        OnchainEvent::ContentiousOutpoint { package } => {
                                                log_debug!(logger, "Removing claim tracking due to maturation of claim tx for outpoints:");
                                                log_debug!(logger, " {:?}", package.outpoints());
-                                               self.claimable_outpoints.remove(&package.outpoints()[0]);
+                                               self.claimable_outpoints.remove(package.outpoints()[0]);
                                        }
                                }
                        } else {
@@ -897,7 +895,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                                //- resurect outpoint back in its claimable set and regenerate tx
                                match entry.event {
                                        OnchainEvent::ContentiousOutpoint { package } => {
-                                               if let Some(ancestor_claimable_txid) = self.claimable_outpoints.get(&package.outpoints()[0]) {
+                                               if let Some(ancestor_claimable_txid) = self.claimable_outpoints.get(package.outpoints()[0]) {
                                                        if let Some(request) = self.pending_claim_requests.get_mut(&ancestor_claimable_txid.0) {
                                                                request.merge_package(package);
                                                                // Using a HashMap guarantee us than if we have multiple outpoints getting
index 227e5ccd119188204b6f374300b0e5dceb777f46..5537a56f2f3898bcee470ae1fae87cbf44c5767c 100644 (file)
@@ -25,7 +25,7 @@ use crate::ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment};
 use crate::ln::chan_utils;
 use crate::ln::msgs::DecodeError;
 use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT};
-use crate::chain::keysinterface::Sign;
+use crate::chain::keysinterface::WriteableEcdsaChannelSigner;
 #[cfg(anchors)]
 use crate::chain::onchaintx::ExternalHTLCClaim;
 use crate::chain::onchaintx::OnchainTxHandler;
@@ -392,7 +392,7 @@ impl PackageSolvingData {
                        _ => { mem::discriminant(self) == mem::discriminant(&input) }
                }
        }
-       fn finalize_input<Signer: Sign>(&self, bumped_tx: &mut Transaction, i: usize, onchain_handler: &mut OnchainTxHandler<Signer>) -> bool {
+       fn finalize_input<Signer: WriteableEcdsaChannelSigner>(&self, bumped_tx: &mut Transaction, i: usize, onchain_handler: &mut OnchainTxHandler<Signer>) -> bool {
                match self {
                        PackageSolvingData::RevokedOutput(ref outp) => {
                                let chan_keys = TxCreationKeys::derive_new(&onchain_handler.secp_ctx, &outp.per_commitment_point, &outp.counterparty_delayed_payment_base_key, &outp.counterparty_htlc_base_key, &onchain_handler.signer.pubkeys().revocation_basepoint, &onchain_handler.signer.pubkeys().htlc_basepoint);
@@ -448,7 +448,7 @@ impl PackageSolvingData {
                }
                true
        }
-       fn get_finalized_tx<Signer: Sign>(&self, outpoint: &BitcoinOutPoint, onchain_handler: &mut OnchainTxHandler<Signer>) -> Option<Transaction> {
+       fn get_finalized_tx<Signer: WriteableEcdsaChannelSigner>(&self, outpoint: &BitcoinOutPoint, onchain_handler: &mut OnchainTxHandler<Signer>) -> Option<Transaction> {
                match self {
                        PackageSolvingData::HolderHTLCOutput(ref outp) => {
                                debug_assert!(!outp.opt_anchors());
@@ -657,7 +657,7 @@ impl PackageTemplate {
                inputs_weight + witnesses_weight + transaction_weight + output_weight
        }
        #[cfg(anchors)]
-       pub(crate) fn construct_malleable_package_with_external_funding<Signer: Sign>(
+       pub(crate) fn construct_malleable_package_with_external_funding<Signer: WriteableEcdsaChannelSigner>(
                &self, onchain_handler: &mut OnchainTxHandler<Signer>,
        ) -> Option<Vec<ExternalHTLCClaim>> {
                debug_assert!(self.requires_external_funding());
@@ -675,7 +675,7 @@ impl PackageTemplate {
                }
                htlcs
        }
-       pub(crate) fn finalize_malleable_package<L: Deref, Signer: Sign>(
+       pub(crate) fn finalize_malleable_package<L: Deref, Signer: WriteableEcdsaChannelSigner>(
                &self, onchain_handler: &mut OnchainTxHandler<Signer>, value: u64, destination_script: Script, logger: &L
        ) -> Option<Transaction> where L::Target: Logger {
                debug_assert!(self.is_malleable());
@@ -703,7 +703,7 @@ impl PackageTemplate {
                log_debug!(logger, "Finalized transaction {} ready to broadcast", bumped_tx.txid());
                Some(bumped_tx)
        }
-       pub(crate) fn finalize_untractable_package<L: Deref, Signer: Sign>(
+       pub(crate) fn finalize_untractable_package<L: Deref, Signer: WriteableEcdsaChannelSigner>(
                &self, onchain_handler: &mut OnchainTxHandler<Signer>, logger: &L,
        ) -> Option<Transaction> where L::Target: Logger {
                debug_assert!(!self.is_malleable());
diff --git a/lightning/src/debug_sync.rs b/lightning/src/debug_sync.rs
deleted file mode 100644 (file)
index b61d1cb..0000000
+++ /dev/null
@@ -1,432 +0,0 @@
-pub use ::alloc::sync::Arc;
-use core::ops::{Deref, DerefMut};
-use core::time::Duration;
-
-use std::cell::RefCell;
-
-use std::sync::atomic::{AtomicUsize, Ordering};
-use std::sync::Mutex as StdMutex;
-use std::sync::MutexGuard as StdMutexGuard;
-use std::sync::RwLock as StdRwLock;
-use std::sync::RwLockReadGuard as StdRwLockReadGuard;
-use std::sync::RwLockWriteGuard as StdRwLockWriteGuard;
-use std::sync::Condvar as StdCondvar;
-
-use crate::prelude::HashMap;
-
-#[cfg(feature = "backtrace")]
-use {crate::prelude::hash_map, backtrace::Backtrace, std::sync::Once};
-
-#[cfg(not(feature = "backtrace"))]
-struct Backtrace{}
-#[cfg(not(feature = "backtrace"))]
-impl Backtrace { fn new() -> Backtrace { Backtrace {} } }
-
-pub type LockResult<Guard> = Result<Guard, ()>;
-
-pub struct Condvar {
-       inner: StdCondvar,
-}
-
-impl Condvar {
-       pub fn new() -> Condvar {
-               Condvar { inner: StdCondvar::new() }
-       }
-
-       pub fn wait<'a, T>(&'a self, guard: MutexGuard<'a, T>) -> LockResult<MutexGuard<'a, T>> {
-               let mutex: &'a Mutex<T> = guard.mutex;
-               self.inner.wait(guard.into_inner()).map(|lock| MutexGuard { mutex, lock }).map_err(|_| ())
-       }
-
-       #[allow(unused)]
-       pub fn wait_timeout<'a, T>(&'a self, guard: MutexGuard<'a, T>, dur: Duration) -> LockResult<(MutexGuard<'a, T>, ())> {
-               let mutex = guard.mutex;
-               self.inner.wait_timeout(guard.into_inner(), dur).map(|(lock, _)| (MutexGuard { mutex, lock }, ())).map_err(|_| ())
-       }
-
-       pub fn notify_all(&self) { self.inner.notify_all(); }
-}
-
-thread_local! {
-       /// We track the set of locks currently held by a reference to their `LockMetadata`
-       static LOCKS_HELD: RefCell<HashMap<u64, Arc<LockMetadata>>> = RefCell::new(HashMap::new());
-}
-static LOCK_IDX: AtomicUsize = AtomicUsize::new(0);
-
-#[cfg(feature = "backtrace")]
-static mut LOCKS: Option<StdMutex<HashMap<String, Arc<LockMetadata>>>> = None;
-#[cfg(feature = "backtrace")]
-static LOCKS_INIT: Once = Once::new();
-
-/// Metadata about a single lock, by id, the set of things locked-before it, and the backtrace of
-/// when the Mutex itself was constructed.
-struct LockMetadata {
-       lock_idx: u64,
-       locked_before: StdMutex<HashMap<u64, LockDep>>,
-       _lock_construction_bt: Backtrace,
-}
-
-struct LockDep {
-       lock: Arc<LockMetadata>,
-       /// lockdep_trace is unused unless we're building with `backtrace`, so we mark it _
-       _lockdep_trace: Backtrace,
-}
-
-#[cfg(feature = "backtrace")]
-fn get_construction_location(backtrace: &Backtrace) -> String {
-       // Find the first frame that is after `debug_sync` (or that is in our tests) and use
-       // that as the mutex construction site. Note that the first few frames may be in
-       // the `backtrace` crate, so we have to ignore those.
-       let sync_mutex_constr_regex = regex::Regex::new(r"lightning.*debug_sync.*new").unwrap();
-       let mut found_debug_sync = false;
-       for frame in backtrace.frames() {
-               for symbol in frame.symbols() {
-                       let symbol_name = symbol.name().unwrap().as_str().unwrap();
-                       if !sync_mutex_constr_regex.is_match(symbol_name) {
-                               if found_debug_sync {
-                                       if let Some(col) = symbol.colno() {
-                                               return format!("{}:{}:{}", symbol.filename().unwrap().display(), symbol.lineno().unwrap(), col);
-                                       } else {
-                                               // Windows debug symbols don't support column numbers, so fall back to
-                                               // line numbers only if no `colno` is available
-                                               return format!("{}:{}", symbol.filename().unwrap().display(), symbol.lineno().unwrap());
-                                       }
-                               }
-                       } else { found_debug_sync = true; }
-               }
-       }
-       panic!("Couldn't find mutex construction callsite");
-}
-
-impl LockMetadata {
-       fn new() -> Arc<LockMetadata> {
-               let backtrace = Backtrace::new();
-               let lock_idx = LOCK_IDX.fetch_add(1, Ordering::Relaxed) as u64;
-
-               let res = Arc::new(LockMetadata {
-                       locked_before: StdMutex::new(HashMap::new()),
-                       lock_idx,
-                       _lock_construction_bt: backtrace,
-               });
-
-               #[cfg(feature = "backtrace")]
-               {
-                       let lock_constr_location = get_construction_location(&res._lock_construction_bt);
-                       LOCKS_INIT.call_once(|| { unsafe { LOCKS = Some(StdMutex::new(HashMap::new())); } });
-                       let mut locks = unsafe { LOCKS.as_ref() }.unwrap().lock().unwrap();
-                       match locks.entry(lock_constr_location) {
-                               hash_map::Entry::Occupied(e) => return Arc::clone(e.get()),
-                               hash_map::Entry::Vacant(e) => { e.insert(Arc::clone(&res)); },
-                       }
-               }
-               res
-       }
-
-       // Returns whether we were a recursive lock (only relevant for read)
-       fn _pre_lock(this: &Arc<LockMetadata>, read: bool) -> bool {
-               let mut inserted = false;
-               LOCKS_HELD.with(|held| {
-                       // For each lock which is currently locked, check that no lock's locked-before
-                       // set includes the lock we're about to lock, which would imply a lockorder
-                       // inversion.
-                       for (locked_idx, _locked) in held.borrow().iter() {
-                               if read && *locked_idx == this.lock_idx {
-                                       // Recursive read locks are explicitly allowed
-                                       return;
-                               }
-                       }
-                       for (locked_idx, locked) in held.borrow().iter() {
-                               if !read && *locked_idx == this.lock_idx {
-                                       // With `feature = "backtrace"` set, we may be looking at different instances
-                                       // of the same lock.
-                                       debug_assert!(cfg!(feature = "backtrace"), "Tried to acquire a lock while it was held!");
-                               }
-                               for (locked_dep_idx, _locked_dep) in locked.locked_before.lock().unwrap().iter() {
-                                       if *locked_dep_idx == this.lock_idx && *locked_dep_idx != locked.lock_idx {
-                                               #[cfg(feature = "backtrace")]
-                                               panic!("Tried to violate existing lockorder.\nMutex that should be locked after the current lock was created at the following backtrace.\nNote that to get a backtrace for the lockorder violation, you should set RUST_BACKTRACE=1\nLock being taken constructed at: {} ({}):\n{:?}\nLock constructed at: {} ({})\n{:?}\n\nLock dep created at:\n{:?}\n\n",
-                                                       get_construction_location(&this._lock_construction_bt), this.lock_idx, this._lock_construction_bt,
-                                                       get_construction_location(&locked._lock_construction_bt), locked.lock_idx, locked._lock_construction_bt,
-                                                       _locked_dep._lockdep_trace);
-                                               #[cfg(not(feature = "backtrace"))]
-                                               panic!("Tried to violate existing lockorder. Build with the backtrace feature for more info.");
-                                       }
-                               }
-                               // Insert any already-held locks in our locked-before set.
-                               let mut locked_before = this.locked_before.lock().unwrap();
-                               if !locked_before.contains_key(&locked.lock_idx) {
-                                       let lockdep = LockDep { lock: Arc::clone(locked), _lockdep_trace: Backtrace::new() };
-                                       locked_before.insert(lockdep.lock.lock_idx, lockdep);
-                               }
-                       }
-                       held.borrow_mut().insert(this.lock_idx, Arc::clone(this));
-                       inserted = true;
-               });
-               inserted
-       }
-
-       fn pre_lock(this: &Arc<LockMetadata>) { Self::_pre_lock(this, false); }
-       fn pre_read_lock(this: &Arc<LockMetadata>) -> bool { Self::_pre_lock(this, true) }
-
-       fn try_locked(this: &Arc<LockMetadata>) {
-               LOCKS_HELD.with(|held| {
-                       // Since a try-lock will simply fail if the lock is held already, we do not
-                       // consider try-locks to ever generate lockorder inversions. However, if a try-lock
-                       // succeeds, we do consider it to have created lockorder dependencies.
-                       let mut locked_before = this.locked_before.lock().unwrap();
-                       for (locked_idx, locked) in held.borrow().iter() {
-                               if !locked_before.contains_key(locked_idx) {
-                                       let lockdep = LockDep { lock: Arc::clone(locked), _lockdep_trace: Backtrace::new() };
-                                       locked_before.insert(*locked_idx, lockdep);
-                               }
-                       }
-                       held.borrow_mut().insert(this.lock_idx, Arc::clone(this));
-               });
-       }
-}
-
-pub struct Mutex<T: Sized> {
-       inner: StdMutex<T>,
-       deps: Arc<LockMetadata>,
-}
-
-#[must_use = "if unused the Mutex will immediately unlock"]
-pub struct MutexGuard<'a, T: Sized + 'a> {
-       mutex: &'a Mutex<T>,
-       lock: StdMutexGuard<'a, T>,
-}
-
-impl<'a, T: Sized> MutexGuard<'a, T> {
-       fn into_inner(self) -> StdMutexGuard<'a, T> {
-               // Somewhat unclear why we cannot move out of self.lock, but doing so gets E0509.
-               unsafe {
-                       let v: StdMutexGuard<'a, T> = std::ptr::read(&self.lock);
-                       std::mem::forget(self);
-                       v
-               }
-       }
-}
-
-impl<T: Sized> Drop for MutexGuard<'_, T> {
-       fn drop(&mut self) {
-               LOCKS_HELD.with(|held| {
-                       held.borrow_mut().remove(&self.mutex.deps.lock_idx);
-               });
-       }
-}
-
-impl<T: Sized> Deref for MutexGuard<'_, T> {
-       type Target = T;
-
-       fn deref(&self) -> &T {
-               &self.lock.deref()
-       }
-}
-
-impl<T: Sized> DerefMut for MutexGuard<'_, T> {
-       fn deref_mut(&mut self) -> &mut T {
-               self.lock.deref_mut()
-       }
-}
-
-impl<T> Mutex<T> {
-       pub fn new(inner: T) -> Mutex<T> {
-               Mutex { inner: StdMutex::new(inner), deps: LockMetadata::new() }
-       }
-
-       pub fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
-               LockMetadata::pre_lock(&self.deps);
-               self.inner.lock().map(|lock| MutexGuard { mutex: self, lock }).map_err(|_| ())
-       }
-
-       pub fn try_lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
-               let res = self.inner.try_lock().map(|lock| MutexGuard { mutex: self, lock }).map_err(|_| ());
-               if res.is_ok() {
-                       LockMetadata::try_locked(&self.deps);
-               }
-               res
-       }
-}
-
-pub struct RwLock<T: Sized> {
-       inner: StdRwLock<T>,
-       deps: Arc<LockMetadata>,
-}
-
-pub struct RwLockReadGuard<'a, T: Sized + 'a> {
-       lock: &'a RwLock<T>,
-       first_lock: bool,
-       guard: StdRwLockReadGuard<'a, T>,
-}
-
-pub struct RwLockWriteGuard<'a, T: Sized + 'a> {
-       lock: &'a RwLock<T>,
-       guard: StdRwLockWriteGuard<'a, T>,
-}
-
-impl<T: Sized> Deref for RwLockReadGuard<'_, T> {
-       type Target = T;
-
-       fn deref(&self) -> &T {
-               &self.guard.deref()
-       }
-}
-
-impl<T: Sized> Drop for RwLockReadGuard<'_, T> {
-       fn drop(&mut self) {
-               if !self.first_lock {
-                       // Note that its not strictly true that the first taken read lock will get unlocked
-                       // last, but in practice our locks are always taken as RAII, so it should basically
-                       // always be true.
-                       return;
-               }
-               LOCKS_HELD.with(|held| {
-                       held.borrow_mut().remove(&self.lock.deps.lock_idx);
-               });
-       }
-}
-
-impl<T: Sized> Deref for RwLockWriteGuard<'_, T> {
-       type Target = T;
-
-       fn deref(&self) -> &T {
-               &self.guard.deref()
-       }
-}
-
-impl<T: Sized> Drop for RwLockWriteGuard<'_, T> {
-       fn drop(&mut self) {
-               LOCKS_HELD.with(|held| {
-                       held.borrow_mut().remove(&self.lock.deps.lock_idx);
-               });
-       }
-}
-
-impl<T: Sized> DerefMut for RwLockWriteGuard<'_, T> {
-       fn deref_mut(&mut self) -> &mut T {
-               self.guard.deref_mut()
-       }
-}
-
-impl<T> RwLock<T> {
-       pub fn new(inner: T) -> RwLock<T> {
-               RwLock { inner: StdRwLock::new(inner), deps: LockMetadata::new() }
-       }
-
-       pub fn read<'a>(&'a self) -> LockResult<RwLockReadGuard<'a, T>> {
-               let first_lock = LockMetadata::pre_read_lock(&self.deps);
-               self.inner.read().map(|guard| RwLockReadGuard { lock: self, guard, first_lock }).map_err(|_| ())
-       }
-
-       pub fn write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
-               LockMetadata::pre_lock(&self.deps);
-               self.inner.write().map(|guard| RwLockWriteGuard { lock: self, guard }).map_err(|_| ())
-       }
-
-       pub fn try_write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
-               let res = self.inner.try_write().map(|guard| RwLockWriteGuard { lock: self, guard }).map_err(|_| ());
-               if res.is_ok() {
-                       LockMetadata::try_locked(&self.deps);
-               }
-               res
-       }
-}
-
-pub type FairRwLock<T> = RwLock<T>;
-
-mod tests {
-       use super::{RwLock, Mutex};
-
-       #[test]
-       #[should_panic]
-       #[cfg(not(feature = "backtrace"))]
-       fn recursive_lock_fail() {
-               let mutex = Mutex::new(());
-               let _a = mutex.lock().unwrap();
-               let _b = mutex.lock().unwrap();
-       }
-
-       #[test]
-       fn recursive_read() {
-               let lock = RwLock::new(());
-               let _a = lock.read().unwrap();
-               let _b = lock.read().unwrap();
-       }
-
-       #[test]
-       #[should_panic]
-       fn lockorder_fail() {
-               let a = Mutex::new(());
-               let b = Mutex::new(());
-               {
-                       let _a = a.lock().unwrap();
-                       let _b = b.lock().unwrap();
-               }
-               {
-                       let _b = b.lock().unwrap();
-                       let _a = a.lock().unwrap();
-               }
-       }
-
-       #[test]
-       #[should_panic]
-       fn write_lockorder_fail() {
-               let a = RwLock::new(());
-               let b = RwLock::new(());
-               {
-                       let _a = a.write().unwrap();
-                       let _b = b.write().unwrap();
-               }
-               {
-                       let _b = b.write().unwrap();
-                       let _a = a.write().unwrap();
-               }
-       }
-
-       #[test]
-       #[should_panic]
-       fn read_lockorder_fail() {
-               let a = RwLock::new(());
-               let b = RwLock::new(());
-               {
-                       let _a = a.read().unwrap();
-                       let _b = b.read().unwrap();
-               }
-               {
-                       let _b = b.read().unwrap();
-                       let _a = a.read().unwrap();
-               }
-       }
-
-       #[test]
-       fn read_recursive_no_lockorder() {
-               // Like the above, but note that no lockorder is implied when we recursively read-lock a
-               // RwLock, causing this to pass just fine.
-               let a = RwLock::new(());
-               let b = RwLock::new(());
-               let _outer = a.read().unwrap();
-               {
-                       let _a = a.read().unwrap();
-                       let _b = b.read().unwrap();
-               }
-               {
-                       let _b = b.read().unwrap();
-                       let _a = a.read().unwrap();
-               }
-       }
-
-       #[test]
-       #[should_panic]
-       fn read_write_lockorder_fail() {
-               let a = RwLock::new(());
-               let b = RwLock::new(());
-               {
-                       let _a = a.write().unwrap();
-                       let _b = b.read().unwrap();
-               }
-               {
-                       let _b = b.read().unwrap();
-                       let _a = a.write().unwrap();
-               }
-       }
-}
index 1f3ab47b1ae3f7d2ca8802e46c267d5428e3822c..71f82ed01340bbeb85546aa435a22e81c9381e4d 100644 (file)
@@ -78,8 +78,7 @@ extern crate core;
 pub mod util;
 pub mod chain;
 pub mod ln;
-#[allow(unused)]
-mod offers;
+pub mod offers;
 pub mod routing;
 pub mod onion_message;
 
@@ -175,20 +174,7 @@ mod prelude {
        pub use alloc::string::ToString;
 }
 
-#[cfg(all(not(feature = "_bench_unstable"), feature = "std", test))]
-mod debug_sync;
 #[cfg(all(not(feature = "_bench_unstable"), feature = "backtrace", feature = "std", test))]
 extern crate backtrace;
 
-#[cfg(feature = "std")]
-mod sync {
-       #[cfg(all(not(feature = "_bench_unstable"), test))]
-       pub use crate::debug_sync::*;
-       #[cfg(any(feature = "_bench_unstable", not(test)))]
-       pub use ::std::sync::{Arc, Mutex, Condvar, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
-       #[cfg(any(feature = "_bench_unstable", not(test)))]
-       pub use crate::util::fairrwlock::FairRwLock;
-}
-
-#[cfg(not(feature = "std"))]
 mod sync;
index bbf0be78893d12e02d62595fb5936410e212ac3d..378b4d794ff495231f1fcc8a133530769bd8bd1a 100644 (file)
@@ -660,13 +660,17 @@ pub fn make_funding_redeemscript(broadcaster: &PublicKey, countersignatory: &Pub
        let broadcaster_funding_key = broadcaster.serialize();
        let countersignatory_funding_key = countersignatory.serialize();
 
+       make_funding_redeemscript_from_slices(&broadcaster_funding_key, &countersignatory_funding_key)
+}
+
+pub(crate) fn make_funding_redeemscript_from_slices(broadcaster_funding_key: &[u8], countersignatory_funding_key: &[u8]) -> Script {
        let builder = Builder::new().push_opcode(opcodes::all::OP_PUSHNUM_2);
        if broadcaster_funding_key[..] < countersignatory_funding_key[..] {
-               builder.push_slice(&broadcaster_funding_key)
-                       .push_slice(&countersignatory_funding_key)
+               builder.push_slice(broadcaster_funding_key)
+                       .push_slice(countersignatory_funding_key)
        } else {
-               builder.push_slice(&countersignatory_funding_key)
-                       .push_slice(&broadcaster_funding_key)
+               builder.push_slice(countersignatory_funding_key)
+                       .push_slice(broadcaster_funding_key)
        }.push_opcode(opcodes::all::OP_PUSHNUM_2).push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script()
 }
 
@@ -1635,7 +1639,7 @@ mod tests {
        use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment};
        use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1};
        use crate::util::test_utils;
-       use crate::chain::keysinterface::{KeysInterface, BaseSign, SignerProvider};
+       use crate::chain::keysinterface::{ChannelSigner, SignerProvider};
        use bitcoin::{Network, Txid};
        use bitcoin::hashes::Hash;
        use crate::ln::PaymentHash;
index 914e5d9a2c5600e0cb6a1d237bbb2f3ba5bdb931..18e461f61a3c0da0ca74c8579542e7571bc39bf2 100644 (file)
@@ -19,7 +19,7 @@ use bitcoin::network::constants::Network;
 use crate::chain::channelmonitor::{ANTI_REORG_DELAY, ChannelMonitor};
 use crate::chain::transaction::OutPoint;
 use crate::chain::{ChannelMonitorUpdateStatus, Listen, Watch};
-use crate::ln::channelmanager::{self, ChannelManager, RAACommitmentOrder, PaymentSendFailure, PaymentId};
+use crate::ln::channelmanager::{ChannelManager, RAACommitmentOrder, PaymentSendFailure, PaymentId};
 use crate::ln::channel::AnnouncementSigsState;
 use crate::ln::msgs;
 use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler};
@@ -46,7 +46,7 @@ fn test_simple_monitor_permanent_update_fail() {
        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);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (route, payment_hash_1, _, payment_secret_1) = get_route_and_payment_hash!(&nodes[0], nodes[1], 1000000);
        chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
@@ -84,7 +84,7 @@ fn test_monitor_and_persister_update_fail() {
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channel
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
        let outpoint = OutPoint { txid: chan.3.txid(), index: 0 };
 
        // Rebalance the network to generate htlc in the two directions
@@ -108,12 +108,13 @@ fn test_monitor_and_persister_update_fail() {
                blocks: Arc::new(Mutex::new(vec![(genesis_block(Network::Testnet), 200); 200])),
        };
        let chain_mon = {
-               let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(outpoint).unwrap();
-               let mut w = test_utils::TestVecWriter(Vec::new());
-               monitor.write(&mut w).unwrap();
-               let new_monitor = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
-                       &mut io::Cursor::new(&w.0), nodes[0].keys_manager).unwrap().1;
-               assert!(new_monitor == *monitor);
+               let new_monitor = {
+                       let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(outpoint).unwrap();
+                       let new_monitor = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
+                               &mut io::Cursor::new(&monitor.encode()), (nodes[0].keys_manager, nodes[0].keys_manager)).unwrap().1;
+                       assert!(new_monitor == *monitor);
+                       new_monitor
+               };
                let chain_mon = test_utils::TestChainMonitor::new(Some(&chain_source), &tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
                assert_eq!(chain_mon.watch_channel(outpoint, new_monitor), ChannelMonitorUpdateStatus::Completed);
                chain_mon
@@ -139,16 +140,19 @@ fn test_monitor_and_persister_update_fail() {
        let updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
        assert_eq!(updates.update_fulfill_htlcs.len(), 1);
        nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]);
-       if let Some(ref mut channel) = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2) {
-               if let Ok((_, _, update)) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].logger) {
+       {
+               let mut node_0_per_peer_lock;
+               let mut node_0_peer_state_lock;
+               let mut channel = get_channel_ref!(nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, chan.2);
+               if let Ok(update) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].logger) {
                        // Check that even though the persister is returning a InProgress,
                        // because the update is bogus, ultimately the error that's returned
                        // should be a PermanentFailure.
-                       if let ChannelMonitorUpdateStatus::PermanentFailure = chain_mon.chain_monitor.update_channel(outpoint, update.clone()) {} else { panic!("Expected monitor error to be permanent"); }
+                       if let ChannelMonitorUpdateStatus::PermanentFailure = chain_mon.chain_monitor.update_channel(outpoint, &update) {} else { panic!("Expected monitor error to be permanent"); }
                        logger.assert_log_regex("lightning::chain::chainmonitor".to_string(), regex::Regex::new("Persistence of ChannelMonitorUpdate for channel [0-9a-f]* in progress").unwrap(), 1);
-                       assert_eq!(nodes[0].chain_monitor.update_channel(outpoint, update), ChannelMonitorUpdateStatus::Completed);
+                       assert_eq!(nodes[0].chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::Completed);
                } else { assert!(false); }
-       } else { assert!(false); };
+       }
 
        check_added_monitors!(nodes[0], 1);
        let events = nodes[0].node.get_and_clear_pending_events();
@@ -162,7 +166,7 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let (route, payment_hash_1, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(&nodes[0], nodes[1], 1000000);
 
@@ -178,8 +182,8 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) {
        assert_eq!(nodes[0].node.list_channels().len(), 1);
 
        if disconnect {
-               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
                reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
        }
 
@@ -231,8 +235,8 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) {
        assert_eq!(nodes[0].node.list_channels().len(), 1);
 
        if disconnect {
-               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
                reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
        }
 
@@ -278,7 +282,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let (payment_preimage_1, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
 
@@ -334,8 +338,8 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
        };
 
        if disconnect_count & !disconnect_flags > 0 {
-               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
        }
 
        // Now fix monitor updating...
@@ -345,13 +349,13 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
        check_added_monitors!(nodes[0], 0);
 
        macro_rules! disconnect_reconnect_peers { () => { {
-               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
-               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
                let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
                assert_eq!(reestablish_1.len(), 1);
-               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
                let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
                assert_eq!(reestablish_2.len(), 1);
 
@@ -370,10 +374,10 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
                assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
                assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
-               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
                let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
                assert_eq!(reestablish_1.len(), 1);
-               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
                let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
                assert_eq!(reestablish_2.len(), 1);
 
@@ -622,7 +626,7 @@ fn test_monitor_update_fail_cs() {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let (route, our_payment_hash, payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        {
@@ -714,7 +718,7 @@ fn test_monitor_update_fail_no_rebroadcast() {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let (route, our_payment_hash, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        {
@@ -760,7 +764,7 @@ fn test_monitor_update_raa_while_paused() {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        send_payment(&nodes[0], &[&nodes[1]], 5000000);
        let (route, our_payment_hash_1, payment_preimage_1, our_payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
@@ -831,8 +835,8 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // Rebalance a bit so that we can send backwards from 2 to 1.
        send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000);
@@ -932,7 +936,8 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
 
        // Note that the ordering of the events for different nodes is non-prescriptive, though the
        // ordering of the two events that both go to nodes[2] have to stay in the same order.
-       let messages_a = match events_3.pop().unwrap() {
+       let nodes_0_event = remove_first_msg_event_to_node(&nodes[0].node.get_our_node_id(), &mut events_3);
+       let messages_a = match nodes_0_event {
                MessageSendEvent::UpdateHTLCs { node_id, mut updates } => {
                        assert_eq!(node_id, nodes[0].node.get_our_node_id());
                        assert!(updates.update_fulfill_htlcs.is_empty());
@@ -944,8 +949,14 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
                },
                _ => panic!("Unexpected event type!"),
        };
+
+       let nodes_2_event = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events_3);
+       let send_event_b = SendEvent::from_event(nodes_2_event);
+       assert_eq!(send_event_b.node_id, nodes[2].node.get_our_node_id());
+
        let raa = if test_ignore_second_cs {
-               match events_3.remove(1) {
+               let nodes_2_event = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events_3);
+               match nodes_2_event {
                        MessageSendEvent::SendRevokeAndACK { node_id, msg } => {
                                assert_eq!(node_id, nodes[2].node.get_our_node_id());
                                Some(msg.clone())
@@ -953,8 +964,6 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
                        _ => panic!("Unexpected event"),
                }
        } else { None };
-       let send_event_b = SendEvent::from_event(events_3.remove(0));
-       assert_eq!(send_event_b.node_id, nodes[2].node.get_our_node_id());
 
        // Now deliver the new messages...
 
@@ -988,6 +997,7 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
                check_added_monitors!(nodes[2], 1);
 
                let bs_revoke_and_commit = nodes[2].node.get_and_clear_pending_msg_events();
+               // As both messages are for nodes[1], they're in order.
                assert_eq!(bs_revoke_and_commit.len(), 2);
                match bs_revoke_and_commit[0] {
                        MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
@@ -1096,13 +1106,13 @@ fn test_monitor_update_fail_reestablish() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       create_announced_chan_between_nodes(&nodes, 1, 2);
 
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000);
 
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
 
        nodes[2].node.claim_funds(payment_preimage);
        check_added_monitors!(nodes[2], 1);
@@ -1121,8 +1131,8 @@ fn test_monitor_update_fail_reestablish() {
        commitment_signed_dance!(nodes[1], nodes[2], updates.commitment_signed, false);
 
        chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), 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(), remote_network_address: None }, false).unwrap();
 
        let as_reestablish = get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap();
        let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
@@ -1137,11 +1147,11 @@ fn test_monitor_update_fail_reestablish() {
        nodes[1].node.get_and_clear_pending_msg_events(); // Free the holding cell
        check_added_monitors!(nodes[1], 1);
 
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), 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(), remote_network_address: None }, false).unwrap();
 
        assert_eq!(get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap(), as_reestablish);
        assert_eq!(get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap(), bs_reestablish);
@@ -1183,7 +1193,7 @@ fn raa_no_response_awaiting_raa_state() {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let (route, payment_hash_1, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
@@ -1301,20 +1311,20 @@ fn claim_while_disconnected_monitor_update_fail() {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        // Forward a payment for B to claim
        let (payment_preimage_1, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        nodes[1].node.claim_funds(payment_preimage_1);
        check_added_monitors!(nodes[1], 1);
        expect_payment_claimed!(nodes[1], payment_hash_1, 1_000_000);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), 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(), remote_network_address: None }, false).unwrap();
 
        let as_reconnect = get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap();
        let bs_reconnect = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
@@ -1413,11 +1423,16 @@ fn monitor_failed_no_reestablish_response() {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
+       {
+               let mut node_0_per_peer_lock;
+               let mut node_0_peer_state_lock;
+               get_channel_ref!(nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, channel_id).announcement_sigs_state = AnnouncementSigsState::PeerReceived;
+       }
        {
-               let mut lock;
-               get_channel_ref!(nodes[0], lock, channel_id).announcement_sigs_state = AnnouncementSigsState::PeerReceived;
-               get_channel_ref!(nodes[1], lock, channel_id).announcement_sigs_state = AnnouncementSigsState::PeerReceived;
+               let mut node_1_per_peer_lock;
+               let mut node_1_peer_state_lock;
+               get_channel_ref!(nodes[1], nodes[0], node_1_per_peer_lock, node_1_peer_state_lock, channel_id).announcement_sigs_state = AnnouncementSigsState::PeerReceived;
        }
 
        // Route the payment and deliver the initial commitment_signed (with a monitor update failure
@@ -1439,11 +1454,11 @@ fn monitor_failed_no_reestablish_response() {
 
        // Now disconnect and immediately reconnect, delivering the channel_reestablish while nodes[1]
        // is still failing to update monitors.
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), 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(), remote_network_address: None }, false).unwrap();
 
        let as_reconnect = get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap();
        let bs_reconnect = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
@@ -1490,7 +1505,7 @@ fn first_message_on_recv_ordering() {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        // Route the first payment outbound, holding the last RAA for B until we are set up so that we
        // can deliver it and fail the monitor update.
@@ -1580,8 +1595,8 @@ fn test_monitor_update_fail_claim() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // Rebalance a bit so that we can send backwards from 3 to 2.
        send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000);
@@ -1590,7 +1605,6 @@ fn test_monitor_update_fail_claim() {
 
        chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
        nodes[1].node.claim_funds(payment_preimage_1);
-       expect_payment_claimed!(nodes[1], payment_hash_1, 1_000_000);
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
        check_added_monitors!(nodes[1], 1);
 
@@ -1616,6 +1630,7 @@ fn test_monitor_update_fail_claim() {
        let events = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 0);
        commitment_signed_dance!(nodes[1], nodes[2], payment_event.commitment_msg, false, true);
+       expect_pending_htlcs_forwardable_ignore!(nodes[1]);
 
        let (_, payment_hash_3, payment_secret_3) = get_payment_preimage_hash!(nodes[0]);
        nodes[2].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3), PaymentId(payment_hash_3.0)).unwrap();
@@ -1633,6 +1648,7 @@ fn test_monitor_update_fail_claim() {
        let channel_id = chan_1.2;
        let (outpoint, latest_update, _) = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone();
        nodes[1].chain_monitor.chain_monitor.force_channel_monitor_updated(outpoint, latest_update);
+       expect_payment_claimed!(nodes[1], payment_hash_1, 1_000_000);
        check_added_monitors!(nodes[1], 0);
 
        let bs_fulfill_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
@@ -1641,7 +1657,7 @@ fn test_monitor_update_fail_claim() {
        expect_payment_sent!(nodes[0], payment_preimage_1);
 
        // Get the payment forwards, note that they were batched into one commitment update.
-       expect_pending_htlcs_forwardable!(nodes[1]);
+       nodes[1].node.process_pending_htlc_forwards();
        check_added_monitors!(nodes[1], 1);
        let bs_forward_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
        nodes[0].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &bs_forward_update.update_add_htlcs[0]);
@@ -1696,8 +1712,8 @@ fn test_monitor_update_on_pending_forwards() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // Rebalance a bit so that we can send backwards from 3 to 1.
        send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000);
@@ -1727,7 +1743,6 @@ fn test_monitor_update_on_pending_forwards() {
        chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
        expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[1], vec![HTLCDestination::NextHopChannel { node_id: Some(nodes[2].node.get_our_node_id()), channel_id: chan_2.2 }]);
        check_added_monitors!(nodes[1], 1);
-       assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
 
        chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
        let (outpoint, latest_update, _) = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_1.2).unwrap().clone();
@@ -1740,12 +1755,18 @@ fn test_monitor_update_on_pending_forwards() {
        commitment_signed_dance!(nodes[0], nodes[1], bs_updates.commitment_signed, false, true);
 
        let events = nodes[0].node.get_and_clear_pending_events();
-       assert_eq!(events.len(), 2);
-       if let Event::PaymentPathFailed { payment_hash, payment_failed_permanently, .. } = events[0] {
+       assert_eq!(events.len(), 3);
+       if let Event::PaymentPathFailed { payment_hash, payment_failed_permanently, .. } = events[1] {
                assert_eq!(payment_hash, payment_hash_1);
                assert!(payment_failed_permanently);
        } else { panic!("Unexpected event!"); }
-       match events[1] {
+       match events[2] {
+               Event::PaymentFailed { payment_hash, .. } => {
+                       assert_eq!(payment_hash, payment_hash_1);
+               },
+               _ => panic!("Unexpected event"),
+       }
+       match events[0] {
                Event::PendingHTLCsForwardable { .. } => { },
                _ => panic!("Unexpected event"),
        };
@@ -1765,7 +1786,7 @@ fn monitor_update_claim_fail_no_response() {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        // Forward a payment for B to claim
        let (payment_preimage_1, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
@@ -1785,7 +1806,6 @@ fn monitor_update_claim_fail_no_response() {
 
        chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
        nodes[1].node.claim_funds(payment_preimage_1);
-       expect_payment_claimed!(nodes[1], payment_hash_1, 1_000_000);
        check_added_monitors!(nodes[1], 1);
 
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
@@ -1793,6 +1813,7 @@ fn monitor_update_claim_fail_no_response() {
        chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
        let (outpoint, latest_update, _) = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone();
        nodes[1].chain_monitor.chain_monitor.force_channel_monitor_updated(outpoint, latest_update);
+       expect_payment_claimed!(nodes[1], payment_hash_1, 1_000_000);
        check_added_monitors!(nodes[1], 0);
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
 
@@ -1820,8 +1841,8 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 43, None).unwrap();
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
 
        let (temporary_channel_id, funding_tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 43);
 
@@ -1861,8 +1882,8 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
        }
 
        // Make sure nodes[1] isn't stupid enough to re-send the ChannelReady on reconnect
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
        reconnect_nodes(&nodes[0], &nodes[1], (false, confirm_a_first), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
@@ -1939,10 +1960,10 @@ fn test_path_paused_mpp() {
        let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
        let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-       let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-       let (chan_2_ann, _, chan_2_id, _) = create_announced_chan_between_nodes(&nodes, 0, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-       let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
+       let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+       let (chan_2_ann, _, chan_2_id, _) = create_announced_chan_between_nodes(&nodes, 0, 2);
+       let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3).0.contents.short_channel_id;
+       let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3).0.contents.short_channel_id;
 
        let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[3], 100000);
 
@@ -2005,7 +2026,7 @@ fn test_pending_update_fee_ack_on_reconnect() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
        send_payment(&nodes[0], &[&nodes[1]], 100_000_00);
 
        let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(&nodes[1], nodes[0], 1_000_000);
@@ -2029,12 +2050,12 @@ fn test_pending_update_fee_ack_on_reconnect() {
        let bs_first_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
        // bs_first_raa is not delivered until it is re-generated after reconnect
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        let as_connect_msg = get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap();
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let bs_connect_msg = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
 
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_connect_msg);
@@ -2093,8 +2114,8 @@ fn test_fail_htlc_on_broadcast_after_claim() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
 
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 2000);
 
@@ -2133,7 +2154,7 @@ fn do_update_fee_resend_test(deliver_update: bool, parallel_updates: bool) {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
        send_payment(&nodes[0], &[&nodes[1]], 1000);
 
        {
@@ -2157,12 +2178,12 @@ fn do_update_fee_resend_test(deliver_update: bool, parallel_updates: bool) {
                assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
        }
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        let as_connect_msg = get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap();
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let bs_connect_msg = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
 
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_connect_msg);
@@ -2231,10 +2252,10 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan_id = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 15_000_000, 7_000_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let chan_id = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 15_000_000, 7_000_000_000).2;
        let (route, payment_hash_1, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(&nodes[0], nodes[1], 100000);
        let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(&nodes[1]);
 
@@ -2272,7 +2293,6 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
        chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
        nodes[0].node.claim_funds(payment_preimage_0);
        check_added_monitors!(nodes[0], 1);
-       expect_payment_claimed!(nodes[0], payment_hash_0, 100_000);
 
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &send.msgs[0]);
        nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &send.commitment_msg);
@@ -2291,15 +2311,15 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
                        let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
                        reload_node!(nodes[0], &nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister, new_chain_monitor, nodes_0_deserialized);
                } else {
-                       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+                       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
                }
-               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
                // Now reconnect the two
-               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
                let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
                assert_eq!(reestablish_1.len(), 1);
-               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
                let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
                assert_eq!(reestablish_2.len(), 1);
 
@@ -2335,6 +2355,7 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
        chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
        let (funding_txo, mon_id, _) = nodes[0].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_id).unwrap().clone();
        nodes[0].chain_monitor.chain_monitor.force_channel_monitor_updated(funding_txo, mon_id);
+       expect_payment_claimed!(nodes[0], payment_hash_0, 100_000);
 
        // New outbound messages should be generated immediately upon a call to
        // get_and_clear_pending_msg_events (but not before).
@@ -2416,8 +2437,8 @@ fn do_test_reconnect_dup_htlc_claims(htlc_status: HTLCStatusAtDupClaim, second_f
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
 
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 100_000);
 
@@ -2481,8 +2502,8 @@ fn do_test_reconnect_dup_htlc_claims(htlc_status: HTLCStatusAtDupClaim, second_f
                assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
        }
 
-       nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false);
-       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id());
+       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id());
 
        if second_fails {
                reconnect_nodes(&nodes[1], &nodes[2], (false, false), (0, 0), (0, 0), (1, 0), (0, 0), (0, 0), (false, false));
@@ -2529,16 +2550,16 @@ fn test_temporary_error_during_shutdown() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config), Some(config)]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
        chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
 
        nodes[0].node.close_channel(&channel_id, &nodes[1].node.get_our_node_id()).unwrap();
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()));
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()));
        check_added_monitors!(nodes[1], 1);
 
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()));
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()));
        check_added_monitors!(nodes[0], 1);
 
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
@@ -2584,11 +2605,19 @@ fn test_permanent_error_during_sending_shutdown() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config), None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
        chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
 
        assert!(nodes[0].node.close_channel(&channel_id, &nodes[1].node.get_our_node_id()).is_ok());
-       check_closed_broadcast!(nodes[0], true);
+
+       // We always send the `shutdown` response when initiating a shutdown, even if we immediately
+       // close the channel thereafter.
+       let msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(msg_events.len(), 3);
+       if let MessageSendEvent::SendShutdown { .. } = msg_events[0] {} else { panic!(); }
+       if let MessageSendEvent::BroadcastChannelUpdate { .. } = msg_events[1] {} else { panic!(); }
+       if let MessageSendEvent::HandleError { .. } =  msg_events[2] {} else { panic!(); }
+
        check_added_monitors!(nodes[0], 2);
        check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: "ChannelMonitor storage failure".to_string() });
 }
@@ -2605,13 +2634,21 @@ fn test_permanent_error_during_handling_shutdown() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(config)]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
        chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
 
        assert!(nodes[0].node.close_channel(&channel_id, &nodes[1].node.get_our_node_id()).is_ok());
        let shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &shutdown);
-       check_closed_broadcast!(nodes[1], true);
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &shutdown);
+
+       // We always send the `shutdown` response when receiving a shutdown, even if we immediately
+       // close the channel thereafter.
+       let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(msg_events.len(), 3);
+       if let MessageSendEvent::SendShutdown { .. } = msg_events[0] {} else { panic!(); }
+       if let MessageSendEvent::BroadcastChannelUpdate { .. } = msg_events[1] {} else { panic!(); }
+       if let MessageSendEvent::HandleError { .. } =  msg_events[2] {} else { panic!(); }
+
        check_added_monitors!(nodes[1], 2);
        check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: "ChannelMonitor storage failure".to_string() });
 }
@@ -2624,7 +2661,7 @@ fn double_temp_error() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let (_, _, channel_id, _) = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let (_, _, channel_id, _) = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (payment_preimage_1, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
        let (payment_preimage_2, payment_hash_2, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
@@ -2633,7 +2670,6 @@ fn double_temp_error() {
        // `claim_funds` results in a ChannelMonitorUpdate.
        nodes[1].node.claim_funds(payment_preimage_1);
        check_added_monitors!(nodes[1], 1);
-       expect_payment_claimed!(nodes[1], payment_hash_1, 1_000_000);
        let (funding_tx, latest_update_1, _) = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone();
 
        chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
@@ -2641,7 +2677,6 @@ fn double_temp_error() {
        // which had some asserts that prevented it from being called twice.
        nodes[1].node.claim_funds(payment_preimage_2);
        check_added_monitors!(nodes[1], 1);
-       expect_payment_claimed!(nodes[1], payment_hash_2, 1_000_000);
        chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
 
        let (_, latest_update_2, _) = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone();
@@ -2650,11 +2685,24 @@ fn double_temp_error() {
        check_added_monitors!(nodes[1], 0);
        nodes[1].chain_monitor.chain_monitor.force_channel_monitor_updated(funding_tx, latest_update_2);
 
-       // Complete the first HTLC.
-       let events = nodes[1].node.get_and_clear_pending_msg_events();
-       assert_eq!(events.len(), 1);
+       // Complete the first HTLC. Note that as a side-effect we handle the monitor update completions
+       // and get both PaymentClaimed events at once.
+       let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
+
+       let events = nodes[1].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 2);
+       match events[0] {
+               Event::PaymentClaimed { amount_msat: 1_000_000, payment_hash, .. } => assert_eq!(payment_hash, payment_hash_1),
+               _ => panic!("Unexpected Event: {:?}", events[0]),
+       }
+       match events[1] {
+               Event::PaymentClaimed { amount_msat: 1_000_000, payment_hash, .. } => assert_eq!(payment_hash, payment_hash_2),
+               _ => panic!("Unexpected Event: {:?}", events[1]),
+       }
+
+       assert_eq!(msg_events.len(), 1);
        let (update_fulfill_1, commitment_signed_b1, node_id) = {
-               match &events[0] {
+               match &msg_events[0] {
                        &MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
                                assert!(update_add_htlcs.is_empty());
                                assert_eq!(update_fulfill_htlcs.len(), 1);
@@ -2725,7 +2773,7 @@ fn do_test_outbound_reload_without_init_mon(use_0conf: bool) {
 
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
 
        let mut chan_config = test_default_channel_config();
        chan_config.manually_accept_inbound_channels = true;
@@ -2735,7 +2783,7 @@ fn do_test_outbound_reload_without_init_mon(use_0conf: bool) {
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 43, None).unwrap();
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &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(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
 
        let events = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 1);
@@ -2750,7 +2798,7 @@ fn do_test_outbound_reload_without_init_mon(use_0conf: bool) {
                _ => panic!("Unexpected event"),
        };
 
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
 
        let (temporary_channel_id, funding_tx, ..) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 43);
 
@@ -2814,7 +2862,7 @@ fn do_test_inbound_reload_without_init_mon(use_0conf: bool, lock_commitment: boo
 
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_1_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_1_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
 
        let mut chan_config = test_default_channel_config();
        chan_config.manually_accept_inbound_channels = true;
@@ -2824,7 +2872,7 @@ fn do_test_inbound_reload_without_init_mon(use_0conf: bool, lock_commitment: boo
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 43, None).unwrap();
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &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(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
 
        let events = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 1);
@@ -2839,7 +2887,7 @@ fn do_test_inbound_reload_without_init_mon(use_0conf: bool, lock_commitment: boo
                _ => panic!("Unexpected event"),
        };
 
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
 
        let (temporary_channel_id, funding_tx, ..) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 43);
 
index ec2810d14cbd8cce512956cb8f7d930f55a8d30f..9af0f6379e5a1672e851a61ef0c54d717235a1a5 100644 (file)
@@ -27,7 +27,7 @@ use crate::ln::features::{ChannelTypeFeatures, InitFeatures};
 use crate::ln::msgs;
 use crate::ln::msgs::{DecodeError, OptionalField, DataLossProtect};
 use crate::ln::script::{self, ShutdownScript};
-use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
+use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, SentHTLCId, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
 use crate::ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, htlc_success_tx_weight, htlc_timeout_tx_weight, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor, ClosingTransaction};
 use crate::ln::chan_utils;
 use crate::ln::onion_utils::HTLCFailReason;
@@ -35,7 +35,8 @@ use crate::chain::BestBlock;
 use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator};
 use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
 use crate::chain::transaction::{OutPoint, TransactionData};
-use crate::chain::keysinterface::{Sign, EntropySource, KeysInterface, BaseSign, SignerProvider};
+use crate::chain::keysinterface::{WriteableEcdsaChannelSigner, EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient};
+use crate::routing::gossip::NodeId;
 use crate::util::events::ClosureReason;
 use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
 use crate::util::logger::Logger;
@@ -191,6 +192,7 @@ enum OutboundHTLCState {
 
 #[derive(Clone)]
 enum OutboundHTLCOutcome {
+       /// LDK version 0.0.105+ will always fill in the preimage here.
        Success(Option<PaymentPreimage>),
        Failure(HTLCFailReason),
 }
@@ -392,35 +394,21 @@ enum UpdateFulfillFetch {
 }
 
 /// The return type of get_update_fulfill_htlc_and_commit.
-pub enum UpdateFulfillCommitFetch {
+pub enum UpdateFulfillCommitFetch<'a> {
        /// Indicates the HTLC fulfill is new, and either generated an update_fulfill message, placed
        /// it in the holding cell, or re-generated the update_fulfill message after the same claim was
        /// previously placed in the holding cell (and has since been removed).
        NewClaim {
                /// The ChannelMonitorUpdate which places the new payment preimage in the channel monitor
-               monitor_update: ChannelMonitorUpdate,
+               monitor_update: &'a ChannelMonitorUpdate,
                /// The value of the HTLC which was claimed, in msat.
                htlc_value_msat: u64,
-               /// The update_fulfill message and commitment_signed message (if the claim was not placed
-               /// in the holding cell).
-               msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>,
        },
        /// Indicates the HTLC fulfill is duplicative and already existed either in the holding cell
        /// or has been forgotten (presumably previously claimed).
        DuplicateClaim {},
 }
 
-/// The return value of `revoke_and_ack` on success, primarily updates to other channels or HTLC
-/// state.
-pub(super) struct RAAUpdates {
-       pub commitment_update: Option<msgs::CommitmentUpdate>,
-       pub accepted_htlcs: Vec<(PendingHTLCInfo, u64)>,
-       pub failed_htlcs: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
-       pub finalized_claimed_htlcs: Vec<HTLCSource>,
-       pub monitor_update: ChannelMonitorUpdate,
-       pub holding_cell_failed_htlcs: Vec<(HTLCSource, PaymentHash)>,
-}
-
 /// The return value of `monitor_updating_restored`
 pub(super) struct MonitorRestoreUpdates {
        pub raa: Option<msgs::RevokeAndACK>,
@@ -498,7 +486,7 @@ pub(crate) const EXPIRE_PREV_CONFIG_TICKS: usize = 5;
 //
 // Holder designates channel data owned for the benefice of the user client.
 // Counterparty designates channel data owned by the another channel participant entity.
-pub(super) struct Channel<Signer: Sign> {
+pub(super) struct Channel<Signer: ChannelSigner> {
        config: LegacyChannelConfig,
 
        // Track the previous `ChannelConfig` so that we can continue forwarding HTLCs that were
@@ -557,6 +545,11 @@ pub(super) struct Channel<Signer: Sign> {
        monitor_pending_channel_ready: bool,
        monitor_pending_revoke_and_ack: bool,
        monitor_pending_commitment_signed: bool,
+
+       // TODO: If a channel is drop'd, we don't know whether the `ChannelMonitor` is ultimately
+       // responsible for some of the HTLCs here or not - we don't know whether the update in question
+       // completed or not. We currently ignore these fields entirely when force-closing a channel,
+       // but need to handle this somehow or we run the risk of losing HTLCs!
        monitor_pending_forwards: Vec<(PendingHTLCInfo, u64)>,
        monitor_pending_failures: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
        monitor_pending_finalized_fulfills: Vec<HTLCSource>,
@@ -742,6 +735,12 @@ pub(super) struct Channel<Signer: Sign> {
        /// The unique identifier used to re-derive the private key material for the channel through
        /// [`SignerProvider::derive_channel_signer`].
        channel_keys_id: [u8; 32],
+
+       /// When we generate [`ChannelMonitorUpdate`]s to persist, they may not be persisted immediately.
+       /// If we then persist the [`channelmanager::ChannelManager`] and crash before the persistence
+       /// completes we still need to be able to complete the persistence. Thus, we have to keep a
+       /// copy of the [`ChannelMonitorUpdate`] here until it is complete.
+       pending_monitor_updates: Vec<ChannelMonitorUpdate>,
 }
 
 #[cfg(any(test, fuzzing))]
@@ -798,7 +797,7 @@ pub const MAX_CHAN_DUST_LIMIT_SATOSHIS: u64 = MAX_STD_OUTPUT_DUST_LIMIT_SATOSHIS
 /// In order to avoid having to concern ourselves with standardness during the closing process, we
 /// simply require our counterparty to use a dust limit which will leave any segwit output
 /// standard.
-/// See https://github.com/lightning/bolts/issues/905 for more details.
+/// See <https://github.com/lightning/bolts/issues/905> for more details.
 pub const MIN_CHAN_DUST_LIMIT_SATOSHIS: u64 = 354;
 
 // Just a reasonable implementation-specific safe lower bound, higher than the dust limit.
@@ -832,7 +831,7 @@ macro_rules! secp_check {
        };
 }
 
-impl<Signer: Sign> Channel<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
        /// Returns the value to use for `holder_max_htlc_value_in_flight_msat` as a percentage of the
        /// `channel_value_satoshis` in msat, set through
        /// [`ChannelHandshakeConfig::max_inbound_htlc_value_in_flight_percent_of_channel`]
@@ -877,15 +876,29 @@ impl<Signer: Sign> Channel<Signer> {
                self.channel_transaction_parameters.opt_anchors.is_some()
        }
 
-       fn get_initial_channel_type(config: &UserConfig) -> ChannelTypeFeatures {
+       fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures) -> ChannelTypeFeatures {
                // The default channel type (ie the first one we try) depends on whether the channel is
                // public - if it is, we just go with `only_static_remotekey` as it's the only option
                // 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`
+               // with no other changes, and fall back to `only_static_remotekey`.
                let mut ret = ChannelTypeFeatures::only_static_remote_key();
-               if !config.channel_handshake_config.announced_channel && config.channel_handshake_config.negotiate_scid_privacy {
+               if !config.channel_handshake_config.announced_channel &&
+                       config.channel_handshake_config.negotiate_scid_privacy &&
+                       their_features.supports_scid_privacy() {
                        ret.set_scid_privacy_required();
                }
+
+               // Optionally, if the user would like to negotiate the `anchors_zero_fee_htlc_tx` option, we
+               // set it now. If they don't understand it, we'll fall back to our default of
+               // `only_static_remotekey`.
+               #[cfg(anchors)]
+               { // Attributes are not allowed on if expressions on our current MSRV of 1.41.
+                       if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx &&
+                               their_features.supports_anchors_zero_fee_htlc_tx() {
+                               ret.set_anchors_zero_fee_htlc_tx_required();
+                       }
+               }
+
                ret
        }
 
@@ -898,24 +911,40 @@ impl<Signer: Sign> Channel<Signer> {
                        // We've exhausted our options
                        return Err(());
                }
-               self.channel_type = ChannelTypeFeatures::only_static_remote_key(); // We only currently support two types
+               // We support opening a few different types of channels. Try removing our additional
+               // features one by one until we've either arrived at our default or the counterparty has
+               // accepted one.
+               //
+               // Due to the order below, we may not negotiate `option_anchors_zero_fee_htlc_tx` if the
+               // counterparty doesn't support `option_scid_privacy`. Since `get_initial_channel_type`
+               // checks whether the counterparty supports every feature, this would only happen if the
+               // counterparty is advertising the feature, but rejecting channels proposing the feature for
+               // whatever reason.
+               if self.channel_type.supports_anchors_zero_fee_htlc_tx() {
+                       self.channel_type.clear_anchors_zero_fee_htlc_tx();
+                       assert!(self.channel_transaction_parameters.opt_non_zero_fee_anchors.is_none());
+                       self.channel_transaction_parameters.opt_anchors = None;
+               } else if self.channel_type.supports_scid_privacy() {
+                       self.channel_type.clear_scid_privacy();
+               } else {
+                       self.channel_type = ChannelTypeFeatures::only_static_remote_key();
+               }
                Ok(self.get_open_channel(chain_hash))
        }
 
        // Constructors:
-       pub fn new_outbound<K: Deref, F: Deref>(
-               fee_estimator: &LowerBoundedFeeEstimator<F>, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
+       pub fn new_outbound<ES: Deref, SP: Deref, F: Deref>(
+               fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP, counterparty_node_id: PublicKey, their_features: &InitFeatures,
                channel_value_satoshis: u64, push_msat: u64, user_id: u128, config: &UserConfig, current_chain_height: u32,
                outbound_scid_alias: u64
        ) -> Result<Channel<Signer>, APIError>
-       where K::Target: KeysInterface<Signer = Signer>,
+       where ES::Target: EntropySource,
+             SP::Target: SignerProvider<Signer = Signer>,
              F::Target: FeeEstimator,
        {
-               let opt_anchors = false; // TODO - should be based on features
-
                let holder_selected_contest_delay = config.channel_handshake_config.our_to_self_delay;
-               let channel_keys_id = keys_provider.generate_channel_keys_id(false, channel_value_satoshis, user_id);
-               let holder_signer = keys_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id);
+               let channel_keys_id = signer_provider.generate_channel_keys_id(false, channel_value_satoshis, user_id);
+               let holder_signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id);
                let pubkeys = holder_signer.pubkeys().clone();
 
                if !their_features.supports_wumbo() && channel_value_satoshis > MAX_FUNDING_SATOSHIS_NO_WUMBO {
@@ -938,19 +967,22 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(APIError::APIMisuseError { err: format!("Holder selected channel  reserve below implemention limit dust_limit_satoshis {}", holder_selected_channel_reserve_satoshis) });
                }
 
+               let channel_type = Self::get_initial_channel_type(&config, their_features);
+               debug_assert!(channel_type.is_subset(&channelmanager::provided_channel_type_features(&config)));
+
                let feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal);
 
                let value_to_self_msat = channel_value_satoshis * 1000 - push_msat;
-               let commitment_tx_fee = Self::commit_tx_fee_msat(feerate, MIN_AFFORDABLE_HTLC_COUNT, opt_anchors);
+               let commitment_tx_fee = Self::commit_tx_fee_msat(feerate, MIN_AFFORDABLE_HTLC_COUNT, channel_type.requires_anchors_zero_fee_htlc_tx());
                if value_to_self_msat < commitment_tx_fee {
                        return Err(APIError::APIMisuseError{ err: format!("Funding amount ({}) can't even pay fee for initial commitment transaction fee of {}.", value_to_self_msat / 1000, commitment_tx_fee / 1000) });
                }
 
                let mut secp_ctx = Secp256k1::new();
-               secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
+               secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
 
                let shutdown_scriptpubkey = if config.channel_handshake_config.commit_upfront_shutdown_pubkey {
-                       Some(keys_provider.get_shutdown_scriptpubkey())
+                       Some(signer_provider.get_shutdown_scriptpubkey())
                } else { None };
 
                if let Some(shutdown_scriptpubkey) = &shutdown_scriptpubkey {
@@ -972,7 +1004,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                        inbound_handshake_limits_override: Some(config.channel_handshake_limits.clone()),
 
-                       channel_id: keys_provider.get_secure_random_bytes(),
+                       channel_id: entropy_source.get_secure_random_bytes(),
                        channel_state: ChannelState::OurInitSent as u32,
                        announcement_sigs_state: AnnouncementSigsState::NotSent,
                        secp_ctx,
@@ -982,7 +1014,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                        holder_signer,
                        shutdown_scriptpubkey,
-                       destination_script: keys_provider.get_destination_script(),
+                       destination_script: signer_provider.get_destination_script(),
 
                        cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
                        cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
@@ -1043,7 +1075,7 @@ impl<Signer: Sign> Channel<Signer> {
                                is_outbound_from_holder: true,
                                counterparty_parameters: None,
                                funding_outpoint: None,
-                               opt_anchors: if opt_anchors { Some(()) } else { None },
+                               opt_anchors: if channel_type.requires_anchors_zero_fee_htlc_tx() { Some(()) } else { None },
                                opt_non_zero_fee_anchors: None
                        },
                        funding_transaction: None,
@@ -1076,8 +1108,10 @@ impl<Signer: Sign> Channel<Signer> {
                        #[cfg(any(test, fuzzing))]
                        historical_inbound_htlc_fulfills: HashSet::new(),
 
-                       channel_type: Self::get_initial_channel_type(&config),
+                       channel_type,
                        channel_keys_id,
+
+                       pending_monitor_updates: Vec::new(),
                })
        }
 
@@ -1115,16 +1149,17 @@ impl<Signer: Sign> Channel<Signer> {
 
        /// Creates a new channel from a remote sides' request for one.
        /// Assumes chain_hash has already been checked and corresponds with what we expect!
-       pub fn new_from_req<K: Deref, F: Deref, L: Deref>(
-               fee_estimator: &LowerBoundedFeeEstimator<F>, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
-               msg: &msgs::OpenChannel, user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
-               outbound_scid_alias: u64
+       pub fn new_from_req<ES: Deref, SP: Deref, F: Deref, L: Deref>(
+               fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
+               counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
+               their_features: &InitFeatures, msg: &msgs::OpenChannel, user_id: u128, config: &UserConfig,
+               current_chain_height: u32, logger: &L, outbound_scid_alias: u64
        ) -> Result<Channel<Signer>, ChannelError>
-               where K::Target: KeysInterface<Signer = Signer>,
-                     F::Target: FeeEstimator,
-                     L::Target: Logger,
+               where ES::Target: EntropySource,
+                         SP::Target: SignerProvider<Signer = Signer>,
+                         F::Target: FeeEstimator,
+                         L::Target: Logger,
        {
-               let opt_anchors = false; // TODO - should be based on features
                let announced_channel = if (msg.channel_flags & 1) == 1 { true } else { false };
 
                // First check the channel type is known, failing before we do anything else if we don't
@@ -1134,34 +1169,31 @@ impl<Signer: Sign> Channel<Signer> {
                                return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
                        }
 
-                       if channel_type.requires_unknown_bits() {
-                               return Err(ChannelError::Close("Channel Type field contains unknown bits".to_owned()));
+                       // We only support the channel types defined by the `ChannelManager` in
+                       // `provided_channel_type_features`. The channel type must always support
+                       // `static_remote_key`.
+                       if !channel_type.requires_static_remote_key() {
+                               return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned()));
                        }
-
-                       // We currently only allow four channel types, so write it all out here - we allow
-                       // `only_static_remote_key` or `static_remote_key | zero_conf` in all contexts, and
-                       // further allow `static_remote_key | scid_privacy` or
-                       // `static_remote_key | scid_privacy | zero_conf`, if the channel is not
-                       // publicly announced.
-                       if *channel_type != ChannelTypeFeatures::only_static_remote_key() {
-                               if !channel_type.requires_scid_privacy() && !channel_type.requires_zero_conf() {
-                                       return Err(ChannelError::Close("Channel Type was not understood".to_owned()));
-                               }
-
-                               if channel_type.requires_scid_privacy() && announced_channel {
-                                       return Err(ChannelError::Close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
-                               }
+                       // Make sure we support all of the features behind the channel type.
+                       if !channel_type.is_subset(our_supported_features) {
+                               return Err(ChannelError::Close("Channel Type contains unsupported features".to_owned()));
+                       }
+                       if channel_type.requires_scid_privacy() && announced_channel {
+                               return Err(ChannelError::Close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
                        }
                        channel_type.clone()
                } else {
-                       ChannelTypeFeatures::from_counterparty_init(&their_features)
+                       let channel_type = ChannelTypeFeatures::from_init(&their_features);
+                       if channel_type != ChannelTypeFeatures::only_static_remote_key() {
+                               return Err(ChannelError::Close("Only static_remote_key is supported for non-negotiated channel types".to_owned()));
+                       }
+                       channel_type
                };
-               if !channel_type.supports_static_remote_key() {
-                       return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned()));
-               }
+               let opt_anchors = channel_type.supports_anchors_zero_fee_htlc_tx();
 
-               let channel_keys_id = keys_provider.generate_channel_keys_id(true, msg.funding_satoshis, user_id);
-               let holder_signer = keys_provider.derive_channel_signer(msg.funding_satoshis, channel_keys_id);
+               let channel_keys_id = signer_provider.generate_channel_keys_id(true, msg.funding_satoshis, user_id);
+               let holder_signer = signer_provider.derive_channel_signer(msg.funding_satoshis, channel_keys_id);
                let pubkeys = holder_signer.pubkeys().clone();
                let counterparty_pubkeys = ChannelPublicKeys {
                        funding_pubkey: msg.funding_pubkey,
@@ -1292,7 +1324,7 @@ impl<Signer: Sign> Channel<Signer> {
                } else { None };
 
                let shutdown_scriptpubkey = if config.channel_handshake_config.commit_upfront_shutdown_pubkey {
-                       Some(keys_provider.get_shutdown_scriptpubkey())
+                       Some(signer_provider.get_shutdown_scriptpubkey())
                } else { None };
 
                if let Some(shutdown_scriptpubkey) = &shutdown_scriptpubkey {
@@ -1302,7 +1334,7 @@ impl<Signer: Sign> Channel<Signer> {
                }
 
                let mut secp_ctx = Secp256k1::new();
-               secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
+               secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
 
                let chan = Channel {
                        user_id,
@@ -1326,7 +1358,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                        holder_signer,
                        shutdown_scriptpubkey,
-                       destination_script: keys_provider.get_destination_script(),
+                       destination_script: signer_provider.get_destination_script(),
 
                        cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
                        cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
@@ -1426,6 +1458,8 @@ impl<Signer: Sign> Channel<Signer> {
 
                        channel_type,
                        channel_keys_id,
+
+                       pending_monitor_updates: Vec::new(),
                };
 
                Ok(chan)
@@ -1932,22 +1966,30 @@ impl<Signer: Sign> Channel<Signer> {
                }
        }
 
-       pub fn get_update_fulfill_htlc_and_commit<L: Deref>(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage, logger: &L) -> Result<UpdateFulfillCommitFetch, (ChannelError, ChannelMonitorUpdate)> where L::Target: Logger {
+       pub fn get_update_fulfill_htlc_and_commit<L: Deref>(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage, logger: &L) -> UpdateFulfillCommitFetch where L::Target: Logger {
                match self.get_update_fulfill_htlc(htlc_id, payment_preimage, logger) {
-                       UpdateFulfillFetch::NewClaim { mut monitor_update, htlc_value_msat, msg: Some(update_fulfill_htlc) } => {
-                               let (commitment, mut additional_update) = match self.send_commitment_no_status_check(logger) {
-                                       Err(e) => return Err((e, monitor_update)),
-                                       Ok(res) => res
-                               };
-                               // send_commitment_no_status_check may bump latest_monitor_id but we want them to be
+                       UpdateFulfillFetch::NewClaim { mut monitor_update, htlc_value_msat, msg: Some(_) } => {
+                               let mut additional_update = self.build_commitment_no_status_check(logger);
+                               // build_commitment_no_status_check may bump latest_monitor_id but we want them to be
                                // strictly increasing by one, so decrement it here.
                                self.latest_monitor_update_id = monitor_update.update_id;
                                monitor_update.updates.append(&mut additional_update.updates);
-                               Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, htlc_value_msat, msgs: Some((update_fulfill_htlc, commitment)) })
+                               self.monitor_updating_paused(false, true, false, Vec::new(), Vec::new(), Vec::new());
+                               self.pending_monitor_updates.push(monitor_update);
+                               UpdateFulfillCommitFetch::NewClaim {
+                                       monitor_update: self.pending_monitor_updates.last().unwrap(),
+                                       htlc_value_msat,
+                               }
                        },
-                       UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None } =>
-                               Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, htlc_value_msat, msgs: None }),
-                       UpdateFulfillFetch::DuplicateClaim {} => Ok(UpdateFulfillCommitFetch::DuplicateClaim {}),
+                       UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None } => {
+                               self.monitor_updating_paused(false, false, false, Vec::new(), Vec::new(), Vec::new());
+                               self.pending_monitor_updates.push(monitor_update);
+                               UpdateFulfillCommitFetch::NewClaim {
+                                       monitor_update: self.pending_monitor_updates.last().unwrap(),
+                                       htlc_value_msat,
+                               }
+                       }
+                       UpdateFulfillFetch::DuplicateClaim {} => UpdateFulfillCommitFetch::DuplicateClaim {},
                }
        }
 
@@ -2128,7 +2170,11 @@ impl<Signer: Sign> Channel<Signer> {
                } else if their_features.supports_channel_type() {
                        // Assume they've accepted the channel type as they said they understand it.
                } else {
-                       self.channel_type = ChannelTypeFeatures::from_counterparty_init(&their_features)
+                       let channel_type = ChannelTypeFeatures::from_init(&their_features);
+                       if channel_type != ChannelTypeFeatures::only_static_remote_key() {
+                               return Err(ChannelError::Close("Only static_remote_key is supported for non-negotiated channel types".to_owned()));
+                       }
+                       self.channel_type = channel_type;
                }
 
                let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
@@ -2221,11 +2267,11 @@ impl<Signer: Sign> Channel<Signer> {
                &self.get_counterparty_pubkeys().funding_pubkey
        }
 
-       pub fn funding_created<K: Deref, L: Deref>(
-               &mut self, msg: &msgs::FundingCreated, best_block: BestBlock, keys_source: &K, logger: &L
-       ) -> Result<(msgs::FundingSigned, ChannelMonitor<<K::Target as SignerProvider>::Signer>, Option<msgs::ChannelReady>), ChannelError>
+       pub fn funding_created<SP: Deref, L: Deref>(
+               &mut self, msg: &msgs::FundingCreated, best_block: BestBlock, signer_provider: &SP, logger: &L
+       ) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>), ChannelError>
        where
-               K::Target: KeysInterface,
+               SP::Target: SignerProvider<Signer = Signer>,
                L::Target: Logger
        {
                if self.is_outbound() {
@@ -2282,7 +2328,7 @@ impl<Signer: Sign> Channel<Signer> {
                let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
                let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
                let shutdown_script = self.shutdown_scriptpubkey.clone().map(|script| script.into_inner());
-               let mut monitor_signer = keys_source.derive_channel_signer(self.channel_value_satoshis, self.channel_keys_id);
+               let mut monitor_signer = signer_provider.derive_channel_signer(self.channel_value_satoshis, self.channel_keys_id);
                monitor_signer.provide_channel_parameters(&self.channel_transaction_parameters);
                let channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), monitor_signer,
                                                          shutdown_script, self.get_holder_selected_contest_delay(),
@@ -2301,19 +2347,22 @@ impl<Signer: Sign> Channel<Signer> {
 
                log_info!(logger, "Generated funding_signed for peer for channel {}", log_bytes!(self.channel_id()));
 
+               let need_channel_ready = self.check_get_channel_ready(0).is_some();
+               self.monitor_updating_paused(false, false, need_channel_ready, Vec::new(), Vec::new(), Vec::new());
+
                Ok((msgs::FundingSigned {
                        channel_id: self.channel_id,
                        signature
-               }, channel_monitor, self.check_get_channel_ready(0)))
+               }, channel_monitor))
        }
 
        /// Handles a funding_signed message from the remote end.
        /// If this call is successful, broadcast the funding transaction (and not before!)
-       pub fn funding_signed<K: Deref, L: Deref>(
-               &mut self, msg: &msgs::FundingSigned, best_block: BestBlock, keys_source: &K, logger: &L
-       ) -> Result<(ChannelMonitor<<K::Target as SignerProvider>::Signer>, Transaction, Option<msgs::ChannelReady>), ChannelError>
+       pub fn funding_signed<SP: Deref, L: Deref>(
+               &mut self, msg: &msgs::FundingSigned, best_block: BestBlock, signer_provider: &SP, logger: &L
+       ) -> Result<ChannelMonitor<Signer>, ChannelError>
        where
-               K::Target: KeysInterface,
+               SP::Target: SignerProvider<Signer = Signer>,
                L::Target: Logger
        {
                if !self.is_outbound() {
@@ -2367,7 +2416,7 @@ impl<Signer: Sign> Channel<Signer> {
                let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
                let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
                let shutdown_script = self.shutdown_scriptpubkey.clone().map(|script| script.into_inner());
-               let mut monitor_signer = keys_source.derive_channel_signer(self.channel_value_satoshis, self.channel_keys_id);
+               let mut monitor_signer = signer_provider.derive_channel_signer(self.channel_value_satoshis, self.channel_keys_id);
                monitor_signer.provide_channel_parameters(&self.channel_transaction_parameters);
                let channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), monitor_signer,
                                                          shutdown_script, self.get_holder_selected_contest_delay(),
@@ -2386,13 +2435,22 @@ impl<Signer: Sign> Channel<Signer> {
 
                log_info!(logger, "Received funding_signed from peer for channel {}", log_bytes!(self.channel_id()));
 
-               Ok((channel_monitor, self.funding_transaction.as_ref().cloned().unwrap(), self.check_get_channel_ready(0)))
+               let need_channel_ready = self.check_get_channel_ready(0).is_some();
+               self.monitor_updating_paused(false, false, need_channel_ready, Vec::new(), Vec::new(), Vec::new());
+               Ok(channel_monitor)
        }
 
        /// Handles a channel_ready message from our peer. If we've already sent our channel_ready
        /// and the channel is now usable (and public), this may generate an announcement_signatures to
        /// reply with.
-       pub fn channel_ready<L: Deref>(&mut self, msg: &msgs::ChannelReady, node_pk: PublicKey, genesis_block_hash: BlockHash, best_block: &BestBlock, logger: &L) -> Result<Option<msgs::AnnouncementSignatures>, ChannelError> where L::Target: Logger {
+       pub fn channel_ready<NS: Deref, L: Deref>(
+               &mut self, msg: &msgs::ChannelReady, node_signer: &NS, genesis_block_hash: BlockHash,
+               user_config: &UserConfig, best_block: &BestBlock, logger: &L
+       ) -> Result<Option<msgs::AnnouncementSignatures>, ChannelError>
+       where
+               NS::Target: NodeSigner,
+               L::Target: Logger
+       {
                if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
                        self.workaround_lnd_bug_4006 = Some(msg.clone());
                        return Err(ChannelError::Ignore("Peer sent channel_ready when we needed a channel_reestablish. The peer is likely lnd, see https://github.com/lightningnetwork/lnd/issues/4006".to_owned()));
@@ -2451,7 +2509,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                log_info!(logger, "Received channel_ready from peer for channel {}", log_bytes!(self.channel_id()));
 
-               Ok(self.get_announcement_sigs(node_pk, genesis_block_hash, best_block.height(), logger))
+               Ok(self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger))
        }
 
        /// Returns transaction if there is pending funding transaction that is yet to broadcast
@@ -2996,17 +3054,17 @@ impl<Signer: Sign> Channel<Signer> {
                Ok(())
        }
 
-       pub fn commitment_signed<L: Deref>(&mut self, msg: &msgs::CommitmentSigned, logger: &L) -> Result<(msgs::RevokeAndACK, Option<msgs::CommitmentSigned>, ChannelMonitorUpdate), (Option<ChannelMonitorUpdate>, ChannelError)>
+       pub fn commitment_signed<L: Deref>(&mut self, msg: &msgs::CommitmentSigned, logger: &L) -> Result<&ChannelMonitorUpdate, ChannelError>
                where L::Target: Logger
        {
                if (self.channel_state & (ChannelState::ChannelReady as u32)) != (ChannelState::ChannelReady as u32) {
-                       return Err((None, ChannelError::Close("Got commitment signed message when channel was not in an operational state".to_owned())));
+                       return Err(ChannelError::Close("Got commitment signed message when channel was not in an operational state".to_owned()));
                }
                if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
-                       return Err((None, ChannelError::Close("Peer sent commitment_signed when we needed a channel_reestablish".to_owned())));
+                       return Err(ChannelError::Close("Peer sent commitment_signed when we needed a channel_reestablish".to_owned()));
                }
                if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK == BOTH_SIDES_SHUTDOWN_MASK && self.last_sent_closing_fee.is_some() {
-                       return Err((None, ChannelError::Close("Peer sent commitment_signed after we'd started exchanging closing_signeds".to_owned())));
+                       return Err(ChannelError::Close("Peer sent commitment_signed after we'd started exchanging closing_signeds".to_owned()));
                }
 
                let funding_script = self.get_funding_redeemscript();
@@ -3024,7 +3082,7 @@ impl<Signer: Sign> Channel<Signer> {
                                log_bytes!(self.counterparty_funding_pubkey().serialize()), encode::serialize_hex(&bitcoin_tx.transaction),
                                log_bytes!(sighash[..]), encode::serialize_hex(&funding_script), log_bytes!(self.channel_id()));
                        if let Err(_) = self.secp_ctx.verify_ecdsa(&sighash, &msg.signature, &self.counterparty_funding_pubkey()) {
-                               return Err((None, ChannelError::Close("Invalid commitment tx signature from peer".to_owned())));
+                               return Err(ChannelError::Close("Invalid commitment tx signature from peer".to_owned()));
                        }
                        bitcoin_tx.txid
                };
@@ -3039,7 +3097,7 @@ impl<Signer: Sign> Channel<Signer> {
                        debug_assert!(!self.is_outbound());
                        let counterparty_reserve_we_require_msat = self.holder_selected_channel_reserve_satoshis * 1000;
                        if commitment_stats.remote_balance_msat < commitment_stats.total_fee_sat * 1000 + counterparty_reserve_we_require_msat {
-                               return Err((None, ChannelError::Close("Funding remote cannot afford proposed new fee".to_owned())));
+                               return Err(ChannelError::Close("Funding remote cannot afford proposed new fee".to_owned()));
                        }
                }
                #[cfg(any(test, fuzzing))]
@@ -3061,7 +3119,7 @@ impl<Signer: Sign> Channel<Signer> {
                }
 
                if msg.htlc_signatures.len() != commitment_stats.num_nondust_htlcs {
-                       return Err((None, ChannelError::Close(format!("Got wrong number of HTLC signatures ({}) from remote. It must be {}", msg.htlc_signatures.len(), commitment_stats.num_nondust_htlcs))));
+                       return Err(ChannelError::Close(format!("Got wrong number of HTLC signatures ({}) from remote. It must be {}", msg.htlc_signatures.len(), commitment_stats.num_nondust_htlcs)));
                }
 
                // TODO: Sadly, we pass HTLCs twice to ChannelMonitor: once via the HolderCommitmentTransaction and once via the update
@@ -3079,7 +3137,7 @@ impl<Signer: Sign> Channel<Signer> {
                                        log_bytes!(msg.htlc_signatures[idx].serialize_compact()[..]), log_bytes!(keys.countersignatory_htlc_key.serialize()),
                                        encode::serialize_hex(&htlc_tx), log_bytes!(htlc_sighash[..]), encode::serialize_hex(&htlc_redeemscript), log_bytes!(self.channel_id()));
                                if let Err(_) = self.secp_ctx.verify_ecdsa(&htlc_sighash, &msg.htlc_signatures[idx], &keys.countersignatory_htlc_key) {
-                                       return Err((None, ChannelError::Close("Invalid HTLC tx signature from peer".to_owned())));
+                                       return Err(ChannelError::Close("Invalid HTLC tx signature from peer".to_owned()));
                                }
                                htlcs_and_sigs.push((htlc, Some(msg.htlc_signatures[idx]), source));
                        } else {
@@ -3095,10 +3153,8 @@ impl<Signer: Sign> Channel<Signer> {
                        self.counterparty_funding_pubkey()
                );
 
-               let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number - 1, &self.secp_ctx);
                self.holder_signer.validate_holder_commitment(&holder_commitment_tx, commitment_stats.preimages)
-                       .map_err(|_| (None, ChannelError::Close("Failed to validate our commitment".to_owned())))?;
-               let per_commitment_secret = self.holder_signer.release_commitment_secret(self.cur_holder_commitment_transaction_number + 1);
+                       .map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;
 
                // Update state now that we've passed all the can-fail calls...
                let mut need_commitment = false;
@@ -3109,15 +3165,6 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
 
-               self.latest_monitor_update_id += 1;
-               let mut monitor_update = ChannelMonitorUpdate {
-                       update_id: self.latest_monitor_update_id,
-                       updates: vec![ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
-                               commitment_tx: holder_commitment_tx,
-                               htlc_outputs: htlcs_and_sigs
-                       }]
-               };
-
                for htlc in self.pending_inbound_htlcs.iter_mut() {
                        let new_forward = if let &InboundHTLCState::RemoteAnnounced(ref forward_info) = &htlc.state {
                                Some(forward_info.clone())
@@ -3129,6 +3176,7 @@ impl<Signer: Sign> Channel<Signer> {
                                need_commitment = true;
                        }
                }
+               let mut claimed_htlcs = Vec::new();
                for htlc in self.pending_outbound_htlcs.iter_mut() {
                        if let &mut OutboundHTLCState::RemoteRemoved(ref mut outcome) = &mut htlc.state {
                                log_trace!(logger, "Updating HTLC {} to AwaitingRemoteRevokeToRemove due to commitment_signed in channel {}.",
@@ -3136,14 +3184,33 @@ impl<Signer: Sign> Channel<Signer> {
                                // Grab the preimage, if it exists, instead of cloning
                                let mut reason = OutboundHTLCOutcome::Success(None);
                                mem::swap(outcome, &mut reason);
+                               if let OutboundHTLCOutcome::Success(Some(preimage)) = reason {
+                                       // If a user (a) receives an HTLC claim using LDK 0.0.104 or before, then (b)
+                                       // upgrades to LDK 0.0.114 or later before the HTLC is fully resolved, we could
+                                       // have a `Success(None)` reason. In this case we could forget some HTLC
+                                       // claims, but such an upgrade is unlikely and including claimed HTLCs here
+                                       // fixes a bug which the user was exposed to on 0.0.104 when they started the
+                                       // claim anyway.
+                                       claimed_htlcs.push((SentHTLCId::from_source(&htlc.source), preimage));
+                               }
                                htlc.state = OutboundHTLCState::AwaitingRemoteRevokeToRemove(reason);
                                need_commitment = true;
                        }
                }
 
+               self.latest_monitor_update_id += 1;
+               let mut monitor_update = ChannelMonitorUpdate {
+                       update_id: self.latest_monitor_update_id,
+                       updates: vec![ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
+                               commitment_tx: holder_commitment_tx,
+                               htlc_outputs: htlcs_and_sigs,
+                               claimed_htlcs,
+                       }]
+               };
+
                self.cur_holder_commitment_transaction_number -= 1;
                // Note that if we need_commitment & !AwaitingRemoteRevoke we'll call
-               // send_commitment_no_status_check() next which will reset this to RAAFirst.
+               // build_commitment_no_status_check() next which will reset this to RAAFirst.
                self.resend_order = RAACommitmentOrder::CommitmentFirst;
 
                if (self.channel_state & ChannelState::MonitorUpdateInProgress as u32) != 0 {
@@ -3155,52 +3222,50 @@ impl<Signer: Sign> Channel<Signer> {
                                // the corresponding HTLC status updates so that get_last_commitment_update
                                // includes the right HTLCs.
                                self.monitor_pending_commitment_signed = true;
-                               let (_, mut additional_update) = self.send_commitment_no_status_check(logger).map_err(|e| (None, e))?;
-                               // send_commitment_no_status_check may bump latest_monitor_id but we want them to be
+                               let mut additional_update = self.build_commitment_no_status_check(logger);
+                               // build_commitment_no_status_check may bump latest_monitor_id but we want them to be
                                // strictly increasing by one, so decrement it here.
                                self.latest_monitor_update_id = monitor_update.update_id;
                                monitor_update.updates.append(&mut additional_update.updates);
                        }
                        log_debug!(logger, "Received valid commitment_signed from peer in channel {}, updated HTLC state but awaiting a monitor update resolution to reply.",
                                log_bytes!(self.channel_id));
-                       return Err((Some(monitor_update), ChannelError::Ignore("Previous monitor update failure prevented generation of RAA".to_owned())));
+                       self.pending_monitor_updates.push(monitor_update);
+                       return Ok(self.pending_monitor_updates.last().unwrap());
                }
 
-               let commitment_signed = if need_commitment && (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 {
+               let need_commitment_signed = if need_commitment && (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 {
                        // If we're AwaitingRemoteRevoke we can't send a new commitment here, but that's ok -
                        // we'll send one right away when we get the revoke_and_ack when we
                        // free_holding_cell_htlcs().
-                       let (msg, mut additional_update) = self.send_commitment_no_status_check(logger).map_err(|e| (None, e))?;
-                       // send_commitment_no_status_check may bump latest_monitor_id but we want them to be
+                       let mut additional_update = self.build_commitment_no_status_check(logger);
+                       // build_commitment_no_status_check may bump latest_monitor_id but we want them to be
                        // strictly increasing by one, so decrement it here.
                        self.latest_monitor_update_id = monitor_update.update_id;
                        monitor_update.updates.append(&mut additional_update.updates);
-                       Some(msg)
-               } else { None };
+                       true
+               } else { false };
 
                log_debug!(logger, "Received valid commitment_signed from peer in channel {}, updating HTLC state and responding with{} a revoke_and_ack.",
-                       log_bytes!(self.channel_id()), if commitment_signed.is_some() { " our own commitment_signed and" } else { "" });
-
-               Ok((msgs::RevokeAndACK {
-                       channel_id: self.channel_id,
-                       per_commitment_secret,
-                       next_per_commitment_point,
-               }, commitment_signed, monitor_update))
+                       log_bytes!(self.channel_id()), if need_commitment_signed { " our own commitment_signed and" } else { "" });
+               self.pending_monitor_updates.push(monitor_update);
+               self.monitor_updating_paused(true, need_commitment_signed, false, Vec::new(), Vec::new(), Vec::new());
+               return Ok(self.pending_monitor_updates.last().unwrap());
        }
 
        /// Public version of the below, checking relevant preconditions first.
        /// If we're not in a state where freeing the holding cell makes sense, this is a no-op and
        /// returns `(None, Vec::new())`.
-       pub fn maybe_free_holding_cell_htlcs<L: Deref>(&mut self, logger: &L) -> Result<(Option<(msgs::CommitmentUpdate, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash)>), ChannelError> where L::Target: Logger {
+       pub fn maybe_free_holding_cell_htlcs<L: Deref>(&mut self, logger: &L) -> (Option<&ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>) where L::Target: Logger {
                if self.channel_state >= ChannelState::ChannelReady as u32 &&
                   (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32)) == 0 {
                        self.free_holding_cell_htlcs(logger)
-               } else { Ok((None, Vec::new())) }
+               } else { (None, Vec::new()) }
        }
 
        /// Frees any pending commitment updates in the holding cell, generating the relevant messages
        /// for our counterparty.
-       fn free_holding_cell_htlcs<L: Deref>(&mut self, logger: &L) -> Result<(Option<(msgs::CommitmentUpdate, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash)>), ChannelError> where L::Target: Logger {
+       fn free_holding_cell_htlcs<L: Deref>(&mut self, logger: &L) -> (Option<&ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>) where L::Target: Logger {
                assert_eq!(self.channel_state & ChannelState::MonitorUpdateInProgress as u32, 0);
                if self.holding_cell_htlc_updates.len() != 0 || self.holding_cell_update_fee.is_some() {
                        log_trace!(logger, "Freeing holding cell with {} HTLC updates{} in channel {}", self.holding_cell_htlc_updates.len(),
@@ -3281,7 +3346,7 @@ impl<Signer: Sign> Channel<Signer> {
                                }
                        }
                        if update_add_htlcs.is_empty() && update_fulfill_htlcs.is_empty() && update_fail_htlcs.is_empty() && self.holding_cell_update_fee.is_none() {
-                               return Ok((None, htlcs_to_fail));
+                               return (None, htlcs_to_fail);
                        }
                        let update_fee = if let Some(feerate) = self.holding_cell_update_fee.take() {
                                self.send_update_fee(feerate, false, logger)
@@ -3289,8 +3354,8 @@ impl<Signer: Sign> Channel<Signer> {
                                None
                        };
 
-                       let (commitment_signed, mut additional_update) = self.send_commitment_no_status_check(logger)?;
-                       // send_commitment_no_status_check and get_update_fulfill_htlc may bump latest_monitor_id
+                       let mut additional_update = self.build_commitment_no_status_check(logger);
+                       // build_commitment_no_status_check and get_update_fulfill_htlc may bump latest_monitor_id
                        // but we want them to be strictly increasing by one, so reset it here.
                        self.latest_monitor_update_id = monitor_update.update_id;
                        monitor_update.updates.append(&mut additional_update.updates);
@@ -3299,16 +3364,11 @@ impl<Signer: Sign> Channel<Signer> {
                                log_bytes!(self.channel_id()), if update_fee.is_some() { "a fee update, " } else { "" },
                                update_add_htlcs.len(), update_fulfill_htlcs.len(), update_fail_htlcs.len());
 
-                       Ok((Some((msgs::CommitmentUpdate {
-                               update_add_htlcs,
-                               update_fulfill_htlcs,
-                               update_fail_htlcs,
-                               update_fail_malformed_htlcs: Vec::new(),
-                               update_fee,
-                               commitment_signed,
-                       }, monitor_update)), htlcs_to_fail))
+                       self.monitor_updating_paused(false, true, false, Vec::new(), Vec::new(), Vec::new());
+                       self.pending_monitor_updates.push(monitor_update);
+                       (Some(self.pending_monitor_updates.last().unwrap()), htlcs_to_fail)
                } else {
-                       Ok((None, Vec::new()))
+                       (None, Vec::new())
                }
        }
 
@@ -3317,7 +3377,7 @@ impl<Signer: Sign> Channel<Signer> {
        /// waiting on this revoke_and_ack. The generation of this new commitment_signed may also fail,
        /// generating an appropriate error *after* the channel state has been updated based on the
        /// revoke_and_ack message.
-       pub fn revoke_and_ack<L: Deref>(&mut self, msg: &msgs::RevokeAndACK, logger: &L) -> Result<RAAUpdates, ChannelError>
+       pub fn revoke_and_ack<L: Deref>(&mut self, msg: &msgs::RevokeAndACK, logger: &L) -> Result<(Vec<(HTLCSource, PaymentHash)>, &ChannelMonitorUpdate), ChannelError>
                where L::Target: Logger,
        {
                if (self.channel_state & (ChannelState::ChannelReady as u32)) != (ChannelState::ChannelReady as u32) {
@@ -3504,8 +3564,8 @@ impl<Signer: Sign> Channel<Signer> {
                                // When the monitor updating is restored we'll call get_last_commitment_update(),
                                // which does not update state, but we're definitely now awaiting a remote revoke
                                // before we can step forward any more, so set it here.
-                               let (_, mut additional_update) = self.send_commitment_no_status_check(logger)?;
-                               // send_commitment_no_status_check may bump latest_monitor_id but we want them to be
+                               let mut additional_update = self.build_commitment_no_status_check(logger);
+                               // build_commitment_no_status_check may bump latest_monitor_id but we want them to be
                                // strictly increasing by one, so decrement it here.
                                self.latest_monitor_update_id = monitor_update.update_id;
                                monitor_update.updates.append(&mut additional_update.updates);
@@ -3514,71 +3574,41 @@ impl<Signer: Sign> Channel<Signer> {
                        self.monitor_pending_failures.append(&mut revoked_htlcs);
                        self.monitor_pending_finalized_fulfills.append(&mut finalized_claimed_htlcs);
                        log_debug!(logger, "Received a valid revoke_and_ack for channel {} but awaiting a monitor update resolution to reply.", log_bytes!(self.channel_id()));
-                       return Ok(RAAUpdates {
-                               commitment_update: None, finalized_claimed_htlcs: Vec::new(),
-                               accepted_htlcs: Vec::new(), failed_htlcs: Vec::new(),
-                               monitor_update,
-                               holding_cell_failed_htlcs: Vec::new()
-                       });
+                       self.pending_monitor_updates.push(monitor_update);
+                       return Ok((Vec::new(), self.pending_monitor_updates.last().unwrap()));
                }
 
-               match self.free_holding_cell_htlcs(logger)? {
-                       (Some((mut commitment_update, mut additional_update)), htlcs_to_fail) => {
-                               commitment_update.update_fail_htlcs.reserve(update_fail_htlcs.len());
-                               for fail_msg in update_fail_htlcs.drain(..) {
-                                       commitment_update.update_fail_htlcs.push(fail_msg);
-                               }
-                               commitment_update.update_fail_malformed_htlcs.reserve(update_fail_malformed_htlcs.len());
-                               for fail_msg in update_fail_malformed_htlcs.drain(..) {
-                                       commitment_update.update_fail_malformed_htlcs.push(fail_msg);
-                               }
-
+               match self.free_holding_cell_htlcs(logger) {
+                       (Some(_), htlcs_to_fail) => {
+                               let mut additional_update = self.pending_monitor_updates.pop().unwrap();
                                // free_holding_cell_htlcs may bump latest_monitor_id multiple times but we want them to be
                                // strictly increasing by one, so decrement it here.
                                self.latest_monitor_update_id = monitor_update.update_id;
                                monitor_update.updates.append(&mut additional_update.updates);
 
-                               Ok(RAAUpdates {
-                                       commitment_update: Some(commitment_update),
-                                       finalized_claimed_htlcs,
-                                       accepted_htlcs: to_forward_infos,
-                                       failed_htlcs: revoked_htlcs,
-                                       monitor_update,
-                                       holding_cell_failed_htlcs: htlcs_to_fail
-                               })
+                               self.monitor_updating_paused(false, true, false, to_forward_infos, revoked_htlcs, finalized_claimed_htlcs);
+                               self.pending_monitor_updates.push(monitor_update);
+                               Ok((htlcs_to_fail, self.pending_monitor_updates.last().unwrap()))
                        },
                        (None, htlcs_to_fail) => {
                                if require_commitment {
-                                       let (commitment_signed, mut additional_update) = self.send_commitment_no_status_check(logger)?;
+                                       let mut additional_update = self.build_commitment_no_status_check(logger);
 
-                                       // send_commitment_no_status_check may bump latest_monitor_id but we want them to be
+                                       // build_commitment_no_status_check may bump latest_monitor_id but we want them to be
                                        // strictly increasing by one, so decrement it here.
                                        self.latest_monitor_update_id = monitor_update.update_id;
                                        monitor_update.updates.append(&mut additional_update.updates);
 
                                        log_debug!(logger, "Received a valid revoke_and_ack for channel {}. Responding with a commitment update with {} HTLCs failed.",
                                                log_bytes!(self.channel_id()), update_fail_htlcs.len() + update_fail_malformed_htlcs.len());
-                                       Ok(RAAUpdates {
-                                               commitment_update: Some(msgs::CommitmentUpdate {
-                                                       update_add_htlcs: Vec::new(),
-                                                       update_fulfill_htlcs: Vec::new(),
-                                                       update_fail_htlcs,
-                                                       update_fail_malformed_htlcs,
-                                                       update_fee: None,
-                                                       commitment_signed
-                                               }),
-                                               finalized_claimed_htlcs,
-                                               accepted_htlcs: to_forward_infos, failed_htlcs: revoked_htlcs,
-                                               monitor_update, holding_cell_failed_htlcs: htlcs_to_fail
-                                       })
+                                       self.monitor_updating_paused(false, true, false, to_forward_infos, revoked_htlcs, finalized_claimed_htlcs);
+                                       self.pending_monitor_updates.push(monitor_update);
+                                       Ok((htlcs_to_fail, self.pending_monitor_updates.last().unwrap()))
                                } else {
                                        log_debug!(logger, "Received a valid revoke_and_ack for channel {} with no reply necessary.", log_bytes!(self.channel_id()));
-                                       Ok(RAAUpdates {
-                                               commitment_update: None,
-                                               finalized_claimed_htlcs,
-                                               accepted_htlcs: to_forward_infos, failed_htlcs: revoked_htlcs,
-                                               monitor_update, holding_cell_failed_htlcs: htlcs_to_fail
-                                       })
+                                       self.monitor_updating_paused(false, false, false, to_forward_infos, revoked_htlcs, finalized_claimed_htlcs);
+                                       self.pending_monitor_updates.push(monitor_update);
+                                       Ok((htlcs_to_fail, self.pending_monitor_updates.last().unwrap()))
                                }
                        }
                }
@@ -3730,15 +3760,17 @@ impl<Signer: Sign> Channel<Signer> {
        }
 
        /// Indicates that a ChannelMonitor update is in progress and has not yet been fully persisted.
-       /// This must be called immediately after the [`chain::Watch`] call which returned
-       /// [`ChannelMonitorUpdateStatus::InProgress`].
+       /// This must be called before we return the [`ChannelMonitorUpdate`] back to the
+       /// [`ChannelManager`], which will call [`Self::monitor_updating_restored`] once the monitor
+       /// update completes (potentially immediately).
        /// The messages which were generated with the monitor update must *not* have been sent to the
        /// remote end, and must instead have been dropped. They will be regenerated when
        /// [`Self::monitor_updating_restored`] is called.
        ///
+       /// [`ChannelManager`]: super::channelmanager::ChannelManager
        /// [`chain::Watch`]: crate::chain::Watch
        /// [`ChannelMonitorUpdateStatus::InProgress`]: crate::chain::ChannelMonitorUpdateStatus::InProgress
-       pub fn monitor_updating_paused(&mut self, resend_raa: bool, resend_commitment: bool,
+       fn monitor_updating_paused(&mut self, resend_raa: bool, resend_commitment: bool,
                resend_channel_ready: bool, mut pending_forwards: Vec<(PendingHTLCInfo, u64)>,
                mut pending_fails: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
                mut pending_finalized_claimed_htlcs: Vec<HTLCSource>
@@ -3755,9 +3787,17 @@ impl<Signer: Sign> Channel<Signer> {
        /// Indicates that the latest ChannelMonitor update has been committed by the client
        /// successfully and we should restore normal operation. Returns messages which should be sent
        /// to the remote side.
-       pub fn monitor_updating_restored<L: Deref>(&mut self, logger: &L, node_pk: PublicKey, genesis_block_hash: BlockHash, best_block_height: u32) -> MonitorRestoreUpdates where L::Target: Logger {
+       pub fn monitor_updating_restored<L: Deref, NS: Deref>(
+               &mut self, logger: &L, node_signer: &NS, genesis_block_hash: BlockHash,
+               user_config: &UserConfig, best_block_height: u32
+       ) -> MonitorRestoreUpdates
+       where
+               L::Target: Logger,
+               NS::Target: NodeSigner
+       {
                assert_eq!(self.channel_state & ChannelState::MonitorUpdateInProgress as u32, ChannelState::MonitorUpdateInProgress as u32);
                self.channel_state &= !(ChannelState::MonitorUpdateInProgress as u32);
+               self.pending_monitor_updates.clear();
 
                // If we're past (or at) the FundingSent stage on an outbound channel, try to
                // (re-)broadcast the funding transaction as we may have declined to broadcast it when we
@@ -3790,7 +3830,7 @@ impl<Signer: Sign> Channel<Signer> {
                        })
                } else { None };
 
-               let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, best_block_height, logger);
+               let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block_height, logger);
 
                let mut accepted_htlcs = Vec::new();
                mem::swap(&mut accepted_htlcs, &mut self.monitor_pending_forwards);
@@ -3942,9 +3982,14 @@ impl<Signer: Sign> Channel<Signer> {
        /// `cargo doc --document-private-items`):
        /// [`super::channelmanager::ChannelManager::force_close_without_broadcasting_txn`] and
        /// [`super::channelmanager::ChannelManager::force_close_all_channels_without_broadcasting_txn`].
-       pub fn channel_reestablish<L: Deref>(&mut self, msg: &msgs::ChannelReestablish, logger: &L,
-               node_pk: PublicKey, genesis_block_hash: BlockHash, best_block: &BestBlock)
-       -> Result<ReestablishResponses, ChannelError> where L::Target: Logger {
+       pub fn channel_reestablish<L: Deref, NS: Deref>(
+               &mut self, msg: &msgs::ChannelReestablish, logger: &L, node_signer: &NS,
+               genesis_block_hash: BlockHash, user_config: &UserConfig, best_block: &BestBlock
+       ) -> Result<ReestablishResponses, ChannelError>
+       where
+               L::Target: Logger,
+               NS::Target: NodeSigner
+       {
                if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
                        // While BOLT 2 doesn't indicate explicitly we should error this channel here, it
                        // almost certainly indicates we are going to end up out-of-sync in some way, so we
@@ -4008,7 +4053,7 @@ impl<Signer: Sign> Channel<Signer> {
                        })
                } else { None };
 
-               let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, best_block.height(), logger);
+               let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger);
 
                if self.channel_state & (ChannelState::FundingSent as u32) == ChannelState::FundingSent as u32 {
                        // If we're waiting on a monitor update, we shouldn't re-send any channel_ready's.
@@ -4228,10 +4273,10 @@ impl<Signer: Sign> Channel<Signer> {
                }), None))
        }
 
-       pub fn shutdown<K: Deref>(
-               &mut self, keys_provider: &K, their_features: &InitFeatures, msg: &msgs::Shutdown
-       ) -> Result<(Option<msgs::Shutdown>, Option<ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>), ChannelError>
-       where K::Target: KeysInterface
+       pub fn shutdown<SP: Deref>(
+               &mut self, signer_provider: &SP, their_features: &InitFeatures, msg: &msgs::Shutdown
+       ) -> Result<(Option<msgs::Shutdown>, Option<&ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>), ChannelError>
+       where SP::Target: SignerProvider
        {
                if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
                        return Err(ChannelError::Close("Peer sent shutdown when we needed a channel_reestablish".to_owned()));
@@ -4270,7 +4315,7 @@ impl<Signer: Sign> Channel<Signer> {
                        Some(_) => false,
                        None => {
                                assert!(send_shutdown);
-                               let shutdown_scriptpubkey = keys_provider.get_shutdown_scriptpubkey();
+                               let shutdown_scriptpubkey = signer_provider.get_shutdown_scriptpubkey();
                                if !shutdown_scriptpubkey.is_compatible(their_features) {
                                        return Err(ChannelError::Close(format!("Provided a scriptpubkey format not accepted by peer: {}", shutdown_scriptpubkey)));
                                }
@@ -4286,12 +4331,15 @@ impl<Signer: Sign> Channel<Signer> {
 
                let monitor_update = if update_shutdown_script {
                        self.latest_monitor_update_id += 1;
-                       Some(ChannelMonitorUpdate {
+                       let monitor_update = ChannelMonitorUpdate {
                                update_id: self.latest_monitor_update_id,
                                updates: vec![ChannelMonitorUpdateStep::ShutdownScript {
                                        scriptpubkey: self.get_closing_scriptpubkey(),
                                }],
-                       })
+                       };
+                       self.monitor_updating_paused(false, false, false, Vec::new(), Vec::new(), Vec::new());
+                       self.pending_monitor_updates.push(monitor_update);
+                       Some(self.pending_monitor_updates.last().unwrap())
                } else { None };
                let shutdown = if send_shutdown {
                        Some(msgs::Shutdown {
@@ -4841,6 +4889,10 @@ impl<Signer: Sign> Channel<Signer> {
                (self.channel_state & ChannelState::MonitorUpdateInProgress as u32) != 0
        }
 
+       pub fn get_next_monitor_update(&self) -> Option<&ChannelMonitorUpdate> {
+               self.pending_monitor_updates.first()
+       }
+
        /// Returns true if funding_created was sent/received.
        pub fn is_funding_initiated(&self) -> bool {
                self.channel_state >= ChannelState::FundingSent as u32
@@ -4980,9 +5032,14 @@ impl<Signer: Sign> Channel<Signer> {
        /// When a transaction is confirmed, we check whether it is or spends the funding transaction
        /// In the first case, we store the confirmation height and calculating the short channel id.
        /// In the second, we simply return an Err indicating we need to be force-closed now.
-       pub fn transactions_confirmed<L: Deref>(&mut self, block_hash: &BlockHash, height: u32,
-               txdata: &TransactionData, genesis_block_hash: BlockHash, node_pk: PublicKey, logger: &L)
-       -> Result<(Option<msgs::ChannelReady>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
+       pub fn transactions_confirmed<NS: Deref, L: Deref>(
+               &mut self, block_hash: &BlockHash, height: u32, txdata: &TransactionData,
+               genesis_block_hash: BlockHash, node_signer: &NS, user_config: &UserConfig, logger: &L
+       ) -> Result<(Option<msgs::ChannelReady>, Option<msgs::AnnouncementSignatures>), ClosureReason>
+       where
+               NS::Target: NodeSigner,
+               L::Target: Logger
+       {
                if let Some(funding_txo) = self.get_funding_txo() {
                        for &(index_in_block, tx) in txdata.iter() {
                                // Check if the transaction is the expected funding transaction, and if it is,
@@ -5028,7 +5085,7 @@ impl<Signer: Sign> Channel<Signer> {
                                        // may have already happened for this block).
                                        if let Some(channel_ready) = self.check_get_channel_ready(height) {
                                                log_info!(logger, "Sending a channel_ready to our peer for channel {}", log_bytes!(self.channel_id));
-                                               let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, height, logger);
+                                               let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger);
                                                return Ok((Some(channel_ready), announcement_sigs));
                                        }
                                }
@@ -5054,13 +5111,25 @@ impl<Signer: Sign> Channel<Signer> {
        ///
        /// May return some HTLCs (and their payment_hash) which have timed out and should be failed
        /// back.
-       pub fn best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, genesis_block_hash: BlockHash, node_pk: PublicKey, logger: &L)
-       -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
-               self.do_best_block_updated(height, highest_header_time, Some((genesis_block_hash, node_pk)), logger)
+       pub fn best_block_updated<NS: Deref, L: Deref>(
+               &mut self, height: u32, highest_header_time: u32, genesis_block_hash: BlockHash,
+               node_signer: &NS, user_config: &UserConfig, logger: &L
+       ) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>
+       where
+               NS::Target: NodeSigner,
+               L::Target: Logger
+       {
+               self.do_best_block_updated(height, highest_header_time, Some((genesis_block_hash, node_signer, user_config)), logger)
        }
 
-       fn do_best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, genesis_node_pk: Option<(BlockHash, PublicKey)>, logger: &L)
-       -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
+       fn do_best_block_updated<NS: Deref, L: Deref>(
+               &mut self, height: u32, highest_header_time: u32,
+               genesis_node_signer: Option<(BlockHash, &NS, &UserConfig)>, logger: &L
+       ) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>
+       where
+               NS::Target: NodeSigner,
+               L::Target: Logger
+       {
                let mut timed_out_htlcs = Vec::new();
                // This mirrors the check in ChannelManager::decode_update_add_htlc_onion, refusing to
                // forward an HTLC when our counterparty should almost certainly just fail it for expiring
@@ -5081,8 +5150,8 @@ impl<Signer: Sign> Channel<Signer> {
                self.update_time_counter = cmp::max(self.update_time_counter, highest_header_time);
 
                if let Some(channel_ready) = self.check_get_channel_ready(height) {
-                       let announcement_sigs = if let Some((genesis_block_hash, node_pk)) = genesis_node_pk {
-                               self.get_announcement_sigs(node_pk, genesis_block_hash, height, logger)
+                       let announcement_sigs = if let Some((genesis_block_hash, node_signer, user_config)) = genesis_node_signer {
+                               self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger)
                        } else { None };
                        log_info!(logger, "Sending a channel_ready to our peer for channel {}", log_bytes!(self.channel_id));
                        return Ok((Some(channel_ready), timed_out_htlcs, announcement_sigs));
@@ -5122,8 +5191,8 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(ClosureReason::FundingTimedOut);
                }
 
-               let announcement_sigs = if let Some((genesis_block_hash, node_pk)) = genesis_node_pk {
-                       self.get_announcement_sigs(node_pk, genesis_block_hash, height, logger)
+               let announcement_sigs = if let Some((genesis_block_hash, node_signer, user_config)) = genesis_node_signer {
+                       self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger)
                } else { None };
                Ok((None, timed_out_htlcs, announcement_sigs))
        }
@@ -5140,7 +5209,7 @@ impl<Signer: Sign> Channel<Signer> {
                        // larger. If we don't know that time has moved forward, we can just set it to the last
                        // time we saw and it will be ignored.
                        let best_time = self.update_time_counter;
-                       match self.do_best_block_updated(reorg_height, best_time, None, logger) {
+                       match self.do_best_block_updated(reorg_height, best_time, None::<(BlockHash, &&NodeSigner, &UserConfig)>, logger) {
                                Ok((channel_ready, timed_out_htlcs, announcement_sigs)) => {
                                        assert!(channel_ready.is_none(), "We can't generate a funding with 0 confirmations?");
                                        assert!(timed_out_htlcs.is_empty(), "We can't have accepted HTLCs with a timeout before our funding confirmation?");
@@ -5340,7 +5409,9 @@ impl<Signer: Sign> Channel<Signer> {
        /// closing).
        ///
        /// This will only return ChannelError::Ignore upon failure.
-       fn get_channel_announcement(&self, node_id: PublicKey, chain_hash: BlockHash) -> Result<msgs::UnsignedChannelAnnouncement, ChannelError> {
+       fn get_channel_announcement<NS: Deref>(
+               &self, node_signer: &NS, chain_hash: BlockHash, user_config: &UserConfig,
+       ) -> Result<msgs::UnsignedChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
                if !self.config.announced_channel {
                        return Err(ChannelError::Ignore("Channel is not available for public announcements".to_owned()));
                }
@@ -5348,24 +5419,33 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement if the channel is not currently usable".to_owned()));
                }
 
-               let were_node_one = node_id.serialize()[..] < self.counterparty_node_id.serialize()[..];
+               let node_id = NodeId::from_pubkey(&node_signer.get_node_id(Recipient::Node)
+                       .map_err(|_| ChannelError::Ignore("Failed to retrieve own public key".to_owned()))?);
+               let counterparty_node_id = NodeId::from_pubkey(&self.get_counterparty_node_id());
+               let were_node_one = node_id.as_slice() < counterparty_node_id.as_slice();
 
                let msg = msgs::UnsignedChannelAnnouncement {
-                       features: channelmanager::provided_channel_features(),
+                       features: channelmanager::provided_channel_features(&user_config),
                        chain_hash,
                        short_channel_id: self.get_short_channel_id().unwrap(),
-                       node_id_1: if were_node_one { node_id } else { self.get_counterparty_node_id() },
-                       node_id_2: if were_node_one { self.get_counterparty_node_id() } else { node_id },
-                       bitcoin_key_1: if were_node_one { self.get_holder_pubkeys().funding_pubkey } else { self.counterparty_funding_pubkey().clone() },
-                       bitcoin_key_2: if were_node_one { self.counterparty_funding_pubkey().clone() } else { self.get_holder_pubkeys().funding_pubkey },
+                       node_id_1: if were_node_one { node_id } else { counterparty_node_id },
+                       node_id_2: if were_node_one { counterparty_node_id } else { node_id },
+                       bitcoin_key_1: NodeId::from_pubkey(if were_node_one { &self.get_holder_pubkeys().funding_pubkey } else { self.counterparty_funding_pubkey() }),
+                       bitcoin_key_2: NodeId::from_pubkey(if were_node_one { self.counterparty_funding_pubkey() } else { &self.get_holder_pubkeys().funding_pubkey }),
                        excess_data: Vec::new(),
                };
 
                Ok(msg)
        }
 
-       fn get_announcement_sigs<L: Deref>(&mut self, node_pk: PublicKey, genesis_block_hash: BlockHash, best_block_height: u32, logger: &L)
-       -> Option<msgs::AnnouncementSignatures> where L::Target: Logger {
+       fn get_announcement_sigs<NS: Deref, L: Deref>(
+               &mut self, node_signer: &NS, genesis_block_hash: BlockHash, user_config: &UserConfig,
+               best_block_height: u32, logger: &L
+       ) -> Option<msgs::AnnouncementSignatures>
+       where
+               NS::Target: NodeSigner,
+               L::Target: Logger
+       {
                if self.funding_tx_confirmation_height == 0 || self.funding_tx_confirmation_height + 5 > best_block_height {
                        return None;
                }
@@ -5384,14 +5464,21 @@ impl<Signer: Sign> Channel<Signer> {
                }
 
                log_trace!(logger, "Creating an announcement_signatures message for channel {}", log_bytes!(self.channel_id()));
-               let announcement = match self.get_channel_announcement(node_pk, genesis_block_hash) {
+               let announcement = match self.get_channel_announcement(node_signer, genesis_block_hash, user_config) {
                        Ok(a) => a,
-                       Err(_) => {
-                               log_trace!(logger, "Cannot create an announcement_signatures as channel is not public.");
+                       Err(e) => {
+                               log_trace!(logger, "{:?}", e);
                                return None;
                        }
                };
-               let (our_node_sig, our_bitcoin_sig) = match self.holder_signer.sign_channel_announcement(&announcement, &self.secp_ctx) {
+               let our_node_sig = match node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(&announcement)) {
+                       Err(_) => {
+                               log_error!(logger, "Failed to generate node signature for channel_announcement. Channel will not be announced!");
+                               return None;
+                       },
+                       Ok(v) => v
+               };
+               let our_bitcoin_sig = match self.holder_signer.sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx) {
                        Err(_) => {
                                log_error!(logger, "Signer rejected channel_announcement signing. Channel will not be announced!");
                                return None;
@@ -5410,11 +5497,17 @@ impl<Signer: Sign> Channel<Signer> {
 
        /// Signs the given channel announcement, returning a ChannelError::Ignore if no keys are
        /// available.
-       fn sign_channel_announcement(&self, our_node_id: PublicKey, announcement: msgs::UnsignedChannelAnnouncement) -> Result<msgs::ChannelAnnouncement, ChannelError> {
+       fn sign_channel_announcement<NS: Deref>(
+               &self, node_signer: &NS, announcement: msgs::UnsignedChannelAnnouncement
+       ) -> Result<msgs::ChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
                if let Some((their_node_sig, their_bitcoin_sig)) = self.announcement_sigs {
-                       let were_node_one = announcement.node_id_1 == our_node_id;
+                       let our_node_key = NodeId::from_pubkey(&node_signer.get_node_id(Recipient::Node)
+                               .map_err(|_| ChannelError::Ignore("Signer failed to retrieve own public key".to_owned()))?);
+                       let were_node_one = announcement.node_id_1 == our_node_key;
 
-                       let (our_node_sig, our_bitcoin_sig) = self.holder_signer.sign_channel_announcement(&announcement, &self.secp_ctx)
+                       let our_node_sig = node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(&announcement))
+                               .map_err(|_| ChannelError::Ignore("Failed to generate node signature for channel_announcement".to_owned()))?;
+                       let our_bitcoin_sig = self.holder_signer.sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx)
                                .map_err(|_| ChannelError::Ignore("Signer rejected channel_announcement".to_owned()))?;
                        Ok(msgs::ChannelAnnouncement {
                                node_signature_1: if were_node_one { our_node_sig } else { their_node_sig },
@@ -5431,8 +5524,11 @@ impl<Signer: Sign> Channel<Signer> {
        /// Processes an incoming announcement_signatures message, providing a fully-signed
        /// channel_announcement message which we can broadcast and storing our counterparty's
        /// signatures for later reconstruction/rebroadcast of the channel_announcement.
-       pub fn announcement_signatures(&mut self, our_node_id: PublicKey, chain_hash: BlockHash, best_block_height: u32, msg: &msgs::AnnouncementSignatures) -> Result<msgs::ChannelAnnouncement, ChannelError> {
-               let announcement = self.get_channel_announcement(our_node_id.clone(), chain_hash)?;
+       pub fn announcement_signatures<NS: Deref>(
+               &mut self, node_signer: &NS, chain_hash: BlockHash, best_block_height: u32,
+               msg: &msgs::AnnouncementSignatures, user_config: &UserConfig
+       ) -> Result<msgs::ChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
+               let announcement = self.get_channel_announcement(node_signer, chain_hash, user_config)?;
 
                let msghash = hash_to_message!(&Sha256d::hash(&announcement.encode()[..])[..]);
 
@@ -5453,20 +5549,22 @@ impl<Signer: Sign> Channel<Signer> {
                                "Got announcement_signatures prior to the required six confirmations - we may not have received a block yet that our peer has".to_owned()));
                }
 
-               self.sign_channel_announcement(our_node_id, announcement)
+               self.sign_channel_announcement(node_signer, announcement)
        }
 
        /// Gets a signed channel_announcement for this channel, if we previously received an
        /// announcement_signatures from our counterparty.
-       pub fn get_signed_channel_announcement(&self, our_node_id: PublicKey, chain_hash: BlockHash, best_block_height: u32) -> Option<msgs::ChannelAnnouncement> {
+       pub fn get_signed_channel_announcement<NS: Deref>(
+               &self, node_signer: &NS, chain_hash: BlockHash, best_block_height: u32, user_config: &UserConfig
+       ) -> Option<msgs::ChannelAnnouncement> where NS::Target: NodeSigner {
                if self.funding_tx_confirmation_height == 0 || self.funding_tx_confirmation_height + 5 > best_block_height {
                        return None;
                }
-               let announcement = match self.get_channel_announcement(our_node_id.clone(), chain_hash) {
+               let announcement = match self.get_channel_announcement(node_signer, chain_hash, user_config) {
                        Ok(res) => res,
                        Err(_) => return None,
                };
-               match self.sign_channel_announcement(our_node_id, announcement) {
+               match self.sign_channel_announcement(node_signer, announcement) {
                        Ok(res) => Some(res),
                        Err(_) => None,
                }
@@ -5695,8 +5793,7 @@ impl<Signer: Sign> Channel<Signer> {
                Ok(Some(res))
        }
 
-       /// Only fails in case of bad keys
-       fn send_commitment_no_status_check<L: Deref>(&mut self, logger: &L) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> where L::Target: Logger {
+       fn build_commitment_no_status_check<L: Deref>(&mut self, logger: &L) -> ChannelMonitorUpdate where L::Target: Logger {
                log_trace!(logger, "Updating HTLC state for a newly-sent commitment_signed...");
                // We can upgrade the status of some HTLCs that are waiting on a commitment, even if we
                // fail to generate this, we still are at least at a position where upgrading their status
@@ -5729,15 +5826,9 @@ impl<Signer: Sign> Channel<Signer> {
                }
                self.resend_order = RAACommitmentOrder::RevokeAndACKFirst;
 
-               let (res, counterparty_commitment_txid, htlcs) = match self.send_commitment_no_state_update(logger) {
-                       Ok((res, (counterparty_commitment_tx, mut htlcs))) => {
-                               // Update state now that we've passed all the can-fail calls...
-                               let htlcs_no_ref: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)> =
-                                       htlcs.drain(..).map(|(htlc, htlc_source)| (htlc, htlc_source.map(|source_ref| Box::new(source_ref.clone())))).collect();
-                               (res, counterparty_commitment_tx, htlcs_no_ref)
-                       },
-                       Err(e) => return Err(e),
-               };
+               let (counterparty_commitment_txid, mut htlcs_ref) = self.build_commitment_no_state_update(logger);
+               let htlcs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)> =
+                       htlcs_ref.drain(..).map(|(htlc, htlc_source)| (htlc, htlc_source.map(|source_ref| Box::new(source_ref.clone())))).collect();
 
                if self.announcement_sigs_state == AnnouncementSigsState::MessageSent {
                        self.announcement_sigs_state = AnnouncementSigsState::Committed;
@@ -5754,16 +5845,13 @@ impl<Signer: Sign> Channel<Signer> {
                        }]
                };
                self.channel_state |= ChannelState::AwaitingRemoteRevoke as u32;
-               Ok((res, monitor_update))
+               monitor_update
        }
 
-       /// Only fails in case of bad keys. Used for channel_reestablish commitment_signed generation
-       /// when we shouldn't change HTLC/channel state.
-       fn send_commitment_no_state_update<L: Deref>(&self, logger: &L) -> Result<(msgs::CommitmentSigned, (Txid, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>)), ChannelError> where L::Target: Logger {
+       fn build_commitment_no_state_update<L: Deref>(&self, logger: &L) -> (Txid, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>) where L::Target: Logger {
                let counterparty_keys = self.build_remote_transaction_keys();
                let commitment_stats = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, true, logger);
                let counterparty_commitment_txid = commitment_stats.tx.trust().txid();
-               let (signature, htlc_signatures);
 
                #[cfg(any(test, fuzzing))]
                {
@@ -5783,6 +5871,21 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
 
+               (counterparty_commitment_txid, commitment_stats.htlcs_included)
+       }
+
+       /// Only fails in case of signer rejection. Used for channel_reestablish commitment_signed
+       /// generation when we shouldn't change HTLC/channel state.
+       fn send_commitment_no_state_update<L: Deref>(&self, logger: &L) -> Result<(msgs::CommitmentSigned, (Txid, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>)), ChannelError> where L::Target: Logger {
+               // Get the fee tests from `build_commitment_no_state_update`
+               #[cfg(any(test, fuzzing))]
+               self.build_commitment_no_state_update(logger);
+
+               let counterparty_keys = self.build_remote_transaction_keys();
+               let commitment_stats = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, true, logger);
+               let counterparty_commitment_txid = commitment_stats.tx.trust().txid();
+               let (signature, htlc_signatures);
+
                {
                        let mut htlcs = Vec::with_capacity(commitment_stats.htlcs_included.len());
                        for &(ref htlc, _) in commitment_stats.htlcs_included.iter() {
@@ -5815,16 +5918,20 @@ impl<Signer: Sign> Channel<Signer> {
                }, (counterparty_commitment_txid, commitment_stats.htlcs_included)))
        }
 
-       /// Adds a pending outbound HTLC to this channel, and creates a signed commitment transaction
-       /// to send to the remote peer in one go.
+       /// Adds a pending outbound HTLC to this channel, and builds a new remote commitment
+       /// transaction and generates the corresponding [`ChannelMonitorUpdate`] in one go.
        ///
        /// Shorthand for calling [`Self::send_htlc`] followed by a commitment update, see docs on
-       /// [`Self::send_htlc`] and [`Self::send_commitment_no_state_update`] for more info.
-       pub fn send_htlc_and_commit<L: Deref>(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket, logger: &L) -> Result<Option<(msgs::UpdateAddHTLC, msgs::CommitmentSigned, ChannelMonitorUpdate)>, ChannelError> where L::Target: Logger {
-               match self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, false, logger)? {
-                       Some(update_add_htlc) => {
-                               let (commitment_signed, monitor_update) = self.send_commitment_no_status_check(logger)?;
-                               Ok(Some((update_add_htlc, commitment_signed, monitor_update)))
+       /// [`Self::send_htlc`] and [`Self::build_commitment_no_state_update`] for more info.
+       pub fn send_htlc_and_commit<L: Deref>(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket, logger: &L) -> Result<Option<&ChannelMonitorUpdate>, ChannelError> where L::Target: Logger {
+               let send_res = self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, false, logger);
+               if let Err(e) = &send_res { if let ChannelError::Ignore(_) = e {} else { debug_assert!(false, "Sending cannot trigger channel failure"); } }
+               match send_res? {
+                       Some(_) => {
+                               let monitor_update = self.build_commitment_no_status_check(logger);
+                               self.monitor_updating_paused(false, true, false, Vec::new(), Vec::new(), Vec::new());
+                               self.pending_monitor_updates.push(monitor_update);
+                               Ok(Some(self.pending_monitor_updates.last().unwrap()))
                        },
                        None => Ok(None)
                }
@@ -5850,9 +5957,13 @@ impl<Signer: Sign> Channel<Signer> {
 
        /// Begins the shutdown process, getting a message for the remote peer and returning all
        /// holding cell HTLCs for payment failure.
-       pub fn get_shutdown<K: Deref>(&mut self, keys_provider: &K, their_features: &InitFeatures, target_feerate_sats_per_kw: Option<u32>)
-       -> Result<(msgs::Shutdown, Option<ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>), APIError>
-       where K::Target: KeysInterface {
+       ///
+       /// May jump to the channel being fully shutdown (see [`Self::is_shutdown`]) in which case no
+       /// [`ChannelMonitorUpdate`] will be returned).
+       pub fn get_shutdown<SP: Deref>(&mut self, signer_provider: &SP, their_features: &InitFeatures,
+               target_feerate_sats_per_kw: Option<u32>)
+       -> Result<(msgs::Shutdown, Option<&ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>), APIError>
+       where SP::Target: SignerProvider {
                for htlc in self.pending_outbound_htlcs.iter() {
                        if let OutboundHTLCState::LocalAnnounced(_) = htlc.state {
                                return Err(APIError::APIMisuseError{err: "Cannot begin shutdown with pending HTLCs. Process pending events first".to_owned()});
@@ -5871,16 +5982,24 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(APIError::ChannelUnavailable{err: "Cannot begin shutdown while peer is disconnected or we're waiting on a monitor update, maybe force-close instead?".to_owned()});
                }
 
+               // If we haven't funded the channel yet, we don't need to bother ensuring the shutdown
+               // script is set, we just force-close and call it a day.
+               let mut chan_closed = false;
+               if self.channel_state < ChannelState::FundingSent as u32 {
+                       chan_closed = true;
+               }
+
                let update_shutdown_script = match self.shutdown_scriptpubkey {
                        Some(_) => false,
-                       None => {
-                               let shutdown_scriptpubkey = keys_provider.get_shutdown_scriptpubkey();
+                       None if !chan_closed => {
+                               let shutdown_scriptpubkey = signer_provider.get_shutdown_scriptpubkey();
                                if !shutdown_scriptpubkey.is_compatible(their_features) {
                                        return Err(APIError::IncompatibleShutdownScript { script: shutdown_scriptpubkey.clone() });
                                }
                                self.shutdown_scriptpubkey = Some(shutdown_scriptpubkey);
                                true
                        },
+                       None => false,
                };
 
                // From here on out, we may not fail!
@@ -5894,12 +6013,15 @@ impl<Signer: Sign> Channel<Signer> {
 
                let monitor_update = if update_shutdown_script {
                        self.latest_monitor_update_id += 1;
-                       Some(ChannelMonitorUpdate {
+                       let monitor_update = ChannelMonitorUpdate {
                                update_id: self.latest_monitor_update_id,
                                updates: vec![ChannelMonitorUpdateStep::ShutdownScript {
                                        scriptpubkey: self.get_closing_scriptpubkey(),
                                }],
-                       })
+                       };
+                       self.monitor_updating_paused(false, false, false, Vec::new(), Vec::new(), Vec::new());
+                       self.pending_monitor_updates.push(monitor_update);
+                       Some(self.pending_monitor_updates.last().unwrap())
                } else { None };
                let shutdown = msgs::Shutdown {
                        channel_id: self.channel_id,
@@ -5920,6 +6042,9 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                });
 
+               debug_assert!(!self.is_shutdown() || monitor_update.is_none(),
+                       "we can't both complete shutdown and return a monitor update");
+
                Ok((shutdown, monitor_update, dropped_outbound_htlcs))
        }
 
@@ -6039,7 +6164,7 @@ impl Readable for AnnouncementSigsState {
        }
 }
 
-impl<Signer: Sign> Writeable for Channel<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> Writeable for Channel<Signer> {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                // Note that we write out as if remove_uncommitted_htlcs_and_mark_paused had just been
                // called.
@@ -6334,10 +6459,13 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
 }
 
 const MAX_ALLOC_SIZE: usize = 64*1024;
-impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as SignerProvider>::Signer>
-               where K::Target: KeysInterface {
-       fn read<R : io::Read>(reader: &mut R, args: (&'a K, u32)) -> Result<Self, DecodeError> {
-               let (keys_source, serialized_height) = args;
+impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c ChannelTypeFeatures)> for Channel<<SP::Target as SignerProvider>::Signer>
+               where
+                       ES::Target: EntropySource,
+                       SP::Target: SignerProvider
+{
+       fn read<R : io::Read>(reader: &mut R, args: (&'a ES, &'b SP, u32, &'c ChannelTypeFeatures)) -> Result<Self, DecodeError> {
+               let (entropy_source, signer_provider, serialized_height, our_supported_features) = args;
                let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                // `user_id` used to be a single u64 value. In order to remain backwards compatible with
@@ -6618,7 +6746,7 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as SignerPr
                });
 
                let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id {
-                       let mut holder_signer = keys_source.derive_channel_signer(channel_value_satoshis, channel_keys_id);
+                       let mut holder_signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id);
                        // If we've gotten to the funding stage of the channel, populate the signer with its
                        // required channel parameters.
                        let non_shutdown_state = channel_state & (!MULTI_STATE_FLAGS);
@@ -6629,7 +6757,7 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as SignerPr
                } else {
                        // `keys_data` can be `None` if we had corrupted data.
                        let keys_data = keys_data.ok_or(DecodeError::InvalidValue)?;
-                       let holder_signer = keys_source.read_chan_signer(&keys_data)?;
+                       let holder_signer = signer_provider.read_chan_signer(&keys_data)?;
                        (holder_signer.channel_keys_id(), holder_signer)
                };
 
@@ -6653,19 +6781,14 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as SignerPr
                }
 
                let chan_features = channel_type.as_ref().unwrap();
-               if chan_features.supports_unknown_bits() || chan_features.requires_unknown_bits() {
+               if !chan_features.is_subset(our_supported_features) {
                        // If the channel was written by a new version and negotiated with features we don't
                        // understand yet, refuse to read it.
                        return Err(DecodeError::UnknownRequiredFeature);
                }
 
-               if channel_parameters.opt_anchors.is_some() {
-                       // Relax this check when ChannelTypeFeatures supports anchors.
-                       return Err(DecodeError::InvalidValue);
-               }
-
                let mut secp_ctx = Secp256k1::new();
-               secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
+               secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
 
                // `user_id` used to be a single u64 value. In order to remain backwards
                // compatible with versions prior to 0.0.113, the u128 is serialized as two
@@ -6783,6 +6906,8 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as SignerPr
 
                        channel_type: channel_type.unwrap(),
                        channel_keys_id,
+
+                       pending_monitor_updates: Vec::new(),
                })
        }
 }
@@ -6798,6 +6923,8 @@ mod tests {
        use hex;
        use crate::ln::PaymentHash;
        use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
+       #[cfg(anchors)]
+       use crate::ln::channel::InitFeatures;
        use crate::ln::channel::{Channel, InboundHTLCOutput, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator};
        use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
        use crate::ln::features::ChannelTypeFeatures;
@@ -6807,22 +6934,19 @@ mod tests {
        use crate::ln::chan_utils::{htlc_success_tx_weight, htlc_timeout_tx_weight};
        use crate::chain::BestBlock;
        use crate::chain::chaininterface::{FeeEstimator, LowerBoundedFeeEstimator, ConfirmationTarget};
-       use crate::chain::keysinterface::{BaseSign, InMemorySigner, Recipient, KeyMaterial, KeysInterface, EntropySource, NodeSigner, SignerProvider};
+       use crate::chain::keysinterface::{ChannelSigner, InMemorySigner, EntropySource, SignerProvider};
        use crate::chain::transaction::OutPoint;
        use crate::util::config::UserConfig;
        use crate::util::enforcing_trait_impls::EnforcingSigner;
        use crate::util::errors::APIError;
        use crate::util::test_utils;
        use crate::util::test_utils::OnGetShutdownScriptpubkey;
-       use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature, Scalar};
+       use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
        use bitcoin::secp256k1::ffi::Signature as FFISignature;
        use bitcoin::secp256k1::{SecretKey,PublicKey};
-       use bitcoin::secp256k1::ecdh::SharedSecret;
-       use bitcoin::secp256k1::ecdsa::RecoverableSignature;
        use bitcoin::hashes::sha256::Hash as Sha256;
        use bitcoin::hashes::Hash;
        use bitcoin::hash_types::WPubkeyHash;
-       use bitcoin::bech32::u5;
        use bitcoin::PackedLockTime;
        use bitcoin::util::address::WitnessVersion;
        use crate::prelude::*;
@@ -6861,21 +6985,6 @@ mod tests {
                fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
        }
 
-       impl NodeSigner for Keys {
-               fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> { panic!(); }
-
-               fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
-                       let secp_ctx = Secp256k1::signing_only();
-                       Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
-               }
-
-               fn ecdh(&self, _recipient: Recipient, _other_key: &PublicKey, _tweak: Option<&Scalar>) -> Result<SharedSecret, ()> { panic!(); }
-
-               fn get_inbound_payment_key_material(&self) -> KeyMaterial { panic!(); }
-
-               fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> { panic!(); }
-       }
-
        impl SignerProvider for Keys {
                type Signer = InMemorySigner;
 
@@ -6903,8 +7012,6 @@ mod tests {
                }
        }
 
-       impl KeysInterface for Keys {}
-
        #[cfg(not(feature = "grind_signatures"))]
        fn public_from_secret_hex(secp_ctx: &Secp256k1<bitcoin::secp256k1::All>, hex: &str) -> PublicKey {
                PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&hex::decode(hex).unwrap()[..]).unwrap())
@@ -6912,7 +7019,7 @@ mod tests {
 
        #[test]
        fn upfront_shutdown_script_incompatibility() {
-               let features = channelmanager::provided_init_features().clear_shutdown_anysegwit();
+               let features = channelmanager::provided_init_features(&UserConfig::default()).clear_shutdown_anysegwit();
                let non_v0_segwit_shutdown_script =
                        ShutdownScript::new_witness_program(WitnessVersion::V16, &[0, 40]).unwrap();
 
@@ -6926,7 +7033,7 @@ mod tests {
                let secp_ctx = Secp256k1::new();
                let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               match Channel::<EnforcingSigner>::new_outbound(&LowerBoundedFeeEstimator::new(&TestFeeEstimator { fee_est: 253 }), &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0, 42) {
+               match Channel::<EnforcingSigner>::new_outbound(&LowerBoundedFeeEstimator::new(&TestFeeEstimator { fee_est: 253 }), &&keys_provider, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0, 42) {
                        Err(APIError::IncompatibleShutdownScript { script }) => {
                                assert_eq!(script.into_inner(), non_v0_segwit_shutdown_script.into_inner());
                        },
@@ -6949,7 +7056,7 @@ mod tests {
 
                let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&bounded_fee_estimator, &&keys_provider, node_a_node_id, &channelmanager::provided_init_features(), 10000000, 100000, 42, &config, 0, 42).unwrap();
+               let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&bounded_fee_estimator, &&keys_provider, &&keys_provider, node_a_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42).unwrap();
 
                // Now change the fee so we can check that the fee in the open_channel message is the
                // same as the old fee.
@@ -6975,18 +7082,18 @@ mod tests {
                // Create Node A's channel pointing to Node B's pubkey
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, node_b_node_id, &channelmanager::provided_init_features(), 10000000, 100000, 42, &config, 0, 42).unwrap();
+               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42).unwrap();
 
                // Create Node B's channel by receiving Node A's open_channel message
                // Make sure A's dust limit is as we expect.
                let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
-               let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, node_b_node_id, &channelmanager::provided_init_features(), &open_channel_msg, 7, &config, 0, &&logger, 42).unwrap();
+               let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, 42).unwrap();
 
                // Node B --> Node A: accept channel, explicitly setting B's dust limit.
                let mut accept_channel_msg = node_b_chan.accept_inbound_channel(0);
                accept_channel_msg.dust_limit_satoshis = 546;
-               node_a_chan.accept_channel(&accept_channel_msg, &config.channel_handshake_limits, &channelmanager::provided_init_features()).unwrap();
+               node_a_chan.accept_channel(&accept_channel_msg, &config.channel_handshake_limits, &channelmanager::provided_init_features(&config)).unwrap();
                node_a_chan.holder_dust_limit_satoshis = 1560;
 
                // Put some inbound and outbound HTLCs in A's channel.
@@ -7045,7 +7152,7 @@ mod tests {
 
                let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let mut chan = Channel::<EnforcingSigner>::new_outbound(&fee_est, &&keys_provider, node_id, &channelmanager::provided_init_features(), 10000000, 100000, 42, &config, 0, 42).unwrap();
+               let mut chan = Channel::<EnforcingSigner>::new_outbound(&fee_est, &&keys_provider, &&keys_provider, node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42).unwrap();
 
                let commitment_tx_fee_0_htlcs = Channel::<EnforcingSigner>::commit_tx_fee_msat(chan.feerate_per_kw, 0, chan.opt_anchors());
                let commitment_tx_fee_1_htlc = Channel::<EnforcingSigner>::commit_tx_fee_msat(chan.feerate_per_kw, 1, chan.opt_anchors());
@@ -7085,7 +7192,7 @@ mod tests {
                let secp_ctx = Secp256k1::new();
                let seed = [42; 32];
                let network = Network::Testnet;
-               let best_block = BestBlock::from_genesis(network);
+               let best_block = BestBlock::from_network(network);
                let chain_hash = best_block.block_hash();
                let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
 
@@ -7094,16 +7201,16 @@ mod tests {
                // Create Node A's channel pointing to Node B's pubkey
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, node_b_node_id, &channelmanager::provided_init_features(), 10000000, 100000, 42, &config, 0, 42).unwrap();
+               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42).unwrap();
 
                // Create Node B's channel by receiving Node A's open_channel message
                let open_channel_msg = node_a_chan.get_open_channel(chain_hash);
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
-               let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, node_b_node_id, &channelmanager::provided_init_features(), &open_channel_msg, 7, &config, 0, &&logger, 42).unwrap();
+               let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, 42).unwrap();
 
                // Node B --> Node A: accept channel
                let accept_channel_msg = node_b_chan.accept_inbound_channel(0);
-               node_a_chan.accept_channel(&accept_channel_msg, &config.channel_handshake_limits, &channelmanager::provided_init_features()).unwrap();
+               node_a_chan.accept_channel(&accept_channel_msg, &config.channel_handshake_limits, &channelmanager::provided_init_features(&config)).unwrap();
 
                // Node A --> Node B: funding created
                let output_script = node_a_chan.get_funding_redeemscript();
@@ -7112,7 +7219,7 @@ mod tests {
                }]};
                let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
                let funding_created_msg = node_a_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).unwrap();
-               let (funding_signed_msg, _, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).unwrap();
+               let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).unwrap();
 
                // Node B --> Node A: funding signed
                let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger);
@@ -7167,12 +7274,12 @@ mod tests {
                // Test that `new_outbound` creates a channel with the correct value for
                // `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value,
                // which is set to the lower bound + 1 (2%) of the `channel_value`.
-               let chan_1 = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(), 10000000, 100000, 42, &config_2_percent, 0, 42).unwrap();
+               let chan_1 = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&config_2_percent), 10000000, 100000, 42, &config_2_percent, 0, 42).unwrap();
                let chan_1_value_msat = chan_1.channel_value_satoshis * 1000;
                assert_eq!(chan_1.holder_max_htlc_value_in_flight_msat, (chan_1_value_msat as f64 * 0.02) as u64);
 
                // Test with the upper bound - 1 of valid values (99%).
-               let chan_2 = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(), 10000000, 100000, 42, &config_99_percent, 0, 42).unwrap();
+               let chan_2 = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&config_99_percent), 10000000, 100000, 42, &config_99_percent, 0, 42).unwrap();
                let chan_2_value_msat = chan_2.channel_value_satoshis * 1000;
                assert_eq!(chan_2.holder_max_htlc_value_in_flight_msat, (chan_2_value_msat as f64 * 0.99) as u64);
 
@@ -7181,38 +7288,38 @@ mod tests {
                // Test that `new_from_req` creates a channel with the correct value for
                // `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value,
                // which is set to the lower bound - 1 (2%) of the `channel_value`.
-               let chan_3 = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, inbound_node_id, &channelmanager::provided_init_features(), &chan_1_open_channel_msg, 7, &config_2_percent, 0, &&logger, 42).unwrap();
+               let chan_3 = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, &&keys_provider, inbound_node_id, &channelmanager::provided_channel_type_features(&config_2_percent), &channelmanager::provided_init_features(&config_2_percent), &chan_1_open_channel_msg, 7, &config_2_percent, 0, &&logger, 42).unwrap();
                let chan_3_value_msat = chan_3.channel_value_satoshis * 1000;
                assert_eq!(chan_3.holder_max_htlc_value_in_flight_msat, (chan_3_value_msat as f64 * 0.02) as u64);
 
                // Test with the upper bound - 1 of valid values (99%).
-               let chan_4 = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, inbound_node_id, &channelmanager::provided_init_features(), &chan_1_open_channel_msg, 7, &config_99_percent, 0, &&logger, 42).unwrap();
+               let chan_4 = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, &&keys_provider, inbound_node_id, &channelmanager::provided_channel_type_features(&config_99_percent), &channelmanager::provided_init_features(&config_99_percent), &chan_1_open_channel_msg, 7, &config_99_percent, 0, &&logger, 42).unwrap();
                let chan_4_value_msat = chan_4.channel_value_satoshis * 1000;
                assert_eq!(chan_4.holder_max_htlc_value_in_flight_msat, (chan_4_value_msat as f64 * 0.99) as u64);
 
                // Test that `new_outbound` uses the lower bound of the configurable percentage values (1%)
                // if `max_inbound_htlc_value_in_flight_percent_of_channel` is set to a value less than 1.
-               let chan_5 = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(), 10000000, 100000, 42, &config_0_percent, 0, 42).unwrap();
+               let chan_5 = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&config_0_percent), 10000000, 100000, 42, &config_0_percent, 0, 42).unwrap();
                let chan_5_value_msat = chan_5.channel_value_satoshis * 1000;
                assert_eq!(chan_5.holder_max_htlc_value_in_flight_msat, (chan_5_value_msat as f64 * 0.01) as u64);
 
                // Test that `new_outbound` uses the upper bound of the configurable percentage values
                // (100%) if `max_inbound_htlc_value_in_flight_percent_of_channel` is set to a larger value
                // than 100.
-               let chan_6 = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(), 10000000, 100000, 42, &config_101_percent, 0, 42).unwrap();
+               let chan_6 = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&config_101_percent), 10000000, 100000, 42, &config_101_percent, 0, 42).unwrap();
                let chan_6_value_msat = chan_6.channel_value_satoshis * 1000;
                assert_eq!(chan_6.holder_max_htlc_value_in_flight_msat, chan_6_value_msat);
 
                // Test that `new_from_req` uses the lower bound of the configurable percentage values (1%)
                // if `max_inbound_htlc_value_in_flight_percent_of_channel` is set to a value less than 1.
-               let chan_7 = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, inbound_node_id, &channelmanager::provided_init_features(), &chan_1_open_channel_msg, 7, &config_0_percent, 0, &&logger, 42).unwrap();
+               let chan_7 = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, &&keys_provider, inbound_node_id, &channelmanager::provided_channel_type_features(&config_0_percent), &channelmanager::provided_init_features(&config_0_percent), &chan_1_open_channel_msg, 7, &config_0_percent, 0, &&logger, 42).unwrap();
                let chan_7_value_msat = chan_7.channel_value_satoshis * 1000;
                assert_eq!(chan_7.holder_max_htlc_value_in_flight_msat, (chan_7_value_msat as f64 * 0.01) as u64);
 
                // Test that `new_from_req` uses the upper bound of the configurable percentage values
                // (100%) if `max_inbound_htlc_value_in_flight_percent_of_channel` is set to a larger value
                // than 100.
-               let chan_8 = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, inbound_node_id, &channelmanager::provided_init_features(), &chan_1_open_channel_msg, 7, &config_101_percent, 0, &&logger, 42).unwrap();
+               let chan_8 = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, &&keys_provider, inbound_node_id, &channelmanager::provided_channel_type_features(&config_101_percent), &channelmanager::provided_init_features(&config_101_percent), &chan_1_open_channel_msg, 7, &config_101_percent, 0, &&logger, 42).unwrap();
                let chan_8_value_msat = chan_8.channel_value_satoshis * 1000;
                assert_eq!(chan_8.holder_max_htlc_value_in_flight_msat, chan_8_value_msat);
        }
@@ -7252,7 +7359,7 @@ mod tests {
 
                let mut outbound_node_config = UserConfig::default();
                outbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (outbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
-               let chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(), channel_value_satoshis, 100_000, 42, &outbound_node_config, 0, 42).unwrap();
+               let chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&outbound_node_config), channel_value_satoshis, 100_000, 42, &outbound_node_config, 0, 42).unwrap();
 
                let expected_outbound_selected_chan_reserve = cmp::max(MIN_THEIR_CHAN_RESERVE_SATOSHIS, (chan.channel_value_satoshis as f64 * outbound_selected_channel_reserve_perc) as u64);
                assert_eq!(chan.holder_selected_channel_reserve_satoshis, expected_outbound_selected_chan_reserve);
@@ -7262,7 +7369,7 @@ mod tests {
                inbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (inbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
 
                if outbound_selected_channel_reserve_perc + inbound_selected_channel_reserve_perc < 1.0 {
-                       let chan_inbound_node = Channel::<EnforcingSigner>::new_from_req(&&fee_est, &&keys_provider, inbound_node_id, &channelmanager::provided_init_features(), &chan_open_channel_msg, 7, &inbound_node_config, 0, &&logger, 42).unwrap();
+                       let chan_inbound_node = Channel::<EnforcingSigner>::new_from_req(&&fee_est, &&keys_provider, &&keys_provider, inbound_node_id, &channelmanager::provided_channel_type_features(&inbound_node_config), &channelmanager::provided_init_features(&outbound_node_config), &chan_open_channel_msg, 7, &inbound_node_config, 0, &&logger, 42).unwrap();
 
                        let expected_inbound_selected_chan_reserve = cmp::max(MIN_THEIR_CHAN_RESERVE_SATOSHIS, (chan.channel_value_satoshis as f64 * inbound_selected_channel_reserve_perc) as u64);
 
@@ -7270,7 +7377,7 @@ mod tests {
                        assert_eq!(chan_inbound_node.counterparty_selected_channel_reserve_satoshis.unwrap(), expected_outbound_selected_chan_reserve);
                } else {
                        // Channel Negotiations failed
-                       let result = Channel::<EnforcingSigner>::new_from_req(&&fee_est, &&keys_provider, inbound_node_id, &channelmanager::provided_init_features(), &chan_open_channel_msg, 7, &inbound_node_config, 0, &&logger, 42);
+                       let result = Channel::<EnforcingSigner>::new_from_req(&&fee_est, &&keys_provider, &&keys_provider, inbound_node_id, &channelmanager::provided_channel_type_features(&inbound_node_config), &channelmanager::provided_init_features(&outbound_node_config), &chan_open_channel_msg, 7, &inbound_node_config, 0, &&logger, 42);
                        assert!(result.is_err());
                }
        }
@@ -7287,7 +7394,7 @@ mod tests {
                // Create a channel.
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, node_b_node_id, &channelmanager::provided_init_features(), 10000000, 100000, 42, &config, 0, 42).unwrap();
+               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42).unwrap();
                assert!(node_a_chan.counterparty_forwarding_info.is_none());
                assert_eq!(node_a_chan.holder_htlc_minimum_msat, 1); // the default
                assert!(node_a_chan.counterparty_forwarding_info().is_none());
@@ -7332,7 +7439,7 @@ mod tests {
                use bitcoin::hashes::hex::FromHex;
                use bitcoin::hash_types::Txid;
                use bitcoin::secp256k1::Message;
-               use crate::chain::keysinterface::BaseSign;
+               use crate::chain::keysinterface::EcdsaChannelSigner;
                use crate::ln::PaymentPreimage;
                use crate::ln::channel::{HTLCOutputInCommitment ,TxCreationKeys};
                use crate::ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
@@ -7346,7 +7453,6 @@ mod tests {
 
                let mut signer = InMemorySigner::new(
                        &secp_ctx,
-                       SecretKey::from_slice(&hex::decode("4242424242424242424242424242424242424242424242424242424242424242").unwrap()[..]).unwrap(),
                        SecretKey::from_slice(&hex::decode("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap(),
                        SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
                        SecretKey::from_slice(&hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(),
@@ -7366,7 +7472,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_handshake_config.announced_channel = false;
-               let mut chan = Channel::<InMemorySigner>::new_outbound(&LowerBoundedFeeEstimator::new(&feeest), &&keys_provider, counterparty_node_id, &channelmanager::provided_init_features(), 10_000_000, 100000, 42, &config, 0, 42).unwrap(); // Nothing uses their network key in this test
+               let mut chan = Channel::<InMemorySigner>::new_outbound(&LowerBoundedFeeEstimator::new(&feeest), &&keys_provider, &&keys_provider, counterparty_node_id, &channelmanager::provided_init_features(&config), 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
 
@@ -8080,8 +8186,8 @@ mod tests {
 
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider,
-                       node_b_node_id, &channelmanager::provided_init_features(), 10000000, 100000, 42, &config, 0, 42).unwrap();
+               let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&feeest, &&keys_provider, &&keys_provider,
+                       node_b_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42).unwrap();
 
                let mut channel_type_features = ChannelTypeFeatures::only_static_remote_key();
                channel_type_features.set_zero_conf_required();
@@ -8089,8 +8195,165 @@ mod tests {
                let mut open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
                open_channel_msg.channel_type = Some(channel_type_features);
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
-               let res = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider,
-                       node_b_node_id, &channelmanager::provided_init_features(), &open_channel_msg, 7, &config, 0, &&logger, 42);
+               let res = Channel::<EnforcingSigner>::new_from_req(&feeest, &&keys_provider, &&keys_provider,
+                       node_b_node_id, &channelmanager::provided_channel_type_features(&config),
+                       &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, 42);
                assert!(res.is_ok());
        }
+
+       #[cfg(anchors)]
+       #[test]
+       fn test_supports_anchors_zero_htlc_tx_fee() {
+               // Tests that if both sides support and negotiate `anchors_zero_fee_htlc_tx`, it is the
+               // resulting `channel_type`.
+               let secp_ctx = Secp256k1::new();
+               let fee_estimator = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000});
+               let network = Network::Testnet;
+               let keys_provider = test_utils::TestKeysInterface::new(&[42; 32], network);
+               let logger = test_utils::TestLogger::new();
+
+               let node_id_a = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap());
+               let node_id_b = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap());
+
+               let mut config = UserConfig::default();
+               config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
+
+               // It is not enough for just the initiator to signal `option_anchors_zero_fee_htlc_tx`, both
+               // need to signal it.
+               let channel_a = Channel::<EnforcingSigner>::new_outbound(
+                       &fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
+                       &channelmanager::provided_init_features(&UserConfig::default()), 10000000, 100000, 42,
+                       &config, 0, 42
+               ).unwrap();
+               assert!(!channel_a.channel_type.supports_anchors_zero_fee_htlc_tx());
+
+               let mut expected_channel_type = ChannelTypeFeatures::empty();
+               expected_channel_type.set_static_remote_key_required();
+               expected_channel_type.set_anchors_zero_fee_htlc_tx_required();
+
+               let channel_a = Channel::<EnforcingSigner>::new_outbound(
+                       &fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
+                       &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
+               ).unwrap();
+
+               let open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
+               let channel_b = Channel::<EnforcingSigner>::new_from_req(
+                       &fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
+                       &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config),
+                       &open_channel_msg, 7, &config, 0, &&logger, 42
+               ).unwrap();
+
+               assert_eq!(channel_a.channel_type, expected_channel_type);
+               assert_eq!(channel_b.channel_type, expected_channel_type);
+       }
+
+       #[cfg(anchors)]
+       #[test]
+       fn test_rejects_implicit_simple_anchors() {
+               // Tests that if `option_anchors` is being negotiated implicitly through the intersection of
+               // each side's `InitFeatures`, it is rejected.
+               let secp_ctx = Secp256k1::new();
+               let fee_estimator = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000});
+               let network = Network::Testnet;
+               let keys_provider = test_utils::TestKeysInterface::new(&[42; 32], network);
+               let logger = test_utils::TestLogger::new();
+
+               let node_id_a = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap());
+               let node_id_b = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap());
+
+               let config = UserConfig::default();
+
+               // See feature bit assignments: https://github.com/lightning/bolts/blob/master/09-features.md
+               let static_remote_key_required: u64 = 1 << 12;
+               let simple_anchors_required: u64 = 1 << 20;
+               let raw_init_features = static_remote_key_required | simple_anchors_required;
+               let init_features_with_simple_anchors = InitFeatures::from_le_bytes(raw_init_features.to_le_bytes().to_vec());
+
+               let channel_a = Channel::<EnforcingSigner>::new_outbound(
+                       &fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
+                       &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
+               ).unwrap();
+
+               // Set `channel_type` to `None` to force the implicit feature negotiation.
+               let mut open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
+               open_channel_msg.channel_type = None;
+
+               // Since A supports both `static_remote_key` and `option_anchors`, but B only accepts
+               // `static_remote_key`, it will fail the channel.
+               let channel_b = Channel::<EnforcingSigner>::new_from_req(
+                       &fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
+                       &channelmanager::provided_channel_type_features(&config), &init_features_with_simple_anchors,
+                       &open_channel_msg, 7, &config, 0, &&logger, 42
+               );
+               assert!(channel_b.is_err());
+       }
+
+       #[cfg(anchors)]
+       #[test]
+       fn test_rejects_simple_anchors_channel_type() {
+               // Tests that if `option_anchors` is being negotiated through the `channel_type` feature,
+               // it is rejected.
+               let secp_ctx = Secp256k1::new();
+               let fee_estimator = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000});
+               let network = Network::Testnet;
+               let keys_provider = test_utils::TestKeysInterface::new(&[42; 32], network);
+               let logger = test_utils::TestLogger::new();
+
+               let node_id_a = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap());
+               let node_id_b = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap());
+
+               let config = UserConfig::default();
+
+               // See feature bit assignments: https://github.com/lightning/bolts/blob/master/09-features.md
+               let static_remote_key_required: u64 = 1 << 12;
+               let simple_anchors_required: u64 = 1 << 20;
+               let simple_anchors_raw_features = static_remote_key_required | simple_anchors_required;
+               let simple_anchors_init = InitFeatures::from_le_bytes(simple_anchors_raw_features.to_le_bytes().to_vec());
+               let simple_anchors_channel_type = ChannelTypeFeatures::from_le_bytes(simple_anchors_raw_features.to_le_bytes().to_vec());
+               assert!(simple_anchors_init.requires_unknown_bits());
+               assert!(simple_anchors_channel_type.requires_unknown_bits());
+
+               // First, we'll try to open a channel between A and B where A requests a channel type for
+               // the original `option_anchors` feature (non zero fee htlc tx). This should be rejected by
+               // B as it's not supported by LDK.
+               let channel_a = Channel::<EnforcingSigner>::new_outbound(
+                       &fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
+                       &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
+               ).unwrap();
+
+               let mut open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
+               open_channel_msg.channel_type = Some(simple_anchors_channel_type.clone());
+
+               let res = Channel::<EnforcingSigner>::new_from_req(
+                       &fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
+                       &channelmanager::provided_channel_type_features(&config), &simple_anchors_init,
+                       &open_channel_msg, 7, &config, 0, &&logger, 42
+               );
+               assert!(res.is_err());
+
+               // Then, we'll try to open another channel where A requests a channel type for
+               // `anchors_zero_fee_htlc_tx`. B is malicious and tries to downgrade the channel type to the
+               // original `option_anchors` feature, which should be rejected by A as it's not supported by
+               // LDK.
+               let mut channel_a = Channel::<EnforcingSigner>::new_outbound(
+                       &fee_estimator, &&keys_provider, &&keys_provider, node_id_b, &simple_anchors_init,
+                       10000000, 100000, 42, &config, 0, 42
+               ).unwrap();
+
+               let open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
+
+               let channel_b = Channel::<EnforcingSigner>::new_from_req(
+                       &fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
+                       &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config),
+                       &open_channel_msg, 7, &config, 0, &&logger, 42
+               ).unwrap();
+
+               let mut accept_channel_msg = channel_b.get_accept_channel_message();
+               accept_channel_msg.channel_type = Some(simple_anchors_channel_type.clone());
+
+               let res = channel_a.accept_channel(
+                       &accept_channel_msg, &config.channel_handshake_limits, &simple_anchors_init
+               );
+               assert!(res.is_err());
+       }
 }
index 03a150e4fe208493dea2480abeba968b5b79a877..62629fc548679dfa56b9a58ae711704942657e06 100644 (file)
 //! responsible for tracking which channels are open, HTLCs are in flight and reestablishing those
 //! upon reconnect to the relevant peer(s).
 //!
-//! It does not manage routing logic (see [`find_route`] for that) nor does it manage constructing
+//! It does not manage routing logic (see [`Router`] for that) nor does it manage constructing
 //! on-chain transactions (it only monitors the chain to watch for any force-closes that might
 //! imply it needs to fail HTLCs/payments/channels it manages).
-//!
-//! [`find_route`]: crate::routing::router::find_route
 
 use bitcoin::blockdata::block::BlockHeader;
 use bitcoin::blockdata::transaction::Transaction;
@@ -26,12 +24,10 @@ use bitcoin::network::constants::Network;
 
 use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
-use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::{BlockHash, Txid};
 
 use bitcoin::secp256k1::{SecretKey,PublicKey};
 use bitcoin::secp256k1::Secp256k1;
-use bitcoin::secp256k1::ecdh::SharedSecret;
 use bitcoin::{LockTime, secp256k1, Sequence};
 
 use crate::chain;
@@ -47,7 +43,7 @@ use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, No
 #[cfg(any(feature = "_test_utils", test))]
 use crate::ln::features::InvoiceFeatures;
 use crate::routing::gossip::NetworkGraph;
-use crate::routing::router::{DefaultRouter, InFlightHtlcs, PaymentParameters, Route, RouteHop, RoutePath, Router};
+use crate::routing::router::{DefaultRouter, InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters, RoutePath, Router};
 use crate::routing::scoring::ProbabilisticScorer;
 use crate::ln::msgs;
 use crate::ln::onion_utils;
@@ -55,9 +51,9 @@ use crate::ln::onion_utils::HTLCFailReason;
 use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VALUE_MSAT};
 #[cfg(test)]
 use crate::ln::outbound_payment;
-use crate::ln::outbound_payment::{OutboundPayments, PendingOutboundPayment};
+use crate::ln::outbound_payment::{OutboundPayments, PaymentAttempts, PendingOutboundPayment};
 use crate::ln::wire::Encode;
-use crate::chain::keysinterface::{EntropySource, KeysInterface, KeysManager, NodeSigner, Recipient, Sign, SignerProvider};
+use crate::chain::keysinterface::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, ChannelSigner};
 use crate::util::config::{UserConfig, ChannelConfig};
 use crate::util::events::{Event, EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
 use crate::util::events;
@@ -67,18 +63,20 @@ use crate::util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, Maybe
 use crate::util::logger::{Level, Logger};
 use crate::util::errors::APIError;
 
+use alloc::collections::BTreeMap;
+
 use crate::io;
 use crate::prelude::*;
 use core::{cmp, mem};
 use core::cell::RefCell;
 use crate::io::Read;
-use crate::sync::{Arc, Mutex, MutexGuard, RwLock, RwLockReadGuard, FairRwLock};
+use crate::sync::{Arc, Mutex, RwLock, RwLockReadGuard, FairRwLock, LockTestExt, LockHeldState};
 use core::sync::atomic::{AtomicUsize, Ordering};
 use core::time::Duration;
 use core::ops::Deref;
 
 // Re-export this for use in the public API.
-pub use crate::ln::outbound_payment::PaymentSendFailure;
+pub use crate::ln::outbound_payment::{PaymentSendFailure, Retry, RetryableSendFailure};
 
 // We hold various information about HTLC relay in the HTLC objects in Channel itself:
 //
@@ -234,6 +232,36 @@ impl Readable for InterceptId {
                Ok(InterceptId(buf))
        }
 }
+
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+/// Uniquely describes an HTLC by its source. Just the guaranteed-unique subset of [`HTLCSource`].
+pub(crate) enum SentHTLCId {
+       PreviousHopData { short_channel_id: u64, htlc_id: u64 },
+       OutboundRoute { session_priv: SecretKey },
+}
+impl SentHTLCId {
+       pub(crate) fn from_source(source: &HTLCSource) -> Self {
+               match source {
+                       HTLCSource::PreviousHopData(hop_data) => Self::PreviousHopData {
+                               short_channel_id: hop_data.short_channel_id,
+                               htlc_id: hop_data.htlc_id,
+                       },
+                       HTLCSource::OutboundRoute { session_priv, .. } =>
+                               Self::OutboundRoute { session_priv: *session_priv },
+               }
+       }
+}
+impl_writeable_tlv_based_enum!(SentHTLCId,
+       (0, PreviousHopData) => {
+               (0, short_channel_id, required),
+               (2, htlc_id, required),
+       },
+       (2, OutboundRoute) => {
+               (0, session_priv, required),
+       };
+);
+
+
 /// Tracks the inbound corresponding to an outbound HTLC
 #[allow(clippy::derive_hash_xor_eq)] // Our Hash is faithful to the data, we just don't have SecretKey::hash
 #[derive(Clone, PartialEq, Eq)]
@@ -247,6 +275,10 @@ pub(crate) enum HTLCSource {
                first_hop_htlc_msat: u64,
                payment_id: PaymentId,
                payment_secret: Option<PaymentSecret>,
+               /// Note that this is now "deprecated" - we write it for forwards (and read it for
+               /// backwards) compatibility reasons, but prefer to use the data in the
+               /// [`super::outbound_payment`] module, which stores per-payment data once instead of in
+               /// each HTLC.
                payment_params: Option<PaymentParameters>,
        },
 }
@@ -291,12 +323,31 @@ struct ReceiveError {
        msg: &'static str,
 }
 
+/// This enum is used to specify which error data to send to peers when failing back an HTLC
+/// using [`ChannelManager::fail_htlc_backwards_with_reason`].
+///
+/// For more info on failure codes, see <https://github.com/lightning/bolts/blob/master/04-onion-routing.md#failure-messages>.
+#[derive(Clone, Copy)]
+pub enum FailureCode {
+       /// We had a temporary error processing the payment. Useful if no other error codes fit
+       /// and you want to indicate that the payer may want to retry.
+       TemporaryNodeFailure             = 0x2000 | 2,
+       /// We have a required feature which was not in this onion. For example, you may require
+       /// some additional metadata that was not provided with this payment.
+       RequiredNodeFeatureMissing       = 0x4000 | 0x2000 | 3,
+       /// You may wish to use this when a `payment_preimage` is unknown, or the CLTV expiry of
+       /// the HTLC is too close to the current block height for safe handling.
+       /// Using this failure code in [`ChannelManager::fail_htlc_backwards_with_reason`] is
+       /// equivalent to calling [`ChannelManager::fail_htlc_backwards`].
+       IncorrectOrUnknownPaymentDetails = 0x4000 | 15,
+}
+
 type ShutdownResult = (Option<(OutPoint, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash, PublicKey, [u8; 32])>);
 
-/// Error type returned across the channel_state mutex boundary. When an Err is generated for a
+/// Error type returned across the peer_state mutex boundary. When an Err is generated for a
 /// Channel, we generally end up with a ChannelError::Close for which we have to close the channel
 /// immediately (ie with no further calls on it made). Thus, this step happens inside a
-/// channel_state lock. We then return the set of things that need to be done outside the lock in
+/// peer_state lock. We then return the set of things that need to be done outside the lock in
 /// this struct and call handle_error!() on it.
 
 struct MsgHandleErrInternal {
@@ -322,17 +373,6 @@ impl MsgHandleErrInternal {
                }
        }
        #[inline]
-       fn ignore_no_close(err: String) -> Self {
-               Self {
-                       err: LightningError {
-                               err,
-                               action: msgs::ErrorAction::IgnoreError,
-                       },
-                       chan_id: None,
-                       shutdown_finish: None,
-               }
-       }
-       #[inline]
        fn from_no_close(err: msgs::LightningError) -> Self {
                Self { err, chan_id: None, shutdown_finish: None }
        }
@@ -390,7 +430,7 @@ impl MsgHandleErrInternal {
 /// Event::PendingHTLCsForwardable for the API guidelines indicating how long should be waited).
 /// This provides some limited amount of privacy. Ideally this would range from somewhere like one
 /// second to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly.
-const MIN_HTLC_RELAY_HOLDING_CELL_MILLIS: u64 = 100;
+pub(super) const MIN_HTLC_RELAY_HOLDING_CELL_MILLIS: u64 = 100;
 
 /// For events which result in both a RevokeAndACK and a CommitmentUpdate, by default they should
 /// be sent in the order they appear in the return value, however sometimes the order needs to be
@@ -434,14 +474,6 @@ struct ClaimablePayments {
        pending_claiming_payments: HashMap<PaymentHash, ClaimingPayment>,
 }
 
-// Note this is only exposed in cfg(test):
-pub(super) struct ChannelHolder<Signer: Sign> {
-       pub(super) by_id: HashMap<[u8; 32], Channel<Signer>>,
-       /// Messages to send to peers - pushed to in the same lock that they are generated in (except
-       /// for broadcast messages, where ordering isn't as strict).
-       pub(super) pending_msg_events: Vec<MessageSendEvent>,
-}
-
 /// Events which we process internally but cannot be procsesed immediately at the generation site
 /// for some reason. They are handled in timer_tick_occurred, so may be processed with
 /// quite some time lag.
@@ -451,6 +483,7 @@ enum BackgroundEvent {
        ClosingMonitorUpdate((OutPoint, ChannelMonitorUpdate)),
 }
 
+#[derive(Debug)]
 pub(crate) enum MonitorUpdateCompletionAction {
        /// Indicates that a payment ultimately destined for us was claimed and we should emit an
        /// [`events::Event::PaymentClaimed`] to the user if we haven't yet generated such an event for
@@ -461,10 +494,55 @@ pub(crate) enum MonitorUpdateCompletionAction {
        EmitEvent { event: events::Event },
 }
 
-/// State we hold per-peer. In the future we should put channels in here, but for now we only hold
-/// the latest Init features we heard from the peer.
-struct PeerState {
+impl_writeable_tlv_based_enum_upgradable!(MonitorUpdateCompletionAction,
+       (0, PaymentClaimed) => { (0, payment_hash, required) },
+       (2, EmitEvent) => { (0, event, upgradable_required) },
+);
+
+/// State we hold per-peer.
+pub(super) struct PeerState<Signer: ChannelSigner> {
+       /// `temporary_channel_id` or `channel_id` -> `channel`.
+       ///
+       /// Holds all channels where the peer is the counterparty. Once a channel has been assigned a
+       /// `channel_id`, the `temporary_channel_id` key in the map is updated and is replaced by the
+       /// `channel_id`.
+       pub(super) channel_by_id: HashMap<[u8; 32], Channel<Signer>>,
+       /// The latest `InitFeatures` we heard from the peer.
        latest_features: InitFeatures,
+       /// Messages to send to the peer - pushed to in the same lock that they are generated in (except
+       /// for broadcast messages, where ordering isn't as strict).
+       pub(super) pending_msg_events: Vec<MessageSendEvent>,
+       /// Map from a specific channel to some action(s) that should be taken when all pending
+       /// [`ChannelMonitorUpdate`]s for the channel complete updating.
+       ///
+       /// Note that because we generally only have one entry here a HashMap is pretty overkill. A
+       /// BTreeMap currently stores more than ten elements per leaf node, so even up to a few
+       /// channels with a peer this will just be one allocation and will amount to a linear list of
+       /// channels to walk, avoiding the whole hashing rigmarole.
+       ///
+       /// Note that the channel may no longer exist. For example, if a channel was closed but we
+       /// later needed to claim an HTLC which is pending on-chain, we may generate a monitor update
+       /// for a missing channel. While a malicious peer could construct a second channel with the
+       /// same `temporary_channel_id` (or final `channel_id` in the case of 0conf channels or prior
+       /// to funding appearing on-chain), the downstream `ChannelMonitor` set is required to ensure
+       /// duplicates do not occur, so such channels should fail without a monitor update completing.
+       monitor_update_blocked_actions: BTreeMap<[u8; 32], Vec<MonitorUpdateCompletionAction>>,
+       /// The peer is currently connected (i.e. we've seen a
+       /// [`ChannelMessageHandler::peer_connected`] and no corresponding
+       /// [`ChannelMessageHandler::peer_disconnected`].
+       is_connected: bool,
+}
+
+impl <Signer: ChannelSigner> PeerState<Signer> {
+       /// Indicates that a peer meets the criteria where we're ok to remove it from our storage.
+       /// If true is passed for `require_disconnected`, the function will return false if we haven't
+       /// disconnected from the node already, ie. `PeerState::is_connected` is set to `true`.
+       fn ok_to_remove(&self, require_disconnected: bool) -> bool {
+               if require_disconnected && self.is_connected {
+                       return false
+               }
+               self.channel_by_id.is_empty() && self.monitor_update_blocked_actions.is_empty()
+       }
 }
 
 /// Stores a PaymentSecret and any other data we may need to validate an inbound payment is
@@ -501,6 +579,8 @@ pub type SimpleArcChannelManager<M, T, F, L> = ChannelManager<
        Arc<M>,
        Arc<T>,
        Arc<KeysManager>,
+       Arc<KeysManager>,
+       Arc<KeysManager>,
        Arc<F>,
        Arc<DefaultRouter<
                Arc<NetworkGraph<Arc<L>>>,
@@ -520,7 +600,7 @@ pub type SimpleArcChannelManager<M, T, F, L> = ChannelManager<
 /// type alias chooses the concrete types of KeysManager and DefaultRouter.
 ///
 /// (C-not exported) as Arcs don't make sense in bindings
-pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L> = ChannelManager<&'a M, &'b T, &'c KeysManager, &'d F, &'e DefaultRouter<&'f NetworkGraph<&'g L>, &'g L, &'h Mutex<ProbabilisticScorer<&'f NetworkGraph<&'g L>, &'g L>>>, &'g L>;
+pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L> = ChannelManager<&'a M, &'b T, &'c KeysManager, &'c KeysManager, &'c KeysManager, &'d F, &'e DefaultRouter<&'f NetworkGraph<&'g L>, &'g L, &'h Mutex<ProbabilisticScorer<&'f NetworkGraph<&'g L>, &'g L>>>, &'g L>;
 
 /// Manager which keeps track of a number of channels and sends messages to the appropriate
 /// channel, also tracking HTLC preimages and forwarding onion packets appropriately.
@@ -553,6 +633,15 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L> = C
 /// offline for a full minute. In order to track this, you must call
 /// timer_tick_occurred roughly once per minute, though it doesn't have to be perfect.
 ///
+/// To avoid trivial DoS issues, ChannelManager limits the number of inbound connections and
+/// inbound channels without confirmed funding transactions. This may result in nodes which we do
+/// not have a channel with being unable to connect to us or open new channels with us if we have
+/// many peers with unfunded channels.
+///
+/// Because it is an indication of trust, inbound channels which we've accepted as 0conf are
+/// exempted from the count of unfunded channels. Similarly, outbound channels and connections are
+/// never limited. Please ensure you limit the count of such channels yourself.
+///
 /// Rather than using a plain ChannelManager, it is preferable to use either a SimpleArcChannelManager
 /// a SimpleRefChannelManager, for conciseness. See their documentation for more details, but
 /// essentially you should default to using a SimpleRefChannelManager, and use a
@@ -574,19 +663,19 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L> = C
 //  |   |
 //  |   |__`pending_intercepted_htlcs`
 //  |
-//  |__`pending_inbound_payments`
+//  |__`per_peer_state`
 //  |   |
-//  |   |__`claimable_payments`
-//  |   |
-//  |   |__`pending_outbound_payments` // This field's struct contains a map of pending outbounds
+//  |   |__`pending_inbound_payments`
 //  |       |
-//  |       |__`channel_state`
-//  |           |
-//  |           |__`id_to_peer`
-//  |           |
-//  |           |__`short_to_chan_info`
+//  |       |__`claimable_payments`
+//  |       |
+//  |       |__`pending_outbound_payments` // This field's struct contains a map of pending outbounds
 //  |           |
-//  |           |__`per_peer_state`
+//  |           |__`peer_state`
+//  |               |
+//  |               |__`id_to_peer`
+//  |               |
+//  |               |__`short_to_chan_info`
 //  |               |
 //  |               |__`outbound_scid_aliases`
 //  |               |
@@ -596,11 +685,13 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L> = C
 //  |                   |
 //  |                   |__`pending_background_events`
 //
-pub struct ChannelManager<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>
+pub struct ChannelManager<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
@@ -620,12 +711,6 @@ where
        best_block: RwLock<BestBlock>,
        secp_ctx: Secp256k1<secp256k1::All>,
 
-       /// See `ChannelManager` struct-level documentation for lock order requirements.
-       #[cfg(any(test, feature = "_test_utils"))]
-       pub(super) channel_state: Mutex<ChannelHolder<<K::Target as SignerProvider>::Signer>>,
-       #[cfg(not(any(test, feature = "_test_utils")))]
-       channel_state: Mutex<ChannelHolder<<K::Target as SignerProvider>::Signer>>,
-
        /// Storage for PaymentSecrets and any requirements on future inbound payments before we will
        /// expose them to users via a PaymentClaimable event. HTLCs which do not meet the requirements
        /// here are failed when we process them as pending-forwardable-HTLCs, and entries are removed
@@ -692,6 +777,9 @@ where
        /// the corresponding channel for the event, as we only have access to the `channel_id` during
        /// the handling of the events.
        ///
+       /// Note that no consistency guarantees are made about the existence of a peer with the
+       /// `counterparty_node_id` in our other maps.
+       ///
        /// TODO:
        /// The `counterparty_node_id` isn't passed with `MonitorEvent`s currently. To pass it, we need
        /// to make `counterparty_node_id`'s a required field in `ChannelMonitor`s, which unfortunately
@@ -719,7 +807,6 @@ where
        #[cfg(not(test))]
        short_to_chan_info: FairRwLock<HashMap<u64, (PublicKey, [u8; 32])>>,
 
-       our_network_key: SecretKey,
        our_network_pubkey: PublicKey,
 
        inbound_payment_key: inbound_payment::ExpandedKey,
@@ -741,15 +828,23 @@ where
        /// very far in the past, and can only ever be up to two hours in the future.
        highest_seen_timestamp: AtomicUsize,
 
-       /// The bulk of our storage will eventually be here (channels and message queues and the like).
+       /// The bulk of our storage. Currently the `per_peer_state` stores our channels on a per-peer
+       /// basis, as well as the peer's latest features.
+       ///
        /// If we are connected to a peer we always at least have an entry here, even if no channels
        /// are currently open with that peer.
+       ///
        /// Because adding or removing an entry is rare, we usually take an outer read lock and then
-       /// operate on the inner value freely. Sadly, this prevents parallel operation when opening a
-       /// new channel.
+       /// operate on the inner value freely. This opens up for parallel per-peer operation for
+       /// channels.
+       ///
+       /// Note that the same thread must never acquire two inner `PeerState` locks at the same time.
        ///
        /// See `ChannelManager` struct-level documentation for lock order requirements.
-       per_peer_state: RwLock<HashMap<PublicKey, Mutex<PeerState>>>,
+       #[cfg(not(any(test, feature = "_test_utils")))]
+       per_peer_state: FairRwLock<HashMap<PublicKey, Mutex<PeerState<<SP::Target as SignerProvider>::Signer>>>>,
+       #[cfg(any(test, feature = "_test_utils"))]
+       pub(super) per_peer_state: FairRwLock<HashMap<PublicKey, Mutex<PeerState<<SP::Target as SignerProvider>::Signer>>>>,
 
        /// See `ChannelManager` struct-level documentation for lock order requirements.
        pending_events: Mutex<Vec<events::Event>>,
@@ -765,7 +860,9 @@ where
 
        persistence_notifier: Notifier,
 
-       keys_manager: K,
+       entropy_source: ES,
+       node_signer: NS,
+       signer_provider: SP,
 
        logger: L,
 }
@@ -864,12 +961,12 @@ pub const MIN_CLTV_EXPIRY_DELTA: u16 = 6*7;
 pub(super) const CLTV_FAR_FAR_AWAY: u32 = 14 * 24 * 6;
 
 /// Minimum CLTV difference between the current block height and received inbound payments.
-/// Invoices generated for payment to us must set their `min_final_cltv_expiry` field to at least
+/// Invoices generated for payment to us must set their `min_final_cltv_expiry_delta` field to at least
 /// this value.
 // Note that we fail if exactly HTLC_FAIL_BACK_BUFFER + 1 was used, so we need to add one for
 // any payments to succeed. Further, we don't want payments to fail if a block was found while
 // a payment was being routed, so we add an extra block to be safe.
-pub const MIN_FINAL_CLTV_EXPIRY: u32 = HTLC_FAIL_BACK_BUFFER + 3;
+pub const MIN_FINAL_CLTV_EXPIRY_DELTA: u16 = HTLC_FAIL_BACK_BUFFER as u16 + 3;
 
 // Check that our CLTV_EXPIRY is at least CLTV_CLAIM_BUFFER + ANTI_REORG_DELAY + LATENCY_GRACE_PERIOD_BLOCKS,
 // ie that if the next-hop peer fails the HTLC within
@@ -895,6 +992,19 @@ pub(crate) const MPP_TIMEOUT_TICKS: u8 = 3;
 /// [`OutboundPayments::remove_stale_resolved_payments`].
 pub(crate) const IDEMPOTENCY_TIMEOUT_TICKS: u8 = 7;
 
+/// The maximum number of unfunded channels we can have per-peer before we start rejecting new
+/// (inbound) ones. The number of peers with unfunded channels is limited separately in
+/// [`MAX_UNFUNDED_CHANNEL_PEERS`].
+const MAX_UNFUNDED_CHANS_PER_PEER: usize = 4;
+
+/// The maximum number of peers from which we will allow pending unfunded channels. Once we reach
+/// this many peers we reject new (inbound) channels from peers with which we don't have a channel.
+const MAX_UNFUNDED_CHANNEL_PEERS: usize = 50;
+
+/// The maximum number of peers which we do not have a (funded) channel with. Once we reach this
+/// many peers we reject new (inbound) connections.
+const MAX_NO_CHANNEL_PEERS: usize = 250;
+
 /// Information needed for constructing an invoice route hint for this channel.
 #[derive(Clone, Debug, PartialEq)]
 pub struct CounterpartyForwardingInfo {
@@ -1121,6 +1231,36 @@ impl ChannelDetails {
        }
 }
 
+/// Used by [`ChannelManager::list_recent_payments`] to express the status of recent payments.
+/// These include payments that have yet to find a successful path, or have unresolved HTLCs.
+#[derive(Debug, PartialEq)]
+pub enum RecentPaymentDetails {
+       /// When a payment is still being sent and awaiting successful delivery.
+       Pending {
+               /// Hash of the payment that is currently being sent but has yet to be fulfilled or
+               /// abandoned.
+               payment_hash: PaymentHash,
+               /// Total amount (in msat, excluding fees) across all paths for this payment,
+               /// not just the amount currently inflight.
+               total_msat: u64,
+       },
+       /// When a pending payment is fulfilled, we continue tracking it until all pending HTLCs have
+       /// been resolved. Upon receiving [`Event::PaymentSent`], we delay for a few minutes before the
+       /// payment is removed from tracking.
+       Fulfilled {
+               /// Hash of the payment that was claimed. `None` for serializations of [`ChannelManager`]
+               /// made before LDK version 0.0.104.
+               payment_hash: Option<PaymentHash>,
+       },
+       /// After a payment's retries are exhausted per the provided [`Retry`], or it is explicitly
+       /// abandoned via [`ChannelManager::abandon_payment`], it is marked as abandoned until all
+       /// pending HTLCs for this payment resolve and an [`Event::PaymentFailed`] is generated.
+       Abandoned {
+               /// Hash of the payment that we have given up trying to send.
+               payment_hash: PaymentHash,
+       },
+}
+
 /// Route hints used in constructing invoices for [phantom node payents].
 ///
 /// [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager
@@ -1140,13 +1280,10 @@ macro_rules! handle_error {
                match $internal {
                        Ok(msg) => Ok(msg),
                        Err(MsgHandleErrInternal { err, chan_id, shutdown_finish }) => {
-                               #[cfg(debug_assertions)]
-                               {
-                                       // In testing, ensure there are no deadlocks where the lock is already held upon
-                                       // entering the macro.
-                                       assert!($self.channel_state.try_lock().is_ok());
-                                       assert!($self.pending_events.try_lock().is_ok());
-                               }
+                               // In testing, ensure there are no deadlocks where the lock is already held upon
+                               // entering the macro.
+                               debug_assert_ne!($self.pending_events.held_by_thread(), LockHeldState::HeldByThread);
+                               debug_assert_ne!($self.per_peer_state.held_by_thread(), LockHeldState::HeldByThread);
 
                                let mut msg_events = Vec::with_capacity(2);
 
@@ -1175,7 +1312,11 @@ macro_rules! handle_error {
                                }
 
                                if !msg_events.is_empty() {
-                                       $self.channel_state.lock().unwrap().pending_msg_events.append(&mut msg_events);
+                                       let per_peer_state = $self.per_peer_state.read().unwrap();
+                                       if let Some(peer_state_mutex) = per_peer_state.get(&$counterparty_node_id) {
+                                               let mut peer_state = peer_state_mutex.lock().unwrap();
+                                               peer_state.pending_msg_events.append(&mut msg_events);
+                                       }
                                }
 
                                // Return error in case higher-API need one
@@ -1266,78 +1407,6 @@ macro_rules! remove_channel {
        }
 }
 
-macro_rules! handle_monitor_update_res {
-       ($self: ident, $err: expr, $chan: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr, $resend_channel_ready: expr, $failed_forwards: expr, $failed_fails: expr, $failed_finalized_fulfills: expr, $chan_id: expr) => {
-               match $err {
-                       ChannelMonitorUpdateStatus::PermanentFailure => {
-                               log_error!($self.logger, "Closing channel {} due to monitor update ChannelMonitorUpdateStatus::PermanentFailure", log_bytes!($chan_id[..]));
-                               update_maps_on_chan_removal!($self, $chan);
-                               // TODO: $failed_fails is dropped here, which will cause other channels to hit the
-                               // chain in a confused state! We need to move them into the ChannelMonitor which
-                               // will be responsible for failing backwards once things confirm on-chain.
-                               // It's ok that we drop $failed_forwards here - at this point we'd rather they
-                               // broadcast HTLC-Timeout and pay the associated fees to get their funds back than
-                               // us bother trying to claim it just to forward on to another peer. If we're
-                               // splitting hairs we'd prefer to claim payments that were to us, but we haven't
-                               // given up the preimage yet, so might as well just wait until the payment is
-                               // retried, avoiding the on-chain fees.
-                               let res: Result<(), _> = Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure".to_owned(), *$chan_id, $chan.get_user_id(),
-                                               $chan.force_shutdown(false), $self.get_channel_update_for_broadcast(&$chan).ok() ));
-                               (res, true)
-                       },
-                       ChannelMonitorUpdateStatus::InProgress => {
-                               log_info!($self.logger, "Disabling channel {} due to monitor update in progress. On restore will send {} and process {} forwards, {} fails, and {} fulfill finalizations",
-                                               log_bytes!($chan_id[..]),
-                                               if $resend_commitment && $resend_raa {
-                                                               match $action_type {
-                                                                       RAACommitmentOrder::CommitmentFirst => { "commitment then RAA" },
-                                                                       RAACommitmentOrder::RevokeAndACKFirst => { "RAA then commitment" },
-                                                               }
-                                                       } else if $resend_commitment { "commitment" }
-                                                       else if $resend_raa { "RAA" }
-                                                       else { "nothing" },
-                                               (&$failed_forwards as &Vec<(PendingHTLCInfo, u64)>).len(),
-                                               (&$failed_fails as &Vec<(HTLCSource, PaymentHash, HTLCFailReason)>).len(),
-                                               (&$failed_finalized_fulfills as &Vec<HTLCSource>).len());
-                               if !$resend_commitment {
-                                       debug_assert!($action_type == RAACommitmentOrder::RevokeAndACKFirst || !$resend_raa);
-                               }
-                               if !$resend_raa {
-                                       debug_assert!($action_type == RAACommitmentOrder::CommitmentFirst || !$resend_commitment);
-                               }
-                               $chan.monitor_updating_paused($resend_raa, $resend_commitment, $resend_channel_ready, $failed_forwards, $failed_fails, $failed_finalized_fulfills);
-                               (Err(MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore("Failed to update ChannelMonitor".to_owned()), *$chan_id)), false)
-                       },
-                       ChannelMonitorUpdateStatus::Completed => {
-                               (Ok(()), false)
-                       },
-               }
-       };
-       ($self: ident, $err: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr, $resend_channel_ready: expr, $failed_forwards: expr, $failed_fails: expr, $failed_finalized_fulfills: expr) => { {
-               let (res, drop) = handle_monitor_update_res!($self, $err, $entry.get_mut(), $action_type, $resend_raa, $resend_commitment, $resend_channel_ready, $failed_forwards, $failed_fails, $failed_finalized_fulfills, $entry.key());
-               if drop {
-                       $entry.remove_entry();
-               }
-               res
-       } };
-       ($self: ident, $err: expr, $entry: expr, $action_type: path, $chan_id: expr, COMMITMENT_UPDATE_ONLY) => { {
-               debug_assert!($action_type == RAACommitmentOrder::CommitmentFirst);
-               handle_monitor_update_res!($self, $err, $entry, $action_type, false, true, false, Vec::new(), Vec::new(), Vec::new(), $chan_id)
-       } };
-       ($self: ident, $err: expr, $entry: expr, $action_type: path, $chan_id: expr, NO_UPDATE) => {
-               handle_monitor_update_res!($self, $err, $entry, $action_type, false, false, false, Vec::new(), Vec::new(), Vec::new(), $chan_id)
-       };
-       ($self: ident, $err: expr, $entry: expr, $action_type: path, $resend_channel_ready: expr, OPTIONALLY_RESEND_FUNDING_LOCKED) => {
-               handle_monitor_update_res!($self, $err, $entry, $action_type, false, false, $resend_channel_ready, Vec::new(), Vec::new(), Vec::new())
-       };
-       ($self: ident, $err: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr) => {
-               handle_monitor_update_res!($self, $err, $entry, $action_type, $resend_raa, $resend_commitment, false, Vec::new(), Vec::new(), Vec::new())
-       };
-       ($self: ident, $err: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr, $failed_forwards: expr, $failed_fails: expr) => {
-               handle_monitor_update_res!($self, $err, $entry, $action_type, $resend_raa, $resend_commitment, false, $failed_forwards, $failed_fails, Vec::new())
-       };
-}
-
 macro_rules! send_channel_ready {
        ($self: ident, $pending_msg_events: expr, $channel: expr, $channel_ready_msg: expr) => {{
                $pending_msg_events.push(events::MessageSendEvent::SendChannelReady {
@@ -1375,11 +1444,101 @@ macro_rules! emit_channel_ready_event {
        }
 }
 
-impl<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref> ChannelManager<M, T, K, F, R, L>
+macro_rules! handle_monitor_update_completion {
+       ($self: ident, $update_id: expr, $peer_state_lock: expr, $peer_state: expr, $per_peer_state_lock: expr, $chan: expr) => { {
+               let mut updates = $chan.monitor_updating_restored(&$self.logger,
+                       &$self.node_signer, $self.genesis_hash, &$self.default_configuration,
+                       $self.best_block.read().unwrap().height());
+               let counterparty_node_id = $chan.get_counterparty_node_id();
+               let channel_update = if updates.channel_ready.is_some() && $chan.is_usable() {
+                       // We only send a channel_update in the case where we are just now sending a
+                       // channel_ready and the channel is in a usable state. We may re-send a
+                       // channel_update later through the announcement_signatures process for public
+                       // channels, but there's no reason not to just inform our counterparty of our fees
+                       // now.
+                       if let Ok(msg) = $self.get_channel_update_for_unicast($chan) {
+                               Some(events::MessageSendEvent::SendChannelUpdate {
+                                       node_id: counterparty_node_id,
+                                       msg,
+                               })
+                       } else { None }
+               } else { None };
+
+               let update_actions = $peer_state.monitor_update_blocked_actions
+                       .remove(&$chan.channel_id()).unwrap_or(Vec::new());
+
+               let htlc_forwards = $self.handle_channel_resumption(
+                       &mut $peer_state.pending_msg_events, $chan, updates.raa,
+                       updates.commitment_update, updates.order, updates.accepted_htlcs,
+                       updates.funding_broadcastable, updates.channel_ready,
+                       updates.announcement_sigs);
+               if let Some(upd) = channel_update {
+                       $peer_state.pending_msg_events.push(upd);
+               }
+
+               let channel_id = $chan.channel_id();
+               core::mem::drop($peer_state_lock);
+               core::mem::drop($per_peer_state_lock);
+
+               $self.handle_monitor_update_completion_actions(update_actions);
+
+               if let Some(forwards) = htlc_forwards {
+                       $self.forward_htlcs(&mut [forwards][..]);
+               }
+               $self.finalize_claims(updates.finalized_claimed_htlcs);
+               for failure in updates.failed_htlcs.drain(..) {
+                       let receiver = HTLCDestination::NextHopChannel { node_id: Some(counterparty_node_id), channel_id };
+                       $self.fail_htlc_backwards_internal(&failure.0, &failure.1, &failure.2, receiver);
+               }
+       } }
+}
+
+macro_rules! handle_new_monitor_update {
+       ($self: ident, $update_res: expr, $update_id: expr, $peer_state_lock: expr, $peer_state: expr, $per_peer_state_lock: expr, $chan: expr, MANUALLY_REMOVING, $remove: expr) => { {
+               // update_maps_on_chan_removal needs to be able to take id_to_peer, so make sure we can in
+               // any case so that it won't deadlock.
+               debug_assert!($self.id_to_peer.try_lock().is_ok());
+               match $update_res {
+                       ChannelMonitorUpdateStatus::InProgress => {
+                               log_debug!($self.logger, "ChannelMonitor update for {} in flight, holding messages until the update completes.",
+                                       log_bytes!($chan.channel_id()[..]));
+                               Ok(())
+                       },
+                       ChannelMonitorUpdateStatus::PermanentFailure => {
+                               log_error!($self.logger, "Closing channel {} due to monitor update ChannelMonitorUpdateStatus::PermanentFailure",
+                                       log_bytes!($chan.channel_id()[..]));
+                               update_maps_on_chan_removal!($self, $chan);
+                               let res: Result<(), _> = Err(MsgHandleErrInternal::from_finish_shutdown(
+                                       "ChannelMonitor storage failure".to_owned(), $chan.channel_id(),
+                                       $chan.get_user_id(), $chan.force_shutdown(false),
+                                       $self.get_channel_update_for_broadcast(&$chan).ok()));
+                               $remove;
+                               res
+                       },
+                       ChannelMonitorUpdateStatus::Completed => {
+                               if ($update_id == 0 || $chan.get_next_monitor_update()
+                                       .expect("We can't be processing a monitor update if it isn't queued")
+                                       .update_id == $update_id) &&
+                                       $chan.get_latest_monitor_update_id() == $update_id
+                               {
+                                       handle_monitor_update_completion!($self, $update_id, $peer_state_lock, $peer_state, $per_peer_state_lock, $chan);
+                               }
+                               Ok(())
+                       },
+               }
+       } };
+       ($self: ident, $update_res: expr, $update_id: expr, $peer_state_lock: expr, $peer_state: expr, $per_peer_state_lock: expr, $chan_entry: expr) => {
+               handle_new_monitor_update!($self, $update_res, $update_id, $peer_state_lock, $peer_state, $per_peer_state_lock, $chan_entry.get_mut(), MANUALLY_REMOVING, $chan_entry.remove_entry())
+       }
+}
+
+impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
@@ -1394,10 +1553,10 @@ where
        /// Users need to notify the new ChannelManager when a new block is connected or
        /// disconnected using its `block_connected` and `block_disconnected` methods, starting
        /// from after `params.latest_hash`.
-       pub fn new(fee_est: F, chain_monitor: M, tx_broadcaster: T, router: R, logger: L, keys_manager: K, config: UserConfig, params: ChainParameters) -> Self {
+       pub fn new(fee_est: F, chain_monitor: M, tx_broadcaster: T, router: R, logger: L, entropy_source: ES, node_signer: NS, signer_provider: SP, config: UserConfig, params: ChainParameters) -> Self {
                let mut secp_ctx = Secp256k1::new();
-               secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
-               let inbound_pmt_key_material = keys_manager.get_inbound_payment_key_material();
+               secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
+               let inbound_pmt_key_material = node_signer.get_inbound_payment_key_material();
                let expanded_inbound_key = inbound_payment::ExpandedKey::new(&inbound_pmt_key_material);
                ChannelManager {
                        default_configuration: config.clone(),
@@ -1409,10 +1568,6 @@ where
 
                        best_block: RwLock::new(params.best_block),
 
-                       channel_state: Mutex::new(ChannelHolder{
-                               by_id: HashMap::new(),
-                               pending_msg_events: Vec::new(),
-                       }),
                        outbound_scid_aliases: Mutex::new(HashSet::new()),
                        pending_inbound_payments: Mutex::new(HashMap::new()),
                        pending_outbound_payments: OutboundPayments::new(),
@@ -1422,25 +1577,26 @@ where
                        id_to_peer: Mutex::new(HashMap::new()),
                        short_to_chan_info: FairRwLock::new(HashMap::new()),
 
-                       our_network_key: keys_manager.get_node_secret(Recipient::Node).unwrap(),
-                       our_network_pubkey: PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret(Recipient::Node).unwrap()),
+                       our_network_pubkey: node_signer.get_node_id(Recipient::Node).unwrap(),
                        secp_ctx,
 
                        inbound_payment_key: expanded_inbound_key,
-                       fake_scid_rand_bytes: keys_manager.get_secure_random_bytes(),
+                       fake_scid_rand_bytes: entropy_source.get_secure_random_bytes(),
 
-                       probing_cookie_secret: keys_manager.get_secure_random_bytes(),
+                       probing_cookie_secret: entropy_source.get_secure_random_bytes(),
 
                        highest_seen_timestamp: AtomicUsize::new(0),
 
-                       per_peer_state: RwLock::new(HashMap::new()),
+                       per_peer_state: FairRwLock::new(HashMap::new()),
 
                        pending_events: Mutex::new(Vec::new()),
                        pending_background_events: Mutex::new(Vec::new()),
                        total_consistency_lock: RwLock::new(()),
                        persistence_notifier: Notifier::new(),
 
-                       keys_manager,
+                       entropy_source,
+                       node_signer,
+                       signer_provider,
 
                        logger,
                }
@@ -1459,7 +1615,7 @@ where
                        if cfg!(fuzzing) { // fuzzing chacha20 doesn't use the key at all so we always get the same alias
                                outbound_scid_alias += 1;
                        } else {
-                               outbound_scid_alias = fake_scid::Namespace::OutboundAlias.get_fake_scid(height, &self.genesis_hash, &self.fake_scid_rand_bytes, &self.keys_manager);
+                               outbound_scid_alias = fake_scid::Namespace::OutboundAlias.get_fake_scid(height, &self.genesis_hash, &self.fake_scid_rand_bytes, &self.entropy_source);
                        }
                        if outbound_scid_alias != 0 && self.outbound_scid_aliases.lock().unwrap().insert(outbound_scid_alias) {
                                break;
@@ -1500,37 +1656,35 @@ where
                        return Err(APIError::APIMisuseError { err: format!("Channel value must be at least 1000 satoshis. It was {}", channel_value_satoshis) });
                }
 
+               let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
+               // We want to make sure the lock is actually acquired by PersistenceNotifierGuard.
+               debug_assert!(&self.total_consistency_lock.try_write().is_err());
+
+               let per_peer_state = self.per_peer_state.read().unwrap();
+
+               let peer_state_mutex = per_peer_state.get(&their_network_key)
+                       .ok_or_else(|| APIError::APIMisuseError{ err: format!("Not connected to node: {}", their_network_key) })?;
+
+               let mut peer_state = peer_state_mutex.lock().unwrap();
                let channel = {
-                       let per_peer_state = self.per_peer_state.read().unwrap();
-                       match per_peer_state.get(&their_network_key) {
-                               Some(peer_state) => {
-                                       let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
-                                       let peer_state = peer_state.lock().unwrap();
-                                       let their_features = &peer_state.latest_features;
-                                       let config = if override_config.is_some() { override_config.as_ref().unwrap() } else { &self.default_configuration };
-                                       match Channel::new_outbound(&self.fee_estimator, &self.keys_manager, their_network_key,
-                                               their_features, channel_value_satoshis, push_msat, user_channel_id, config,
-                                               self.best_block.read().unwrap().height(), outbound_scid_alias)
-                                       {
-                                               Ok(res) => res,
-                                               Err(e) => {
-                                                       self.outbound_scid_aliases.lock().unwrap().remove(&outbound_scid_alias);
-                                                       return Err(e);
-                                               },
-                                       }
+                       let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
+                       let their_features = &peer_state.latest_features;
+                       let config = if override_config.is_some() { override_config.as_ref().unwrap() } else { &self.default_configuration };
+                       match Channel::new_outbound(&self.fee_estimator, &self.entropy_source, &self.signer_provider, their_network_key,
+                               their_features, channel_value_satoshis, push_msat, user_channel_id, config,
+                               self.best_block.read().unwrap().height(), outbound_scid_alias)
+                       {
+                               Ok(res) => res,
+                               Err(e) => {
+                                       self.outbound_scid_aliases.lock().unwrap().remove(&outbound_scid_alias);
+                                       return Err(e);
                                },
-                               None => return Err(APIError::ChannelUnavailable { err: format!("Not connected to node: {}", their_network_key) }),
                        }
                };
                let res = channel.get_open_channel(self.genesis_hash.clone());
 
-               let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
-               // We want to make sure the lock is actually acquired by PersistenceNotifierGuard.
-               debug_assert!(&self.total_consistency_lock.try_write().is_err());
-
                let temporary_channel_id = channel.channel_id();
-               let mut channel_state = self.channel_state.lock().unwrap();
-               match channel_state.by_id.entry(temporary_channel_id) {
+               match peer_state.channel_by_id.entry(temporary_channel_id) {
                        hash_map::Entry::Occupied(_) => {
                                if cfg!(fuzzing) {
                                        return Err(APIError::APIMisuseError { err: "Fuzzy bad RNG".to_owned() });
@@ -1540,70 +1694,74 @@ where
                        },
                        hash_map::Entry::Vacant(entry) => { entry.insert(channel); }
                }
-               channel_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
+
+               peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
                        node_id: their_network_key,
                        msg: res,
                });
                Ok(temporary_channel_id)
        }
 
-       fn list_channels_with_filter<Fn: FnMut(&(&[u8; 32], &Channel<<K::Target as SignerProvider>::Signer>)) -> bool>(&self, f: Fn) -> Vec<ChannelDetails> {
-               let mut res = Vec::new();
+       fn list_channels_with_filter<Fn: FnMut(&(&[u8; 32], &Channel<<SP::Target as SignerProvider>::Signer>)) -> bool + Copy>(&self, f: Fn) -> Vec<ChannelDetails> {
+               // Allocate our best estimate of the number of channels we have in the `res`
+               // Vec. Sadly the `short_to_chan_info` map doesn't cover channels without
+               // a scid or a scid alias, and the `id_to_peer` shouldn't be used outside
+               // of the ChannelMonitor handling. Therefore reallocations may still occur, but is
+               // unlikely as the `short_to_chan_info` map often contains 2 entries for
+               // the same channel.
+               let mut res = Vec::with_capacity(self.short_to_chan_info.read().unwrap().len());
                {
-                       let channel_state = self.channel_state.lock().unwrap();
                        let best_block_height = self.best_block.read().unwrap().height();
-                       res.reserve(channel_state.by_id.len());
-                       for (channel_id, channel) in channel_state.by_id.iter().filter(f) {
-                               let balance = channel.get_available_balances();
-                               let (to_remote_reserve_satoshis, to_self_reserve_satoshis) =
-                                       channel.get_holder_counterparty_selected_channel_reserve_satoshis();
-                               res.push(ChannelDetails {
-                                       channel_id: (*channel_id).clone(),
-                                       counterparty: ChannelCounterparty {
-                                               node_id: channel.get_counterparty_node_id(),
-                                               features: InitFeatures::empty(),
-                                               unspendable_punishment_reserve: to_remote_reserve_satoshis,
-                                               forwarding_info: channel.counterparty_forwarding_info(),
-                                               // Ensures that we have actually received the `htlc_minimum_msat` value
-                                               // from the counterparty through the `OpenChannel` or `AcceptChannel`
-                                               // message (as they are always the first message from the counterparty).
-                                               // Else `Channel::get_counterparty_htlc_minimum_msat` could return the
-                                               // default `0` value set by `Channel::new_outbound`.
-                                               outbound_htlc_minimum_msat: if channel.have_received_message() {
-                                                       Some(channel.get_counterparty_htlc_minimum_msat()) } else { None },
-                                               outbound_htlc_maximum_msat: channel.get_counterparty_htlc_maximum_msat(),
-                                       },
-                                       funding_txo: channel.get_funding_txo(),
-                                       // Note that accept_channel (or open_channel) is always the first message, so
-                                       // `have_received_message` indicates that type negotiation has completed.
-                                       channel_type: if channel.have_received_message() { Some(channel.get_channel_type().clone()) } else { None },
-                                       short_channel_id: channel.get_short_channel_id(),
-                                       outbound_scid_alias: if channel.is_usable() { Some(channel.outbound_scid_alias()) } else { None },
-                                       inbound_scid_alias: channel.latest_inbound_scid_alias(),
-                                       channel_value_satoshis: channel.get_value_satoshis(),
-                                       unspendable_punishment_reserve: to_self_reserve_satoshis,
-                                       balance_msat: balance.balance_msat,
-                                       inbound_capacity_msat: balance.inbound_capacity_msat,
-                                       outbound_capacity_msat: balance.outbound_capacity_msat,
-                                       next_outbound_htlc_limit_msat: balance.next_outbound_htlc_limit_msat,
-                                       user_channel_id: channel.get_user_id(),
-                                       confirmations_required: channel.minimum_depth(),
-                                       confirmations: Some(channel.get_funding_tx_confirmations(best_block_height)),
-                                       force_close_spend_delay: channel.get_counterparty_selected_contest_delay(),
-                                       is_outbound: channel.is_outbound(),
-                                       is_channel_ready: channel.is_usable(),
-                                       is_usable: channel.is_live(),
-                                       is_public: channel.should_announce(),
-                                       inbound_htlc_minimum_msat: Some(channel.get_holder_htlc_minimum_msat()),
-                                       inbound_htlc_maximum_msat: channel.get_holder_htlc_maximum_msat(),
-                                       config: Some(channel.config()),
-                               });
-                       }
-               }
-               let per_peer_state = self.per_peer_state.read().unwrap();
-               for chan in res.iter_mut() {
-                       if let Some(peer_state) = per_peer_state.get(&chan.counterparty.node_id) {
-                               chan.counterparty.features = peer_state.lock().unwrap().latest_features.clone();
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       for (_cp_id, peer_state_mutex) in per_peer_state.iter() {
+                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               for (channel_id, channel) in peer_state.channel_by_id.iter().filter(f) {
+                                       let balance = channel.get_available_balances();
+                                       let (to_remote_reserve_satoshis, to_self_reserve_satoshis) =
+                                               channel.get_holder_counterparty_selected_channel_reserve_satoshis();
+                                       res.push(ChannelDetails {
+                                               channel_id: (*channel_id).clone(),
+                                               counterparty: ChannelCounterparty {
+                                                       node_id: channel.get_counterparty_node_id(),
+                                                       features: peer_state.latest_features.clone(),
+                                                       unspendable_punishment_reserve: to_remote_reserve_satoshis,
+                                                       forwarding_info: channel.counterparty_forwarding_info(),
+                                                       // Ensures that we have actually received the `htlc_minimum_msat` value
+                                                       // from the counterparty through the `OpenChannel` or `AcceptChannel`
+                                                       // message (as they are always the first message from the counterparty).
+                                                       // Else `Channel::get_counterparty_htlc_minimum_msat` could return the
+                                                       // default `0` value set by `Channel::new_outbound`.
+                                                       outbound_htlc_minimum_msat: if channel.have_received_message() {
+                                                               Some(channel.get_counterparty_htlc_minimum_msat()) } else { None },
+                                                       outbound_htlc_maximum_msat: channel.get_counterparty_htlc_maximum_msat(),
+                                               },
+                                               funding_txo: channel.get_funding_txo(),
+                                               // Note that accept_channel (or open_channel) is always the first message, so
+                                               // `have_received_message` indicates that type negotiation has completed.
+                                               channel_type: if channel.have_received_message() { Some(channel.get_channel_type().clone()) } else { None },
+                                               short_channel_id: channel.get_short_channel_id(),
+                                               outbound_scid_alias: if channel.is_usable() { Some(channel.outbound_scid_alias()) } else { None },
+                                               inbound_scid_alias: channel.latest_inbound_scid_alias(),
+                                               channel_value_satoshis: channel.get_value_satoshis(),
+                                               unspendable_punishment_reserve: to_self_reserve_satoshis,
+                                               balance_msat: balance.balance_msat,
+                                               inbound_capacity_msat: balance.inbound_capacity_msat,
+                                               outbound_capacity_msat: balance.outbound_capacity_msat,
+                                               next_outbound_htlc_limit_msat: balance.next_outbound_htlc_limit_msat,
+                                               user_channel_id: channel.get_user_id(),
+                                               confirmations_required: channel.minimum_depth(),
+                                               confirmations: Some(channel.get_funding_tx_confirmations(best_block_height)),
+                                               force_close_spend_delay: channel.get_counterparty_selected_contest_delay(),
+                                               is_outbound: channel.is_outbound(),
+                                               is_channel_ready: channel.is_usable(),
+                                               is_usable: channel.is_live(),
+                                               is_public: channel.should_announce(),
+                                               inbound_htlc_minimum_msat: Some(channel.get_holder_htlc_minimum_msat()),
+                                               inbound_htlc_maximum_msat: channel.get_holder_htlc_maximum_msat(),
+                                               config: Some(channel.config()),
+                                       });
+                               }
                        }
                }
                res
@@ -1615,14 +1773,12 @@ where
                self.list_channels_with_filter(|_| true)
        }
 
-       /// Gets the list of usable channels, in random order. Useful as an argument to [`find_route`]
-       /// to ensure non-announced channels are used.
+       /// Gets the list of usable channels, in random order. Useful as an argument to
+       /// [`Router::find_route`] to ensure non-announced channels are used.
        ///
        /// These are guaranteed to have their [`ChannelDetails::is_usable`] value set to true, see the
        /// documentation for [`ChannelDetails::is_usable`] for more info on exactly what the criteria
        /// are.
-       ///
-       /// [`find_route`]: crate::routing::router::find_route
        pub fn list_usable_channels(&self) -> Vec<ChannelDetails> {
                // Note we use is_live here instead of usable which leads to somewhat confused
                // internal/external nomenclature, but that's ok cause that's probably what the user
@@ -1630,8 +1786,36 @@ where
                self.list_channels_with_filter(|&(_, ref channel)| channel.is_live())
        }
 
+       /// Returns in an undefined order recent payments that -- if not fulfilled -- have yet to find a
+       /// successful path, or have unresolved HTLCs.
+       ///
+       /// This can be useful for payments that may have been prepared, but ultimately not sent, as a
+       /// result of a crash. If such a payment exists, is not listed here, and an
+       /// [`Event::PaymentSent`] has not been received, you may consider resending the payment.
+       ///
+       /// [`Event::PaymentSent`]: events::Event::PaymentSent
+       pub fn list_recent_payments(&self) -> Vec<RecentPaymentDetails> {
+               self.pending_outbound_payments.pending_outbound_payments.lock().unwrap().iter()
+                       .filter_map(|(_, pending_outbound_payment)| match pending_outbound_payment {
+                               PendingOutboundPayment::Retryable { payment_hash, total_msat, .. } => {
+                                       Some(RecentPaymentDetails::Pending {
+                                               payment_hash: *payment_hash,
+                                               total_msat: *total_msat,
+                                       })
+                               },
+                               PendingOutboundPayment::Abandoned { payment_hash, .. } => {
+                                       Some(RecentPaymentDetails::Abandoned { payment_hash: *payment_hash })
+                               },
+                               PendingOutboundPayment::Fulfilled { payment_hash, .. } => {
+                                       Some(RecentPaymentDetails::Fulfilled { payment_hash: *payment_hash })
+                               },
+                               PendingOutboundPayment::Legacy { .. } => None
+                       })
+                       .collect()
+       }
+
        /// Helper function that issues the channel close events
-       fn issue_channel_close_events(&self, channel: &Channel<<K::Target as SignerProvider>::Signer>, closure_reason: ClosureReason) {
+       fn issue_channel_close_events(&self, channel: &Channel<<SP::Target as SignerProvider>::Signer>, closure_reason: ClosureReason) {
                let mut pending_events_lock = self.pending_events.lock().unwrap();
                match channel.unbroadcasted_funding() {
                        Some(transaction) => {
@@ -1651,46 +1835,40 @@ where
 
                let mut failed_htlcs: Vec<(HTLCSource, PaymentHash)>;
                let result: Result<(), _> = loop {
-                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_state_lock;
-                       match channel_state.by_id.entry(channel_id.clone()) {
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+
+                       let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                               .ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id) })?;
+
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       match peer_state.channel_by_id.entry(channel_id.clone()) {
                                hash_map::Entry::Occupied(mut chan_entry) => {
-                                       if *counterparty_node_id != chan_entry.get().get_counterparty_node_id(){
-                                               return Err(APIError::APIMisuseError { err: "The passed counterparty_node_id doesn't match the channel's counterparty node_id".to_owned() });
-                                       }
-                                       let (shutdown_msg, monitor_update, htlcs) = {
-                                               let per_peer_state = self.per_peer_state.read().unwrap();
-                                               match per_peer_state.get(&counterparty_node_id) {
-                                                       Some(peer_state) => {
-                                                               let peer_state = peer_state.lock().unwrap();
-                                                               let their_features = &peer_state.latest_features;
-                                                               chan_entry.get_mut().get_shutdown(&self.keys_manager, their_features, target_feerate_sats_per_1000_weight)?
-                                                       },
-                                                       None => return Err(APIError::ChannelUnavailable { err: format!("Not connected to node: {}", counterparty_node_id) }),
-                                               }
-                                       };
+                                       let funding_txo_opt = chan_entry.get().get_funding_txo();
+                                       let their_features = &peer_state.latest_features;
+                                       let (shutdown_msg, mut monitor_update_opt, htlcs) = chan_entry.get_mut()
+                                               .get_shutdown(&self.signer_provider, their_features, target_feerate_sats_per_1000_weight)?;
                                        failed_htlcs = htlcs;
 
-                                       // Update the monitor with the shutdown script if necessary.
-                                       if let Some(monitor_update) = monitor_update {
-                                               let update_res = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update);
-                                               let (result, is_permanent) =
-                                                       handle_monitor_update_res!(self, update_res, chan_entry.get_mut(), RAACommitmentOrder::CommitmentFirst, chan_entry.key(), NO_UPDATE);
-                                               if is_permanent {
-                                                       remove_channel!(self, chan_entry);
-                                                       break result;
-                                               }
-                                       }
-
-                                       channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
+                                       // We can send the `shutdown` message before updating the `ChannelMonitor`
+                                       // here as we don't need the monitor update to complete until we send a
+                                       // `shutdown_signed`, which we'll delay if we're pending a monitor update.
+                                       peer_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
                                                node_id: *counterparty_node_id,
-                                               msg: shutdown_msg
+                                               msg: shutdown_msg,
                                        });
 
+                                       // Update the monitor with the shutdown script if necessary.
+                                       if let Some(monitor_update) = monitor_update_opt.take() {
+                                               let update_id = monitor_update.update_id;
+                                               let update_res = self.chain_monitor.update_channel(funding_txo_opt.unwrap(), monitor_update);
+                                               break handle_new_monitor_update!(self, update_res, update_id, peer_state_lock, peer_state, per_peer_state, chan_entry);
+                                       }
+
                                        if chan_entry.get().is_shutdown() {
                                                let channel = remove_channel!(self, chan_entry);
                                                if let Ok(channel_update) = self.get_channel_update_for_broadcast(&channel) {
-                                                       channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
+                                                       peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
                                                                msg: channel_update
                                                        });
                                                }
@@ -1698,7 +1876,7 @@ where
                                        }
                                        break Ok(());
                                },
-                               hash_map::Entry::Vacant(_) => return Err(APIError::ChannelUnavailable{err: "No such channel".to_owned()})
+                               hash_map::Entry::Vacant(_) => return Err(APIError::ChannelUnavailable{err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(*channel_id), counterparty_node_id) })
                        }
                };
 
@@ -1771,7 +1949,7 @@ where
                        // force-closing. The monitor update on the required in-memory copy should broadcast
                        // the latest local state, which is the best we can do anyway. Thus, it is safe to
                        // ignore the result here.
-                       let _ = self.chain_monitor.update_channel(funding_txo, monitor_update);
+                       let _ = self.chain_monitor.update_channel(funding_txo, &monitor_update);
                }
        }
 
@@ -1779,13 +1957,13 @@ where
        /// user closes, which will be re-exposed as the `ChannelClosed` reason.
        fn force_close_channel_with_peer(&self, channel_id: &[u8; 32], peer_node_id: &PublicKey, peer_msg: Option<&String>, broadcast: bool)
        -> Result<PublicKey, APIError> {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(peer_node_id)
+                       .ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", peer_node_id) })?;
                let mut chan = {
-                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_state_lock;
-                       if let hash_map::Entry::Occupied(chan) = channel_state.by_id.entry(channel_id.clone()) {
-                               if chan.get().get_counterparty_node_id() != *peer_node_id {
-                                       return Err(APIError::ChannelUnavailable{err: "No such channel".to_owned()});
-                               }
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       if let hash_map::Entry::Occupied(chan) = peer_state.channel_by_id.entry(channel_id.clone()) {
                                if let Some(peer_msg) = peer_msg {
                                        self.issue_channel_close_events(chan.get(),ClosureReason::CounterpartyForceClosed { peer_msg: peer_msg.to_string() });
                                } else {
@@ -1793,14 +1971,14 @@ where
                                }
                                remove_channel!(self, chan)
                        } else {
-                               return Err(APIError::ChannelUnavailable{err: "No such channel".to_owned()});
+                               return Err(APIError::ChannelUnavailable{ err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(*channel_id), peer_node_id) });
                        }
                };
                log_error!(self.logger, "Force-closing channel {}", log_bytes!(channel_id[..]));
                self.finish_force_close_channel(chan.force_shutdown(broadcast));
                if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
-                       let mut channel_state = self.channel_state.lock().unwrap();
-                       channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
+                       let mut peer_state = peer_state_mutex.lock().unwrap();
+                       peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
                                msg: update
                        });
                }
@@ -1812,14 +1990,18 @@ where
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
                match self.force_close_channel_with_peer(channel_id, counterparty_node_id, None, broadcast) {
                        Ok(counterparty_node_id) => {
-                               self.channel_state.lock().unwrap().pending_msg_events.push(
-                                       events::MessageSendEvent::HandleError {
-                                               node_id: counterparty_node_id,
-                                               action: msgs::ErrorAction::SendErrorMessage {
-                                                       msg: msgs::ErrorMessage { channel_id: *channel_id, data: "Channel force-closed".to_owned() }
-                                               },
-                                       }
-                               );
+                               let per_peer_state = self.per_peer_state.read().unwrap();
+                               if let Some(peer_state_mutex) = per_peer_state.get(&counterparty_node_id) {
+                                       let mut peer_state = peer_state_mutex.lock().unwrap();
+                                       peer_state.pending_msg_events.push(
+                                               events::MessageSendEvent::HandleError {
+                                                       node_id: counterparty_node_id,
+                                                       action: msgs::ErrorAction::SendErrorMessage {
+                                                               msg: msgs::ErrorMessage { channel_id: *channel_id, data: "Channel force-closed".to_owned() }
+                                                       },
+                                               }
+                                       );
+                               }
                                Ok(())
                        },
                        Err(e) => Err(e)
@@ -1876,6 +2058,7 @@ where
                // final_expiry_too_soon
                // We have to have some headroom to broadcast on chain if we have the preimage, so make sure
                // we have at least HTLC_FAIL_BACK_BUFFER blocks to go.
+               //
                // Also, ensure that, in the case of an unknown preimage for the received payment hash, our
                // payment logic has enough time to fail the HTLC backward before our onchain logic triggers a
                // channel closure (see HTLC_FAIL_BACK_BUFFER rationale).
@@ -1975,7 +2158,9 @@ where
                        return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6);
                }
 
-               let shared_secret = SharedSecret::new(&msg.onion_routing_packet.public_key.unwrap(), &self.our_network_key).secret_bytes();
+               let shared_secret = self.node_signer.ecdh(
+                       Recipient::Node, &msg.onion_routing_packet.public_key.unwrap(), None
+               ).unwrap().secret_bytes();
 
                if msg.onion_routing_packet.version != 0 {
                        //TODO: Spec doesn't indicate if we should only hash hop_data here (and in other
@@ -2060,9 +2245,8 @@ where
                        // short_channel_id is non-0 in any ::Forward.
                        if let &PendingHTLCRouting::Forward { ref short_channel_id, .. } = routing {
                                if let Some((err, mut code, chan_update)) = loop {
-                                       let id_option = self.short_to_chan_info.read().unwrap().get(&short_channel_id).cloned();
-                                       let mut channel_state = self.channel_state.lock().unwrap();
-                                       let forwarding_id_opt = match id_option {
+                                       let id_option = self.short_to_chan_info.read().unwrap().get(short_channel_id).cloned();
+                                       let forwarding_chan_info_opt = match id_option {
                                                None => { // unknown_next_peer
                                                        // Note that this is likely a timing oracle for detecting whether an scid is a
                                                        // phantom or an intercept.
@@ -2075,13 +2259,20 @@ where
                                                                break Some(("Don't have available channel for forwarding as requested.", 0x4000 | 10, None));
                                                        }
                                                },
-                                               Some((_cp_id, chan_id)) => Some(chan_id.clone()),
+                                               Some((cp_id, id)) => Some((cp_id.clone(), id.clone())),
                                        };
-                                       let chan_update_opt = if let Some(forwarding_id) = forwarding_id_opt {
-                                               let chan = match channel_state.by_id.get_mut(&forwarding_id) {
+                                       let chan_update_opt = if let Some((counterparty_node_id, forwarding_id)) = forwarding_chan_info_opt {
+                                               let per_peer_state = self.per_peer_state.read().unwrap();
+                                               let peer_state_mutex_opt = per_peer_state.get(&counterparty_node_id);
+                                               if peer_state_mutex_opt.is_none() {
+                                                       break Some(("Don't have available channel for forwarding as requested.", 0x4000 | 10, None));
+                                               }
+                                               let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
+                                               let peer_state = &mut *peer_state_lock;
+                                               let chan = match peer_state.channel_by_id.get_mut(&forwarding_id) {
                                                        None => {
-                                                               // Channel was removed. The short_to_chan_info and by_id maps have
-                                                               // no consistency guarantees.
+                                                               // Channel was removed. The short_to_chan_info and channel_by_id maps
+                                                               // have no consistency guarantees.
                                                                break Some(("Don't have available channel for forwarding as requested.", 0x4000 | 10, None));
                                                        },
                                                        Some(chan) => chan
@@ -2187,8 +2378,10 @@ where
        /// public, and thus should be called whenever the result is going to be passed out in a
        /// [`MessageSendEvent::BroadcastChannelUpdate`] event.
        ///
-       /// May be called with channel_state already locked!
-       fn get_channel_update_for_broadcast(&self, chan: &Channel<<K::Target as SignerProvider>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
+       /// Note that in `internal_closing_signed`, this function is called without the `peer_state`
+       /// corresponding to the channel's counterparty locked, as the channel been removed from the
+       /// storage and the `peer_state` lock has been dropped.
+       fn get_channel_update_for_broadcast(&self, chan: &Channel<<SP::Target as SignerProvider>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
                if !chan.should_announce() {
                        return Err(LightningError {
                                err: "Cannot broadcast a channel_update for a private channel".to_owned(),
@@ -2206,8 +2399,11 @@ where
        /// is public (only returning an Err if the channel does not yet have an assigned short_id),
        /// and thus MUST NOT be called unless the recipient of the resulting message has already
        /// provided evidence that they know about the existence of the channel.
-       /// May be called with channel_state already locked!
-       fn get_channel_update_for_unicast(&self, chan: &Channel<<K::Target as SignerProvider>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
+       ///
+       /// Note that through `internal_closing_signed`, this function is called without the
+       /// `peer_state`  corresponding to the channel's counterparty locked, as the channel been
+       /// removed from the storage and the `peer_state` lock has been dropped.
+       fn get_channel_update_for_unicast(&self, chan: &Channel<<SP::Target as SignerProvider>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
                log_trace!(self.logger, "Attempting to generate channel update for channel {}", log_bytes!(chan.channel_id()));
                let short_channel_id = match chan.get_short_channel_id().or(chan.latest_inbound_scid_alias()) {
                        None => return Err(LightningError{err: "Channel not yet established".to_owned(), action: msgs::ErrorAction::IgnoreError}),
@@ -2216,9 +2412,9 @@ where
 
                self.get_channel_update_for_onion(short_channel_id, chan)
        }
-       fn get_channel_update_for_onion(&self, short_channel_id: u64, chan: &Channel<<K::Target as SignerProvider>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
+       fn get_channel_update_for_onion(&self, short_channel_id: u64, chan: &Channel<<SP::Target as SignerProvider>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
                log_trace!(self.logger, "Generating channel update for channel {}", log_bytes!(chan.channel_id()));
-               let were_node_one = PublicKey::from_secret_key(&self.secp_ctx, &self.our_network_key).serialize()[..] < chan.get_counterparty_node_id().serialize()[..];
+               let were_node_one = self.our_network_pubkey.serialize()[..] < chan.get_counterparty_node_id().serialize()[..];
 
                let unsigned = msgs::UnsignedChannelUpdate {
                        chain_hash: self.genesis_hash,
@@ -2232,9 +2428,11 @@ where
                        fee_proportional_millionths: chan.get_fee_proportional_millionths(),
                        excess_data: Vec::new(),
                };
-
-               let msg_hash = Sha256dHash::hash(&unsigned.encode()[..]);
-               let sig = self.secp_ctx.sign_ecdsa(&hash_to_message!(&msg_hash[..]), &self.our_network_key);
+               // Panic on failure to signal LDK should be restarted to retry signing the `ChannelUpdate`.
+               // If we returned an error and the `node_signer` cannot provide a signature for whatever
+               // reason`, we wouldn't be able to receive inbound payments through the corresponding
+               // channel.
+               let sig = self.node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelUpdate(&unsigned)).unwrap();
 
                Ok(msgs::ChannelUpdate {
                        signature: sig,
@@ -2242,88 +2440,76 @@ where
                })
        }
 
-       // Only public for testing, this should otherwise never be called direcly
-       pub(crate) fn send_payment_along_path(&self, path: &Vec<RouteHop>, payment_params: &Option<PaymentParameters>, payment_hash: &PaymentHash, payment_secret: &Option<PaymentSecret>, total_value: u64, cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option<PaymentPreimage>, session_priv_bytes: [u8; 32]) -> Result<(), APIError> {
+       #[cfg(test)]
+       pub(crate) fn test_send_payment_along_path(&self, path: &Vec<RouteHop>, payment_params: &Option<PaymentParameters>, payment_hash: &PaymentHash, payment_secret: &Option<PaymentSecret>, total_value: u64, cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option<PaymentPreimage>, session_priv_bytes: [u8; 32]) -> Result<(), APIError> {
+               let _lck = self.total_consistency_lock.read().unwrap();
+               self.send_payment_along_path(path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv_bytes)
+       }
+
+       fn send_payment_along_path(&self, path: &Vec<RouteHop>, payment_params: &Option<PaymentParameters>, payment_hash: &PaymentHash, payment_secret: &Option<PaymentSecret>, total_value: u64, cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option<PaymentPreimage>, session_priv_bytes: [u8; 32]) -> Result<(), APIError> {
+               // The top-level caller should hold the total_consistency_lock read lock.
+               debug_assert!(self.total_consistency_lock.try_write().is_err());
+
                log_trace!(self.logger, "Attempting to send payment for path with next hop {}", path.first().unwrap().short_channel_id);
-               let prng_seed = self.keys_manager.get_secure_random_bytes();
+               let prng_seed = self.entropy_source.get_secure_random_bytes();
                let session_priv = SecretKey::from_slice(&session_priv_bytes[..]).expect("RNG is busted");
 
                let onion_keys = onion_utils::construct_onion_keys(&self.secp_ctx, &path, &session_priv)
-                       .map_err(|_| APIError::InvalidRoute{err: "Pubkey along hop was maliciously selected"})?;
+                       .map_err(|_| APIError::InvalidRoute{err: "Pubkey along hop was maliciously selected".to_owned()})?;
                let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(path, total_value, payment_secret, cur_height, keysend_preimage)?;
                if onion_utils::route_size_insane(&onion_payloads) {
-                       return Err(APIError::InvalidRoute{err: "Route size too large considering onion data"});
+                       return Err(APIError::InvalidRoute{err: "Route size too large considering onion data".to_owned()});
                }
                let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, prng_seed, payment_hash);
 
-               let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
-
                let err: Result<(), _> = loop {
-                       let id = match self.short_to_chan_info.read().unwrap().get(&path.first().unwrap().short_channel_id) {
+                       let (counterparty_node_id, id) = match self.short_to_chan_info.read().unwrap().get(&path.first().unwrap().short_channel_id) {
                                None => return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!".to_owned()}),
-                               Some((_cp_id, chan_id)) => chan_id.clone(),
+                               Some((cp_id, chan_id)) => (cp_id.clone(), chan_id.clone()),
                        };
 
-                       let mut channel_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_lock;
-                       if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(id) {
-                               match {
-                                       if chan.get().get_counterparty_node_id() != path.first().unwrap().pubkey {
-                                               return Err(APIError::InvalidRoute{err: "Node ID mismatch on first hop!"});
-                                       }
-                                       if !chan.get().is_live() {
-                                               return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected/pending monitor update!".to_owned()});
-                                       }
-                                       break_chan_entry!(self, chan.get_mut().send_htlc_and_commit(
-                                               htlc_msat, payment_hash.clone(), htlc_cltv, HTLCSource::OutboundRoute {
-                                                       path: path.clone(),
-                                                       session_priv: session_priv.clone(),
-                                                       first_hop_htlc_msat: htlc_msat,
-                                                       payment_id,
-                                                       payment_secret: payment_secret.clone(),
-                                                       payment_params: payment_params.clone(),
-                                               }, onion_packet, &self.logger),
-                                               chan)
-                               } {
-                                       Some((update_add, commitment_signed, monitor_update)) => {
-                                               let update_err = self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), monitor_update);
-                                               let chan_id = chan.get().channel_id();
-                                               match (update_err,
-                                                       handle_monitor_update_res!(self, update_err, chan,
-                                                               RAACommitmentOrder::CommitmentFirst, false, true))
-                                               {
-                                                       (ChannelMonitorUpdateStatus::PermanentFailure, Err(e)) => break Err(e),
-                                                       (ChannelMonitorUpdateStatus::Completed, Ok(())) => {},
-                                                       (ChannelMonitorUpdateStatus::InProgress, Err(_)) => {
-                                                               // Note that MonitorUpdateInProgress here indicates (per function
-                                                               // docs) that we will resend the commitment update once monitor
-                                                               // updating completes. Therefore, we must return an error
-                                                               // indicating that it is unsafe to retry the payment wholesale,
-                                                               // which we do in the send_payment check for
-                                                               // MonitorUpdateInProgress, below.
-                                                               return Err(APIError::MonitorUpdateInProgress);
-                                                       },
-                                                       _ => unreachable!(),
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       let peer_state_mutex = per_peer_state.get(&counterparty_node_id)
+                               .ok_or_else(|| APIError::ChannelUnavailable{err: "No peer matching the path's first hop found!".to_owned() })?;
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       if let hash_map::Entry::Occupied(mut chan) = peer_state.channel_by_id.entry(id) {
+                               if !chan.get().is_live() {
+                                       return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected".to_owned()});
+                               }
+                               let funding_txo = chan.get().get_funding_txo().unwrap();
+                               let send_res = chan.get_mut().send_htlc_and_commit(htlc_msat, payment_hash.clone(),
+                                       htlc_cltv, HTLCSource::OutboundRoute {
+                                               path: path.clone(),
+                                               session_priv: session_priv.clone(),
+                                               first_hop_htlc_msat: htlc_msat,
+                                               payment_id,
+                                               payment_secret: payment_secret.clone(),
+                                               payment_params: payment_params.clone(),
+                                       }, onion_packet, &self.logger);
+                               match break_chan_entry!(self, send_res, chan) {
+                                       Some(monitor_update) => {
+                                               let update_id = monitor_update.update_id;
+                                               let update_res = self.chain_monitor.update_channel(funding_txo, monitor_update);
+                                               if let Err(e) = handle_new_monitor_update!(self, update_res, update_id, peer_state_lock, peer_state, per_peer_state, chan) {
+                                                       break Err(e);
+                                               }
+                                               if update_res == ChannelMonitorUpdateStatus::InProgress {
+                                                       // Note that MonitorUpdateInProgress here indicates (per function
+                                                       // docs) that we will resend the commitment update once monitor
+                                                       // updating completes. Therefore, we must return an error
+                                                       // indicating that it is unsafe to retry the payment wholesale,
+                                                       // which we do in the send_payment check for
+                                                       // MonitorUpdateInProgress, below.
+                                                       return Err(APIError::MonitorUpdateInProgress);
                                                }
-
-                                               log_debug!(self.logger, "Sending payment along path resulted in a commitment_signed for channel {}", log_bytes!(chan_id));
-                                               channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
-                                                       node_id: path.first().unwrap().pubkey,
-                                                       updates: msgs::CommitmentUpdate {
-                                                               update_add_htlcs: vec![update_add],
-                                                               update_fulfill_htlcs: Vec::new(),
-                                                               update_fail_htlcs: Vec::new(),
-                                                               update_fail_malformed_htlcs: Vec::new(),
-                                                               update_fee: None,
-                                                               commitment_signed,
-                                                       },
-                                               });
                                        },
                                        None => { },
                                }
                        } else {
                                // The channel was likely removed after we fetched the id from the
-                               // `short_to_chan_info` map, but before we successfully locked the `by_id` map.
+                               // `short_to_chan_info` map, but before we successfully locked the
+                               // `channel_by_id` map.
                                // This can occur as no consistency guarantees exists between the two maps.
                                return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!".to_owned()});
                        }
@@ -2340,14 +2526,19 @@ where
 
        /// Sends a payment along a given route.
        ///
-       /// Value parameters are provided via the last hop in route, see documentation for RouteHop
+       /// Value parameters are provided via the last hop in route, see documentation for [`RouteHop`]
        /// fields for more info.
        ///
+       /// May generate SendHTLCs message(s) event on success, which should be relayed (e.g. via
+       /// [`PeerManager::process_events`]).
+       ///
+       /// # Avoiding Duplicate Payments
+       ///
        /// If a pending payment is currently in-flight with the same [`PaymentId`] provided, this
        /// method will error with an [`APIError::InvalidRoute`]. Note, however, that once a payment
        /// is no longer pending (either via [`ChannelManager::abandon_payment`], or handling of an
-       /// [`Event::PaymentSent`]) LDK will not stop you from sending a second payment with the same
-       /// [`PaymentId`].
+       /// [`Event::PaymentSent`] or [`Event::PaymentFailed`]) LDK will not stop you from sending a
+       /// second payment with the same [`PaymentId`].
        ///
        /// Thus, in order to ensure duplicate payments are not sent, you should implement your own
        /// tracking of payments, including state to indicate once a payment has completed. Because you
@@ -2355,12 +2546,16 @@ where
        /// consider using the [`PaymentHash`] as the key for tracking payments. In that case, the
        /// [`PaymentId`] should be a copy of the [`PaymentHash`] bytes.
        ///
-       /// May generate SendHTLCs message(s) event on success, which should be relayed (e.g. via
-       /// [`PeerManager::process_events`]).
+       /// Additionally, in the scenario where we begin the process of sending a payment, but crash
+       /// before `send_payment` returns (or prior to [`ChannelMonitorUpdate`] persistence if you're
+       /// using [`ChannelMonitorUpdateStatus::InProgress`]), the payment may be lost on restart. See
+       /// [`ChannelManager::list_recent_payments`] for more information.
+       ///
+       /// # Possible Error States on [`PaymentSendFailure`]
        ///
        /// Each path may have a different return value, and PaymentSendValue may return a Vec with
        /// each entry matching the corresponding-index entry in the route paths, see
-       /// PaymentSendFailure for more info.
+       /// [`PaymentSendFailure`] for more info.
        ///
        /// In general, a path may raise:
        ///  * [`APIError::InvalidRoute`] when an invalid route or forwarding parameter (cltv_delta, fee,
@@ -2375,22 +2570,41 @@ where
        /// irrevocably committed to on our end. In such a case, do NOT retry the payment with a
        /// different route unless you intend to pay twice!
        ///
-       /// payment_secret is unrelated to payment_hash (or PaymentPreimage) and exists to authenticate
-       /// the sender to the recipient and prevent payment-probing (deanonymization) attacks. For
-       /// newer nodes, it will be provided to you in the invoice. If you do not have one, the Route
-       /// must not contain multiple paths as multi-path payments require a recipient-provided
-       /// payment_secret.
+       /// # A caution on `payment_secret`
        ///
-       /// If a payment_secret *is* provided, we assume that the invoice had the payment_secret feature
-       /// bit set (either as required or as available). If multiple paths are present in the Route,
-       /// we assume the invoice had the basic_mpp feature set.
+       /// `payment_secret` is unrelated to `payment_hash` (or [`PaymentPreimage`]) and exists to
+       /// authenticate the sender to the recipient and prevent payment-probing (deanonymization)
+       /// attacks. For newer nodes, it will be provided to you in the invoice. If you do not have one,
+       /// the [`Route`] must not contain multiple paths as multi-path payments require a
+       /// recipient-provided `payment_secret`.
+       ///
+       /// If a `payment_secret` *is* provided, we assume that the invoice had the payment_secret
+       /// feature bit set (either as required or as available). If multiple paths are present in the
+       /// [`Route`], we assume the invoice had the basic_mpp feature set.
        ///
        /// [`Event::PaymentSent`]: events::Event::PaymentSent
+       /// [`Event::PaymentFailed`]: events::Event::PaymentFailed
        /// [`PeerManager::process_events`]: crate::ln::peer_handler::PeerManager::process_events
+       /// [`ChannelMonitorUpdateStatus::InProgress`]: crate::chain::ChannelMonitorUpdateStatus::InProgress
        pub fn send_payment(&self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>, payment_id: PaymentId) -> Result<(), PaymentSendFailure> {
                let best_block_height = self.best_block.read().unwrap().height();
+               let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
+               self.pending_outbound_payments
+                       .send_payment_with_route(route, payment_hash, payment_secret, payment_id, &self.entropy_source, &self.node_signer, best_block_height,
+                               |path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv|
+                               self.send_payment_along_path(path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv))
+       }
+
+       /// Similar to [`ChannelManager::send_payment`], but will automatically find a route based on
+       /// `route_params` and retry failed payment paths based on `retry_strategy`.
+       pub fn send_payment_with_retry(&self, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>, payment_id: PaymentId, route_params: RouteParameters, retry_strategy: Retry) -> Result<(), RetryableSendFailure> {
+               let best_block_height = self.best_block.read().unwrap().height();
+               let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
                self.pending_outbound_payments
-                       .send_payment_with_route(route, payment_hash, payment_secret, payment_id, &self.keys_manager, best_block_height,
+                       .send_payment(payment_hash, payment_secret, payment_id, retry_strategy, route_params,
+                               &self.router, self.list_usable_channels(), || self.compute_inflight_htlcs(),
+                               &self.entropy_source, &self.node_signer, best_block_height, &self.logger,
+                               &self.pending_events,
                                |path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv|
                                self.send_payment_along_path(path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv))
        }
@@ -2398,7 +2612,8 @@ where
        #[cfg(test)]
        fn test_send_payment_internal(&self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>, keysend_preimage: Option<PaymentPreimage>, payment_id: PaymentId, recv_value_msat: Option<u64>, onion_session_privs: Vec<[u8; 32]>) -> Result<(), PaymentSendFailure> {
                let best_block_height = self.best_block.read().unwrap().height();
-               self.pending_outbound_payments.test_send_payment_internal(route, payment_hash, payment_secret, keysend_preimage, payment_id, recv_value_msat, onion_session_privs, &self.keys_manager, best_block_height,
+               let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
+               self.pending_outbound_payments.test_send_payment_internal(route, payment_hash, payment_secret, keysend_preimage, payment_id, recv_value_msat, onion_session_privs, &self.node_signer, best_block_height,
                        |path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv|
                        self.send_payment_along_path(path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv))
        }
@@ -2406,52 +2621,29 @@ where
        #[cfg(test)]
        pub(crate) fn test_add_new_pending_payment(&self, payment_hash: PaymentHash, payment_secret: Option<PaymentSecret>, payment_id: PaymentId, route: &Route) -> Result<Vec<[u8; 32]>, PaymentSendFailure> {
                let best_block_height = self.best_block.read().unwrap().height();
-               self.pending_outbound_payments.test_add_new_pending_payment(payment_hash, payment_secret, payment_id, route, &self.keys_manager, best_block_height)
+               self.pending_outbound_payments.test_add_new_pending_payment(payment_hash, payment_secret, payment_id, route, None, &self.entropy_source, best_block_height)
        }
 
 
-       /// Retries a payment along the given [`Route`].
-       ///
-       /// Errors returned are a superset of those returned from [`send_payment`], so see
-       /// [`send_payment`] documentation for more details on errors. This method will also error if the
-       /// retry amount puts the payment more than 10% over the payment's total amount, if the payment
-       /// for the given `payment_id` cannot be found (likely due to timeout or success), or if
-       /// further retries have been disabled with [`abandon_payment`].
-       ///
-       /// [`send_payment`]: [`ChannelManager::send_payment`]
-       /// [`abandon_payment`]: [`ChannelManager::abandon_payment`]
-       pub fn retry_payment(&self, route: &Route, payment_id: PaymentId) -> Result<(), PaymentSendFailure> {
-               let best_block_height = self.best_block.read().unwrap().height();
-               self.pending_outbound_payments.retry_payment_with_route(route, payment_id, &self.keys_manager, best_block_height,
-                       |path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv|
-                       self.send_payment_along_path(path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv))
-       }
-
-       /// Signals that no further retries for the given payment will occur.
+       /// Signals that no further retries for the given payment should occur. Useful if you have a
+       /// pending outbound payment with retries remaining, but wish to stop retrying the payment before
+       /// retries are exhausted.
        ///
-       /// After this method returns, no future calls to [`retry_payment`] for the given `payment_id`
-       /// are allowed. If no [`Event::PaymentFailed`] event had been generated before, one will be
-       /// generated as soon as there are no remaining pending HTLCs for this payment.
+       /// If no [`Event::PaymentFailed`] event had been generated before, one will be generated as soon
+       /// as there are no remaining pending HTLCs for this payment.
        ///
        /// Note that calling this method does *not* prevent a payment from succeeding. You must still
        /// wait until you receive either a [`Event::PaymentFailed`] or [`Event::PaymentSent`] event to
        /// determine the ultimate status of a payment.
        ///
        /// If an [`Event::PaymentFailed`] event is generated and we restart without this
-       /// [`ChannelManager`] having been persisted, the payment may still be in the pending state
-       /// upon restart. This allows further calls to [`retry_payment`] (and requiring a second call
-       /// to [`abandon_payment`] to mark the payment as failed again). Otherwise, future calls to
-       /// [`retry_payment`] will fail with [`PaymentSendFailure::ParameterError`].
+       /// [`ChannelManager`] having been persisted, another [`Event::PaymentFailed`] may be generated.
        ///
-       /// [`abandon_payment`]: Self::abandon_payment
-       /// [`retry_payment`]: Self::retry_payment
        /// [`Event::PaymentFailed`]: events::Event::PaymentFailed
        /// [`Event::PaymentSent`]: events::Event::PaymentSent
        pub fn abandon_payment(&self, payment_id: PaymentId) {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
-               if let Some(payment_failed_ev) = self.pending_outbound_payments.abandon_payment(payment_id) {
-                       self.pending_events.lock().unwrap().push(payment_failed_ev);
-               }
+               self.pending_outbound_payments.abandon_payment(payment_id, &self.pending_events);
        }
 
        /// Send a spontaneous payment, which is a payment that does not require the recipient to have
@@ -2471,7 +2663,28 @@ where
        /// [`send_payment`]: Self::send_payment
        pub fn send_spontaneous_payment(&self, route: &Route, payment_preimage: Option<PaymentPreimage>, payment_id: PaymentId) -> Result<PaymentHash, PaymentSendFailure> {
                let best_block_height = self.best_block.read().unwrap().height();
-               self.pending_outbound_payments.send_spontaneous_payment(route, payment_preimage, payment_id, &self.keys_manager, best_block_height,
+               let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
+               self.pending_outbound_payments.send_spontaneous_payment_with_route(
+                       route, payment_preimage, payment_id, &self.entropy_source, &self.node_signer,
+                       best_block_height,
+                       |path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv|
+                       self.send_payment_along_path(path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv))
+       }
+
+       /// Similar to [`ChannelManager::send_spontaneous_payment`], but will automatically find a route
+       /// based on `route_params` and retry failed payment paths based on `retry_strategy`.
+       ///
+       /// See [`PaymentParameters::for_keysend`] for help in constructing `route_params` for spontaneous
+       /// payments.
+       ///
+       /// [`PaymentParameters::for_keysend`]: crate::routing::router::PaymentParameters::for_keysend
+       pub fn send_spontaneous_payment_with_retry(&self, payment_preimage: Option<PaymentPreimage>, payment_id: PaymentId, route_params: RouteParameters, retry_strategy: Retry) -> Result<PaymentHash, RetryableSendFailure> {
+               let best_block_height = self.best_block.read().unwrap().height();
+               let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
+               self.pending_outbound_payments.send_spontaneous_payment(payment_preimage, payment_id,
+                       retry_strategy, route_params, &self.router, self.list_usable_channels(),
+                       || self.compute_inflight_htlcs(),  &self.entropy_source, &self.node_signer, best_block_height,
+                       &self.logger, &self.pending_events,
                        |path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv|
                        self.send_payment_along_path(path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv))
        }
@@ -2481,7 +2694,8 @@ where
        /// us to easily discern them from real payments.
        pub fn send_probe(&self, hops: Vec<RouteHop>) -> Result<(PaymentHash, PaymentId), PaymentSendFailure> {
                let best_block_height = self.best_block.read().unwrap().height();
-               self.pending_outbound_payments.send_probe(hops, self.probing_cookie_secret, &self.keys_manager, best_block_height,
+               let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
+               self.pending_outbound_payments.send_probe(hops, self.probing_cookie_secret, &self.entropy_source, &self.node_signer, best_block_height,
                        |path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv|
                        self.send_payment_along_path(path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv))
        }
@@ -2495,38 +2709,45 @@ where
 
        /// Handles the generation of a funding transaction, optionally (for tests) with a function
        /// which checks the correctness of the funding transaction given the associated channel.
-       fn funding_transaction_generated_intern<FundingOutput: Fn(&Channel<<K::Target as SignerProvider>::Signer>, &Transaction) -> Result<OutPoint, APIError>>(
-               &self, temporary_channel_id: &[u8; 32], _counterparty_node_id: &PublicKey, funding_transaction: Transaction, find_funding_output: FundingOutput
+       fn funding_transaction_generated_intern<FundingOutput: Fn(&Channel<<SP::Target as SignerProvider>::Signer>, &Transaction) -> Result<OutPoint, APIError>>(
+               &self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, funding_transaction: Transaction, find_funding_output: FundingOutput
        ) -> Result<(), APIError> {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id) })?;
+
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
                let (chan, msg) = {
-                       let (res, chan) = match self.channel_state.lock().unwrap().by_id.remove(temporary_channel_id) {
-                               Some(mut chan) => {
-                                       let funding_txo = find_funding_output(&chan, &funding_transaction)?;
-
-                                       (chan.get_outbound_funding_created(funding_transaction, funding_txo, &self.logger)
-                                               .map_err(|e| if let ChannelError::Close(msg) = e {
-                                                       MsgHandleErrInternal::from_finish_shutdown(msg, chan.channel_id(), chan.get_user_id(), chan.force_shutdown(true), None)
-                                               } else { unreachable!(); })
-                                       , chan)
-                               },
-                               None => { return Err(APIError::ChannelUnavailable { err: "No such channel".to_owned() }) },
+                       let (res, chan) = {
+                               match peer_state.channel_by_id.remove(temporary_channel_id) {
+                                       Some(mut chan) => {
+                                               let funding_txo = find_funding_output(&chan, &funding_transaction)?;
+
+                                               (chan.get_outbound_funding_created(funding_transaction, funding_txo, &self.logger)
+                                                       .map_err(|e| if let ChannelError::Close(msg) = e {
+                                                               MsgHandleErrInternal::from_finish_shutdown(msg, chan.channel_id(), chan.get_user_id(), chan.force_shutdown(true), None)
+                                                       } else { unreachable!(); })
+                                               , chan)
+                                       },
+                                       None => { return Err(APIError::ChannelUnavailable { err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(*temporary_channel_id), counterparty_node_id) }) },
+                               }
                        };
                        match handle_error!(self, res, chan.get_counterparty_node_id()) {
                                Ok(funding_msg) => {
                                        (chan, funding_msg)
                                },
                                Err(_) => { return Err(APIError::ChannelUnavailable {
-                                       err: "Error deriving keys or signing initial commitment transactions - either our RNG or our counterparty's RNG is broken or the Signer refused to sign".to_owned()
+                                       err: "Signer refused to sign the initial commitment transaction".to_owned()
                                }) },
                        }
                };
 
-               let mut channel_state = self.channel_state.lock().unwrap();
-               channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated {
+               peer_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated {
                        node_id: chan.get_counterparty_node_id(),
                        msg,
                });
-               match channel_state.by_id.entry(chan.channel_id()) {
+               match peer_state.channel_by_id.entry(chan.channel_id()) {
                        hash_map::Entry::Occupied(_) => {
                                panic!("Generated duplicate funding txid?");
                        },
@@ -2660,34 +2881,30 @@ where
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(
                        &self.total_consistency_lock, &self.persistence_notifier,
                );
-               {
-                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_state_lock;
-                       for channel_id in channel_ids {
-                               let channel_counterparty_node_id = channel_state.by_id.get(channel_id)
-                                       .ok_or(APIError::ChannelUnavailable {
-                                               err: format!("Channel with ID {} was not found", log_bytes!(*channel_id)),
-                                       })?
-                                       .get_counterparty_node_id();
-                               if channel_counterparty_node_id != *counterparty_node_id {
-                                       return Err(APIError::APIMisuseError {
-                                               err: "counterparty node id mismatch".to_owned(),
-                                       });
-                               }
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id) })?;
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               for channel_id in channel_ids {
+                       if !peer_state.channel_by_id.contains_key(channel_id) {
+                               return Err(APIError::ChannelUnavailable {
+                                       err: format!("Channel with ID {} was not found for the passed counterparty_node_id {}", log_bytes!(*channel_id), counterparty_node_id),
+                               });
                        }
-                       for channel_id in channel_ids {
-                               let channel = channel_state.by_id.get_mut(channel_id).unwrap();
-                               if !channel.update_config(config) {
-                                       continue;
-                               }
-                               if let Ok(msg) = self.get_channel_update_for_broadcast(channel) {
-                                       channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg });
-                               } else if let Ok(msg) = self.get_channel_update_for_unicast(channel) {
-                                       channel_state.pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
-                                               node_id: channel.get_counterparty_node_id(),
-                                               msg,
-                                       });
-                               }
+               }
+               for channel_id in channel_ids {
+                       let channel = peer_state.channel_by_id.get_mut(channel_id).unwrap();
+                       if !channel.update_config(config) {
+                               continue;
+                       }
+                       if let Ok(msg) = self.get_channel_update_for_broadcast(channel) {
+                               peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg });
+                       } else if let Ok(msg) = self.get_channel_update_for_unicast(channel) {
+                               peer_state.pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
+                                       node_id: channel.get_counterparty_node_id(),
+                                       msg,
+                               });
                        }
                }
                Ok(())
@@ -2715,21 +2932,28 @@ where
        /// [`HTLCIntercepted`]: events::Event::HTLCIntercepted
        // TODO: when we move to deciding the best outbound channel at forward time, only take
        // `next_node_id` and not `next_hop_channel_id`
-       pub fn forward_intercepted_htlc(&self, intercept_id: InterceptId, next_hop_channel_id: &[u8; 32], _next_node_id: PublicKey, amt_to_forward_msat: u64) -> Result<(), APIError> {
+       pub fn forward_intercepted_htlc(&self, intercept_id: InterceptId, next_hop_channel_id: &[u8; 32], next_node_id: PublicKey, amt_to_forward_msat: u64) -> Result<(), APIError> {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
 
-               let next_hop_scid = match self.channel_state.lock().unwrap().by_id.get(next_hop_channel_id) {
-                       Some(chan) => {
-                               if !chan.is_usable() {
-                                       return Err(APIError::ChannelUnavailable {
-                                               err: format!("Channel with id {} not fully established", log_bytes!(*next_hop_channel_id))
-                                       })
-                               }
-                               chan.get_short_channel_id().unwrap_or(chan.outbound_scid_alias())
-                       },
-                       None => return Err(APIError::ChannelUnavailable {
-                               err: format!("Channel with id {} not found", log_bytes!(*next_hop_channel_id))
-                       })
+               let next_hop_scid = {
+                       let peer_state_lock = self.per_peer_state.read().unwrap();
+                       let peer_state_mutex = peer_state_lock.get(&next_node_id)
+                               .ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", next_node_id) })?;
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       match peer_state.channel_by_id.get(next_hop_channel_id) {
+                               Some(chan) => {
+                                       if !chan.is_usable() {
+                                               return Err(APIError::ChannelUnavailable {
+                                                       err: format!("Channel with id {} not fully established", log_bytes!(*next_hop_channel_id))
+                                               })
+                                       }
+                                       chan.get_short_channel_id().unwrap_or(chan.outbound_scid_alias())
+                               },
+                               None => return Err(APIError::ChannelUnavailable {
+                                       err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(*next_hop_channel_id), next_node_id)
+                               })
+                       }
                };
 
                let payment = self.pending_intercepted_htlcs.lock().unwrap().remove(&intercept_id)
@@ -2856,9 +3080,9 @@ where
                                                                                        }
                                                                                }
                                                                                if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
-                                                                                       let phantom_secret_res = self.keys_manager.get_node_secret(Recipient::PhantomNode);
-                                                                                       if phantom_secret_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
-                                                                                               let phantom_shared_secret = SharedSecret::new(&onion_packet.public_key.unwrap(), &phantom_secret_res.unwrap()).secret_bytes();
+                                                                                       let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
+                                                                                       if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
+                                                                                               let phantom_shared_secret = self.node_signer.ecdh(Recipient::PhantomNode, &onion_packet.public_key.unwrap(), None).unwrap().secret_bytes();
                                                                                                let next_hop = match onion_utils::decode_next_payment_hop(phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
                                                                                                        Ok(res) => res,
                                                                                                        Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
@@ -2899,16 +3123,22 @@ where
                                                        }
                                                }
                                        }
-                                       let forward_chan_id = match self.short_to_chan_info.read().unwrap().get(&short_chan_id) {
-                                               Some((_cp_id, chan_id)) => chan_id.clone(),
+                                       let (counterparty_node_id, forward_chan_id) = match self.short_to_chan_info.read().unwrap().get(&short_chan_id) {
+                                               Some((cp_id, chan_id)) => (cp_id.clone(), chan_id.clone()),
                                                None => {
                                                        forwarding_channel_not_found!();
                                                        continue;
                                                }
                                        };
-                                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                                       let channel_state = &mut *channel_state_lock;
-                                       match channel_state.by_id.entry(forward_chan_id) {
+                                       let per_peer_state = self.per_peer_state.read().unwrap();
+                                       let peer_state_mutex_opt = per_peer_state.get(&counterparty_node_id);
+                                       if peer_state_mutex_opt.is_none() {
+                                               forwarding_channel_not_found!();
+                                               continue;
+                                       }
+                                       let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
+                                       let peer_state = &mut *peer_state_lock;
+                                       match peer_state.channel_by_id.entry(forward_chan_id) {
                                                hash_map::Entry::Vacant(_) => {
                                                        forwarding_channel_not_found!();
                                                        continue;
@@ -3028,7 +3258,7 @@ where
                                                                let phantom_shared_secret = claimable_htlc.prev_hop.phantom_shared_secret;
                                                                let mut receiver_node_id = self.our_network_pubkey;
                                                                if phantom_shared_secret.is_some() {
-                                                                       receiver_node_id = self.keys_manager.get_node_id(Recipient::PhantomNode)
+                                                                       receiver_node_id = self.node_signer.get_node_id(Recipient::PhantomNode)
                                                                                .expect("Failed to get node_id for phantom node recipient");
                                                                }
 
@@ -3108,13 +3338,23 @@ where
                                                                                match claimable_htlc.onion_payload {
                                                                                        OnionPayload::Invoice { .. } => {
                                                                                                let payment_data = payment_data.unwrap();
-                                                                                               let payment_preimage = match inbound_payment::verify(payment_hash, &payment_data, self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger) {
-                                                                                                       Ok(payment_preimage) => payment_preimage,
+                                                                                               let (payment_preimage, min_final_cltv_expiry_delta) = match inbound_payment::verify(payment_hash, &payment_data, self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger) {
+                                                                                                       Ok(result) => result,
                                                                                                        Err(()) => {
+                                                                                                               log_trace!(self.logger, "Failing new HTLC with payment_hash {} as payment verification failed", log_bytes!(payment_hash.0));
                                                                                                                fail_htlc!(claimable_htlc, payment_hash);
                                                                                                                continue
                                                                                                        }
                                                                                                };
+                                                                                               if let Some(min_final_cltv_expiry_delta) = min_final_cltv_expiry_delta {
+                                                                                                       let expected_min_expiry_height = (self.current_best_block().height() + min_final_cltv_expiry_delta as u32) as u64;
+                                                                                                       if (cltv_expiry as u64) < expected_min_expiry_height {
+                                                                                                               log_trace!(self.logger, "Failing new HTLC with payment_hash {} as its CLTV expiry was too soon (had {}, earliest expected {})",
+                                                                                                                       log_bytes!(payment_hash.0), cltv_expiry, expected_min_expiry_height);
+                                                                                                               fail_htlc!(claimable_htlc, payment_hash);
+                                                                                                               continue;
+                                                                                                       }
+                                                                                               }
                                                                                                check_total_value!(payment_data, payment_preimage);
                                                                                        },
                                                                                        OnionPayload::Spontaneous(preimage) => {
@@ -3177,6 +3417,13 @@ where
                        }
                }
 
+               let best_block_height = self.best_block.read().unwrap().height();
+               self.pending_outbound_payments.check_retry_payments(&self.router, || self.list_usable_channels(),
+                       || self.compute_inflight_htlcs(), &self.entropy_source, &self.node_signer, best_block_height,
+                       &self.pending_events, &self.logger,
+                       |path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv|
+                       self.send_payment_along_path(path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv));
+
                for (htlc_source, payment_hash, failure_reason, destination) in failed_forwards.drain(..) {
                        self.fail_htlc_backwards_internal(&htlc_source, &payment_hash, &failure_reason, destination);
                }
@@ -3211,7 +3458,7 @@ where
                                BackgroundEvent::ClosingMonitorUpdate((funding_txo, update)) => {
                                        // The channel has already been closed, so no use bothering to care about the
                                        // monitor updating completing.
-                                       let _ = self.chain_monitor.update_channel(funding_txo, update);
+                                       let _ = self.chain_monitor.update_channel(funding_txo, &update);
                                },
                        }
                }
@@ -3224,7 +3471,7 @@ where
                self.process_background_events();
        }
 
-       fn update_channel_fee(&self, chan_id: &[u8; 32], chan: &mut Channel<<K::Target as SignerProvider>::Signer>, new_feerate: u32) -> NotifyOption {
+       fn update_channel_fee(&self, chan_id: &[u8; 32], chan: &mut Channel<<SP::Target as SignerProvider>::Signer>, new_feerate: u32) -> NotifyOption {
                if !chan.is_outbound() { return NotifyOption::SkipPersist; }
                // If the feerate has decreased by less than half, don't bother
                if new_feerate <= chan.get_feerate() && new_feerate * 2 > chan.get_feerate() {
@@ -3255,10 +3502,14 @@ where
 
                        let new_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal);
 
-                       let mut channel_state = self.channel_state.lock().unwrap();
-                       for (chan_id, chan) in channel_state.by_id.iter_mut() {
-                               let chan_needs_persist = self.update_channel_fee(chan_id, chan, new_feerate);
-                               if chan_needs_persist == NotifyOption::DoPersist { should_persist = NotifyOption::DoPersist; }
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       for (_cp_id, peer_state_mutex) in per_peer_state.iter() {
+                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               for (chan_id, chan) in peer_state.channel_by_id.iter_mut() {
+                                       let chan_needs_persist = self.update_channel_fee(chan_id, chan, new_feerate);
+                                       if chan_needs_persist == NotifyOption::DoPersist { should_persist = NotifyOption::DoPersist; }
+                               }
                        }
 
                        should_persist
@@ -3274,6 +3525,7 @@ where
        ///    the channel.
        ///  * Expiring a channel's previous `ChannelConfig` if necessary to only allow forwarding HTLCs
        ///    with the current `ChannelConfig`.
+       ///  * Removing peers which have disconnected but and no longer have any channels.
        ///
        /// Note that this may cause reentrancy through `chain::Watch::update_channel` calls or feerate
        /// estimate fetches.
@@ -3286,50 +3538,85 @@ where
 
                        let mut handle_errors: Vec<(Result<(), _>, _)> = Vec::new();
                        let mut timed_out_mpp_htlcs = Vec::new();
+                       let mut pending_peers_awaiting_removal = Vec::new();
                        {
-                               let mut channel_state_lock = self.channel_state.lock().unwrap();
-                               let channel_state = &mut *channel_state_lock;
-                               let pending_msg_events = &mut channel_state.pending_msg_events;
-                               channel_state.by_id.retain(|chan_id, chan| {
-                                       let chan_needs_persist = self.update_channel_fee(chan_id, chan, new_feerate);
-                                       if chan_needs_persist == NotifyOption::DoPersist { should_persist = NotifyOption::DoPersist; }
+                               let per_peer_state = self.per_peer_state.read().unwrap();
+                               for (counterparty_node_id, peer_state_mutex) in per_peer_state.iter() {
+                                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                                       let peer_state = &mut *peer_state_lock;
+                                       let pending_msg_events = &mut peer_state.pending_msg_events;
+                                       let counterparty_node_id = *counterparty_node_id;
+                                       peer_state.channel_by_id.retain(|chan_id, chan| {
+                                               let chan_needs_persist = self.update_channel_fee(chan_id, chan, new_feerate);
+                                               if chan_needs_persist == NotifyOption::DoPersist { should_persist = NotifyOption::DoPersist; }
+
+                                               if let Err(e) = chan.timer_check_closing_negotiation_progress() {
+                                                       let (needs_close, err) = convert_chan_err!(self, e, chan, chan_id);
+                                                       handle_errors.push((Err(err), counterparty_node_id));
+                                                       if needs_close { return false; }
+                                               }
 
-                                       if let Err(e) = chan.timer_check_closing_negotiation_progress() {
-                                               let (needs_close, err) = convert_chan_err!(self, e, chan, chan_id);
-                                               handle_errors.push((Err(err), chan.get_counterparty_node_id()));
-                                               if needs_close { return false; }
+                                               match chan.channel_update_status() {
+                                                       ChannelUpdateStatus::Enabled if !chan.is_live() => chan.set_channel_update_status(ChannelUpdateStatus::DisabledStaged),
+                                                       ChannelUpdateStatus::Disabled if chan.is_live() => chan.set_channel_update_status(ChannelUpdateStatus::EnabledStaged),
+                                                       ChannelUpdateStatus::DisabledStaged if chan.is_live() => chan.set_channel_update_status(ChannelUpdateStatus::Enabled),
+                                                       ChannelUpdateStatus::EnabledStaged if !chan.is_live() => chan.set_channel_update_status(ChannelUpdateStatus::Disabled),
+                                                       ChannelUpdateStatus::DisabledStaged if !chan.is_live() => {
+                                                               if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
+                                                                       pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
+                                                                               msg: update
+                                                                       });
+                                                               }
+                                                               should_persist = NotifyOption::DoPersist;
+                                                               chan.set_channel_update_status(ChannelUpdateStatus::Disabled);
+                                                       },
+                                                       ChannelUpdateStatus::EnabledStaged if chan.is_live() => {
+                                                               if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
+                                                                       pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
+                                                                               msg: update
+                                                                       });
+                                                               }
+                                                               should_persist = NotifyOption::DoPersist;
+                                                               chan.set_channel_update_status(ChannelUpdateStatus::Enabled);
+                                                       },
+                                                       _ => {},
+                                               }
+
+                                               chan.maybe_expire_prev_config();
+
+                                               true
+                                       });
+                                       if peer_state.ok_to_remove(true) {
+                                               pending_peers_awaiting_removal.push(counterparty_node_id);
                                        }
+                               }
+                       }
 
-                                       match chan.channel_update_status() {
-                                               ChannelUpdateStatus::Enabled if !chan.is_live() => chan.set_channel_update_status(ChannelUpdateStatus::DisabledStaged),
-                                               ChannelUpdateStatus::Disabled if chan.is_live() => chan.set_channel_update_status(ChannelUpdateStatus::EnabledStaged),
-                                               ChannelUpdateStatus::DisabledStaged if chan.is_live() => chan.set_channel_update_status(ChannelUpdateStatus::Enabled),
-                                               ChannelUpdateStatus::EnabledStaged if !chan.is_live() => chan.set_channel_update_status(ChannelUpdateStatus::Disabled),
-                                               ChannelUpdateStatus::DisabledStaged if !chan.is_live() => {
-                                                       if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
-                                                               pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
-                                                                       msg: update
-                                                               });
-                                                       }
-                                                       should_persist = NotifyOption::DoPersist;
-                                                       chan.set_channel_update_status(ChannelUpdateStatus::Disabled);
-                                               },
-                                               ChannelUpdateStatus::EnabledStaged if chan.is_live() => {
-                                                       if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
-                                                               pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
-                                                                       msg: update
-                                                               });
+                       // When a peer disconnects but still has channels, the peer's `peer_state` entry in the
+                       // `per_peer_state` is not removed by the `peer_disconnected` function. If the channels
+                       // of to that peer is later closed while still being disconnected (i.e. force closed),
+                       // we therefore need to remove the peer from `peer_state` separately.
+                       // To avoid having to take the `per_peer_state` `write` lock once the channels are
+                       // closed, we instead remove such peers awaiting removal here on a timer, to limit the
+                       // negative effects on parallelism as much as possible.
+                       if pending_peers_awaiting_removal.len() > 0 {
+                               let mut per_peer_state = self.per_peer_state.write().unwrap();
+                               for counterparty_node_id in pending_peers_awaiting_removal {
+                                       match per_peer_state.entry(counterparty_node_id) {
+                                               hash_map::Entry::Occupied(entry) => {
+                                                       // Remove the entry if the peer is still disconnected and we still
+                                                       // have no channels to the peer.
+                                                       let remove_entry = {
+                                                               let peer_state = entry.get().lock().unwrap();
+                                                               peer_state.ok_to_remove(true)
+                                                       };
+                                                       if remove_entry {
+                                                               entry.remove_entry();
                                                        }
-                                                       should_persist = NotifyOption::DoPersist;
-                                                       chan.set_channel_update_status(ChannelUpdateStatus::Enabled);
                                                },
-                                               _ => {},
+                                               hash_map::Entry::Vacant(_) => { /* The PeerState has already been removed */ }
                                        }
-
-                                       chan.maybe_expire_prev_config();
-
-                                       true
-                               });
+                               }
                        }
 
                        self.claimable_payments.lock().unwrap().claimable_htlcs.retain(|payment_hash, (_, htlcs)| {
@@ -3392,27 +3679,46 @@ where
        /// [`events::Event::PaymentClaimed`] events even for payments you intend to fail, especially on
        /// startup during which time claims that were in-progress at shutdown may be replayed.
        pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash) {
+               self.fail_htlc_backwards_with_reason(payment_hash, FailureCode::IncorrectOrUnknownPaymentDetails);
+       }
+
+       /// This is a variant of [`ChannelManager::fail_htlc_backwards`] that allows you to specify the
+       /// reason for the failure.
+       ///
+       /// See [`FailureCode`] for valid failure codes.
+       pub fn fail_htlc_backwards_with_reason(&self, payment_hash: &PaymentHash, failure_code: FailureCode) {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
 
                let removed_source = self.claimable_payments.lock().unwrap().claimable_htlcs.remove(payment_hash);
                if let Some((_, mut sources)) = removed_source {
                        for htlc in sources.drain(..) {
-                               let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
-                               htlc_msat_height_data.extend_from_slice(&self.best_block.read().unwrap().height().to_be_bytes());
+                               let reason = self.get_htlc_fail_reason_from_failure_code(failure_code, &htlc);
                                let source = HTLCSource::PreviousHopData(htlc.prev_hop);
-                               let reason = HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data);
                                let receiver = HTLCDestination::FailedPayment { payment_hash: *payment_hash };
                                self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
                        }
                }
        }
 
+       /// Gets error data to form an [`HTLCFailReason`] given a [`FailureCode`] and [`ClaimableHTLC`].
+       fn get_htlc_fail_reason_from_failure_code(&self, failure_code: FailureCode, htlc: &ClaimableHTLC) -> HTLCFailReason {
+               match failure_code {
+                       FailureCode::TemporaryNodeFailure => HTLCFailReason::from_failure_code(failure_code as u16),
+                       FailureCode::RequiredNodeFeatureMissing => HTLCFailReason::from_failure_code(failure_code as u16),
+                       FailureCode::IncorrectOrUnknownPaymentDetails => {
+                               let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
+                               htlc_msat_height_data.extend_from_slice(&self.best_block.read().unwrap().height().to_be_bytes());
+                               HTLCFailReason::reason(failure_code as u16, htlc_msat_height_data)
+                       }
+               }
+       }
+
        /// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
        /// that we want to return and a channel.
        ///
        /// This is for failures on the channel on which the HTLC was *received*, not failures
        /// forwarding
-       fn get_htlc_inbound_temp_fail_err_and_data(&self, desired_err_code: u16, chan: &Channel<<K::Target as SignerProvider>::Signer>) -> (u16, Vec<u8>) {
+       fn get_htlc_inbound_temp_fail_err_and_data(&self, desired_err_code: u16, chan: &Channel<<SP::Target as SignerProvider>::Signer>) -> (u16, Vec<u8>) {
                // We can't be sure what SCID was used when relaying inbound towards us, so we have to
                // guess somewhat. If its a public channel, we figure best to just use the real SCID (as
                // we're not leaking that we have a channel with the counterparty), otherwise we try to use
@@ -3432,7 +3738,7 @@ where
 
        /// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
        /// that we want to return and a channel.
-       fn get_htlc_temp_fail_err_and_data(&self, desired_err_code: u16, scid: u64, chan: &Channel<<K::Target as SignerProvider>::Signer>) -> (u16, Vec<u8>) {
+       fn get_htlc_temp_fail_err_and_data(&self, desired_err_code: u16, scid: u64, chan: &Channel<<SP::Target as SignerProvider>::Signer>) -> (u16, Vec<u8>) {
                debug_assert_eq!(desired_err_code & 0x1000, 0x1000);
                if let Ok(upd) = self.get_channel_update_for_onion(scid, chan) {
                        let mut enc = VecWriter(Vec::with_capacity(upd.serialized_length() + 6));
@@ -3461,13 +3767,19 @@ where
                &self, mut htlcs_to_fail: Vec<(HTLCSource, PaymentHash)>, channel_id: [u8; 32],
                counterparty_node_id: &PublicKey
        ) {
-               let (failure_code, onion_failure_data) =
-                       match self.channel_state.lock().unwrap().by_id.entry(channel_id) {
-                               hash_map::Entry::Occupied(chan_entry) => {
-                                       self.get_htlc_inbound_temp_fail_err_and_data(0x1000|7, &chan_entry.get())
-                               },
-                               hash_map::Entry::Vacant(_) => (0x4000|10, Vec::new())
-                       };
+               let (failure_code, onion_failure_data) = {
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       if let Some(peer_state_mutex) = per_peer_state.get(counterparty_node_id) {
+                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               match peer_state.channel_by_id.entry(channel_id) {
+                                       hash_map::Entry::Occupied(chan_entry) => {
+                                               self.get_htlc_inbound_temp_fail_err_and_data(0x1000|7, &chan_entry.get())
+                                       },
+                                       hash_map::Entry::Vacant(_) => (0x4000|10, Vec::new())
+                               }
+                       } else { (0x4000|10, Vec::new()) }
+               };
 
                for (htlc_src, payment_hash) in htlcs_to_fail.drain(..) {
                        let reason = HTLCFailReason::reason(failure_code, onion_failure_data.clone());
@@ -3479,13 +3791,12 @@ where
        /// Fails an HTLC backwards to the sender of it to us.
        /// Note that we do not assume that channels corresponding to failed HTLCs are still available.
        fn fail_htlc_backwards_internal(&self, source: &HTLCSource, payment_hash: &PaymentHash, onion_error: &HTLCFailReason, destination: HTLCDestination) {
-               #[cfg(debug_assertions)]
-               {
-                       // Ensure that the `channel_state` lock is not held when calling this function.
-                       // This ensures that future code doesn't introduce a lock_order requirement for
-                       // `forward_htlcs` to be locked after the `channel_state` lock, which calling this
-                       // function with the `channel_state` locked would.
-                       assert!(self.channel_state.try_lock().is_ok());
+               // Ensure that no peer state channel storage lock is held when calling this function.
+               // This ensures that future code doesn't introduce a lock-order requirement for
+               // `forward_htlcs` to be locked after the `per_peer_state` peer locks, which calling
+               // this function with any `per_peer_state` peer lock acquired would.
+               for (_, peer) in self.per_peer_state.read().unwrap().iter() {
+                       debug_assert_ne!(peer.held_by_thread(), LockHeldState::HeldByThread);
                }
 
                //TODO: There is a timing attack here where if a node fails an HTLC back to us they can
@@ -3498,16 +3809,19 @@ where
                // being fully configured. See the docs for `ChannelManagerReadArgs` for more.
                match source {
                        HTLCSource::OutboundRoute { ref path, ref session_priv, ref payment_id, ref payment_params, .. } => {
-                               self.pending_outbound_payments.fail_htlc(source, payment_hash, onion_error, path, session_priv, payment_id, payment_params, self.probing_cookie_secret, &self.secp_ctx, &self.pending_events, &self.logger);
+                               if self.pending_outbound_payments.fail_htlc(source, payment_hash, onion_error, path,
+                                       session_priv, payment_id, payment_params, self.probing_cookie_secret, &self.secp_ctx,
+                                       &self.pending_events, &self.logger)
+                               { self.push_pending_forwards_ev(); }
                        },
                        HTLCSource::PreviousHopData(HTLCPreviousHopData { ref short_channel_id, ref htlc_id, ref incoming_packet_shared_secret, ref phantom_shared_secret, ref outpoint }) => {
                                log_trace!(self.logger, "Failing HTLC with payment_hash {} backwards from us with {:?}", log_bytes!(payment_hash.0), onion_error);
                                let err_packet = onion_error.get_encrypted_failure_packet(incoming_packet_shared_secret, phantom_shared_secret);
 
-                               let mut forward_event = None;
+                               let mut push_forward_ev = false;
                                let mut forward_htlcs = self.forward_htlcs.lock().unwrap();
                                if forward_htlcs.is_empty() {
-                                       forward_event = Some(Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS));
+                                       push_forward_ev = true;
                                }
                                match forward_htlcs.entry(*short_channel_id) {
                                        hash_map::Entry::Occupied(mut entry) => {
@@ -3518,12 +3832,8 @@ where
                                        }
                                }
                                mem::drop(forward_htlcs);
+                               if push_forward_ev { self.push_pending_forwards_ev(); }
                                let mut pending_events = self.pending_events.lock().unwrap();
-                               if let Some(time) = forward_event {
-                                       pending_events.push(events::Event::PendingHTLCsForwardable {
-                                               time_forwardable: time
-                                       });
-                               }
                                pending_events.push(events::Event::HTLCHandlingFailed {
                                        prev_channel_id: outpoint.to_channel_id(),
                                        failed_next_destination: destination,
@@ -3560,7 +3870,7 @@ where
                                let mut receiver_node_id = self.our_network_pubkey;
                                for htlc in sources.iter() {
                                        if htlc.prev_hop.phantom_shared_secret.is_some() {
-                                               let phantom_pubkey = self.keys_manager.get_node_id(Recipient::PhantomNode)
+                                               let phantom_pubkey = self.node_signer.get_node_id(Recipient::PhantomNode)
                                                        .expect("Failed to get node_id for phantom node recipient");
                                                receiver_node_id = phantom_pubkey;
                                                break;
@@ -3600,17 +3910,26 @@ where
                let mut expected_amt_msat = None;
                let mut valid_mpp = true;
                let mut errs = Vec::new();
-               let mut channel_state = Some(self.channel_state.lock().unwrap());
+               let per_peer_state = self.per_peer_state.read().unwrap();
                for htlc in sources.iter() {
-                       let chan_id = match self.short_to_chan_info.read().unwrap().get(&htlc.prev_hop.short_channel_id) {
-                               Some((_cp_id, chan_id)) => chan_id.clone(),
+                       let (counterparty_node_id, chan_id) = match self.short_to_chan_info.read().unwrap().get(&htlc.prev_hop.short_channel_id) {
+                               Some((cp_id, chan_id)) => (cp_id.clone(), chan_id.clone()),
                                None => {
                                        valid_mpp = false;
                                        break;
                                }
                        };
 
-                       if let None = channel_state.as_ref().unwrap().by_id.get(&chan_id) {
+                       let peer_state_mutex_opt = per_peer_state.get(&counterparty_node_id);
+                       if peer_state_mutex_opt.is_none() {
+                               valid_mpp = false;
+                               break;
+                       }
+
+                       let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+
+                       if peer_state.channel_by_id.get(&chan_id).is_none() {
                                valid_mpp = false;
                                break;
                        }
@@ -3621,6 +3940,7 @@ where
                                valid_mpp = false;
                                break;
                        }
+
                        expected_amt_msat = Some(htlc.total_msat);
                        if let OnionPayload::Spontaneous(_) = &htlc.onion_payload {
                                // We don't currently support MPP for spontaneous payments, so just check
@@ -3635,14 +3955,13 @@ where
 
                        claimable_amt_msat += htlc.value;
                }
+               mem::drop(per_peer_state);
                if sources.is_empty() || expected_amt_msat.is_none() {
-                       mem::drop(channel_state);
                        self.claimable_payments.lock().unwrap().pending_claiming_payments.remove(&payment_hash);
                        log_info!(self.logger, "Attempted to claim an incomplete payment which no longer had any available HTLCs!");
                        return;
                }
                if claimable_amt_msat != expected_amt_msat.unwrap() {
-                       mem::drop(channel_state);
                        self.claimable_payments.lock().unwrap().pending_claiming_payments.remove(&payment_hash);
                        log_info!(self.logger, "Attempted to claim an incomplete payment, expected {} msat, had {} available to claim.",
                                expected_amt_msat.unwrap(), claimable_amt_msat);
@@ -3650,9 +3969,8 @@ where
                }
                if valid_mpp {
                        for htlc in sources.drain(..) {
-                               if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
-                               if let Err((pk, err)) = self.claim_funds_from_hop(channel_state.take().unwrap(), htlc.prev_hop,
-                                       payment_preimage,
+                               if let Err((pk, err)) = self.claim_funds_from_hop(
+                                       htlc.prev_hop, payment_preimage,
                                        |_| Some(MonitorUpdateCompletionAction::PaymentClaimed { payment_hash }))
                                {
                                        if let msgs::ErrorAction::IgnoreError = err.err.action {
@@ -3663,7 +3981,6 @@ where
                                }
                        }
                }
-               mem::drop(channel_state);
                if !valid_mpp {
                        for htlc in sources.drain(..) {
                                let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
@@ -3684,116 +4001,89 @@ where
        }
 
        fn claim_funds_from_hop<ComplFunc: FnOnce(Option<u64>) -> Option<MonitorUpdateCompletionAction>>(&self,
-               mut channel_state_lock: MutexGuard<ChannelHolder<<K::Target as SignerProvider>::Signer>>,
                prev_hop: HTLCPreviousHopData, payment_preimage: PaymentPreimage, completion_action: ComplFunc)
        -> Result<(), (PublicKey, MsgHandleErrInternal)> {
                //TODO: Delay the claimed_funds relaying just like we do outbound relay!
 
+               let per_peer_state = self.per_peer_state.read().unwrap();
                let chan_id = prev_hop.outpoint.to_channel_id();
-               let channel_state = &mut *channel_state_lock;
-               if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(chan_id) {
-                       let counterparty_node_id = chan.get().get_counterparty_node_id();
-                       match chan.get_mut().get_update_fulfill_htlc_and_commit(prev_hop.htlc_id, payment_preimage, &self.logger) {
-                               Ok(msgs_monitor_option) => {
-                                       if let UpdateFulfillCommitFetch::NewClaim { msgs, htlc_value_msat, monitor_update } = msgs_monitor_option {
-                                               match self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), monitor_update) {
-                                                       ChannelMonitorUpdateStatus::Completed => {},
-                                                       e => {
-                                                               log_given_level!(self.logger, if e == ChannelMonitorUpdateStatus::PermanentFailure { Level::Error } else { Level::Debug },
-                                                                       "Failed to update channel monitor with preimage {:?}: {:?}",
-                                                                       payment_preimage, e);
-                                                               let err = handle_monitor_update_res!(self, e, chan, RAACommitmentOrder::CommitmentFirst, false, msgs.is_some()).unwrap_err();
-                                                               mem::drop(channel_state_lock);
-                                                               self.handle_monitor_update_completion_actions(completion_action(Some(htlc_value_msat)));
-                                                               return Err((counterparty_node_id, err));
-                                                       }
-                                               }
-                                               if let Some((msg, commitment_signed)) = msgs {
-                                                       log_debug!(self.logger, "Claiming funds for HTLC with preimage {} resulted in a commitment_signed for channel {}",
-                                                               log_bytes!(payment_preimage.0), log_bytes!(chan.get().channel_id()));
-                                                       channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
-                                                               node_id: chan.get().get_counterparty_node_id(),
-                                                               updates: msgs::CommitmentUpdate {
-                                                                       update_add_htlcs: Vec::new(),
-                                                                       update_fulfill_htlcs: vec![msg],
-                                                                       update_fail_htlcs: Vec::new(),
-                                                                       update_fail_malformed_htlcs: Vec::new(),
-                                                                       update_fee: None,
-                                                                       commitment_signed,
-                                                               }
-                                                       });
-                                               }
-                                               mem::drop(channel_state_lock);
-                                               self.handle_monitor_update_completion_actions(completion_action(Some(htlc_value_msat)));
-                                               Ok(())
-                                       } else {
-                                               Ok(())
-                                       }
-                               },
-                               Err((e, monitor_update)) => {
-                                       match self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), monitor_update) {
-                                               ChannelMonitorUpdateStatus::Completed => {},
-                                               e => {
-                                                       // TODO: This needs to be handled somehow - if we receive a monitor update
-                                                       // with a preimage we *must* somehow manage to propagate it to the upstream
-                                                       // channel, or we must have an ability to receive the same update and try
-                                                       // again on restart.
-                                                       log_given_level!(self.logger, if e == ChannelMonitorUpdateStatus::PermanentFailure { Level::Error } else { Level::Info },
-                                                               "Failed to update channel monitor with preimage {:?} immediately prior to force-close: {:?}",
-                                                               payment_preimage, e);
-                                               },
+               let counterparty_node_id_opt = match self.short_to_chan_info.read().unwrap().get(&prev_hop.short_channel_id) {
+                       Some((cp_id, _dup_chan_id)) => Some(cp_id.clone()),
+                       None => None
+               };
+
+               let peer_state_opt = counterparty_node_id_opt.as_ref().map(
+                       |counterparty_node_id| per_peer_state.get(counterparty_node_id).map(
+                               |peer_mutex| peer_mutex.lock().unwrap()
+                       )
+               ).unwrap_or(None);
+
+               if peer_state_opt.is_some() {
+                       let mut peer_state_lock = peer_state_opt.unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       if let hash_map::Entry::Occupied(mut chan) = peer_state.channel_by_id.entry(chan_id) {
+                               let counterparty_node_id = chan.get().get_counterparty_node_id();
+                               let fulfill_res = chan.get_mut().get_update_fulfill_htlc_and_commit(prev_hop.htlc_id, payment_preimage, &self.logger);
+
+                               if let UpdateFulfillCommitFetch::NewClaim { htlc_value_msat, monitor_update } = fulfill_res {
+                                       if let Some(action) = completion_action(Some(htlc_value_msat)) {
+                                               log_trace!(self.logger, "Tracking monitor update completion action for channel {}: {:?}",
+                                                       log_bytes!(chan_id), action);
+                                               peer_state.monitor_update_blocked_actions.entry(chan_id).or_insert(Vec::new()).push(action);
                                        }
-                                       let (drop, res) = convert_chan_err!(self, e, chan.get_mut(), &chan_id);
-                                       if drop {
-                                               chan.remove_entry();
+                                       let update_id = monitor_update.update_id;
+                                       let update_res = self.chain_monitor.update_channel(prev_hop.outpoint, monitor_update);
+                                       let res = handle_new_monitor_update!(self, update_res, update_id, peer_state_lock,
+                                               peer_state, per_peer_state, chan);
+                                       if let Err(e) = res {
+                                               // TODO: This is a *critical* error - we probably updated the outbound edge
+                                               // of the HTLC's monitor with a preimage. We should retry this monitor
+                                               // update over and over again until morale improves.
+                                               log_error!(self.logger, "Failed to update channel monitor with preimage {:?}", payment_preimage);
+                                               return Err((counterparty_node_id, e));
                                        }
-                                       mem::drop(channel_state_lock);
-                                       self.handle_monitor_update_completion_actions(completion_action(None));
-                                       Err((counterparty_node_id, res))
-                               },
-                       }
-               } else {
-                       let preimage_update = ChannelMonitorUpdate {
-                               update_id: CLOSED_CHANNEL_UPDATE_ID,
-                               updates: vec![ChannelMonitorUpdateStep::PaymentPreimage {
-                                       payment_preimage,
-                               }],
-                       };
-                       // We update the ChannelMonitor on the backward link, after
-                       // receiving an `update_fulfill_htlc` from the forward link.
-                       let update_res = self.chain_monitor.update_channel(prev_hop.outpoint, preimage_update);
-                       if update_res != ChannelMonitorUpdateStatus::Completed {
-                               // TODO: This needs to be handled somehow - if we receive a monitor update
-                               // with a preimage we *must* somehow manage to propagate it to the upstream
-                               // channel, or we must have an ability to receive the same event and try
-                               // again on restart.
-                               log_error!(self.logger, "Critical error: failed to update channel monitor with preimage {:?}: {:?}",
-                                       payment_preimage, update_res);
+                               }
+                               return Ok(());
                        }
-                       mem::drop(channel_state_lock);
-                       // Note that we do process the completion action here. This totally could be a
-                       // duplicate claim, but we have no way of knowing without interrogating the
-                       // `ChannelMonitor` we've provided the above update to. Instead, note that `Event`s are
-                       // generally always allowed to be duplicative (and it's specifically noted in
-                       // `PaymentForwarded`).
-                       self.handle_monitor_update_completion_actions(completion_action(None));
-                       Ok(())
                }
+               let preimage_update = ChannelMonitorUpdate {
+                       update_id: CLOSED_CHANNEL_UPDATE_ID,
+                       updates: vec![ChannelMonitorUpdateStep::PaymentPreimage {
+                               payment_preimage,
+                       }],
+               };
+               // We update the ChannelMonitor on the backward link, after
+               // receiving an `update_fulfill_htlc` from the forward link.
+               let update_res = self.chain_monitor.update_channel(prev_hop.outpoint, &preimage_update);
+               if update_res != ChannelMonitorUpdateStatus::Completed {
+                       // TODO: This needs to be handled somehow - if we receive a monitor update
+                       // with a preimage we *must* somehow manage to propagate it to the upstream
+                       // channel, or we must have an ability to receive the same event and try
+                       // again on restart.
+                       log_error!(self.logger, "Critical error: failed to update channel monitor with preimage {:?}: {:?}",
+                               payment_preimage, update_res);
+               }
+               // Note that we do process the completion action here. This totally could be a
+               // duplicate claim, but we have no way of knowing without interrogating the
+               // `ChannelMonitor` we've provided the above update to. Instead, note that `Event`s are
+               // generally always allowed to be duplicative (and it's specifically noted in
+               // `PaymentForwarded`).
+               self.handle_monitor_update_completion_actions(completion_action(None));
+               Ok(())
        }
 
        fn finalize_claims(&self, sources: Vec<HTLCSource>) {
                self.pending_outbound_payments.finalize_claims(sources, &self.pending_events);
        }
 
-       fn claim_funds_internal(&self, channel_state_lock: MutexGuard<ChannelHolder<<K::Target as SignerProvider>::Signer>>, source: HTLCSource, payment_preimage: PaymentPreimage, forwarded_htlc_value_msat: Option<u64>, from_onchain: bool, next_channel_id: [u8; 32]) {
+       fn claim_funds_internal(&self, source: HTLCSource, payment_preimage: PaymentPreimage, forwarded_htlc_value_msat: Option<u64>, from_onchain: bool, next_channel_id: [u8; 32]) {
                match source {
                        HTLCSource::OutboundRoute { session_priv, payment_id, path, .. } => {
-                               mem::drop(channel_state_lock);
                                self.pending_outbound_payments.claim_htlc(payment_id, payment_preimage, session_priv, path, from_onchain, &self.pending_events, &self.logger);
                        },
                        HTLCSource::PreviousHopData(hop_data) => {
                                let prev_outpoint = hop_data.outpoint;
-                               let res = self.claim_funds_from_hop(channel_state_lock, hop_data, payment_preimage,
+                               let res = self.claim_funds_from_hop(hop_data, payment_preimage,
                                        |htlc_claim_value_msat| {
                                                if let Some(forwarded_htlc_value) = forwarded_htlc_value_msat {
                                                        let fee_earned_msat = if let Some(claimed_htlc_value) = htlc_claim_value_msat {
@@ -3845,11 +4135,19 @@ where
        /// Handles a channel reentering a functional state, either due to reconnect or a monitor
        /// update completion.
        fn handle_channel_resumption(&self, pending_msg_events: &mut Vec<MessageSendEvent>,
-               channel: &mut Channel<<K::Target as SignerProvider>::Signer>, raa: Option<msgs::RevokeAndACK>,
+               channel: &mut Channel<<SP::Target as SignerProvider>::Signer>, raa: Option<msgs::RevokeAndACK>,
                commitment_update: Option<msgs::CommitmentUpdate>, order: RAACommitmentOrder,
                pending_forwards: Vec<(PendingHTLCInfo, u64)>, funding_broadcastable: Option<Transaction>,
                channel_ready: Option<msgs::ChannelReady>, announcement_sigs: Option<msgs::AnnouncementSignatures>)
        -> Option<(u64, OutPoint, u128, Vec<(PendingHTLCInfo, u64)>)> {
+               log_trace!(self.logger, "Handling channel resumption for channel {} with {} RAA, {} commitment update, {} pending forwards, {}broadcasting funding, {} channel ready, {} announcement",
+                       log_bytes!(channel.channel_id()),
+                       if raa.is_some() { "an" } else { "no" },
+                       if commitment_update.is_some() { "a" } else { "no" }, pending_forwards.len(),
+                       if funding_broadcastable.is_some() { "" } else { "not " },
+                       if channel_ready.is_some() { "sending" } else { "without" },
+                       if announcement_sigs.is_some() { "sending" } else { "without" });
+
                let mut htlc_forwards = None;
 
                let counterparty_node_id = channel.get_counterparty_node_id();
@@ -3905,51 +4203,39 @@ where
                htlc_forwards
        }
 
-       fn channel_monitor_updated(&self, funding_txo: &OutPoint, highest_applied_update_id: u64) {
-               let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
+       fn channel_monitor_updated(&self, funding_txo: &OutPoint, highest_applied_update_id: u64, counterparty_node_id: Option<&PublicKey>) {
+               debug_assert!(self.total_consistency_lock.try_write().is_err()); // Caller holds read lock
 
-               let htlc_forwards;
-               let (mut pending_failures, finalized_claims, counterparty_node_id) = {
-                       let mut channel_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_lock;
-                       let mut channel = match channel_state.by_id.entry(funding_txo.to_channel_id()) {
+               let counterparty_node_id = match counterparty_node_id {
+                       Some(cp_id) => cp_id.clone(),
+                       None => {
+                               // TODO: Once we can rely on the counterparty_node_id from the
+                               // monitor event, this and the id_to_peer map should be removed.
+                               let id_to_peer = self.id_to_peer.lock().unwrap();
+                               match id_to_peer.get(&funding_txo.to_channel_id()) {
+                                       Some(cp_id) => cp_id.clone(),
+                                       None => return,
+                               }
+                       }
+               };
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let mut peer_state_lock;
+               let peer_state_mutex_opt = per_peer_state.get(&counterparty_node_id);
+               if peer_state_mutex_opt.is_none() { return }
+               peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               let mut channel = {
+                       match peer_state.channel_by_id.entry(funding_txo.to_channel_id()){
                                hash_map::Entry::Occupied(chan) => chan,
                                hash_map::Entry::Vacant(_) => return,
-                       };
-                       if !channel.get().is_awaiting_monitor_update() || channel.get().get_latest_monitor_update_id() != highest_applied_update_id {
-                               return;
                        }
-
-                       let counterparty_node_id = channel.get().get_counterparty_node_id();
-                       let updates = channel.get_mut().monitor_updating_restored(&self.logger, self.get_our_node_id(), self.genesis_hash, self.best_block.read().unwrap().height());
-                       let channel_update = if updates.channel_ready.is_some() && channel.get().is_usable() {
-                               // We only send a channel_update in the case where we are just now sending a
-                               // channel_ready and the channel is in a usable state. We may re-send a
-                               // channel_update later through the announcement_signatures process for public
-                               // channels, but there's no reason not to just inform our counterparty of our fees
-                               // now.
-                               if let Ok(msg) = self.get_channel_update_for_unicast(channel.get()) {
-                                       Some(events::MessageSendEvent::SendChannelUpdate {
-                                               node_id: channel.get().get_counterparty_node_id(),
-                                               msg,
-                                       })
-                               } else { None }
-                       } else { None };
-                       htlc_forwards = self.handle_channel_resumption(&mut channel_state.pending_msg_events, channel.get_mut(), updates.raa, updates.commitment_update, updates.order, updates.accepted_htlcs, updates.funding_broadcastable, updates.channel_ready, updates.announcement_sigs);
-                       if let Some(upd) = channel_update {
-                               channel_state.pending_msg_events.push(upd);
-                       }
-
-                       (updates.failed_htlcs, updates.finalized_claimed_htlcs, counterparty_node_id)
                };
-               if let Some(forwards) = htlc_forwards {
-                       self.forward_htlcs(&mut [forwards][..]);
-               }
-               self.finalize_claims(finalized_claims);
-               for failure in pending_failures.drain(..) {
-                       let receiver = HTLCDestination::NextHopChannel { node_id: Some(counterparty_node_id), channel_id: funding_txo.to_channel_id() };
-                       self.fail_htlc_backwards_internal(&failure.0, &failure.1, &failure.2, receiver);
+               log_trace!(self.logger, "ChannelMonitor updated to {}. Current highest is {}",
+                       highest_applied_update_id, channel.get().get_latest_monitor_update_id());
+               if !channel.get().is_awaiting_monitor_update() || channel.get().get_latest_monitor_update_id() != highest_applied_update_id {
+                       return;
                }
+               handle_monitor_update_completion!(self, highest_applied_update_id, peer_state_lock, peer_state, per_peer_state, channel.get_mut());
        }
 
        /// Accepts a request to open a channel after a [`Event::OpenChannelRequest`].
@@ -3997,16 +4283,18 @@ where
        fn do_accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u128) -> Result<(), APIError> {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
 
-               let mut channel_state_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_state_lock;
-               match channel_state.by_id.entry(temporary_channel_id.clone()) {
+               let peers_without_funded_channels = self.peers_without_funded_channels(|peer| !peer.channel_by_id.is_empty());
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id) })?;
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               let is_only_peer_channel = peer_state.channel_by_id.len() == 1;
+               match peer_state.channel_by_id.entry(temporary_channel_id.clone()) {
                        hash_map::Entry::Occupied(mut channel) => {
                                if !channel.get().inbound_is_awaiting_accept() {
                                        return Err(APIError::APIMisuseError { err: "The channel isn't currently awaiting to be accepted.".to_owned() });
                                }
-                               if *counterparty_node_id != channel.get().get_counterparty_node_id() {
-                                       return Err(APIError::APIMisuseError { err: "The passed counterparty_node_id doesn't match the channel's counterparty node_id".to_owned() });
-                               }
                                if accept_0conf {
                                        channel.get_mut().set_0conf();
                                } else if channel.get().get_channel_type().requires_zero_conf() {
@@ -4016,24 +4304,76 @@ where
                                                        msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "No zero confirmation channels accepted".to_owned(), }
                                                }
                                        };
-                                       channel_state.pending_msg_events.push(send_msg_err_event);
+                                       peer_state.pending_msg_events.push(send_msg_err_event);
                                        let _ = remove_channel!(self, channel);
                                        return Err(APIError::APIMisuseError { err: "Please use accept_inbound_channel_from_trusted_peer_0conf to accept channels with zero confirmations.".to_owned() });
+                               } else {
+                                       // If this peer already has some channels, a new channel won't increase our number of peers
+                                       // with unfunded channels, so as long as we aren't over the maximum number of unfunded
+                                       // channels per-peer we can accept channels from a peer with existing ones.
+                                       if is_only_peer_channel && peers_without_funded_channels >= MAX_UNFUNDED_CHANNEL_PEERS {
+                                               let send_msg_err_event = events::MessageSendEvent::HandleError {
+                                                       node_id: channel.get().get_counterparty_node_id(),
+                                                       action: msgs::ErrorAction::SendErrorMessage{
+                                                               msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "Have too many peers with unfunded channels, not accepting new ones".to_owned(), }
+                                                       }
+                                               };
+                                               peer_state.pending_msg_events.push(send_msg_err_event);
+                                               let _ = remove_channel!(self, channel);
+                                               return Err(APIError::APIMisuseError { err: "Too many peers with unfunded channels, refusing to accept new ones".to_owned() });
+                                       }
                                }
 
-                               channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
+                               peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
                                        node_id: channel.get().get_counterparty_node_id(),
                                        msg: channel.get_mut().accept_inbound_channel(user_channel_id),
                                });
                        }
                        hash_map::Entry::Vacant(_) => {
-                               return Err(APIError::ChannelUnavailable { err: "Can't accept a channel that doesn't exist".to_owned() });
+                               return Err(APIError::ChannelUnavailable { err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(*temporary_channel_id), counterparty_node_id) });
                        }
                }
                Ok(())
        }
 
-       fn internal_open_channel(&self, counterparty_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel) -> Result<(), MsgHandleErrInternal> {
+       /// Gets the number of peers which match the given filter and do not have any funded, outbound,
+       /// or 0-conf channels.
+       ///
+       /// The filter is called for each peer and provided with the number of unfunded, inbound, and
+       /// non-0-conf channels we have with the peer.
+       fn peers_without_funded_channels<Filter>(&self, maybe_count_peer: Filter) -> usize
+       where Filter: Fn(&PeerState<<SP::Target as SignerProvider>::Signer>) -> bool {
+               let mut peers_without_funded_channels = 0;
+               let best_block_height = self.best_block.read().unwrap().height();
+               {
+                       let peer_state_lock = self.per_peer_state.read().unwrap();
+                       for (_, peer_mtx) in peer_state_lock.iter() {
+                               let peer = peer_mtx.lock().unwrap();
+                               if !maybe_count_peer(&*peer) { continue; }
+                               let num_unfunded_channels = Self::unfunded_channel_count(&peer, best_block_height);
+                               if num_unfunded_channels == peer.channel_by_id.len() {
+                                       peers_without_funded_channels += 1;
+                               }
+                       }
+               }
+               return peers_without_funded_channels;
+       }
+
+       fn unfunded_channel_count(
+               peer: &PeerState<<SP::Target as SignerProvider>::Signer>, best_block_height: u32
+       ) -> usize {
+               let mut num_unfunded_channels = 0;
+               for (_, chan) in peer.channel_by_id.iter() {
+                       if !chan.is_outbound() && chan.minimum_depth().unwrap_or(1) != 0 &&
+                               chan.get_funding_tx_confirmations(best_block_height) == 0
+                       {
+                               num_unfunded_channels += 1;
+                       }
+               }
+               num_unfunded_channels
+       }
+
+       fn internal_open_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<(), MsgHandleErrInternal> {
                if msg.chain_hash != self.genesis_hash {
                        return Err(MsgHandleErrInternal::send_err_msg_no_close("Unknown genesis block hash".to_owned(), msg.temporary_channel_id.clone()));
                }
@@ -4043,13 +4383,46 @@ where
                }
 
                let mut random_bytes = [0u8; 16];
-               random_bytes.copy_from_slice(&self.keys_manager.get_secure_random_bytes()[..16]);
+               random_bytes.copy_from_slice(&self.entropy_source.get_secure_random_bytes()[..16]);
                let user_channel_id = u128::from_be_bytes(random_bytes);
-
                let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
-               let mut channel = match Channel::new_from_req(&self.fee_estimator, &self.keys_manager,
-                       counterparty_node_id.clone(), &their_features, msg, user_channel_id, &self.default_configuration,
-                       self.best_block.read().unwrap().height(), &self.logger, outbound_scid_alias)
+
+               // Get the number of peers with channels, but without funded ones. We don't care too much
+               // about peers that never open a channel, so we filter by peers that have at least one
+               // channel, and then limit the number of those with unfunded channels.
+               let channeled_peers_without_funding = self.peers_without_funded_channels(|node| !node.channel_by_id.is_empty());
+
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                   .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.temporary_channel_id.clone())
+                       })?;
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+
+               // If this peer already has some channels, a new channel won't increase our number of peers
+               // with unfunded channels, so as long as we aren't over the maximum number of unfunded
+               // channels per-peer we can accept channels from a peer with existing ones.
+               if peer_state.channel_by_id.is_empty() &&
+                       channeled_peers_without_funding >= MAX_UNFUNDED_CHANNEL_PEERS &&
+                       !self.default_configuration.manually_accept_inbound_channels
+               {
+                       return Err(MsgHandleErrInternal::send_err_msg_no_close(
+                               "Have too many peers with unfunded channels, not accepting new ones".to_owned(),
+                               msg.temporary_channel_id.clone()));
+               }
+
+               let best_block_height = self.best_block.read().unwrap().height();
+               if Self::unfunded_channel_count(peer_state, best_block_height) >= MAX_UNFUNDED_CHANS_PER_PEER {
+                       return Err(MsgHandleErrInternal::send_err_msg_no_close(
+                               format!("Refusing more than {} unfunded channels.", MAX_UNFUNDED_CHANS_PER_PEER),
+                               msg.temporary_channel_id.clone()));
+               }
+
+               let mut channel = match Channel::new_from_req(&self.fee_estimator, &self.entropy_source, &self.signer_provider,
+                       counterparty_node_id.clone(), &self.channel_type_features(), &peer_state.latest_features, msg, user_channel_id,
+                       &self.default_configuration, best_block_height, &self.logger, outbound_scid_alias)
                {
                        Err(e) => {
                                self.outbound_scid_aliases.lock().unwrap().remove(&outbound_scid_alias);
@@ -4057,19 +4430,17 @@ where
                        },
                        Ok(res) => res
                };
-               let mut channel_state_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_state_lock;
-               match channel_state.by_id.entry(channel.channel_id()) {
+               match peer_state.channel_by_id.entry(channel.channel_id()) {
                        hash_map::Entry::Occupied(_) => {
                                self.outbound_scid_aliases.lock().unwrap().remove(&outbound_scid_alias);
-                               return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision!".to_owned(), msg.temporary_channel_id.clone()))
+                               return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision for the same peer!".to_owned(), msg.temporary_channel_id.clone()))
                        },
                        hash_map::Entry::Vacant(entry) => {
                                if !self.default_configuration.manually_accept_inbound_channels {
                                        if channel.get_channel_type().requires_zero_conf() {
                                                return Err(MsgHandleErrInternal::send_err_msg_no_close("No zero confirmation channels accepted".to_owned(), msg.temporary_channel_id.clone()));
                                        }
-                                       channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
+                                       peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
                                                node_id: counterparty_node_id.clone(),
                                                msg: channel.accept_inbound_channel(user_channel_id),
                                        });
@@ -4092,19 +4463,22 @@ where
                Ok(())
        }
 
-       fn internal_accept_channel(&self, counterparty_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::AcceptChannel) -> Result<(), MsgHandleErrInternal> {
+       fn internal_accept_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannel) -> Result<(), MsgHandleErrInternal> {
                let (value, output_script, user_id) = {
-                       let mut channel_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_lock;
-                       match channel_state.by_id.entry(msg.temporary_channel_id) {
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                               .ok_or_else(|| {
+                                       debug_assert!(false);
+                                       MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.temporary_channel_id)
+                               })?;
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       match peer_state.channel_by_id.entry(msg.temporary_channel_id) {
                                hash_map::Entry::Occupied(mut chan) => {
-                                       if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                               return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.temporary_channel_id));
-                                       }
-                                       try_chan_entry!(self, chan.get_mut().accept_channel(&msg, &self.default_configuration.channel_handshake_limits, &their_features), chan);
+                                       try_chan_entry!(self, chan.get_mut().accept_channel(&msg, &self.default_configuration.channel_handshake_limits, &peer_state.latest_features), chan);
                                        (chan.get().get_value_satoshis(), chan.get().get_funding_redeemscript().to_v0_p2wsh(), chan.get().get_user_id())
                                },
-                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.temporary_channel_id))
+                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.temporary_channel_id))
                        }
                };
                let mut pending_events = self.pending_events.lock().unwrap();
@@ -4119,54 +4493,31 @@ where
        }
 
        fn internal_funding_created(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> {
-               let ((funding_msg, monitor, mut channel_ready), mut chan) = {
-                       let best_block = *self.best_block.read().unwrap();
-                       let mut channel_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_lock;
-                       match channel_state.by_id.entry(msg.temporary_channel_id.clone()) {
+               let best_block = *self.best_block.read().unwrap();
+
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.temporary_channel_id)
+                       })?;
+
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               let ((funding_msg, monitor), chan) =
+                       match peer_state.channel_by_id.entry(msg.temporary_channel_id) {
                                hash_map::Entry::Occupied(mut chan) => {
-                                       if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                               return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.temporary_channel_id));
-                                       }
-                                       (try_chan_entry!(self, chan.get_mut().funding_created(msg, best_block, &self.keys_manager, &self.logger), chan), chan.remove())
+                                       (try_chan_entry!(self, chan.get_mut().funding_created(msg, best_block, &self.signer_provider, &self.logger), chan), chan.remove())
                                },
-                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.temporary_channel_id))
-                       }
-               };
-               // Because we have exclusive ownership of the channel here we can release the channel_state
-               // lock before watch_channel
-               match self.chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor) {
-                       ChannelMonitorUpdateStatus::Completed => {},
-                       ChannelMonitorUpdateStatus::PermanentFailure => {
-                               // Note that we reply with the new channel_id in error messages if we gave up on the
-                               // channel, not the temporary_channel_id. This is compatible with ourselves, but the
-                               // spec is somewhat ambiguous here. Not a huge deal since we'll send error messages for
-                               // any messages referencing a previously-closed channel anyway.
-                               // We do not propagate the monitor update to the user as it would be for a monitor
-                               // that we didn't manage to store (and that we don't care about - we don't respond
-                               // with the funding_signed so the channel can never go on chain).
-                               let (_monitor_update, failed_htlcs) = chan.force_shutdown(false);
-                               assert!(failed_htlcs.is_empty());
-                               return Err(MsgHandleErrInternal::send_err_msg_no_close("ChannelMonitor storage failure".to_owned(), funding_msg.channel_id));
-                       },
-                       ChannelMonitorUpdateStatus::InProgress => {
-                               // There's no problem signing a counterparty's funding transaction if our monitor
-                               // hasn't persisted to disk yet - we can't lose money on a transaction that we haven't
-                               // accepted payment from yet. We do, however, need to wait to send our channel_ready
-                               // until we have persisted our monitor.
-                               chan.monitor_updating_paused(false, false, channel_ready.is_some(), Vec::new(), Vec::new(), Vec::new());
-                               channel_ready = None; // Don't send the channel_ready now
-                       },
-               }
-               let mut channel_state_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_state_lock;
-               match channel_state.by_id.entry(funding_msg.channel_id) {
+                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.temporary_channel_id))
+                       };
+
+               match peer_state.channel_by_id.entry(funding_msg.channel_id) {
                        hash_map::Entry::Occupied(_) => {
-                               return Err(MsgHandleErrInternal::send_err_msg_no_close("Already had channel with the new channel_id".to_owned(), funding_msg.channel_id))
+                               Err(MsgHandleErrInternal::send_err_msg_no_close("Already had channel with the new channel_id".to_owned(), funding_msg.channel_id))
                        },
                        hash_map::Entry::Vacant(e) => {
-                               let mut id_to_peer = self.id_to_peer.lock().unwrap();
-                               match id_to_peer.entry(chan.channel_id()) {
+                               match self.id_to_peer.lock().unwrap().entry(chan.channel_id()) {
                                        hash_map::Entry::Occupied(_) => {
                                                return Err(MsgHandleErrInternal::send_err_msg_no_close(
                                                        "The funding_created message had the same funding_txid as an existing channel - funding is not possible".to_owned(),
@@ -4176,74 +4527,85 @@ where
                                                i_e.insert(chan.get_counterparty_node_id());
                                        }
                                }
-                               channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingSigned {
+
+                               // There's no problem signing a counterparty's funding transaction if our monitor
+                               // hasn't persisted to disk yet - we can't lose money on a transaction that we haven't
+                               // accepted payment from yet. We do, however, need to wait to send our channel_ready
+                               // until we have persisted our monitor.
+                               let new_channel_id = funding_msg.channel_id;
+                               peer_state.pending_msg_events.push(events::MessageSendEvent::SendFundingSigned {
                                        node_id: counterparty_node_id.clone(),
                                        msg: funding_msg,
                                });
-                               if let Some(msg) = channel_ready {
-                                       send_channel_ready!(self, channel_state.pending_msg_events, chan, msg);
+
+                               let monitor_res = self.chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor);
+
+                               let chan = e.insert(chan);
+                               let mut res = handle_new_monitor_update!(self, monitor_res, 0, peer_state_lock, peer_state,
+                                       per_peer_state, chan, MANUALLY_REMOVING, { peer_state.channel_by_id.remove(&new_channel_id) });
+
+                               // Note that we reply with the new channel_id in error messages if we gave up on the
+                               // channel, not the temporary_channel_id. This is compatible with ourselves, but the
+                               // spec is somewhat ambiguous here. Not a huge deal since we'll send error messages for
+                               // any messages referencing a previously-closed channel anyway.
+                               // We do not propagate the monitor update to the user as it would be for a monitor
+                               // that we didn't manage to store (and that we don't care about - we don't respond
+                               // with the funding_signed so the channel can never go on chain).
+                               if let Err(MsgHandleErrInternal { shutdown_finish: Some((res, _)), .. }) = &mut res {
+                                       res.0 = None;
                                }
-                               e.insert(chan);
+                               res
                        }
                }
-               Ok(())
        }
 
        fn internal_funding_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingSigned) -> Result<(), MsgHandleErrInternal> {
-               let funding_tx = {
-                       let best_block = *self.best_block.read().unwrap();
-                       let mut channel_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_lock;
-                       match channel_state.by_id.entry(msg.channel_id) {
-                               hash_map::Entry::Occupied(mut chan) => {
-                                       if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                               return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                                       }
-                                       let (monitor, funding_tx, channel_ready) = match chan.get_mut().funding_signed(&msg, best_block, &self.keys_manager, &self.logger) {
-                                               Ok(update) => update,
-                                               Err(e) => try_chan_entry!(self, Err(e), chan),
-                                       };
-                                       match self.chain_monitor.watch_channel(chan.get().get_funding_txo().unwrap(), monitor) {
-                                               ChannelMonitorUpdateStatus::Completed => {},
-                                               e => {
-                                                       let mut res = handle_monitor_update_res!(self, e, chan, RAACommitmentOrder::RevokeAndACKFirst, channel_ready.is_some(), OPTIONALLY_RESEND_FUNDING_LOCKED);
-                                                       if let Err(MsgHandleErrInternal { ref mut shutdown_finish, .. }) = res {
-                                                               // We weren't able to watch the channel to begin with, so no updates should be made on
-                                                               // it. Previously, full_stack_target found an (unreachable) panic when the
-                                                               // monitor update contained within `shutdown_finish` was applied.
-                                                               if let Some((ref mut shutdown_finish, _)) = shutdown_finish {
-                                                                       shutdown_finish.0.take();
-                                                               }
-                                                       }
-                                                       return res
-                                               },
-                                       }
-                                       if let Some(msg) = channel_ready {
-                                               send_channel_ready!(self, channel_state.pending_msg_events, chan.get(), msg);
+               let best_block = *self.best_block.read().unwrap();
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                       })?;
+
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               match peer_state.channel_by_id.entry(msg.channel_id) {
+                       hash_map::Entry::Occupied(mut chan) => {
+                               let monitor = try_chan_entry!(self,
+                                       chan.get_mut().funding_signed(&msg, best_block, &self.signer_provider, &self.logger), chan);
+                               let update_res = self.chain_monitor.watch_channel(chan.get().get_funding_txo().unwrap(), monitor);
+                               let mut res = handle_new_monitor_update!(self, update_res, 0, peer_state_lock, peer_state, per_peer_state, chan);
+                               if let Err(MsgHandleErrInternal { ref mut shutdown_finish, .. }) = res {
+                                       // We weren't able to watch the channel to begin with, so no updates should be made on
+                                       // it. Previously, full_stack_target found an (unreachable) panic when the
+                                       // monitor update contained within `shutdown_finish` was applied.
+                                       if let Some((ref mut shutdown_finish, _)) = shutdown_finish {
+                                               shutdown_finish.0.take();
                                        }
-                                       funding_tx
-                               },
-                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
-                       }
-               };
-               log_info!(self.logger, "Broadcasting funding transaction with txid {}", funding_tx.txid());
-               self.tx_broadcaster.broadcast_transaction(&funding_tx);
-               Ok(())
+                               }
+                               res
+                       },
+                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+               }
        }
 
        fn internal_channel_ready(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReady) -> Result<(), MsgHandleErrInternal> {
-               let mut channel_state_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_state_lock;
-               match channel_state.by_id.entry(msg.channel_id) {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                       })?;
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               match peer_state.channel_by_id.entry(msg.channel_id) {
                        hash_map::Entry::Occupied(mut chan) => {
-                               if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                       return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                               }
-                               let announcement_sigs_opt = try_chan_entry!(self, chan.get_mut().channel_ready(&msg, self.get_our_node_id(),
-                                       self.genesis_hash.clone(), &self.best_block.read().unwrap(), &self.logger), chan);
+                               let announcement_sigs_opt = try_chan_entry!(self, chan.get_mut().channel_ready(&msg, &self.node_signer,
+                                       self.genesis_hash.clone(), &self.default_configuration, &self.best_block.read().unwrap(), &self.logger), chan);
                                if let Some(announcement_sigs) = announcement_sigs_opt {
                                        log_trace!(self.logger, "Sending announcement_signatures for channel {}", log_bytes!(chan.get().channel_id()));
-                                       channel_state.pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
+                                       peer_state.pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
                                                node_id: counterparty_node_id.clone(),
                                                msg: announcement_sigs,
                                        });
@@ -4255,7 +4617,7 @@ where
                                        // announcement_signatures.
                                        log_trace!(self.logger, "Sending private initial channel_update for our counterparty on channel {}", log_bytes!(chan.get().channel_id()));
                                        if let Ok(msg) = self.get_channel_update_for_unicast(chan.get()) {
-                                               channel_state.pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
+                                               peer_state.pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
                                                        node_id: counterparty_node_id.clone(),
                                                        msg,
                                                });
@@ -4266,21 +4628,23 @@ where
 
                                Ok(())
                        },
-                       hash_map::Entry::Vacant(_) => Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                       hash_map::Entry::Vacant(_) => Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                }
        }
 
-       fn internal_shutdown(&self, counterparty_node_id: &PublicKey, their_features: &InitFeatures, msg: &msgs::Shutdown) -> Result<(), MsgHandleErrInternal> {
+       fn internal_shutdown(&self, counterparty_node_id: &PublicKey, msg: &msgs::Shutdown) -> Result<(), MsgHandleErrInternal> {
                let mut dropped_htlcs: Vec<(HTLCSource, PaymentHash)>;
                let result: Result<(), _> = loop {
-                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_state_lock;
-
-                       match channel_state.by_id.entry(msg.channel_id.clone()) {
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                               .ok_or_else(|| {
+                                       debug_assert!(false);
+                                       MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                               })?;
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       match peer_state.channel_by_id.entry(msg.channel_id.clone()) {
                                hash_map::Entry::Occupied(mut chan_entry) => {
-                                       if chan_entry.get().get_counterparty_node_id() != *counterparty_node_id {
-                                               return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                                       }
 
                                        if !chan_entry.get().received_shutdown() {
                                                log_info!(self.logger, "Received a shutdown message from our counterparty for channel {}{}.",
@@ -4288,30 +4652,30 @@ where
                                                        if chan_entry.get().sent_shutdown() { " after we initiated shutdown" } else { "" });
                                        }
 
-                                       let (shutdown, monitor_update, htlcs) = try_chan_entry!(self, chan_entry.get_mut().shutdown(&self.keys_manager, &their_features, &msg), chan_entry);
+                                       let funding_txo_opt = chan_entry.get().get_funding_txo();
+                                       let (shutdown, monitor_update_opt, htlcs) = try_chan_entry!(self,
+                                               chan_entry.get_mut().shutdown(&self.signer_provider, &peer_state.latest_features, &msg), chan_entry);
                                        dropped_htlcs = htlcs;
 
-                                       // Update the monitor with the shutdown script if necessary.
-                                       if let Some(monitor_update) = monitor_update {
-                                               let update_res = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update);
-                                               let (result, is_permanent) =
-                                                       handle_monitor_update_res!(self, update_res, chan_entry.get_mut(), RAACommitmentOrder::CommitmentFirst, chan_entry.key(), NO_UPDATE);
-                                               if is_permanent {
-                                                       remove_channel!(self, chan_entry);
-                                                       break result;
-                                               }
-                                       }
-
                                        if let Some(msg) = shutdown {
-                                               channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
+                                               // We can send the `shutdown` message before updating the `ChannelMonitor`
+                                               // here as we don't need the monitor update to complete until we send a
+                                               // `shutdown_signed`, which we'll delay if we're pending a monitor update.
+                                               peer_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
                                                        node_id: *counterparty_node_id,
                                                        msg,
                                                });
                                        }
 
+                                       // Update the monitor with the shutdown script if necessary.
+                                       if let Some(monitor_update) = monitor_update_opt {
+                                               let update_id = monitor_update.update_id;
+                                               let update_res = self.chain_monitor.update_channel(funding_txo_opt.unwrap(), monitor_update);
+                                               break handle_new_monitor_update!(self, update_res, update_id, peer_state_lock, peer_state, per_peer_state, chan_entry);
+                                       }
                                        break Ok(());
                                },
-                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                        }
                };
                for htlc_source in dropped_htlcs.drain(..) {
@@ -4320,22 +4684,24 @@ where
                        self.fail_htlc_backwards_internal(&htlc_source.0, &htlc_source.1, &reason, receiver);
                }
 
-               let _ = handle_error!(self, result, *counterparty_node_id);
-               Ok(())
+               result
        }
 
        fn internal_closing_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::ClosingSigned) -> Result<(), MsgHandleErrInternal> {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                       })?;
                let (tx, chan_option) = {
-                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_state_lock;
-                       match channel_state.by_id.entry(msg.channel_id.clone()) {
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       match peer_state.channel_by_id.entry(msg.channel_id.clone()) {
                                hash_map::Entry::Occupied(mut chan_entry) => {
-                                       if chan_entry.get().get_counterparty_node_id() != *counterparty_node_id {
-                                               return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                                       }
                                        let (closing_signed, tx) = try_chan_entry!(self, chan_entry.get_mut().closing_signed(&self.fee_estimator, &msg), chan_entry);
                                        if let Some(msg) = closing_signed {
-                                               channel_state.pending_msg_events.push(events::MessageSendEvent::SendClosingSigned {
+                                               peer_state.pending_msg_events.push(events::MessageSendEvent::SendClosingSigned {
                                                        node_id: counterparty_node_id.clone(),
                                                        msg,
                                                });
@@ -4349,7 +4715,7 @@ where
                                                (tx, Some(remove_channel!(self, chan_entry)))
                                        } else { (tx, None) }
                                },
-                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                        }
                };
                if let Some(broadcast_tx) = tx {
@@ -4358,8 +4724,9 @@ where
                }
                if let Some(chan) = chan_option {
                        if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
-                               let mut channel_state = self.channel_state.lock().unwrap();
-                               channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
+                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
                                        msg: update
                                });
                        }
@@ -4379,16 +4746,18 @@ where
                //but we should prevent it anyway.
 
                let pending_forward_info = self.decode_update_add_htlc_onion(msg);
-               let mut channel_state_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_state_lock;
-
-               match channel_state.by_id.entry(msg.channel_id) {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                       })?;
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               match peer_state.channel_by_id.entry(msg.channel_id) {
                        hash_map::Entry::Occupied(mut chan) => {
-                               if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                       return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                               }
 
-                               let create_pending_htlc_status = |chan: &Channel<<K::Target as SignerProvider>::Signer>, pending_forward_info: PendingHTLCStatus, error_code: u16| {
+                               let create_pending_htlc_status = |chan: &Channel<<SP::Target as SignerProvider>::Signer>, pending_forward_info: PendingHTLCStatus, error_code: u16| {
                                        // If the update_add is completely bogus, the call will Err and we will close,
                                        // but if we've sent a shutdown and they haven't acknowledged it yet, we just
                                        // want to reject the new HTLC and fail it backwards instead of forwarding.
@@ -4412,52 +4781,61 @@ where
                                };
                                try_chan_entry!(self, chan.get_mut().update_add_htlc(&msg, pending_forward_info, create_pending_htlc_status, &self.logger), chan);
                        },
-                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                }
                Ok(())
        }
 
        fn internal_update_fulfill_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFulfillHTLC) -> Result<(), MsgHandleErrInternal> {
-               let mut channel_lock = self.channel_state.lock().unwrap();
                let (htlc_source, forwarded_htlc_value) = {
-                       let channel_state = &mut *channel_lock;
-                       match channel_state.by_id.entry(msg.channel_id) {
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                               .ok_or_else(|| {
+                                       debug_assert!(false);
+                                       MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                               })?;
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       match peer_state.channel_by_id.entry(msg.channel_id) {
                                hash_map::Entry::Occupied(mut chan) => {
-                                       if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                               return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                                       }
                                        try_chan_entry!(self, chan.get_mut().update_fulfill_htlc(&msg), chan)
                                },
-                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                        }
                };
-               self.claim_funds_internal(channel_lock, htlc_source, msg.payment_preimage.clone(), Some(forwarded_htlc_value), false, msg.channel_id);
+               self.claim_funds_internal(htlc_source, msg.payment_preimage.clone(), Some(forwarded_htlc_value), false, msg.channel_id);
                Ok(())
        }
 
        fn internal_update_fail_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<(), MsgHandleErrInternal> {
-               let mut channel_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_lock;
-               match channel_state.by_id.entry(msg.channel_id) {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                       })?;
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               match peer_state.channel_by_id.entry(msg.channel_id) {
                        hash_map::Entry::Occupied(mut chan) => {
-                               if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                       return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                               }
                                try_chan_entry!(self, chan.get_mut().update_fail_htlc(&msg, HTLCFailReason::from_msg(msg)), chan);
                        },
-                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                }
                Ok(())
        }
 
        fn internal_update_fail_malformed_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFailMalformedHTLC) -> Result<(), MsgHandleErrInternal> {
-               let mut channel_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_lock;
-               match channel_state.by_id.entry(msg.channel_id) {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                       })?;
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               match peer_state.channel_by_id.entry(msg.channel_id) {
                        hash_map::Entry::Occupied(mut chan) => {
-                               if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                       return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                               }
                                if (msg.failure_code & 0x8000) == 0 {
                                        let chan_err: ChannelError = ChannelError::Close("Got update_fail_malformed_htlc with BADONION not set".to_owned());
                                        try_chan_entry!(self, Err(chan_err), chan);
@@ -4465,61 +4843,36 @@ where
                                try_chan_entry!(self, chan.get_mut().update_fail_malformed_htlc(&msg, HTLCFailReason::reason(msg.failure_code, msg.sha256_of_onion.to_vec())), chan);
                                Ok(())
                        },
-                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                }
        }
 
        fn internal_commitment_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::CommitmentSigned) -> Result<(), MsgHandleErrInternal> {
-               let mut channel_state_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_state_lock;
-               match channel_state.by_id.entry(msg.channel_id) {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                       })?;
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               match peer_state.channel_by_id.entry(msg.channel_id) {
                        hash_map::Entry::Occupied(mut chan) => {
-                               if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                       return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                               }
-                               let (revoke_and_ack, commitment_signed, monitor_update) =
-                                       match chan.get_mut().commitment_signed(&msg, &self.logger) {
-                                               Err((None, e)) => try_chan_entry!(self, Err(e), chan),
-                                               Err((Some(update), e)) => {
-                                                       assert!(chan.get().is_awaiting_monitor_update());
-                                                       let _ = self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), update);
-                                                       try_chan_entry!(self, Err(e), chan);
-                                                       unreachable!();
-                                               },
-                                               Ok(res) => res
-                                       };
-                               let update_res = self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), monitor_update);
-                               if let Err(e) = handle_monitor_update_res!(self, update_res, chan, RAACommitmentOrder::RevokeAndACKFirst, true, commitment_signed.is_some()) {
-                                       return Err(e);
-                               }
-
-                               channel_state.pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK {
-                                       node_id: counterparty_node_id.clone(),
-                                       msg: revoke_and_ack,
-                               });
-                               if let Some(msg) = commitment_signed {
-                                       channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
-                                               node_id: counterparty_node_id.clone(),
-                                               updates: msgs::CommitmentUpdate {
-                                                       update_add_htlcs: Vec::new(),
-                                                       update_fulfill_htlcs: Vec::new(),
-                                                       update_fail_htlcs: Vec::new(),
-                                                       update_fail_malformed_htlcs: Vec::new(),
-                                                       update_fee: None,
-                                                       commitment_signed: msg,
-                                               },
-                                       });
-                               }
-                               Ok(())
+                               let funding_txo = chan.get().get_funding_txo();
+                               let monitor_update = try_chan_entry!(self, chan.get_mut().commitment_signed(&msg, &self.logger), chan);
+                               let update_res = self.chain_monitor.update_channel(funding_txo.unwrap(), monitor_update);
+                               let update_id = monitor_update.update_id;
+                               handle_new_monitor_update!(self, update_res, update_id, peer_state_lock,
+                                       peer_state, per_peer_state, chan)
                        },
-                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                }
        }
 
        #[inline]
        fn forward_htlcs(&self, per_source_pending_forwards: &mut [(u64, OutPoint, u128, Vec<(PendingHTLCInfo, u64)>)]) {
                for &mut (prev_short_channel_id, prev_funding_outpoint, prev_user_channel_id, ref mut pending_forwards) in per_source_pending_forwards {
-                       let mut forward_event = None;
+                       let mut push_forward_event = false;
                        let mut new_intercept_events = Vec::new();
                        let mut failed_intercept_forwards = Vec::new();
                        if !pending_forwards.is_empty() {
@@ -4577,7 +4930,7 @@ where
                                                                // We don't want to generate a PendingHTLCsForwardable event if only intercepted
                                                                // payments are being processed.
                                                                if forward_htlcs_empty {
-                                                                       forward_event = Some(Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS));
+                                                                       push_forward_event = true;
                                                                }
                                                                entry.insert(vec!(HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
                                                                        prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, prev_user_channel_id, forward_info })));
@@ -4595,137 +4948,115 @@ where
                                let mut events = self.pending_events.lock().unwrap();
                                events.append(&mut new_intercept_events);
                        }
+                       if push_forward_event { self.push_pending_forwards_ev() }
+               }
+       }
 
-                       match forward_event {
-                               Some(time) => {
-                                       let mut pending_events = self.pending_events.lock().unwrap();
-                                       pending_events.push(events::Event::PendingHTLCsForwardable {
-                                               time_forwardable: time
-                                       });
-                               }
-                               None => {},
-                       }
+       // We only want to push a PendingHTLCsForwardable event if no others are queued.
+       fn push_pending_forwards_ev(&self) {
+               let mut pending_events = self.pending_events.lock().unwrap();
+               let forward_ev_exists = pending_events.iter()
+                       .find(|ev| if let events::Event::PendingHTLCsForwardable { .. } = ev { true } else { false })
+                       .is_some();
+               if !forward_ev_exists {
+                       pending_events.push(events::Event::PendingHTLCsForwardable {
+                               time_forwardable:
+                                       Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS),
+                       });
                }
        }
 
        fn internal_revoke_and_ack(&self, counterparty_node_id: &PublicKey, msg: &msgs::RevokeAndACK) -> Result<(), MsgHandleErrInternal> {
-               let mut htlcs_to_fail = Vec::new();
-               let res = loop {
-                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_state_lock;
-                       match channel_state.by_id.entry(msg.channel_id) {
+               let (htlcs_to_fail, res) = {
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       let mut peer_state_lock = per_peer_state.get(counterparty_node_id)
+                               .ok_or_else(|| {
+                                       debug_assert!(false);
+                                       MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                               }).map(|mtx| mtx.lock().unwrap())?;
+                       let peer_state = &mut *peer_state_lock;
+                       match peer_state.channel_by_id.entry(msg.channel_id) {
                                hash_map::Entry::Occupied(mut chan) => {
-                                       if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                               break Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                                       }
-                                       let was_paused_for_mon_update = chan.get().is_awaiting_monitor_update();
-                                       let raa_updates = break_chan_entry!(self,
-                                               chan.get_mut().revoke_and_ack(&msg, &self.logger), chan);
-                                       htlcs_to_fail = raa_updates.holding_cell_failed_htlcs;
-                                       let update_res = self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), raa_updates.monitor_update);
-                                       if was_paused_for_mon_update {
-                                               assert!(update_res != ChannelMonitorUpdateStatus::Completed);
-                                               assert!(raa_updates.commitment_update.is_none());
-                                               assert!(raa_updates.accepted_htlcs.is_empty());
-                                               assert!(raa_updates.failed_htlcs.is_empty());
-                                               assert!(raa_updates.finalized_claimed_htlcs.is_empty());
-                                               break Err(MsgHandleErrInternal::ignore_no_close("Existing pending monitor update prevented responses to RAA".to_owned()));
-                                       }
-                                       if update_res != ChannelMonitorUpdateStatus::Completed {
-                                               if let Err(e) = handle_monitor_update_res!(self, update_res, chan,
-                                                               RAACommitmentOrder::CommitmentFirst, false,
-                                                               raa_updates.commitment_update.is_some(), false,
-                                                               raa_updates.accepted_htlcs, raa_updates.failed_htlcs,
-                                                               raa_updates.finalized_claimed_htlcs) {
-                                                       break Err(e);
-                                               } else { unreachable!(); }
-                                       }
-                                       if let Some(updates) = raa_updates.commitment_update {
-                                               channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
-                                                       node_id: counterparty_node_id.clone(),
-                                                       updates,
-                                               });
-                                       }
-                                       break Ok((raa_updates.accepted_htlcs, raa_updates.failed_htlcs,
-                                                       raa_updates.finalized_claimed_htlcs,
-                                                       chan.get().get_short_channel_id()
-                                                               .unwrap_or(chan.get().outbound_scid_alias()),
-                                                       chan.get().get_funding_txo().unwrap(),
-                                                       chan.get().get_user_id()))
+                                       let funding_txo = chan.get().get_funding_txo();
+                                       let (htlcs_to_fail, monitor_update) = try_chan_entry!(self, chan.get_mut().revoke_and_ack(&msg, &self.logger), chan);
+                                       let update_res = self.chain_monitor.update_channel(funding_txo.unwrap(), monitor_update);
+                                       let update_id = monitor_update.update_id;
+                                       let res = handle_new_monitor_update!(self, update_res, update_id,
+                                               peer_state_lock, peer_state, per_peer_state, chan);
+                                       (htlcs_to_fail, res)
                                },
-                               hash_map::Entry::Vacant(_) => break Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                        }
                };
                self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id, counterparty_node_id);
-               match res {
-                       Ok((pending_forwards, mut pending_failures, finalized_claim_htlcs,
-                               short_channel_id, channel_outpoint, user_channel_id)) =>
-                       {
-                               for failure in pending_failures.drain(..) {
-                                       let receiver = HTLCDestination::NextHopChannel { node_id: Some(*counterparty_node_id), channel_id: channel_outpoint.to_channel_id() };
-                                       self.fail_htlc_backwards_internal(&failure.0, &failure.1, &failure.2, receiver);
-                               }
-                               self.forward_htlcs(&mut [(short_channel_id, channel_outpoint, user_channel_id, pending_forwards)]);
-                               self.finalize_claims(finalized_claim_htlcs);
-                               Ok(())
-                       },
-                       Err(e) => Err(e)
-               }
+               res
        }
 
        fn internal_update_fee(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFee) -> Result<(), MsgHandleErrInternal> {
-               let mut channel_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_lock;
-               match channel_state.by_id.entry(msg.channel_id) {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                       })?;
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               match peer_state.channel_by_id.entry(msg.channel_id) {
                        hash_map::Entry::Occupied(mut chan) => {
-                               if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                       return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                               }
                                try_chan_entry!(self, chan.get_mut().update_fee(&self.fee_estimator, &msg, &self.logger), chan);
                        },
-                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                }
                Ok(())
        }
 
        fn internal_announcement_signatures(&self, counterparty_node_id: &PublicKey, msg: &msgs::AnnouncementSignatures) -> Result<(), MsgHandleErrInternal> {
-               let mut channel_state_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_state_lock;
-
-               match channel_state.by_id.entry(msg.channel_id) {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                       .ok_or_else(|| {
+                               debug_assert!(false);
+                               MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                       })?;
+               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               match peer_state.channel_by_id.entry(msg.channel_id) {
                        hash_map::Entry::Occupied(mut chan) => {
-                               if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                       return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                               }
                                if !chan.get().is_usable() {
                                        return Err(MsgHandleErrInternal::from_no_close(LightningError{err: "Got an announcement_signatures before we were ready for it".to_owned(), action: msgs::ErrorAction::IgnoreError}));
                                }
 
-                               channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
+                               peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
                                        msg: try_chan_entry!(self, chan.get_mut().announcement_signatures(
-                                               self.get_our_node_id(), self.genesis_hash.clone(), self.best_block.read().unwrap().height(), msg), chan),
+                                               &self.node_signer, self.genesis_hash.clone(), self.best_block.read().unwrap().height(),
+                                               msg, &self.default_configuration
+                                       ), chan),
                                        // Note that announcement_signatures fails if the channel cannot be announced,
                                        // so get_channel_update_for_broadcast will never fail by the time we get here.
-                                       update_msg: self.get_channel_update_for_broadcast(chan.get()).unwrap(),
+                                       update_msg: Some(self.get_channel_update_for_broadcast(chan.get()).unwrap()),
                                });
                        },
-                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                       hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                }
                Ok(())
        }
 
        /// Returns ShouldPersist if anything changed, otherwise either SkipPersist or an Err.
        fn internal_channel_update(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelUpdate) -> Result<NotifyOption, MsgHandleErrInternal> {
-               let chan_id = match self.short_to_chan_info.read().unwrap().get(&msg.contents.short_channel_id) {
-                       Some((_cp_id, chan_id)) => chan_id.clone(),
+               let (chan_counterparty_node_id, chan_id) = match self.short_to_chan_info.read().unwrap().get(&msg.contents.short_channel_id) {
+                       Some((cp_id, chan_id)) => (cp_id.clone(), chan_id.clone()),
                        None => {
                                // It's not a local channel
                                return Ok(NotifyOption::SkipPersist)
                        }
                };
-               let mut channel_state_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_state_lock;
-               match channel_state.by_id.entry(chan_id) {
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               let peer_state_mutex_opt = per_peer_state.get(&chan_counterparty_node_id);
+               if peer_state_mutex_opt.is_none() {
+                       return Ok(NotifyOption::SkipPersist)
+               }
+               let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
+               let peer_state = &mut *peer_state_lock;
+               match peer_state.channel_by_id.entry(chan_id) {
                        hash_map::Entry::Occupied(mut chan) => {
                                if chan.get().get_counterparty_node_id() != *counterparty_node_id {
                                        if chan.get().should_announce() {
@@ -4753,24 +5084,27 @@ where
        fn internal_channel_reestablish(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), MsgHandleErrInternal> {
                let htlc_forwards;
                let need_lnd_workaround = {
-                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_state_lock;
+                       let per_peer_state = self.per_peer_state.read().unwrap();
 
-                       match channel_state.by_id.entry(msg.channel_id) {
+                       let peer_state_mutex = per_peer_state.get(counterparty_node_id)
+                               .ok_or_else(|| {
+                                       debug_assert!(false);
+                                       MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
+                               })?;
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       match peer_state.channel_by_id.entry(msg.channel_id) {
                                hash_map::Entry::Occupied(mut chan) => {
-                                       if chan.get().get_counterparty_node_id() != *counterparty_node_id {
-                                               return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
-                                       }
                                        // Currently, we expect all holding cell update_adds to be dropped on peer
                                        // disconnect, so Channel's reestablish will never hand us any holding cell
                                        // freed HTLCs to fail backwards. If in the future we no longer drop pending
                                        // add-HTLCs on disconnect, we may be handed HTLCs to fail backwards here.
                                        let responses = try_chan_entry!(self, chan.get_mut().channel_reestablish(
-                                               msg, &self.logger, self.our_network_pubkey.clone(), self.genesis_hash,
-                                               &*self.best_block.read().unwrap()), chan);
+                                               msg, &self.logger, &self.node_signer, self.genesis_hash,
+                                               &self.default_configuration, &*self.best_block.read().unwrap()), chan);
                                        let mut channel_update = None;
                                        if let Some(msg) = responses.shutdown_msg {
-                                               channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
+                                               peer_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
                                                        node_id: counterparty_node_id.clone(),
                                                        msg,
                                                });
@@ -4787,14 +5121,14 @@ where
                                        }
                                        let need_lnd_workaround = chan.get_mut().workaround_lnd_bug_4006.take();
                                        htlc_forwards = self.handle_channel_resumption(
-                                               &mut channel_state.pending_msg_events, chan.get_mut(), responses.raa, responses.commitment_update, responses.order,
+                                               &mut peer_state.pending_msg_events, chan.get_mut(), responses.raa, responses.commitment_update, responses.order,
                                                Vec::new(), None, responses.channel_ready, responses.announcement_sigs);
                                        if let Some(upd) = channel_update {
-                                               channel_state.pending_msg_events.push(upd);
+                                               peer_state.pending_msg_events.push(upd);
                                        }
                                        need_lnd_workaround
                                },
-                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
+                               hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
                        }
                };
 
@@ -4810,6 +5144,8 @@ where
 
        /// Process pending events from the `chain::Watch`, returning whether any events were processed.
        fn process_pending_monitor_events(&self) -> bool {
+               debug_assert!(self.total_consistency_lock.try_write().is_err()); // Caller holds read lock
+
                let mut failed_channels = Vec::new();
                let mut pending_monitor_events = self.chain_monitor.release_pending_monitor_events();
                let has_pending_monitor_events = !pending_monitor_events.is_empty();
@@ -4819,7 +5155,7 @@ where
                                        MonitorEvent::HTLCEvent(htlc_update) => {
                                                if let Some(preimage) = htlc_update.payment_preimage {
                                                        log_trace!(self.logger, "Claiming HTLC with preimage {} from our monitor", log_bytes!(preimage.0));
-                                                       self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage, htlc_update.htlc_value_satoshis.map(|v| v * 1000), true, funding_outpoint.to_channel_id());
+                                                       self.claim_funds_internal(htlc_update.source, preimage, htlc_update.htlc_value_satoshis.map(|v| v * 1000), true, funding_outpoint.to_channel_id());
                                                } else {
                                                        log_trace!(self.logger, "Failing HTLC with hash {} from our monitor", log_bytes!(htlc_update.payment_hash.0));
                                                        let receiver = HTLCDestination::NextHopChannel { node_id: counterparty_node_id, channel_id: funding_outpoint.to_channel_id() };
@@ -4829,34 +5165,47 @@ where
                                        },
                                        MonitorEvent::CommitmentTxConfirmed(funding_outpoint) |
                                        MonitorEvent::UpdateFailed(funding_outpoint) => {
-                                               let mut channel_lock = self.channel_state.lock().unwrap();
-                                               let channel_state = &mut *channel_lock;
-                                               let by_id = &mut channel_state.by_id;
-                                               let pending_msg_events = &mut channel_state.pending_msg_events;
-                                               if let hash_map::Entry::Occupied(chan_entry) = by_id.entry(funding_outpoint.to_channel_id()) {
-                                                       let mut chan = remove_channel!(self, chan_entry);
-                                                       failed_channels.push(chan.force_shutdown(false));
-                                                       if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
-                                                               pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
-                                                                       msg: update
-                                                               });
+                                               let counterparty_node_id_opt = match counterparty_node_id {
+                                                       Some(cp_id) => Some(cp_id),
+                                                       None => {
+                                                               // TODO: Once we can rely on the counterparty_node_id from the
+                                                               // monitor event, this and the id_to_peer map should be removed.
+                                                               let id_to_peer = self.id_to_peer.lock().unwrap();
+                                                               id_to_peer.get(&funding_outpoint.to_channel_id()).cloned()
+                                                       }
+                                               };
+                                               if let Some(counterparty_node_id) = counterparty_node_id_opt {
+                                                       let per_peer_state = self.per_peer_state.read().unwrap();
+                                                       if let Some(peer_state_mutex) = per_peer_state.get(&counterparty_node_id) {
+                                                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                                                               let peer_state = &mut *peer_state_lock;
+                                                               let pending_msg_events = &mut peer_state.pending_msg_events;
+                                                               if let hash_map::Entry::Occupied(chan_entry) = peer_state.channel_by_id.entry(funding_outpoint.to_channel_id()) {
+                                                                       let mut chan = remove_channel!(self, chan_entry);
+                                                                       failed_channels.push(chan.force_shutdown(false));
+                                                                       if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
+                                                                               pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
+                                                                                       msg: update
+                                                                               });
+                                                                       }
+                                                                       let reason = if let MonitorEvent::UpdateFailed(_) = monitor_event {
+                                                                               ClosureReason::ProcessingError { err: "Failed to persist ChannelMonitor update during chain sync".to_string() }
+                                                                       } else {
+                                                                               ClosureReason::CommitmentTxConfirmed
+                                                                       };
+                                                                       self.issue_channel_close_events(&chan, reason);
+                                                                       pending_msg_events.push(events::MessageSendEvent::HandleError {
+                                                                               node_id: chan.get_counterparty_node_id(),
+                                                                               action: msgs::ErrorAction::SendErrorMessage {
+                                                                                       msg: msgs::ErrorMessage { channel_id: chan.channel_id(), data: "Channel force-closed".to_owned() }
+                                                                               },
+                                                                       });
+                                                               }
                                                        }
-                                                       let reason = if let MonitorEvent::UpdateFailed(_) = monitor_event {
-                                                               ClosureReason::ProcessingError { err: "Failed to persist ChannelMonitor update during chain sync".to_string() }
-                                                       } else {
-                                                               ClosureReason::CommitmentTxConfirmed
-                                                       };
-                                                       self.issue_channel_close_events(&chan, reason);
-                                                       pending_msg_events.push(events::MessageSendEvent::HandleError {
-                                                               node_id: chan.get_counterparty_node_id(),
-                                                               action: msgs::ErrorAction::SendErrorMessage {
-                                                                       msg: msgs::ErrorMessage { channel_id: chan.channel_id(), data: "Channel force-closed".to_owned() }
-                                                               },
-                                                       });
                                                }
                                        },
                                        MonitorEvent::Completed { funding_txo, monitor_update_id } => {
-                                               self.channel_monitor_updated(&funding_txo, monitor_update_id);
+                                               self.channel_monitor_updated(&funding_txo, monitor_update_id, counterparty_node_id.as_ref());
                                        },
                                }
                        }
@@ -4874,7 +5223,13 @@ where
        /// update events as a separate process method here.
        #[cfg(fuzzing)]
        pub fn process_monitor_events(&self) {
-               self.process_pending_monitor_events();
+               PersistenceNotifierGuard::optionally_notify(&self.total_consistency_lock, &self.persistence_notifier, || {
+                       if self.process_pending_monitor_events() {
+                               NotifyOption::DoPersist
+                       } else {
+                               NotifyOption::SkipPersist
+                       }
+               });
        }
 
        /// Check the holding cell in each channel and free any pending HTLCs in them if possible.
@@ -4884,48 +5239,45 @@ where
                let mut has_monitor_update = false;
                let mut failed_htlcs = Vec::new();
                let mut handle_errors = Vec::new();
-               {
-                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_state_lock;
-                       let by_id = &mut channel_state.by_id;
-                       let pending_msg_events = &mut channel_state.pending_msg_events;
-
-                       by_id.retain(|channel_id, chan| {
-                               match chan.maybe_free_holding_cell_htlcs(&self.logger) {
-                                       Ok((commitment_opt, holding_cell_failed_htlcs)) => {
+
+               // Walk our list of channels and find any that need to update. Note that when we do find an
+               // update, if it includes actions that must be taken afterwards, we have to drop the
+               // per-peer state lock as well as the top level per_peer_state lock. Thus, we loop until we
+               // manage to go through all our peers without finding a single channel to update.
+               'peer_loop: loop {
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       for (_cp_id, peer_state_mutex) in per_peer_state.iter() {
+                               'chan_loop: loop {
+                                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                                       let peer_state: &mut PeerState<_> = &mut *peer_state_lock;
+                                       for (channel_id, chan) in peer_state.channel_by_id.iter_mut() {
+                                               let counterparty_node_id = chan.get_counterparty_node_id();
+                                               let funding_txo = chan.get_funding_txo();
+                                               let (monitor_opt, holding_cell_failed_htlcs) =
+                                                       chan.maybe_free_holding_cell_htlcs(&self.logger);
                                                if !holding_cell_failed_htlcs.is_empty() {
-                                                       failed_htlcs.push((
-                                                               holding_cell_failed_htlcs,
-                                                               *channel_id,
-                                                               chan.get_counterparty_node_id()
-                                                       ));
+                                                       failed_htlcs.push((holding_cell_failed_htlcs, *channel_id, counterparty_node_id));
                                                }
-                                               if let Some((commitment_update, monitor_update)) = commitment_opt {
-                                                       match self.chain_monitor.update_channel(chan.get_funding_txo().unwrap(), monitor_update) {
-                                                               ChannelMonitorUpdateStatus::Completed => {
-                                                                       pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
-                                                                               node_id: chan.get_counterparty_node_id(),
-                                                                               updates: commitment_update,
-                                                                       });
-                                                               },
-                                                               e => {
-                                                                       has_monitor_update = true;
-                                                                       let (res, close_channel) = handle_monitor_update_res!(self, e, chan, RAACommitmentOrder::CommitmentFirst, channel_id, COMMITMENT_UPDATE_ONLY);
-                                                                       handle_errors.push((chan.get_counterparty_node_id(), res));
-                                                                       if close_channel { return false; }
-                                                               },
+                                               if let Some(monitor_update) = monitor_opt {
+                                                       has_monitor_update = true;
+
+                                                       let update_res = self.chain_monitor.update_channel(
+                                                               funding_txo.expect("channel is live"), monitor_update);
+                                                       let update_id = monitor_update.update_id;
+                                                       let channel_id: [u8; 32] = *channel_id;
+                                                       let res = handle_new_monitor_update!(self, update_res, update_id,
+                                                               peer_state_lock, peer_state, per_peer_state, chan, MANUALLY_REMOVING,
+                                                               peer_state.channel_by_id.remove(&channel_id));
+                                                       if res.is_err() {
+                                                               handle_errors.push((counterparty_node_id, res));
                                                        }
+                                                       continue 'peer_loop;
                                                }
-                                               true
-                                       },
-                                       Err(e) => {
-                                               let (close_channel, res) = convert_chan_err!(self, e, chan, channel_id);
-                                               handle_errors.push((chan.get_counterparty_node_id(), Err(res)));
-                                               // ChannelClosed event is generated by handle_error for us
-                                               !close_channel
                                        }
+                                       break 'chan_loop;
                                }
-                       });
+                       }
+                       break 'peer_loop;
                }
 
                let has_update = has_monitor_update || !failed_htlcs.is_empty() || !handle_errors.is_empty();
@@ -4947,45 +5299,47 @@ where
                let mut handle_errors: Vec<(PublicKey, Result<(), _>)> = Vec::new();
                let mut has_update = false;
                {
-                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_state_lock;
-                       let by_id = &mut channel_state.by_id;
-                       let pending_msg_events = &mut channel_state.pending_msg_events;
-
-                       by_id.retain(|channel_id, chan| {
-                               match chan.maybe_propose_closing_signed(&self.fee_estimator, &self.logger) {
-                                       Ok((msg_opt, tx_opt)) => {
-                                               if let Some(msg) = msg_opt {
-                                                       has_update = true;
-                                                       pending_msg_events.push(events::MessageSendEvent::SendClosingSigned {
-                                                               node_id: chan.get_counterparty_node_id(), msg,
-                                                       });
-                                               }
-                                               if let Some(tx) = tx_opt {
-                                                       // We're done with this channel. We got a closing_signed and sent back
-                                                       // a closing_signed with a closing transaction to broadcast.
-                                                       if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
-                                                               pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
-                                                                       msg: update
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+
+                       for (_cp_id, peer_state_mutex) in per_peer_state.iter() {
+                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               let pending_msg_events = &mut peer_state.pending_msg_events;
+                               peer_state.channel_by_id.retain(|channel_id, chan| {
+                                       match chan.maybe_propose_closing_signed(&self.fee_estimator, &self.logger) {
+                                               Ok((msg_opt, tx_opt)) => {
+                                                       if let Some(msg) = msg_opt {
+                                                               has_update = true;
+                                                               pending_msg_events.push(events::MessageSendEvent::SendClosingSigned {
+                                                                       node_id: chan.get_counterparty_node_id(), msg,
                                                                });
                                                        }
+                                                       if let Some(tx) = tx_opt {
+                                                               // We're done with this channel. We got a closing_signed and sent back
+                                                               // a closing_signed with a closing transaction to broadcast.
+                                                               if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
+                                                                       pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
+                                                                               msg: update
+                                                                       });
+                                                               }
 
-                                                       self.issue_channel_close_events(chan, ClosureReason::CooperativeClosure);
+                                                               self.issue_channel_close_events(chan, ClosureReason::CooperativeClosure);
 
-                                                       log_info!(self.logger, "Broadcasting {}", log_tx!(tx));
-                                                       self.tx_broadcaster.broadcast_transaction(&tx);
-                                                       update_maps_on_chan_removal!(self, chan);
-                                                       false
-                                               } else { true }
-                                       },
-                                       Err(e) => {
-                                               has_update = true;
-                                               let (close_channel, res) = convert_chan_err!(self, e, chan, channel_id);
-                                               handle_errors.push((chan.get_counterparty_node_id(), Err(res)));
-                                               !close_channel
+                                                               log_info!(self.logger, "Broadcasting {}", log_tx!(tx));
+                                                               self.tx_broadcaster.broadcast_transaction(&tx);
+                                                               update_maps_on_chan_removal!(self, chan);
+                                                               false
+                                                       } else { true }
+                                               },
+                                               Err(e) => {
+                                                       has_update = true;
+                                                       let (close_channel, res) = convert_chan_err!(self, e, chan, channel_id);
+                                                       handle_errors.push((chan.get_counterparty_node_id(), Err(res)));
+                                                       !close_channel
+                                               }
                                        }
-                               }
-                       });
+                               });
+                       }
                }
 
                for (counterparty_node_id, err) in handle_errors.drain(..) {
@@ -5025,7 +5379,7 @@ where
                        return Err(APIError::APIMisuseError { err: format!("min_value_msat of {} greater than total 21 million bitcoin supply", min_value_msat.unwrap()) });
                }
 
-               let payment_secret = PaymentSecret(self.keys_manager.get_secure_random_bytes());
+               let payment_secret = PaymentSecret(self.entropy_source.get_secure_random_bytes());
 
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
                let mut payment_secrets = self.pending_inbound_payments.lock().unwrap();
@@ -5056,7 +5410,8 @@ where
        /// [`PaymentHash`] and [`PaymentPreimage`] for you.
        ///
        /// The [`PaymentPreimage`] will ultimately be returned to you in the [`PaymentClaimable`], which
-       /// will have the [`PaymentClaimable::payment_preimage`] field filled in. That should then be
+       /// will have the [`PaymentClaimable::purpose`] be [`PaymentPurpose::InvoicePayment`] with
+       /// its [`PaymentPurpose::InvoicePayment::payment_preimage`] field filled in. That should then be
        /// passed directly to [`claim_funds`].
        ///
        /// See [`create_inbound_payment_for_hash`] for detailed documentation on behavior and requirements.
@@ -5071,12 +5426,20 @@ where
        ///
        /// Errors if `min_value_msat` is greater than total bitcoin supply.
        ///
+       /// If `min_final_cltv_expiry_delta` is set to some value, then the payment will not be receivable
+       /// on versions of LDK prior to 0.0.114.
+       ///
        /// [`claim_funds`]: Self::claim_funds
        /// [`PaymentClaimable`]: events::Event::PaymentClaimable
-       /// [`PaymentClaimable::payment_preimage`]: events::Event::PaymentClaimable::payment_preimage
+       /// [`PaymentClaimable::purpose`]: events::Event::PaymentClaimable::purpose
+       /// [`PaymentPurpose::InvoicePayment`]: events::PaymentPurpose::InvoicePayment
+       /// [`PaymentPurpose::InvoicePayment::payment_preimage`]: events::PaymentPurpose::InvoicePayment::payment_preimage
        /// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
-       pub fn create_inbound_payment(&self, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32) -> Result<(PaymentHash, PaymentSecret), ()> {
-               inbound_payment::create(&self.inbound_payment_key, min_value_msat, invoice_expiry_delta_secs, &self.keys_manager, self.highest_seen_timestamp.load(Ordering::Acquire) as u64)
+       pub fn create_inbound_payment(&self, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32,
+               min_final_cltv_expiry_delta: Option<u16>) -> Result<(PaymentHash, PaymentSecret), ()> {
+               inbound_payment::create(&self.inbound_payment_key, min_value_msat, invoice_expiry_delta_secs,
+                       &self.entropy_source, self.highest_seen_timestamp.load(Ordering::Acquire) as u64,
+                       min_final_cltv_expiry_delta)
        }
 
        /// Legacy version of [`create_inbound_payment`]. Use this method if you wish to share
@@ -5090,7 +5453,7 @@ where
        /// [`create_inbound_payment`]: Self::create_inbound_payment
        #[deprecated]
        pub fn create_inbound_payment_legacy(&self, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32) -> Result<(PaymentHash, PaymentSecret), APIError> {
-               let payment_preimage = PaymentPreimage(self.keys_manager.get_secure_random_bytes());
+               let payment_preimage = PaymentPreimage(self.entropy_source.get_secure_random_bytes());
                let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
                let payment_secret = self.set_payment_hash_secret_map(payment_hash, Some(payment_preimage), min_value_msat, invoice_expiry_delta_secs)?;
                Ok((payment_hash, payment_secret))
@@ -5124,8 +5487,8 @@ where
        /// If you need exact expiry semantics, you should enforce them upon receipt of
        /// [`PaymentClaimable`].
        ///
-       /// Note that invoices generated for inbound payments should have their `min_final_cltv_expiry`
-       /// set to at least [`MIN_FINAL_CLTV_EXPIRY`].
+       /// Note that invoices generated for inbound payments should have their `min_final_cltv_expiry_delta`
+       /// set to at least [`MIN_FINAL_CLTV_EXPIRY_DELTA`].
        ///
        /// Note that a malicious eavesdropper can intuit whether an inbound payment was created by
        /// `create_inbound_payment` or `create_inbound_payment_for_hash` based on runtime.
@@ -5137,10 +5500,16 @@ where
        ///
        /// Errors if `min_value_msat` is greater than total bitcoin supply.
        ///
+       /// If `min_final_cltv_expiry_delta` is set to some value, then the payment will not be receivable
+       /// on versions of LDK prior to 0.0.114.
+       ///
        /// [`create_inbound_payment`]: Self::create_inbound_payment
        /// [`PaymentClaimable`]: events::Event::PaymentClaimable
-       pub fn create_inbound_payment_for_hash(&self, payment_hash: PaymentHash, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32) -> Result<PaymentSecret, ()> {
-               inbound_payment::create_from_hash(&self.inbound_payment_key, min_value_msat, payment_hash, invoice_expiry_delta_secs, self.highest_seen_timestamp.load(Ordering::Acquire) as u64)
+       pub fn create_inbound_payment_for_hash(&self, payment_hash: PaymentHash, min_value_msat: Option<u64>,
+               invoice_expiry_delta_secs: u32, min_final_cltv_expiry: Option<u16>) -> Result<PaymentSecret, ()> {
+               inbound_payment::create_from_hash(&self.inbound_payment_key, min_value_msat, payment_hash,
+                       invoice_expiry_delta_secs, self.highest_seen_timestamp.load(Ordering::Acquire) as u64,
+                       min_final_cltv_expiry)
        }
 
        /// Legacy version of [`create_inbound_payment_for_hash`]. Use this method if you wish to share
@@ -5173,7 +5542,7 @@ where
                let best_block_height = self.best_block.read().unwrap().height();
                let short_to_chan_info = self.short_to_chan_info.read().unwrap();
                loop {
-                       let scid_candidate = fake_scid::Namespace::Phantom.get_fake_scid(best_block_height, &self.genesis_hash, &self.fake_scid_rand_bytes, &self.keys_manager);
+                       let scid_candidate = fake_scid::Namespace::Phantom.get_fake_scid(best_block_height, &self.genesis_hash, &self.fake_scid_rand_bytes, &self.entropy_source);
                        // Ensure the generated scid doesn't conflict with a real channel.
                        match short_to_chan_info.get(&scid_candidate) {
                                Some(_) => continue,
@@ -5203,7 +5572,7 @@ where
                let best_block_height = self.best_block.read().unwrap().height();
                let short_to_chan_info = self.short_to_chan_info.read().unwrap();
                loop {
-                       let scid_candidate = fake_scid::Namespace::Intercept.get_fake_scid(best_block_height, &self.genesis_hash, &self.fake_scid_rand_bytes, &self.keys_manager);
+                       let scid_candidate = fake_scid::Namespace::Intercept.get_fake_scid(best_block_height, &self.genesis_hash, &self.fake_scid_rand_bytes, &self.entropy_source);
                        // Ensure the generated scid doesn't conflict with a real channel.
                        if short_to_chan_info.contains_key(&scid_candidate) { continue }
                        return scid_candidate
@@ -5215,10 +5584,15 @@ where
        pub fn compute_inflight_htlcs(&self) -> InFlightHtlcs {
                let mut inflight_htlcs = InFlightHtlcs::new();
 
-               for chan in self.channel_state.lock().unwrap().by_id.values() {
-                       for (htlc_source, _) in chan.inflight_htlc_sources() {
-                               if let HTLCSource::OutboundRoute { path, .. } = htlc_source {
-                                       inflight_htlcs.process_path(path, self.get_our_node_id());
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               for (_cp_id, peer_state_mutex) in per_peer_state.iter() {
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       for chan in peer_state.channel_by_id.values() {
+                               for (htlc_source, _) in chan.inflight_htlc_sources() {
+                                       if let HTLCSource::OutboundRoute { path, .. } = htlc_source {
+                                               inflight_htlcs.process_path(path, self.get_our_node_id());
+                                       }
                                }
                        }
                }
@@ -5234,6 +5608,12 @@ where
                events.into_inner()
        }
 
+       #[cfg(feature = "_test_utils")]
+       pub fn push_pending_event(&self, event: events::Event) {
+               let mut events = self.pending_events.lock().unwrap();
+               events.push(event);
+       }
+
        #[cfg(test)]
        pub fn pop_pending_event(&self) -> Option<events::Event> {
                let mut events = self.pending_events.lock().unwrap();
@@ -5284,15 +5664,30 @@ where
        }
 }
 
-impl<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref> MessageSendEventsProvider for ChannelManager<M, T, K, F, R, L>
+impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> MessageSendEventsProvider for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
 {
+       /// Returns `MessageSendEvent`s strictly ordered per-peer, in the order they were generated.
+       /// The returned array will contain `MessageSendEvent`s for different peers if
+       /// `MessageSendEvent`s to more than one peer exists, but `MessageSendEvent`s to the same peer
+       /// is always placed next to each other.
+       ///
+       /// Note that that while `MessageSendEvent`s are strictly ordered per-peer, the peer order for
+       /// the chunks of `MessageSendEvent`s for different peers is random. I.e. if the array contains
+       /// `MessageSendEvent`s  for both `node_a` and `node_b`, the `MessageSendEvent`s for `node_a`
+       /// will randomly be placed first or last in the returned array.
+       ///
+       /// Note that even though `BroadcastChannelAnnouncement` and `BroadcastChannelUpdate`
+       /// `MessageSendEvent`s are intended to be broadcasted to all peers, they will be pleaced among
+       /// the `MessageSendEvent`s to the specific peer they were generated under.
        fn get_and_clear_pending_msg_events(&self) -> Vec<MessageSendEvent> {
                let events = RefCell::new(Vec::new());
                PersistenceNotifierGuard::optionally_notify(&self.total_consistency_lock, &self.persistence_notifier, || {
@@ -5312,8 +5707,14 @@ where
                        }
 
                        let mut pending_events = Vec::new();
-                       let mut channel_state = self.channel_state.lock().unwrap();
-                       mem::swap(&mut pending_events, &mut channel_state.pending_msg_events);
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       for (_cp_id, peer_state_mutex) in per_peer_state.iter() {
+                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               if peer_state.pending_msg_events.len() > 0 {
+                                       pending_events.append(&mut peer_state.pending_msg_events);
+                               }
+                       }
 
                        if !pending_events.is_empty() {
                                events.replace(pending_events);
@@ -5325,11 +5726,13 @@ where
        }
 }
 
-impl<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref> EventsProvider for ChannelManager<M, T, K, F, R, L>
+impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> EventsProvider for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
@@ -5362,11 +5765,13 @@ where
        }
 }
 
-impl<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref> chain::Listen for ChannelManager<M, T, K, F, R, L>
+impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> chain::Listen for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
@@ -5396,15 +5801,17 @@ where
                        *best_block = BestBlock::new(header.prev_blockhash, new_height)
                }
 
-               self.do_chain_event(Some(new_height), |channel| channel.best_block_updated(new_height, header.time, self.genesis_hash.clone(), self.get_our_node_id(), &self.logger));
+               self.do_chain_event(Some(new_height), |channel| channel.best_block_updated(new_height, header.time, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger));
        }
 }
 
-impl<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref> chain::Confirm for ChannelManager<M, T, K, F, R, L>
+impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> chain::Confirm for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
@@ -5418,13 +5825,13 @@ where
                log_trace!(self.logger, "{} transactions included in block {} at height {} provided", txdata.len(), block_hash, height);
 
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
-               self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, self.genesis_hash.clone(), self.get_our_node_id(), &self.logger)
+               self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger)
                        .map(|(a, b)| (a, Vec::new(), b)));
 
                let last_best_block_height = self.best_block.read().unwrap().height();
                if height < last_best_block_height {
                        let timestamp = self.highest_seen_timestamp.load(Ordering::Acquire);
-                       self.do_chain_event(Some(last_best_block_height), |channel| channel.best_block_updated(last_best_block_height, timestamp as u32, self.genesis_hash.clone(), self.get_our_node_id(), &self.logger));
+                       self.do_chain_event(Some(last_best_block_height), |channel| channel.best_block_updated(last_best_block_height, timestamp as u32, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger));
                }
        }
 
@@ -5440,7 +5847,7 @@ where
 
                *self.best_block.write().unwrap() = BestBlock::new(block_hash, height);
 
-               self.do_chain_event(Some(height), |channel| channel.best_block_updated(height, header.time, self.genesis_hash.clone(), self.get_our_node_id(), &self.logger));
+               self.do_chain_event(Some(height), |channel| channel.best_block_updated(height, header.time, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger));
 
                macro_rules! max_time {
                        ($timestamp: expr) => {
@@ -5466,11 +5873,14 @@ where
        }
 
        fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)> {
-               let channel_state = self.channel_state.lock().unwrap();
-               let mut res = Vec::with_capacity(channel_state.by_id.len());
-               for chan in channel_state.by_id.values() {
-                       if let (Some(funding_txo), block_hash) = (chan.get_funding_txo(), chan.get_funding_tx_confirmed_in()) {
-                               res.push((funding_txo.txid, block_hash));
+               let mut res = Vec::with_capacity(self.short_to_chan_info.read().unwrap().len());
+               for (_cp_id, peer_state_mutex) in self.per_peer_state.read().unwrap().iter() {
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       for chan in peer_state.channel_by_id.values() {
+                               if let (Some(funding_txo), Some(block_hash)) = (chan.get_funding_txo(), chan.get_funding_tx_confirmed_in()) {
+                                       res.push((funding_txo.txid, Some(block_hash)));
+                               }
                        }
                }
                res
@@ -5488,11 +5898,13 @@ where
        }
 }
 
-impl<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref> ChannelManager<M, T, K, F, R, L>
+impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
@@ -5500,7 +5912,7 @@ where
        /// Calls a function which handles an on-chain event (blocks dis/connected, transactions
        /// un/confirmed, etc) on each channel, handling any resulting errors or messages generated by
        /// the function.
-       fn do_chain_event<FN: Fn(&mut Channel<<K::Target as SignerProvider>::Signer>) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>>
+       fn do_chain_event<FN: Fn(&mut Channel<<SP::Target as SignerProvider>::Signer>) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>>
                        (&self, height_opt: Option<u32>, f: FN) {
                // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
                // during initialization prior to the chain_monitor being fully configured in some cases.
@@ -5509,89 +5921,92 @@ where
                let mut failed_channels = Vec::new();
                let mut timed_out_htlcs = Vec::new();
                {
-                       let mut channel_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_lock;
-                       let pending_msg_events = &mut channel_state.pending_msg_events;
-                       channel_state.by_id.retain(|_, channel| {
-                               let res = f(channel);
-                               if let Ok((channel_ready_opt, mut timed_out_pending_htlcs, announcement_sigs)) = res {
-                                       for (source, payment_hash) in timed_out_pending_htlcs.drain(..) {
-                                               let (failure_code, data) = self.get_htlc_inbound_temp_fail_err_and_data(0x1000|14 /* expiry_too_soon */, &channel);
-                                               timed_out_htlcs.push((source, payment_hash, HTLCFailReason::reason(failure_code, data),
-                                                       HTLCDestination::NextHopChannel { node_id: Some(channel.get_counterparty_node_id()), channel_id: channel.channel_id() }));
-                                       }
-                                       if let Some(channel_ready) = channel_ready_opt {
-                                               send_channel_ready!(self, pending_msg_events, channel, channel_ready);
-                                               if channel.is_usable() {
-                                                       log_trace!(self.logger, "Sending channel_ready with private initial channel_update for our counterparty on channel {}", log_bytes!(channel.channel_id()));
-                                                       if let Ok(msg) = self.get_channel_update_for_unicast(channel) {
-                                                               pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
-                                                                       node_id: channel.get_counterparty_node_id(),
-                                                                       msg,
-                                                               });
+                       let per_peer_state = self.per_peer_state.read().unwrap();
+                       for (_cp_id, peer_state_mutex) in per_peer_state.iter() {
+                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               let pending_msg_events = &mut peer_state.pending_msg_events;
+                               peer_state.channel_by_id.retain(|_, channel| {
+                                       let res = f(channel);
+                                       if let Ok((channel_ready_opt, mut timed_out_pending_htlcs, announcement_sigs)) = res {
+                                               for (source, payment_hash) in timed_out_pending_htlcs.drain(..) {
+                                                       let (failure_code, data) = self.get_htlc_inbound_temp_fail_err_and_data(0x1000|14 /* expiry_too_soon */, &channel);
+                                                       timed_out_htlcs.push((source, payment_hash, HTLCFailReason::reason(failure_code, data),
+                                                               HTLCDestination::NextHopChannel { node_id: Some(channel.get_counterparty_node_id()), channel_id: channel.channel_id() }));
+                                               }
+                                               if let Some(channel_ready) = channel_ready_opt {
+                                                       send_channel_ready!(self, pending_msg_events, channel, channel_ready);
+                                                       if channel.is_usable() {
+                                                               log_trace!(self.logger, "Sending channel_ready with private initial channel_update for our counterparty on channel {}", log_bytes!(channel.channel_id()));
+                                                               if let Ok(msg) = self.get_channel_update_for_unicast(channel) {
+                                                                       pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
+                                                                               node_id: channel.get_counterparty_node_id(),
+                                                                               msg,
+                                                                       });
+                                                               }
+                                                       } else {
+                                                               log_trace!(self.logger, "Sending channel_ready WITHOUT channel_update for {}", log_bytes!(channel.channel_id()));
                                                        }
-                                               } else {
-                                                       log_trace!(self.logger, "Sending channel_ready WITHOUT channel_update for {}", log_bytes!(channel.channel_id()));
                                                }
-                                       }
 
-                                       emit_channel_ready_event!(self, channel);
+                                               emit_channel_ready_event!(self, channel);
 
-                                       if let Some(announcement_sigs) = announcement_sigs {
-                                               log_trace!(self.logger, "Sending announcement_signatures for channel {}", log_bytes!(channel.channel_id()));
-                                               pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
-                                                       node_id: channel.get_counterparty_node_id(),
-                                                       msg: announcement_sigs,
-                                               });
-                                               if let Some(height) = height_opt {
-                                                       if let Some(announcement) = channel.get_signed_channel_announcement(self.get_our_node_id(), self.genesis_hash, height) {
-                                                               pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
-                                                                       msg: announcement,
-                                                                       // Note that announcement_signatures fails if the channel cannot be announced,
-                                                                       // so get_channel_update_for_broadcast will never fail by the time we get here.
-                                                                       update_msg: self.get_channel_update_for_broadcast(channel).unwrap(),
-                                                               });
+                                               if let Some(announcement_sigs) = announcement_sigs {
+                                                       log_trace!(self.logger, "Sending announcement_signatures for channel {}", log_bytes!(channel.channel_id()));
+                                                       pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
+                                                               node_id: channel.get_counterparty_node_id(),
+                                                               msg: announcement_sigs,
+                                                       });
+                                                       if let Some(height) = height_opt {
+                                                               if let Some(announcement) = channel.get_signed_channel_announcement(&self.node_signer, self.genesis_hash, height, &self.default_configuration) {
+                                                                       pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
+                                                                               msg: announcement,
+                                                                               // Note that announcement_signatures fails if the channel cannot be announced,
+                                                                               // so get_channel_update_for_broadcast will never fail by the time we get here.
+                                                                               update_msg: Some(self.get_channel_update_for_broadcast(channel).unwrap()),
+                                                                       });
+                                                               }
                                                        }
                                                }
-                                       }
-                                       if channel.is_our_channel_ready() {
-                                               if let Some(real_scid) = channel.get_short_channel_id() {
-                                                       // If we sent a 0conf channel_ready, and now have an SCID, we add it
-                                                       // to the short_to_chan_info map here. Note that we check whether we
-                                                       // can relay using the real SCID at relay-time (i.e.
-                                                       // enforce option_scid_alias then), and if the funding tx is ever
-                                                       // un-confirmed we force-close the channel, ensuring short_to_chan_info
-                                                       // is always consistent.
-                                                       let mut short_to_chan_info = self.short_to_chan_info.write().unwrap();
-                                                       let scid_insert = short_to_chan_info.insert(real_scid, (channel.get_counterparty_node_id(), channel.channel_id()));
-                                                       assert!(scid_insert.is_none() || scid_insert.unwrap() == (channel.get_counterparty_node_id(), channel.channel_id()),
-                                                               "SCIDs should never collide - ensure you weren't behind by a full {} blocks when creating channels",
-                                                               fake_scid::MAX_SCID_BLOCKS_FROM_NOW);
+                                               if channel.is_our_channel_ready() {
+                                                       if let Some(real_scid) = channel.get_short_channel_id() {
+                                                               // If we sent a 0conf channel_ready, and now have an SCID, we add it
+                                                               // to the short_to_chan_info map here. Note that we check whether we
+                                                               // can relay using the real SCID at relay-time (i.e.
+                                                               // enforce option_scid_alias then), and if the funding tx is ever
+                                                               // un-confirmed we force-close the channel, ensuring short_to_chan_info
+                                                               // is always consistent.
+                                                               let mut short_to_chan_info = self.short_to_chan_info.write().unwrap();
+                                                               let scid_insert = short_to_chan_info.insert(real_scid, (channel.get_counterparty_node_id(), channel.channel_id()));
+                                                               assert!(scid_insert.is_none() || scid_insert.unwrap() == (channel.get_counterparty_node_id(), channel.channel_id()),
+                                                                       "SCIDs should never collide - ensure you weren't behind by a full {} blocks when creating channels",
+                                                                       fake_scid::MAX_SCID_BLOCKS_FROM_NOW);
+                                                       }
                                                }
-                                       }
-                               } else if let Err(reason) = res {
-                                       update_maps_on_chan_removal!(self, channel);
-                                       // It looks like our counterparty went on-chain or funding transaction was
-                                       // reorged out of the main chain. Close the channel.
-                                       failed_channels.push(channel.force_shutdown(true));
-                                       if let Ok(update) = self.get_channel_update_for_broadcast(&channel) {
-                                               pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
-                                                       msg: update
+                                       } else if let Err(reason) = res {
+                                               update_maps_on_chan_removal!(self, channel);
+                                               // It looks like our counterparty went on-chain or funding transaction was
+                                               // reorged out of the main chain. Close the channel.
+                                               failed_channels.push(channel.force_shutdown(true));
+                                               if let Ok(update) = self.get_channel_update_for_broadcast(&channel) {
+                                                       pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
+                                                               msg: update
+                                                       });
+                                               }
+                                               let reason_message = format!("{}", reason);
+                                               self.issue_channel_close_events(channel, reason);
+                                               pending_msg_events.push(events::MessageSendEvent::HandleError {
+                                                       node_id: channel.get_counterparty_node_id(),
+                                                       action: msgs::ErrorAction::SendErrorMessage { msg: msgs::ErrorMessage {
+                                                               channel_id: channel.channel_id(),
+                                                               data: reason_message,
+                                                       } },
                                                });
+                                               return false;
                                        }
-                                       let reason_message = format!("{}", reason);
-                                       self.issue_channel_close_events(channel, reason);
-                                       pending_msg_events.push(events::MessageSendEvent::HandleError {
-                                               node_id: channel.get_counterparty_node_id(),
-                                               action: msgs::ErrorAction::SendErrorMessage { msg: msgs::ErrorMessage {
-                                                       channel_id: channel.channel_id(),
-                                                       data: reason_message,
-                                               } },
-                                       });
-                                       return false;
-                               }
-                               true
-                       });
+                                       true
+                               });
+                       }
                }
 
                if let Some(height) = height_opt {
@@ -5687,26 +6102,62 @@ where
        pub fn current_best_block(&self) -> BestBlock {
                self.best_block.read().unwrap().clone()
        }
+
+       /// Fetches the set of [`NodeFeatures`] flags which are provided by or required by
+       /// [`ChannelManager`].
+       pub fn node_features(&self) -> NodeFeatures {
+               provided_node_features(&self.default_configuration)
+       }
+
+       /// Fetches the set of [`InvoiceFeatures`] flags which are provided by or required by
+       /// [`ChannelManager`].
+       ///
+       /// Note that the invoice feature flags can vary depending on if the invoice is a "phantom invoice"
+       /// or not. Thus, this method is not public.
+       #[cfg(any(feature = "_test_utils", test))]
+       pub fn invoice_features(&self) -> InvoiceFeatures {
+               provided_invoice_features(&self.default_configuration)
+       }
+
+       /// Fetches the set of [`ChannelFeatures`] flags which are provided by or required by
+       /// [`ChannelManager`].
+       pub fn channel_features(&self) -> ChannelFeatures {
+               provided_channel_features(&self.default_configuration)
+       }
+
+       /// Fetches the set of [`ChannelTypeFeatures`] flags which are provided by or required by
+       /// [`ChannelManager`].
+       pub fn channel_type_features(&self) -> ChannelTypeFeatures {
+               provided_channel_type_features(&self.default_configuration)
+       }
+
+       /// Fetches the set of [`InitFeatures`] flags which are provided by or required by
+       /// [`ChannelManager`].
+       pub fn init_features(&self) -> InitFeatures {
+               provided_init_features(&self.default_configuration)
+       }
 }
 
-impl<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>
-       ChannelMessageHandler for ChannelManager<M, T, K, F, R, L>
+impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
+       ChannelMessageHandler for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
 {
-       fn handle_open_channel(&self, counterparty_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel) {
+       fn handle_open_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannel) {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
-               let _ = handle_error!(self, self.internal_open_channel(counterparty_node_id, their_features, msg), *counterparty_node_id);
+               let _ = handle_error!(self, self.internal_open_channel(counterparty_node_id, msg), *counterparty_node_id);
        }
 
-       fn handle_accept_channel(&self, counterparty_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::AcceptChannel) {
+       fn handle_accept_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannel) {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
-               let _ = handle_error!(self, self.internal_accept_channel(counterparty_node_id, their_features, msg), *counterparty_node_id);
+               let _ = handle_error!(self, self.internal_accept_channel(counterparty_node_id, msg), *counterparty_node_id);
        }
 
        fn handle_funding_created(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingCreated) {
@@ -5724,9 +6175,9 @@ where
                let _ = handle_error!(self, self.internal_channel_ready(counterparty_node_id, msg), *counterparty_node_id);
        }
 
-       fn handle_shutdown(&self, counterparty_node_id: &PublicKey, their_features: &InitFeatures, msg: &msgs::Shutdown) {
+       fn handle_shutdown(&self, counterparty_node_id: &PublicKey, msg: &msgs::Shutdown) {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
-               let _ = handle_error!(self, self.internal_shutdown(counterparty_node_id, their_features, msg), *counterparty_node_id);
+               let _ = handle_error!(self, self.internal_shutdown(counterparty_node_id, msg), *counterparty_node_id);
        }
 
        fn handle_closing_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::ClosingSigned) {
@@ -5789,118 +6240,150 @@ where
                let _ = handle_error!(self, self.internal_channel_reestablish(counterparty_node_id, msg), *counterparty_node_id);
        }
 
-       fn peer_disconnected(&self, counterparty_node_id: &PublicKey, no_connection_possible: bool) {
+       fn peer_disconnected(&self, counterparty_node_id: &PublicKey) {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
                let mut failed_channels = Vec::new();
-               let mut no_channels_remain = true;
-               {
-                       let mut channel_state_lock = self.channel_state.lock().unwrap();
-                       let channel_state = &mut *channel_state_lock;
-                       let pending_msg_events = &mut channel_state.pending_msg_events;
-                       log_debug!(self.logger, "Marking channels with {} disconnected and generating channel_updates. We believe we {} make future connections to this peer.",
-                               log_pubkey!(counterparty_node_id), if no_connection_possible { "cannot" } else { "can" });
-                       channel_state.by_id.retain(|_, chan| {
-                               if chan.get_counterparty_node_id() == *counterparty_node_id {
+               let mut per_peer_state = self.per_peer_state.write().unwrap();
+               let remove_peer = {
+                       log_debug!(self.logger, "Marking channels with {} disconnected and generating channel_updates.",
+                               log_pubkey!(counterparty_node_id));
+                       if let Some(peer_state_mutex) = per_peer_state.get(counterparty_node_id) {
+                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               let pending_msg_events = &mut peer_state.pending_msg_events;
+                               peer_state.channel_by_id.retain(|_, chan| {
                                        chan.remove_uncommitted_htlcs_and_mark_paused(&self.logger);
                                        if chan.is_shutdown() {
                                                update_maps_on_chan_removal!(self, chan);
                                                self.issue_channel_close_events(chan, ClosureReason::DisconnectedPeer);
                                                return false;
-                                       } else {
-                                               no_channels_remain = false;
                                        }
-                               }
-                               true
-                       });
-                       pending_msg_events.retain(|msg| {
-                               match msg {
-                                       &events::MessageSendEvent::SendAcceptChannel { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendOpenChannel { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendFundingCreated { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendFundingSigned { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendChannelReady { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendAnnouncementSignatures { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::UpdateHTLCs { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendRevokeAndACK { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendClosingSigned { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendShutdown { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendChannelReestablish { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendChannelAnnouncement { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::BroadcastChannelAnnouncement { .. } => true,
-                                       &events::MessageSendEvent::BroadcastChannelUpdate { .. } => true,
-                                       &events::MessageSendEvent::SendChannelUpdate { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::HandleError { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendChannelRangeQuery { .. } => false,
-                                       &events::MessageSendEvent::SendShortIdsQuery { .. } => false,
-                                       &events::MessageSendEvent::SendReplyChannelRange { .. } => false,
-                                       &events::MessageSendEvent::SendGossipTimestampFilter { .. } => false,
-                               }
-                       });
-               }
-               if no_channels_remain {
-                       self.per_peer_state.write().unwrap().remove(counterparty_node_id);
+                                       true
+                               });
+                               pending_msg_events.retain(|msg| {
+                                       match msg {
+                                               &events::MessageSendEvent::SendAcceptChannel { .. } => false,
+                                               &events::MessageSendEvent::SendOpenChannel { .. } => false,
+                                               &events::MessageSendEvent::SendFundingCreated { .. } => false,
+                                               &events::MessageSendEvent::SendFundingSigned { .. } => false,
+                                               &events::MessageSendEvent::SendChannelReady { .. } => false,
+                                               &events::MessageSendEvent::SendAnnouncementSignatures { .. } => false,
+                                               &events::MessageSendEvent::UpdateHTLCs { .. } => false,
+                                               &events::MessageSendEvent::SendRevokeAndACK { .. } => false,
+                                               &events::MessageSendEvent::SendClosingSigned { .. } => false,
+                                               &events::MessageSendEvent::SendShutdown { .. } => false,
+                                               &events::MessageSendEvent::SendChannelReestablish { .. } => false,
+                                               &events::MessageSendEvent::SendChannelAnnouncement { .. } => false,
+                                               &events::MessageSendEvent::BroadcastChannelAnnouncement { .. } => true,
+                                               &events::MessageSendEvent::BroadcastChannelUpdate { .. } => true,
+                                               &events::MessageSendEvent::BroadcastNodeAnnouncement { .. } => true,
+                                               &events::MessageSendEvent::SendChannelUpdate { .. } => false,
+                                               &events::MessageSendEvent::HandleError { .. } => false,
+                                               &events::MessageSendEvent::SendChannelRangeQuery { .. } => false,
+                                               &events::MessageSendEvent::SendShortIdsQuery { .. } => false,
+                                               &events::MessageSendEvent::SendReplyChannelRange { .. } => false,
+                                               &events::MessageSendEvent::SendGossipTimestampFilter { .. } => false,
+                                       }
+                               });
+                               debug_assert!(peer_state.is_connected, "A disconnected peer cannot disconnect");
+                               peer_state.is_connected = false;
+                               peer_state.ok_to_remove(true)
+                       } else { debug_assert!(false, "Unconnected peer disconnected"); true }
+               };
+               if remove_peer {
+                       per_peer_state.remove(counterparty_node_id);
                }
+               mem::drop(per_peer_state);
 
                for failure in failed_channels.drain(..) {
                        self.finish_force_close_channel(failure);
                }
        }
 
-       fn peer_connected(&self, counterparty_node_id: &PublicKey, init_msg: &msgs::Init) -> Result<(), ()> {
+       fn peer_connected(&self, counterparty_node_id: &PublicKey, init_msg: &msgs::Init, inbound: bool) -> Result<(), ()> {
                if !init_msg.features.supports_static_remote_key() {
-                       log_debug!(self.logger, "Peer {} does not support static remote key, disconnecting with no_connection_possible", log_pubkey!(counterparty_node_id));
+                       log_debug!(self.logger, "Peer {} does not support static remote key, disconnecting", log_pubkey!(counterparty_node_id));
                        return Err(());
                }
 
-               log_debug!(self.logger, "Generating channel_reestablish events for {}", log_pubkey!(counterparty_node_id));
-
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
 
+               // If we have too many peers connected which don't have funded channels, disconnect the
+               // peer immediately (as long as it doesn't have funded channels). If we have a bunch of
+               // unfunded channels taking up space in memory for disconnected peers, we still let new
+               // peers connect, but we'll reject new channels from them.
+               let connected_peers_without_funded_channels = self.peers_without_funded_channels(|node| node.is_connected);
+               let inbound_peer_limited = inbound && connected_peers_without_funded_channels >= MAX_NO_CHANNEL_PEERS;
+
                {
                        let mut peer_state_lock = self.per_peer_state.write().unwrap();
                        match peer_state_lock.entry(counterparty_node_id.clone()) {
                                hash_map::Entry::Vacant(e) => {
+                                       if inbound_peer_limited {
+                                               return Err(());
+                                       }
                                        e.insert(Mutex::new(PeerState {
+                                               channel_by_id: HashMap::new(),
                                                latest_features: init_msg.features.clone(),
+                                               pending_msg_events: Vec::new(),
+                                               monitor_update_blocked_actions: BTreeMap::new(),
+                                               is_connected: true,
                                        }));
                                },
                                hash_map::Entry::Occupied(e) => {
-                                       e.get().lock().unwrap().latest_features = init_msg.features.clone();
+                                       let mut peer_state = e.get().lock().unwrap();
+                                       peer_state.latest_features = init_msg.features.clone();
+
+                                       let best_block_height = self.best_block.read().unwrap().height();
+                                       if inbound_peer_limited &&
+                                               Self::unfunded_channel_count(&*peer_state, best_block_height) ==
+                                               peer_state.channel_by_id.len()
+                                       {
+                                               return Err(());
+                                       }
+
+                                       debug_assert!(!peer_state.is_connected, "A peer shouldn't be connected twice");
+                                       peer_state.is_connected = true;
                                },
                        }
                }
 
-               let mut channel_state_lock = self.channel_state.lock().unwrap();
-               let channel_state = &mut *channel_state_lock;
-               let pending_msg_events = &mut channel_state.pending_msg_events;
-               channel_state.by_id.retain(|_, chan| {
-                       let retain = if chan.get_counterparty_node_id() == *counterparty_node_id {
-                               if !chan.have_received_message() {
-                                       // If we created this (outbound) channel while we were disconnected from the
-                                       // peer we probably failed to send the open_channel message, which is now
-                                       // lost. We can't have had anything pending related to this channel, so we just
-                                       // drop it.
-                                       false
-                               } else {
-                                       pending_msg_events.push(events::MessageSendEvent::SendChannelReestablish {
-                                               node_id: chan.get_counterparty_node_id(),
-                                               msg: chan.get_channel_reestablish(&self.logger),
-                                       });
-                                       true
-                               }
-                       } else { true };
-                       if retain && chan.get_counterparty_node_id() != *counterparty_node_id {
-                               if let Some(msg) = chan.get_signed_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone(), self.best_block.read().unwrap().height()) {
-                                       if let Ok(update_msg) = self.get_channel_update_for_broadcast(chan) {
-                                               pending_msg_events.push(events::MessageSendEvent::SendChannelAnnouncement {
-                                                       node_id: *counterparty_node_id,
-                                                       msg, update_msg,
+               log_debug!(self.logger, "Generating channel_reestablish events for {}", log_pubkey!(counterparty_node_id));
+
+               let per_peer_state = self.per_peer_state.read().unwrap();
+               for (_cp_id, peer_state_mutex) in per_peer_state.iter() {
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       let pending_msg_events = &mut peer_state.pending_msg_events;
+                       peer_state.channel_by_id.retain(|_, chan| {
+                               let retain = if chan.get_counterparty_node_id() == *counterparty_node_id {
+                                       if !chan.have_received_message() {
+                                               // If we created this (outbound) channel while we were disconnected from the
+                                               // peer we probably failed to send the open_channel message, which is now
+                                               // lost. We can't have had anything pending related to this channel, so we just
+                                               // drop it.
+                                               false
+                                       } else {
+                                               pending_msg_events.push(events::MessageSendEvent::SendChannelReestablish {
+                                                       node_id: chan.get_counterparty_node_id(),
+                                                       msg: chan.get_channel_reestablish(&self.logger),
                                                });
+                                               true
+                                       }
+                               } else { true };
+                               if retain && chan.get_counterparty_node_id() != *counterparty_node_id {
+                                       if let Some(msg) = chan.get_signed_channel_announcement(&self.node_signer, self.genesis_hash.clone(), self.best_block.read().unwrap().height(), &self.default_configuration) {
+                                               if let Ok(update_msg) = self.get_channel_update_for_broadcast(chan) {
+                                                       pending_msg_events.push(events::MessageSendEvent::SendChannelAnnouncement {
+                                                               node_id: *counterparty_node_id,
+                                                               msg, update_msg,
+                                                       });
+                                               }
                                        }
                                }
-                       }
-                       retain
-               });
+                               retain
+                       });
+               }
                //TODO: Also re-broadcast announcement_signatures
                Ok(())
        }
@@ -5909,22 +6392,29 @@ where
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
 
                if msg.channel_id == [0; 32] {
-                       for chan in self.list_channels() {
-                               if chan.counterparty.node_id == *counterparty_node_id {
-                                       // Untrusted messages from peer, we throw away the error if id points to a non-existent channel
-                                       let _ = self.force_close_channel_with_peer(&chan.channel_id, counterparty_node_id, Some(&msg.data), true);
-                               }
+                       let channel_ids: Vec<[u8; 32]> = {
+                               let per_peer_state = self.per_peer_state.read().unwrap();
+                               let peer_state_mutex_opt = per_peer_state.get(counterparty_node_id);
+                               if peer_state_mutex_opt.is_none() { return; }
+                               let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               peer_state.channel_by_id.keys().cloned().collect()
+                       };
+                       for channel_id in channel_ids {
+                               // Untrusted messages from peer, we throw away the error if id points to a non-existent channel
+                               let _ = self.force_close_channel_with_peer(&channel_id, counterparty_node_id, Some(&msg.data), true);
                        }
                } else {
                        {
                                // First check if we can advance the channel type and try again.
-                               let mut channel_state = self.channel_state.lock().unwrap();
-                               if let Some(chan) = channel_state.by_id.get_mut(&msg.channel_id) {
-                                       if chan.get_counterparty_node_id() != *counterparty_node_id {
-                                               return;
-                                       }
+                               let per_peer_state = self.per_peer_state.read().unwrap();
+                               let peer_state_mutex_opt = per_peer_state.get(counterparty_node_id);
+                               if peer_state_mutex_opt.is_none() { return; }
+                               let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               if let Some(chan) = peer_state.channel_by_id.get_mut(&msg.channel_id) {
                                        if let Ok(msg) = chan.maybe_handle_error_without_close(self.genesis_hash) {
-                                               channel_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
+                                               peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
                                                        node_id: *counterparty_node_id,
                                                        msg,
                                                });
@@ -5939,18 +6429,18 @@ where
        }
 
        fn provided_node_features(&self) -> NodeFeatures {
-               provided_node_features()
+               provided_node_features(&self.default_configuration)
        }
 
        fn provided_init_features(&self, _their_init_features: &PublicKey) -> InitFeatures {
-               provided_init_features()
+               provided_init_features(&self.default_configuration)
        }
 }
 
 /// Fetches the set of [`NodeFeatures`] flags which are provided by or required by
 /// [`ChannelManager`].
-pub fn provided_node_features() -> NodeFeatures {
-       provided_init_features().to_context()
+pub(crate) fn provided_node_features(config: &UserConfig) -> NodeFeatures {
+       provided_init_features(config).to_context()
 }
 
 /// Fetches the set of [`InvoiceFeatures`] flags which are provided by or required by
@@ -5959,19 +6449,25 @@ pub fn provided_node_features() -> NodeFeatures {
 /// Note that the invoice feature flags can vary depending on if the invoice is a "phantom invoice"
 /// or not. Thus, this method is not public.
 #[cfg(any(feature = "_test_utils", test))]
-pub fn provided_invoice_features() -> InvoiceFeatures {
-       provided_init_features().to_context()
+pub(crate) fn provided_invoice_features(config: &UserConfig) -> InvoiceFeatures {
+       provided_init_features(config).to_context()
 }
 
 /// Fetches the set of [`ChannelFeatures`] flags which are provided by or required by
 /// [`ChannelManager`].
-pub fn provided_channel_features() -> ChannelFeatures {
-       provided_init_features().to_context()
+pub(crate) fn provided_channel_features(config: &UserConfig) -> ChannelFeatures {
+       provided_init_features(config).to_context()
+}
+
+/// Fetches the set of [`ChannelTypeFeatures`] flags which are provided by or required by
+/// [`ChannelManager`].
+pub(crate) fn provided_channel_type_features(config: &UserConfig) -> ChannelTypeFeatures {
+       ChannelTypeFeatures::from_init(&provided_init_features(config))
 }
 
 /// Fetches the set of [`InitFeatures`] flags which are provided by or required by
 /// [`ChannelManager`].
-pub fn provided_init_features() -> InitFeatures {
+pub fn provided_init_features(_config: &UserConfig) -> InitFeatures {
        // Note that if new features are added here which other peers may (eventually) require, we
        // should also add the corresponding (optional) bit to the ChannelMessageHandler impl for
        // ErroringMessageHandler.
@@ -5987,6 +6483,12 @@ pub fn provided_init_features() -> InitFeatures {
        features.set_channel_type_optional();
        features.set_scid_privacy_optional();
        features.set_zero_conf_optional();
+       #[cfg(anchors)]
+       { // Attributes are not allowed on if expressions on our current MSRV of 1.41.
+               if _config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx {
+                       features.set_anchors_zero_fee_htlc_tx_optional();
+               }
+       }
        features
 }
 
@@ -6049,7 +6551,7 @@ impl Writeable for ChannelDetails {
 
 impl Readable for ChannelDetails {
        fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
-               init_and_read_tlv_fields!(reader, {
+               _init_and_read_tlv_fields!(reader, {
                        (1, inbound_scid_alias, option),
                        (2, channel_id, required),
                        (3, channel_type, option),
@@ -6246,7 +6748,7 @@ impl Writeable for ClaimableHTLC {
 
 impl Readable for ClaimableHTLC {
        fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
-               let mut prev_hop = crate::util::ser::OptionDeserWrapper(None);
+               let mut prev_hop = crate::util::ser::RequiredWrapper(None);
                let mut value = 0;
                let mut payment_data: Option<msgs::FinalOnionHopData> = None;
                let mut cltv_expiry = 0;
@@ -6296,29 +6798,38 @@ impl Readable for HTLCSource {
                let id: u8 = Readable::read(reader)?;
                match id {
                        0 => {
-                               let mut session_priv: crate::util::ser::OptionDeserWrapper<SecretKey> = crate::util::ser::OptionDeserWrapper(None);
+                               let mut session_priv: crate::util::ser::RequiredWrapper<SecretKey> = crate::util::ser::RequiredWrapper(None);
                                let mut first_hop_htlc_msat: u64 = 0;
-                               let mut path = Some(Vec::new());
+                               let mut path: Option<Vec<RouteHop>> = Some(Vec::new());
                                let mut payment_id = None;
                                let mut payment_secret = None;
-                               let mut payment_params = None;
+                               let mut payment_params: Option<PaymentParameters> = None;
                                read_tlv_fields!(reader, {
                                        (0, session_priv, required),
                                        (1, payment_id, option),
                                        (2, first_hop_htlc_msat, required),
                                        (3, payment_secret, option),
                                        (4, path, vec_type),
-                                       (5, payment_params, option),
+                                       (5, payment_params, (option: ReadableArgs, 0)),
                                });
                                if payment_id.is_none() {
                                        // For backwards compat, if there was no payment_id written, use the session_priv bytes
                                        // instead.
                                        payment_id = Some(PaymentId(*session_priv.0.unwrap().as_ref()));
                                }
+                               if path.is_none() || path.as_ref().unwrap().is_empty() {
+                                       return Err(DecodeError::InvalidValue);
+                               }
+                               let path = path.unwrap();
+                               if let Some(params) = payment_params.as_mut() {
+                                       if params.final_cltv_expiry_delta == 0 {
+                                               params.final_cltv_expiry_delta = path.last().unwrap().cltv_expiry_delta;
+                                       }
+                               }
                                Ok(HTLCSource::OutboundRoute {
                                        session_priv: session_priv.0.unwrap(),
                                        first_hop_htlc_msat,
-                                       path: path.unwrap(),
+                                       path,
                                        payment_id: payment_id.unwrap(),
                                        payment_secret,
                                        payment_params,
@@ -6378,11 +6889,13 @@ impl_writeable_tlv_based!(PendingInboundPayment, {
        (8, min_value_msat, required),
 });
 
-impl<M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref> Writeable for ChannelManager<M, T, K, F, R, L>
+impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> Writeable for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
@@ -6399,20 +6912,34 @@ where
                        best_block.block_hash().write(writer)?;
                }
 
+               let mut serializable_peer_count: u64 = 0;
                {
-                       // Take `channel_state` lock temporarily to avoid creating a lock order that requires
-                       // that the `forward_htlcs` lock is taken after `channel_state`
-                       let channel_state = self.channel_state.lock().unwrap();
+                       let per_peer_state = self.per_peer_state.read().unwrap();
                        let mut unfunded_channels = 0;
-                       for (_, channel) in channel_state.by_id.iter() {
-                               if !channel.is_funding_initiated() {
-                                       unfunded_channels += 1;
+                       let mut number_of_channels = 0;
+                       for (_, peer_state_mutex) in per_peer_state.iter() {
+                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               if !peer_state.ok_to_remove(false) {
+                                       serializable_peer_count += 1;
+                               }
+                               number_of_channels += peer_state.channel_by_id.len();
+                               for (_, channel) in peer_state.channel_by_id.iter() {
+                                       if !channel.is_funding_initiated() {
+                                               unfunded_channels += 1;
+                                       }
                                }
                        }
-                       ((channel_state.by_id.len() - unfunded_channels) as u64).write(writer)?;
-                       for (_, channel) in channel_state.by_id.iter() {
-                               if channel.is_funding_initiated() {
-                                       channel.write(writer)?;
+
+                       ((number_of_channels - unfunded_channels) as u64).write(writer)?;
+
+                       for (_, peer_state_mutex) in per_peer_state.iter() {
+                               let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                               let peer_state = &mut *peer_state_lock;
+                               for (_, channel) in peer_state.channel_by_id.iter() {
+                                       if channel.is_funding_initiated() {
+                                               channel.write(writer)?;
+                                       }
                                }
                        }
                }
@@ -6429,6 +6956,8 @@ where
                        }
                }
 
+               let per_peer_state = self.per_peer_state.write().unwrap();
+
                let pending_inbound_payments = self.pending_inbound_payments.lock().unwrap();
                let claimable_payments = self.claimable_payments.lock().unwrap();
                let pending_outbound_payments = self.pending_outbound_payments.pending_outbound_payments.lock().unwrap();
@@ -6444,12 +6973,30 @@ where
                        htlc_purposes.push(purpose);
                }
 
-               let per_peer_state = self.per_peer_state.write().unwrap();
-               (per_peer_state.len() as u64).write(writer)?;
-               for (peer_pubkey, peer_state_mutex) in per_peer_state.iter() {
-                       peer_pubkey.write(writer)?;
-                       let peer_state = peer_state_mutex.lock().unwrap();
-                       peer_state.latest_features.write(writer)?;
+               let mut monitor_update_blocked_actions_per_peer = None;
+               let mut peer_states = Vec::new();
+               for (_, peer_state_mutex) in per_peer_state.iter() {
+                       // Because we're holding the owning `per_peer_state` write lock here there's no chance
+                       // of a lockorder violation deadlock - no other thread can be holding any
+                       // per_peer_state lock at all.
+                       peer_states.push(peer_state_mutex.unsafe_well_ordered_double_lock_self());
+               }
+
+               (serializable_peer_count).write(writer)?;
+               for ((peer_pubkey, _), peer_state) in per_peer_state.iter().zip(peer_states.iter()) {
+                       // Peers which we have no channels to should be dropped once disconnected. As we
+                       // disconnect all peers when shutting down and serializing the ChannelManager, we
+                       // consider all peers as disconnected here. There's therefore no need write peers with
+                       // no channels.
+                       if !peer_state.ok_to_remove(false) {
+                               peer_pubkey.write(writer)?;
+                               peer_state.latest_features.write(writer)?;
+                               if !peer_state.monitor_update_blocked_actions.is_empty() {
+                                       monitor_update_blocked_actions_per_peer
+                                               .get_or_insert_with(Vec::new)
+                                               .push((*peer_pubkey, &peer_state.monitor_update_blocked_actions));
+                               }
+                       }
                }
 
                let events = self.pending_events.lock().unwrap();
@@ -6526,8 +7073,6 @@ where
                        // LDK versions prior to 0.0.113 do not know how to read the pending claimed payments
                        // map. Thus, if there are no entries we skip writing a TLV for it.
                        pending_claiming_payments = None;
-               } else {
-                       debug_assert!(false, "While we have code to serialize pending_claiming_payments, the map should always be empty until a later PR");
                }
 
                write_tlv_fields!(writer, {
@@ -6536,6 +7081,7 @@ where
                        (3, pending_outbound_payments, required),
                        (4, pending_claiming_payments, option),
                        (5, self.our_network_pubkey, required),
+                       (6, monitor_update_blocked_actions_per_peer, option),
                        (7, self.fake_scid_rand_bytes, required),
                        (9, htlc_purposes, vec_type),
                        (11, self.probing_cookie_secret, required),
@@ -6577,19 +7123,27 @@ where
 /// which you've already broadcasted the transaction.
 ///
 /// [`ChainMonitor`]: crate::chain::chainmonitor::ChainMonitor
-pub struct ChannelManagerReadArgs<'a, M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>
+pub struct ChannelManagerReadArgs<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
 {
+       /// A cryptographically secure source of entropy.
+       pub entropy_source: ES,
+
+       /// A signer that is able to perform node-scoped cryptographic operations.
+       pub node_signer: NS,
+
        /// The keys provider which will give us relevant keys. Some keys will be loaded during
        /// deserialization and KeysInterface::read_chan_signer will be used to read per-Channel
        /// signing data.
-       pub keys_manager: K,
+       pub signer_provider: SP,
 
        /// The fee_estimator for use in the ChannelManager in the future.
        ///
@@ -6630,15 +7184,17 @@ where
        /// this struct.
        ///
        /// (C-not exported) because we have no HashMap bindings
-       pub channel_monitors: HashMap<OutPoint, &'a mut ChannelMonitor<<K::Target as SignerProvider>::Signer>>,
+       pub channel_monitors: HashMap<OutPoint, &'a mut ChannelMonitor<<SP::Target as SignerProvider>::Signer>>,
 }
 
-impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>
-               ChannelManagerReadArgs<'a, M, T, K, F, R, L>
+impl<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
+               ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
@@ -6646,10 +7202,10 @@ where
        /// Simple utility function to create a ChannelManagerReadArgs which creates the monitor
        /// HashMap for you. This is primarily useful for C bindings where it is not practical to
        /// populate a HashMap directly from C.
-       pub fn new(keys_manager: K, fee_estimator: F, chain_monitor: M, tx_broadcaster: T, router: R, logger: L, default_config: UserConfig,
-                       mut channel_monitors: Vec<&'a mut ChannelMonitor<<K::Target as SignerProvider>::Signer>>) -> Self {
+       pub fn new(entropy_source: ES, node_signer: NS, signer_provider: SP, fee_estimator: F, chain_monitor: M, tx_broadcaster: T, router: R, logger: L, default_config: UserConfig,
+                       mut channel_monitors: Vec<&'a mut ChannelMonitor<<SP::Target as SignerProvider>::Signer>>) -> Self {
                Self {
-                       keys_manager, fee_estimator, chain_monitor, tx_broadcaster, router, logger, default_config,
+                       entropy_source, node_signer, signer_provider, fee_estimator, chain_monitor, tx_broadcaster, router, logger, default_config,
                        channel_monitors: channel_monitors.drain(..).map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect()
                }
        }
@@ -6657,33 +7213,37 @@ where
 
 // Implement ReadableArgs for an Arc'd ChannelManager to make it a bit easier to work with the
 // SipmleArcChannelManager type:
-impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>
-       ReadableArgs<ChannelManagerReadArgs<'a, M, T, K, F, R, L>> for (BlockHash, Arc<ChannelManager<M, T, K, F, R, L>>)
+impl<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
+       ReadableArgs<ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, L>> for (BlockHash, Arc<ChannelManager<M, T, ES, NS, SP, F, R, L>>)
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
 {
-       fn read<Reader: io::Read>(reader: &mut Reader, args: ChannelManagerReadArgs<'a, M, T, K, F, R, L>) -> Result<Self, DecodeError> {
-               let (blockhash, chan_manager) = <(BlockHash, ChannelManager<M, T, K, F, R, L>)>::read(reader, args)?;
+       fn read<Reader: io::Read>(reader: &mut Reader, args: ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, L>) -> Result<Self, DecodeError> {
+               let (blockhash, chan_manager) = <(BlockHash, ChannelManager<M, T, ES, NS, SP, F, R, L>)>::read(reader, args)?;
                Ok((blockhash, Arc::new(chan_manager)))
        }
 }
 
-impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref>
-       ReadableArgs<ChannelManagerReadArgs<'a, M, T, K, F, R, L>> for (BlockHash, ChannelManager<M, T, K, F, R, L>)
+impl<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
+       ReadableArgs<ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, L>> for (BlockHash, ChannelManager<M, T, ES, NS, SP, F, R, L>)
 where
-       M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
        F::Target: FeeEstimator,
        R::Target: Router,
        L::Target: Logger,
 {
-       fn read<Reader: io::Read>(reader: &mut Reader, mut args: ChannelManagerReadArgs<'a, M, T, K, F, R, L>) -> Result<Self, DecodeError> {
+       fn read<Reader: io::Read>(reader: &mut Reader, mut args: ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, L>) -> Result<Self, DecodeError> {
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                let genesis_hash: BlockHash = Readable::read(reader)?;
@@ -6694,12 +7254,14 @@ where
 
                let channel_count: u64 = Readable::read(reader)?;
                let mut funding_txo_set = HashSet::with_capacity(cmp::min(channel_count as usize, 128));
-               let mut by_id = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
+               let mut peer_channels: HashMap<PublicKey, HashMap<[u8; 32], Channel<<SP::Target as SignerProvider>::Signer>>> = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
                let mut id_to_peer = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
                let mut short_to_chan_info = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
                let mut channel_closures = Vec::new();
                for _ in 0..channel_count {
-                       let mut channel: Channel<<K::Target as SignerProvider>::Signer> = Channel::read(reader, (&args.keys_manager, best_block_height))?;
+                       let mut channel: Channel<<SP::Target as SignerProvider>::Signer> = Channel::read(reader, (
+                               &args.entropy_source, &args.signer_provider, best_block_height, &provided_channel_type_features(&args.default_config)
+                       ))?;
                        let funding_txo = channel.get_funding_txo().ok_or(DecodeError::InvalidValue)?;
                        funding_txo_set.insert(funding_txo.clone());
                        if let Some(ref mut monitor) = args.channel_monitors.get_mut(&funding_txo) {
@@ -6760,7 +7322,17 @@ where
                                        if channel.is_funding_initiated() {
                                                id_to_peer.insert(channel.channel_id(), channel.get_counterparty_node_id());
                                        }
-                                       by_id.insert(channel.channel_id(), channel);
+                                       match peer_channels.entry(channel.get_counterparty_node_id()) {
+                                               hash_map::Entry::Occupied(mut entry) => {
+                                                       let by_id_map = entry.get_mut();
+                                                       by_id_map.insert(channel.channel_id(), channel);
+                                               },
+                                               hash_map::Entry::Vacant(entry) => {
+                                                       let mut by_id_map = HashMap::new();
+                                                       by_id_map.insert(channel.channel_id(), channel);
+                                                       entry.insert(by_id_map);
+                                               }
+                                       }
                                }
                        } else if channel.is_awaiting_initial_mon_persist() {
                                // If we were persisted and shut down while the initial ChannelMonitor persistence
@@ -6782,7 +7354,7 @@ where
                        }
                }
 
-               for (ref funding_txo, ref mut monitor) in args.channel_monitors.iter_mut() {
+               for (funding_txo, monitor) in args.channel_monitors.iter_mut() {
                        if !funding_txo_set.contains(funding_txo) {
                                log_info!(args.logger, "Broadcasting latest holder commitment transaction for closed channel {}", log_bytes!(funding_txo.to_channel_id()));
                                monitor.broadcast_latest_holder_commitment_txn(&args.tx_broadcaster, &args.logger);
@@ -6815,11 +7387,15 @@ where
                }
 
                let peer_count: u64 = Readable::read(reader)?;
-               let mut per_peer_state = HashMap::with_capacity(cmp::min(peer_count as usize, MAX_ALLOC_SIZE/mem::size_of::<(PublicKey, Mutex<PeerState>)>()));
+               let mut per_peer_state = HashMap::with_capacity(cmp::min(peer_count as usize, MAX_ALLOC_SIZE/mem::size_of::<(PublicKey, Mutex<PeerState<<SP::Target as SignerProvider>::Signer>>)>()));
                for _ in 0..peer_count {
                        let peer_pubkey = Readable::read(reader)?;
                        let peer_state = PeerState {
+                               channel_by_id: peer_channels.remove(&peer_pubkey).unwrap_or(HashMap::new()),
                                latest_features: Readable::read(reader)?,
+                               pending_msg_events: Vec::new(),
+                               monitor_update_blocked_actions: BTreeMap::new(),
+                               is_connected: false,
                        };
                        per_peer_state.insert(peer_pubkey, Mutex::new(peer_state));
                }
@@ -6875,22 +7451,28 @@ where
                let mut probing_cookie_secret: Option<[u8; 32]> = None;
                let mut claimable_htlc_purposes = None;
                let mut pending_claiming_payments = Some(HashMap::new());
+               let mut monitor_update_blocked_actions_per_peer = Some(Vec::new());
                read_tlv_fields!(reader, {
                        (1, pending_outbound_payments_no_retry, option),
                        (2, pending_intercepted_htlcs, option),
                        (3, pending_outbound_payments, option),
                        (4, pending_claiming_payments, option),
                        (5, received_network_pubkey, option),
+                       (6, monitor_update_blocked_actions_per_peer, option),
                        (7, fake_scid_rand_bytes, option),
                        (9, claimable_htlc_purposes, vec_type),
                        (11, probing_cookie_secret, option),
                });
                if fake_scid_rand_bytes.is_none() {
-                       fake_scid_rand_bytes = Some(args.keys_manager.get_secure_random_bytes());
+                       fake_scid_rand_bytes = Some(args.entropy_source.get_secure_random_bytes());
                }
 
                if probing_cookie_secret.is_none() {
-                       probing_cookie_secret = Some(args.keys_manager.get_secure_random_bytes());
+                       probing_cookie_secret = Some(args.entropy_source.get_secure_random_bytes());
+               }
+
+               if !channel_closures.is_empty() {
+                       pending_events_read.append(&mut channel_closures);
                }
 
                if pending_outbound_payments.is_none() && pending_outbound_payments_no_retry.is_none() {
@@ -6901,7 +7483,13 @@ where
                                outbounds.insert(id, PendingOutboundPayment::Legacy { session_privs });
                        }
                        pending_outbound_payments = Some(outbounds);
-               } else {
+               }
+               let pending_outbounds = OutboundPayments {
+                       pending_outbound_payments: Mutex::new(pending_outbound_payments.unwrap()),
+                       retry_lock: Mutex::new(())
+               };
+
+               {
                        // If we're tracking pending payments, ensure we haven't lost any by looking at the
                        // ChannelMonitor data for any channels for which we do not have authorative state
                        // (i.e. those for which we just force-closed above or we otherwise don't have a
@@ -6911,17 +7499,18 @@ where
                        // We only rebuild the pending payments map if we were most recently serialized by
                        // 0.0.102+
                        for (_, monitor) in args.channel_monitors.iter() {
-                               if by_id.get(&monitor.get_funding_txo().0.to_channel_id()).is_none() {
-                                       for (htlc_source, htlc) in monitor.get_pending_outbound_htlcs() {
+                               if id_to_peer.get(&monitor.get_funding_txo().0.to_channel_id()).is_none() {
+                                       for (htlc_source, (htlc, _)) in monitor.get_pending_or_resolved_outbound_htlcs() {
                                                if let HTLCSource::OutboundRoute { payment_id, session_priv, path, payment_secret, .. } = htlc_source {
                                                        if path.is_empty() {
                                                                log_error!(args.logger, "Got an empty path for a pending payment");
                                                                return Err(DecodeError::InvalidValue);
                                                        }
+
                                                        let path_amt = path.last().unwrap().fee_msat;
                                                        let mut session_priv_bytes = [0; 32];
                                                        session_priv_bytes[..].copy_from_slice(&session_priv[..]);
-                                                       match pending_outbound_payments.as_mut().unwrap().entry(payment_id) {
+                                                       match pending_outbounds.pending_outbound_payments.lock().unwrap().entry(payment_id) {
                                                                hash_map::Entry::Occupied(mut entry) => {
                                                                        let newly_added = entry.get_mut().insert(session_priv_bytes, &path);
                                                                        log_info!(args.logger, "{} a pending payment path for {} msat for session priv {} on an existing pending payment with payment hash {}",
@@ -6930,9 +7519,13 @@ where
                                                                hash_map::Entry::Vacant(entry) => {
                                                                        let path_fee = path.get_path_fees();
                                                                        entry.insert(PendingOutboundPayment::Retryable {
+                                                                               retry_strategy: None,
+                                                                               attempts: PaymentAttempts::new(),
+                                                                               payment_params: None,
                                                                                session_privs: [session_priv_bytes].iter().map(|a| *a).collect(),
                                                                                payment_hash: htlc.payment_hash,
                                                                                payment_secret,
+                                                                               keysend_preimage: None, // only used for retries, and we'll never retry on startup
                                                                                pending_amt_msat: path_amt,
                                                                                pending_fee_msat: Some(path_fee),
                                                                                total_msat: path_amt,
@@ -6944,48 +7537,65 @@ where
                                                        }
                                                }
                                        }
-                                       for (htlc_source, htlc) in monitor.get_all_current_outbound_htlcs() {
-                                               if let HTLCSource::PreviousHopData(prev_hop_data) = htlc_source {
-                                                       let pending_forward_matches_htlc = |info: &PendingAddHTLCInfo| {
-                                                               info.prev_funding_outpoint == prev_hop_data.outpoint &&
-                                                                       info.prev_htlc_id == prev_hop_data.htlc_id
-                                                       };
-                                                       // The ChannelMonitor is now responsible for this HTLC's
-                                                       // failure/success and will let us know what its outcome is. If we
-                                                       // still have an entry for this HTLC in `forward_htlcs` or
-                                                       // `pending_intercepted_htlcs`, we were apparently not persisted after
-                                                       // the monitor was when forwarding the payment.
-                                                       forward_htlcs.retain(|_, forwards| {
-                                                               forwards.retain(|forward| {
-                                                                       if let HTLCForwardInfo::AddHTLC(htlc_info) = forward {
-                                                                               if pending_forward_matches_htlc(&htlc_info) {
-                                                                                       log_info!(args.logger, "Removing pending to-forward HTLC with hash {} as it was forwarded to the closed channel {}",
-                                                                                               log_bytes!(htlc.payment_hash.0), log_bytes!(monitor.get_funding_txo().0.to_channel_id()));
-                                                                                       false
+                                       for (htlc_source, (htlc, preimage_opt)) in monitor.get_all_current_outbound_htlcs() {
+                                               match htlc_source {
+                                                       HTLCSource::PreviousHopData(prev_hop_data) => {
+                                                               let pending_forward_matches_htlc = |info: &PendingAddHTLCInfo| {
+                                                                       info.prev_funding_outpoint == prev_hop_data.outpoint &&
+                                                                               info.prev_htlc_id == prev_hop_data.htlc_id
+                                                               };
+                                                               // The ChannelMonitor is now responsible for this HTLC's
+                                                               // failure/success and will let us know what its outcome is. If we
+                                                               // still have an entry for this HTLC in `forward_htlcs` or
+                                                               // `pending_intercepted_htlcs`, we were apparently not persisted after
+                                                               // the monitor was when forwarding the payment.
+                                                               forward_htlcs.retain(|_, forwards| {
+                                                                       forwards.retain(|forward| {
+                                                                               if let HTLCForwardInfo::AddHTLC(htlc_info) = forward {
+                                                                                       if pending_forward_matches_htlc(&htlc_info) {
+                                                                                               log_info!(args.logger, "Removing pending to-forward HTLC with hash {} as it was forwarded to the closed channel {}",
+                                                                                                       log_bytes!(htlc.payment_hash.0), log_bytes!(monitor.get_funding_txo().0.to_channel_id()));
+                                                                                               false
+                                                                                       } else { true }
                                                                                } else { true }
+                                                                       });
+                                                                       !forwards.is_empty()
+                                                               });
+                                                               pending_intercepted_htlcs.as_mut().unwrap().retain(|intercepted_id, htlc_info| {
+                                                                       if pending_forward_matches_htlc(&htlc_info) {
+                                                                               log_info!(args.logger, "Removing pending intercepted HTLC with hash {} as it was forwarded to the closed channel {}",
+                                                                                       log_bytes!(htlc.payment_hash.0), log_bytes!(monitor.get_funding_txo().0.to_channel_id()));
+                                                                               pending_events_read.retain(|event| {
+                                                                                       if let Event::HTLCIntercepted { intercept_id: ev_id, .. } = event {
+                                                                                               intercepted_id != ev_id
+                                                                                       } else { true }
+                                                                               });
+                                                                               false
                                                                        } else { true }
                                                                });
-                                                               !forwards.is_empty()
-                                                       });
-                                                       pending_intercepted_htlcs.as_mut().unwrap().retain(|intercepted_id, htlc_info| {
-                                                               if pending_forward_matches_htlc(&htlc_info) {
-                                                                       log_info!(args.logger, "Removing pending intercepted HTLC with hash {} as it was forwarded to the closed channel {}",
-                                                                               log_bytes!(htlc.payment_hash.0), log_bytes!(monitor.get_funding_txo().0.to_channel_id()));
-                                                                       pending_events_read.retain(|event| {
-                                                                               if let Event::HTLCIntercepted { intercept_id: ev_id, .. } = event {
-                                                                                       intercepted_id != ev_id
-                                                                               } else { true }
-                                                                       });
-                                                                       false
-                                                               } else { true }
-                                                       });
+                                                       },
+                                                       HTLCSource::OutboundRoute { payment_id, session_priv, path, .. } => {
+                                                               if let Some(preimage) = preimage_opt {
+                                                                       let pending_events = Mutex::new(pending_events_read);
+                                                                       // Note that we set `from_onchain` to "false" here,
+                                                                       // deliberately keeping the pending payment around forever.
+                                                                       // Given it should only occur when we have a channel we're
+                                                                       // force-closing for being stale that's okay.
+                                                                       // The alternative would be to wipe the state when claiming,
+                                                                       // generating a `PaymentPathSuccessful` event but regenerating
+                                                                       // it and the `PaymentSent` on every restart until the
+                                                                       // `ChannelMonitor` is removed.
+                                                                       pending_outbounds.claim_htlc(payment_id, preimage, session_priv, path, false, &pending_events, &args.logger);
+                                                                       pending_events_read = pending_events.into_inner().unwrap();
+                                                               }
+                                                       },
                                                }
                                        }
                                }
                        }
                }
 
-               if !forward_htlcs.is_empty() {
+               if !forward_htlcs.is_empty() || pending_outbounds.needs_abandon() {
                        // If we have pending HTLCs to forward, assume we either dropped a
                        // `PendingHTLCsForwardable` or the user received it but never processed it as they
                        // shut down before the timer hit. Either way, set the time_forwardable to a small
@@ -6996,7 +7606,7 @@ where
                        });
                }
 
-               let inbound_pmt_key_material = args.keys_manager.get_inbound_payment_key_material();
+               let inbound_pmt_key_material = args.node_signer.get_inbound_payment_key_material();
                let expanded_inbound_key = inbound_payment::ExpandedKey::new(&inbound_pmt_key_material);
 
                let mut claimable_htlcs = HashMap::with_capacity(claimable_htlcs_list.len());
@@ -7021,7 +7631,7 @@ where
                                                                payment_preimage: match pending_inbound_payments.get(&payment_hash) {
                                                                        Some(inbound_payment) => inbound_payment.payment_preimage,
                                                                        None => match inbound_payment::verify(payment_hash, &hop_data, 0, &expanded_inbound_key, &args.logger) {
-                                                                               Ok(payment_preimage) => payment_preimage,
+                                                                               Ok((payment_preimage, _)) => payment_preimage,
                                                                                Err(()) => {
                                                                                        log_error!(args.logger, "Failed to read claimable payment data for HTLC with payment hash {} - was not a pending inbound payment and didn't match our payment key", log_bytes!(payment_hash.0));
                                                                                        return Err(DecodeError::InvalidValue);
@@ -7040,17 +7650,12 @@ where
                }
 
                let mut secp_ctx = Secp256k1::new();
-               secp_ctx.seeded_randomize(&args.keys_manager.get_secure_random_bytes());
-
-               if !channel_closures.is_empty() {
-                       pending_events_read.append(&mut channel_closures);
-               }
+               secp_ctx.seeded_randomize(&args.entropy_source.get_secure_random_bytes());
 
-               let our_network_key = match args.keys_manager.get_node_secret(Recipient::Node) {
+               let our_network_pubkey = match args.node_signer.get_node_id(Recipient::Node) {
                        Ok(key) => key,
                        Err(()) => return Err(DecodeError::InvalidValue)
                };
-               let our_network_pubkey = PublicKey::from_secret_key(&secp_ctx, &our_network_key);
                if let Some(network_pubkey) = received_network_pubkey {
                        if network_pubkey != our_network_pubkey {
                                log_error!(args.logger, "Key that was generated does not match the existing key.");
@@ -7059,28 +7664,32 @@ where
                }
 
                let mut outbound_scid_aliases = HashSet::new();
-               for (chan_id, chan) in by_id.iter_mut() {
-                       if chan.outbound_scid_alias() == 0 {
-                               let mut outbound_scid_alias;
-                               loop {
-                                       outbound_scid_alias = fake_scid::Namespace::OutboundAlias
-                                               .get_fake_scid(best_block_height, &genesis_hash, fake_scid_rand_bytes.as_ref().unwrap(), &args.keys_manager);
-                                       if outbound_scid_aliases.insert(outbound_scid_alias) { break; }
-                               }
-                               chan.set_outbound_scid_alias(outbound_scid_alias);
-                       } else if !outbound_scid_aliases.insert(chan.outbound_scid_alias()) {
-                               // Note that in rare cases its possible to hit this while reading an older
-                               // channel if we just happened to pick a colliding outbound alias above.
-                               log_error!(args.logger, "Got duplicate outbound SCID alias; {}", chan.outbound_scid_alias());
-                               return Err(DecodeError::InvalidValue);
-                       }
-                       if chan.is_usable() {
-                               if short_to_chan_info.insert(chan.outbound_scid_alias(), (chan.get_counterparty_node_id(), *chan_id)).is_some() {
+               for (_peer_node_id, peer_state_mutex) in per_peer_state.iter_mut() {
+                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                       let peer_state = &mut *peer_state_lock;
+                       for (chan_id, chan) in peer_state.channel_by_id.iter_mut() {
+                               if chan.outbound_scid_alias() == 0 {
+                                       let mut outbound_scid_alias;
+                                       loop {
+                                               outbound_scid_alias = fake_scid::Namespace::OutboundAlias
+                                                       .get_fake_scid(best_block_height, &genesis_hash, fake_scid_rand_bytes.as_ref().unwrap(), &args.entropy_source);
+                                               if outbound_scid_aliases.insert(outbound_scid_alias) { break; }
+                                       }
+                                       chan.set_outbound_scid_alias(outbound_scid_alias);
+                               } else if !outbound_scid_aliases.insert(chan.outbound_scid_alias()) {
                                        // Note that in rare cases its possible to hit this while reading an older
                                        // channel if we just happened to pick a colliding outbound alias above.
                                        log_error!(args.logger, "Got duplicate outbound SCID alias; {}", chan.outbound_scid_alias());
                                        return Err(DecodeError::InvalidValue);
                                }
+                               if chan.is_usable() {
+                                       if short_to_chan_info.insert(chan.outbound_scid_alias(), (chan.get_counterparty_node_id(), *chan_id)).is_some() {
+                                               // Note that in rare cases its possible to hit this while reading an older
+                                               // channel if we just happened to pick a colliding outbound alias above.
+                                               log_error!(args.logger, "Got duplicate outbound SCID alias; {}", chan.outbound_scid_alias());
+                                               return Err(DecodeError::InvalidValue);
+                                       }
+                               }
                        }
                }
 
@@ -7094,7 +7703,7 @@ where
                                        let mut receiver_node_id = Some(our_network_pubkey);
                                        let phantom_shared_secret = claimable_htlcs[0].prev_hop.phantom_shared_secret;
                                        if phantom_shared_secret.is_some() {
-                                               let phantom_pubkey = args.keys_manager.get_node_id(Recipient::PhantomNode)
+                                               let phantom_pubkey = args.node_signer.get_node_id(Recipient::PhantomNode)
                                                        .expect("Failed to get node_id for phantom node recipient");
                                                receiver_node_id = Some(phantom_pubkey)
                                        }
@@ -7117,8 +7726,13 @@ where
                                                // without the new monitor persisted - we'll end up right back here on
                                                // restart.
                                                let previous_channel_id = claimable_htlc.prev_hop.outpoint.to_channel_id();
-                                               if let Some(channel) = by_id.get_mut(&previous_channel_id) {
-                                                       channel.claim_htlc_while_disconnected_dropping_mon_update(claimable_htlc.prev_hop.htlc_id, payment_preimage, &args.logger);
+                                               if let Some(peer_node_id) = id_to_peer.get(&previous_channel_id){
+                                                       let peer_state_mutex = per_peer_state.get(peer_node_id).unwrap();
+                                                       let mut peer_state_lock = peer_state_mutex.lock().unwrap();
+                                                       let peer_state = &mut *peer_state_lock;
+                                                       if let Some(channel) = peer_state.channel_by_id.get_mut(&previous_channel_id) {
+                                                               channel.claim_htlc_while_disconnected_dropping_mon_update(claimable_htlc.prev_hop.htlc_id, payment_preimage, &args.logger);
+                                                       }
                                                }
                                                if let Some(previous_hop_monitor) = args.channel_monitors.get(&claimable_htlc.prev_hop.outpoint) {
                                                        previous_hop_monitor.provide_payment_preimage(&payment_hash, &payment_preimage, &args.tx_broadcaster, &bounded_fee_estimator, &args.logger);
@@ -7134,6 +7748,15 @@ where
                        }
                }
 
+               for (node_id, monitor_update_blocked_actions) in monitor_update_blocked_actions_per_peer.unwrap() {
+                       if let Some(peer_state) = per_peer_state.get_mut(&node_id) {
+                               peer_state.lock().unwrap().monitor_update_blocked_actions = monitor_update_blocked_actions;
+                       } else {
+                               log_error!(args.logger, "Got blocked actions without a per-peer-state for {}", node_id);
+                               return Err(DecodeError::InvalidValue);
+                       }
+               }
+
                let channel_manager = ChannelManager {
                        genesis_hash,
                        fee_estimator: bounded_fee_estimator,
@@ -7143,13 +7766,9 @@ where
 
                        best_block: RwLock::new(BestBlock::new(best_block_hash, best_block_height)),
 
-                       channel_state: Mutex::new(ChannelHolder {
-                               by_id,
-                               pending_msg_events: Vec::new(),
-                       }),
                        inbound_payment_key: expanded_inbound_key,
                        pending_inbound_payments: Mutex::new(pending_inbound_payments),
-                       pending_outbound_payments: OutboundPayments { pending_outbound_payments: Mutex::new(pending_outbound_payments.unwrap()) },
+                       pending_outbound_payments: pending_outbounds,
                        pending_intercepted_htlcs: Mutex::new(pending_intercepted_htlcs.unwrap()),
 
                        forward_htlcs: Mutex::new(forward_htlcs),
@@ -7161,20 +7780,22 @@ where
 
                        probing_cookie_secret: probing_cookie_secret.unwrap(),
 
-                       our_network_key,
                        our_network_pubkey,
                        secp_ctx,
 
                        highest_seen_timestamp: AtomicUsize::new(highest_seen_timestamp as usize),
 
-                       per_peer_state: RwLock::new(per_peer_state),
+                       per_peer_state: FairRwLock::new(per_peer_state),
 
                        pending_events: Mutex::new(pending_events_read),
                        pending_background_events: Mutex::new(pending_background_events_read),
                        total_consistency_lock: RwLock::new(()),
                        persistence_notifier: Notifier::new(),
 
-                       keys_manager: args.keys_manager,
+                       entropy_source: args.entropy_source,
+                       node_signer: args.node_signer,
+                       signer_provider: args.signer_provider,
+
                        logger: args.logger,
                        default_configuration: args.default_config,
                };
@@ -7197,10 +7818,11 @@ where
 mod tests {
        use bitcoin::hashes::Hash;
        use bitcoin::hashes::sha256::Hash as Sha256;
+       use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
        use core::time::Duration;
        use core::sync::atomic::Ordering;
        use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
-       use crate::ln::channelmanager::{self, inbound_payment, PaymentId, PaymentSendFailure};
+       use crate::ln::channelmanager::{inbound_payment, PaymentId, PaymentSendFailure, InterceptId};
        use crate::ln::functional_test_utils::*;
        use crate::ln::msgs;
        use crate::ln::msgs::ChannelMessageHandler;
@@ -7208,7 +7830,8 @@ mod tests {
        use crate::util::errors::APIError;
        use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
        use crate::util::test_utils;
-       use crate::chain::keysinterface::{EntropySource, KeysInterface};
+       use crate::util::config::ChannelConfig;
+       use crate::chain::keysinterface::EntropySource;
 
        #[test]
        fn test_notify_limits() {
@@ -7225,7 +7848,7 @@ mod tests {
                assert!(nodes[1].node.await_persistable_update_timeout(Duration::from_millis(1)));
                assert!(nodes[2].node.await_persistable_update_timeout(Duration::from_millis(1)));
 
-               let mut chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let mut chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
                // We check that the channel info nodes have doesn't change too early, even though we try
                // to connect messages with new values
@@ -7296,7 +7919,7 @@ mod tests {
                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);
-               create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes(&nodes, 0, 1);
 
                // First, send a partial MPP payment.
                let (route, our_payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], 100_000);
@@ -7308,7 +7931,7 @@ mod tests {
                // indicates there are more HTLCs coming.
                let cur_height = CHAN_CONFIRM_DEPTH + 1; // route_payment calls send_payment, which adds 1 to the current height. So we do the same here to match.
                let session_privs = nodes[0].node.test_add_new_pending_payment(our_payment_hash, Some(payment_secret), payment_id, &mpp_route).unwrap();
-               nodes[0].node.send_payment_along_path(&mpp_route.paths[0], &route.payment_params, &our_payment_hash, &Some(payment_secret), 200_000, cur_height, payment_id, &None, session_privs[0]).unwrap();
+               nodes[0].node.test_send_payment_along_path(&mpp_route.paths[0], &route.payment_params, &our_payment_hash, &Some(payment_secret), 200_000, cur_height, payment_id, &None, session_privs[0]).unwrap();
                check_added_monitors!(nodes[0], 1);
                let mut events = nodes[0].node.get_and_clear_pending_msg_events();
                assert_eq!(events.len(), 1);
@@ -7338,7 +7961,7 @@ mod tests {
                expect_payment_failed!(nodes[0], our_payment_hash, true);
 
                // Send the second half of the original MPP payment.
-               nodes[0].node.send_payment_along_path(&mpp_route.paths[1], &route.payment_params, &our_payment_hash, &Some(payment_secret), 200_000, cur_height, payment_id, &None, session_privs[1]).unwrap();
+               nodes[0].node.test_send_payment_along_path(&mpp_route.paths[1], &route.payment_params, &our_payment_hash, &Some(payment_secret), 200_000, cur_height, payment_id, &None, session_privs[1]).unwrap();
                check_added_monitors!(nodes[0], 1);
                let mut events = nodes[0].node.get_and_clear_pending_msg_events();
                assert_eq!(events.len(), 1);
@@ -7418,8 +8041,8 @@ mod tests {
                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);
-               create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               let scorer = test_utils::TestScorer::with_penalty(0);
+               create_announced_chan_between_nodes(&nodes, 0, 1);
+               let scorer = test_utils::TestScorer::new();
                let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
 
                // To start (1), send a regular payment but don't claim it.
@@ -7428,9 +8051,8 @@ mod tests {
 
                // Next, attempt a keysend payment and make sure it fails.
                let route_params = RouteParameters {
-                       payment_params: PaymentParameters::for_keysend(expected_route.last().unwrap().node.get_our_node_id()),
+                       payment_params: PaymentParameters::for_keysend(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV),
                        final_value_msat: 100_000,
-                       final_cltv_expiry_delta: TEST_FINAL_CLTV,
                };
                let route = find_route(
                        &nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph,
@@ -7516,18 +8138,15 @@ mod tests {
 
                let payer_pubkey = nodes[0].node.get_our_node_id();
                let payee_pubkey = nodes[1].node.get_our_node_id();
-               nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-               nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
 
-               let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let _chan = create_chan_between_nodes(&nodes[0], &nodes[1]);
                let route_params = RouteParameters {
-                       payment_params: PaymentParameters::for_keysend(payee_pubkey),
+                       payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
                        final_value_msat: 10_000,
-                       final_cltv_expiry_delta: 40,
                };
                let network_graph = nodes[0].network_graph.clone();
                let first_hops = nodes[0].node.list_usable_channels();
-               let scorer = test_utils::TestScorer::with_penalty(0);
+               let scorer = test_utils::TestScorer::new();
                let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
                let route = find_route(
                        &payer_pubkey, &route_params, &network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
@@ -7561,18 +8180,15 @@ mod tests {
 
                let payer_pubkey = nodes[0].node.get_our_node_id();
                let payee_pubkey = nodes[1].node.get_our_node_id();
-               nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-               nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
 
-               let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let _chan = create_chan_between_nodes(&nodes[0], &nodes[1]);
                let route_params = RouteParameters {
-                       payment_params: PaymentParameters::for_keysend(payee_pubkey),
+                       payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
                        final_value_msat: 10_000,
-                       final_cltv_expiry_delta: 40,
                };
                let network_graph = nodes[0].network_graph.clone();
                let first_hops = nodes[0].node.list_usable_channels();
-               let scorer = test_utils::TestScorer::with_penalty(0);
+               let scorer = test_utils::TestScorer::new();
                let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
                let route = find_route(
                        &payer_pubkey, &route_params, &network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
@@ -7604,10 +8220,10 @@ mod tests {
                let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
                let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-               let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-               let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-               let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-               let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
+               let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+               let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2).0.contents.short_channel_id;
+               let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3).0.contents.short_channel_id;
+               let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3).0.contents.short_channel_id;
 
                // Marshall an MPP route.
                let (mut route, payment_hash, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[3], 100000);
@@ -7627,6 +8243,40 @@ mod tests {
                }
        }
 
+       #[test]
+       fn test_drop_disconnected_peers_when_removing_channels() {
+               let chanmon_cfgs = create_chanmon_cfgs(2);
+               let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+               let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+               let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+               let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+
+               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
+
+               nodes[0].node.force_close_broadcasting_latest_txn(&chan.2, &nodes[1].node.get_our_node_id()).unwrap();
+               check_closed_broadcast!(nodes[0], true);
+               check_added_monitors!(nodes[0], 1);
+               check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed);
+
+               {
+                       // Assert that nodes[1] is awaiting removal for nodes[0] once nodes[1] has been
+                       // disconnected and the channel between has been force closed.
+                       let nodes_0_per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+                       // Assert that nodes[1] isn't removed before `timer_tick_occurred` has been executed.
+                       assert_eq!(nodes_0_per_peer_state.len(), 1);
+                       assert!(nodes_0_per_peer_state.get(&nodes[1].node.get_our_node_id()).is_some());
+               }
+
+               nodes[0].node.timer_tick_occurred();
+
+               {
+                       // Assert that nodes[1] has now been removed.
+                       assert_eq!(nodes[0].node.per_peer_state.read().unwrap().len(), 0);
+               }
+       }
+
        #[test]
        fn bad_inbound_payment_hash() {
                // Add coverage for checking that a user-provided payment hash matches the payment secret.
@@ -7668,9 +8318,9 @@ mod tests {
 
                nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1_000_000, 500_000_000, 42, None).unwrap();
                let open_channel = 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(), channelmanager::provided_init_features(), &open_channel);
+               nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
                let accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
-               nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+               nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
 
                let (temporary_channel_id, tx, _funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 1_000_000, 42);
                let channel_id = &tx.txid().into_inner();
@@ -7688,10 +8338,10 @@ mod tests {
                        let nodes_0_lock = nodes[0].node.id_to_peer.lock().unwrap();
                        assert_eq!(nodes_0_lock.len(), 1);
                        assert!(nodes_0_lock.contains_key(channel_id));
-
-                       assert_eq!(nodes[1].node.id_to_peer.lock().unwrap().len(), 0);
                }
 
+               assert_eq!(nodes[1].node.id_to_peer.lock().unwrap().len(), 0);
+
                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);
@@ -7699,7 +8349,9 @@ mod tests {
                        let nodes_0_lock = nodes[0].node.id_to_peer.lock().unwrap();
                        assert_eq!(nodes_0_lock.len(), 1);
                        assert!(nodes_0_lock.contains_key(channel_id));
+               }
 
+               {
                        // Assert that `nodes[1]`'s `id_to_peer` map is populated with the channel as soon as
                        // as it has the funding transaction.
                        let nodes_1_lock = nodes[1].node.id_to_peer.lock().unwrap();
@@ -7715,9 +8367,9 @@ mod tests {
                update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &nodes_0_update, &nodes_1_update);
 
                nodes[0].node.close_channel(channel_id, &nodes[1].node.get_our_node_id()).unwrap();
-               nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()));
+               nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()));
                let nodes_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
-               nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &nodes_1_shutdown);
+               nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &nodes_1_shutdown);
 
                let closing_signed_node_0 = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
                nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &closing_signed_node_0);
@@ -7729,7 +8381,9 @@ mod tests {
                        let nodes_0_lock = nodes[0].node.id_to_peer.lock().unwrap();
                        assert_eq!(nodes_0_lock.len(), 1);
                        assert!(nodes_0_lock.contains_key(channel_id));
+               }
 
+               {
                        // At this stage, `nodes[1]` has proposed a fee for the closing transaction in the
                        // `handle_closing_signed` call above. As `nodes[1]` has not yet received the signature
                        // from `nodes[0]` for the closing transaction with the proposed fee, the channel is
@@ -7768,13 +8422,310 @@ mod tests {
                check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure);
                check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure);
        }
+
+       fn check_not_connected_to_peer_error<T>(res_err: Result<T, APIError>, expected_public_key: PublicKey) {
+               let expected_message = format!("Not connected to node: {}", expected_public_key);
+               check_api_error_message(expected_message, res_err)
+       }
+
+       fn check_unkown_peer_error<T>(res_err: Result<T, APIError>, expected_public_key: PublicKey) {
+               let expected_message = format!("Can't find a peer matching the passed counterparty node_id {}", expected_public_key);
+               check_api_error_message(expected_message, res_err)
+       }
+
+       fn check_api_error_message<T>(expected_err_message: String, res_err: Result<T, APIError>) {
+               match res_err {
+                       Err(APIError::APIMisuseError { err }) => {
+                               assert_eq!(err, expected_err_message);
+                       },
+                       Err(APIError::ChannelUnavailable { err }) => {
+                               assert_eq!(err, expected_err_message);
+                       },
+                       Ok(_) => panic!("Unexpected Ok"),
+                       Err(_) => panic!("Unexpected Error"),
+               }
+       }
+
+       #[test]
+       fn test_api_calls_with_unkown_counterparty_node() {
+               // Tests that our API functions that expects a `counterparty_node_id` as input, behaves as
+               // expected if the `counterparty_node_id` is an unkown peer in the
+               // `ChannelManager::per_peer_state` map.
+               let chanmon_cfg = create_chanmon_cfgs(2);
+               let node_cfg = create_node_cfgs(2, &chanmon_cfg);
+               let node_chanmgr = create_node_chanmgrs(2, &node_cfg, &[None, None]);
+               let nodes = create_network(2, &node_cfg, &node_chanmgr);
+
+               // Dummy values
+               let channel_id = [4; 32];
+               let unkown_public_key = PublicKey::from_secret_key(&Secp256k1::signing_only(), &SecretKey::from_slice(&[42; 32]).unwrap());
+               let intercept_id = InterceptId([0; 32]);
+
+               // Test the API functions.
+               check_not_connected_to_peer_error(nodes[0].node.create_channel(unkown_public_key, 1_000_000, 500_000_000, 42, None), unkown_public_key);
+
+               check_unkown_peer_error(nodes[0].node.accept_inbound_channel(&channel_id, &unkown_public_key, 42), unkown_public_key);
+
+               check_unkown_peer_error(nodes[0].node.close_channel(&channel_id, &unkown_public_key), unkown_public_key);
+
+               check_unkown_peer_error(nodes[0].node.force_close_broadcasting_latest_txn(&channel_id, &unkown_public_key), unkown_public_key);
+
+               check_unkown_peer_error(nodes[0].node.force_close_without_broadcasting_txn(&channel_id, &unkown_public_key), unkown_public_key);
+
+               check_unkown_peer_error(nodes[0].node.forward_intercepted_htlc(intercept_id, &channel_id, unkown_public_key, 1_000_000), unkown_public_key);
+
+               check_unkown_peer_error(nodes[0].node.update_channel_config(&unkown_public_key, &[channel_id], &ChannelConfig::default()), unkown_public_key);
+       }
+
+       #[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);
+                               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);
+                       }
+                       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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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);
+       }
+
+       #[cfg(anchors)]
+       #[test]
+       fn test_anchors_zero_fee_htlc_tx_fallback() {
+               // Tests that if both nodes support anchors, but the remote node does not want to accept
+               // anchor channels at the moment, an error it sent to the local node such that it can retry
+               // the channel without the anchors feature.
+               let chanmon_cfgs = create_chanmon_cfgs(2);
+               let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+               let mut anchors_config = test_default_channel_config();
+               anchors_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
+               anchors_config.manually_accept_inbound_channels = true;
+               let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(anchors_config.clone()), Some(anchors_config.clone())]);
+               let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+               nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 0, None).unwrap();
+               let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+               assert!(open_channel_msg.channel_type.as_ref().unwrap().supports_anchors_zero_fee_htlc_tx());
+
+               nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
+               let events = nodes[1].node.get_and_clear_pending_events();
+               match events[0] {
+                       Event::OpenChannelRequest { temporary_channel_id, .. } => {
+                               nodes[1].node.force_close_broadcasting_latest_txn(&temporary_channel_id, &nodes[0].node.get_our_node_id()).unwrap();
+                       }
+                       _ => panic!("Unexpected event"),
+               }
+
+               let error_msg = get_err_msg!(nodes[1], nodes[0].node.get_our_node_id());
+               nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &error_msg);
+
+               let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+               assert!(!open_channel_msg.channel_type.unwrap().supports_anchors_zero_fee_htlc_tx());
+
+               check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed);
+       }
 }
 
 #[cfg(all(any(test, feature = "_test_utils"), feature = "_bench_unstable"))]
 pub mod bench {
        use crate::chain::Listen;
        use crate::chain::chainmonitor::{ChainMonitor, Persist};
-       use crate::chain::keysinterface::{EntropySource, KeysManager, KeysInterface, InMemorySigner};
+       use crate::chain::keysinterface::{EntropySource, KeysManager, InMemorySigner};
        use crate::ln::channelmanager::{self, BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentId};
        use crate::ln::functional_test_utils::*;
        use crate::ln::msgs::{ChannelMessageHandler, Init};
@@ -7797,7 +8748,7 @@ pub mod bench {
                        &'a ChainMonitor<InMemorySigner, &'a test_utils::TestChainSource,
                                &'a test_utils::TestBroadcaster, &'a test_utils::TestFeeEstimator,
                                &'a test_utils::TestLogger, &'a P>,
-                       &'a test_utils::TestBroadcaster, &'a KeysManager,
+                       &'a test_utils::TestBroadcaster, &'a KeysManager, &'a KeysManager, &'a KeysManager,
                        &'a test_utils::TestFeeEstimator, &'a test_utils::TestRouter<'a>,
                        &'a test_utils::TestLogger>,
        }
@@ -7813,12 +8764,12 @@ pub mod bench {
                // Note that this is unrealistic as each payment send will require at least two fsync
                // calls per node.
                let network = bitcoin::Network::Testnet;
-               let genesis_hash = bitcoin::blockdata::constants::genesis_block(network).header.block_hash();
 
                let tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))};
                let fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) };
                let logger_a = test_utils::TestLogger::with_id("node a".to_owned());
-               let router = test_utils::TestRouter::new(Arc::new(NetworkGraph::new(genesis_hash, &logger_a)));
+               let scorer = Mutex::new(test_utils::TestScorer::new());
+               let router = test_utils::TestRouter::new(Arc::new(NetworkGraph::new(network, &logger_a)), &scorer);
 
                let mut config: UserConfig = Default::default();
                config.channel_handshake_config.minimum_depth = 1;
@@ -7826,9 +8777,9 @@ pub mod bench {
                let chain_monitor_a = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_a);
                let seed_a = [1u8; 32];
                let keys_manager_a = KeysManager::new(&seed_a, 42, 42);
-               let node_a = ChannelManager::new(&fee_estimator, &chain_monitor_a, &tx_broadcaster, &router, &logger_a, &keys_manager_a, config.clone(), ChainParameters {
+               let node_a = ChannelManager::new(&fee_estimator, &chain_monitor_a, &tx_broadcaster, &router, &logger_a, &keys_manager_a, &keys_manager_a, &keys_manager_a, config.clone(), ChainParameters {
                        network,
-                       best_block: BestBlock::from_genesis(network),
+                       best_block: BestBlock::from_network(network),
                });
                let node_a_holder = NodeHolder { node: &node_a };
 
@@ -7836,17 +8787,17 @@ pub mod bench {
                let chain_monitor_b = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_b);
                let seed_b = [2u8; 32];
                let keys_manager_b = KeysManager::new(&seed_b, 42, 42);
-               let node_b = ChannelManager::new(&fee_estimator, &chain_monitor_b, &tx_broadcaster, &router, &logger_b, &keys_manager_b, config.clone(), ChainParameters {
+               let node_b = ChannelManager::new(&fee_estimator, &chain_monitor_b, &tx_broadcaster, &router, &logger_b, &keys_manager_b, &keys_manager_b, &keys_manager_b, config.clone(), ChainParameters {
                        network,
-                       best_block: BestBlock::from_genesis(network),
+                       best_block: BestBlock::from_network(network),
                });
                let node_b_holder = NodeHolder { node: &node_b };
 
-               node_a.peer_connected(&node_b.get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-               node_b.peer_connected(&node_a.get_our_node_id(), &Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+               node_a.peer_connected(&node_b.get_our_node_id(), &Init { features: node_b.init_features(), remote_network_address: None }, true).unwrap();
+               node_b.peer_connected(&node_a.get_our_node_id(), &Init { features: node_a.init_features(), remote_network_address: None }, false).unwrap();
                node_a.create_channel(node_b.get_our_node_id(), 8_000_000, 100_000_000, 42, None).unwrap();
-               node_b.handle_open_channel(&node_a.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(node_a_holder, MessageSendEvent::SendOpenChannel, node_b.get_our_node_id()));
-               node_a.handle_accept_channel(&node_b.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(node_b_holder, MessageSendEvent::SendAcceptChannel, node_a.get_our_node_id()));
+               node_b.handle_open_channel(&node_a.get_our_node_id(), &get_event_msg!(node_a_holder, MessageSendEvent::SendOpenChannel, node_b.get_our_node_id()));
+               node_a.handle_accept_channel(&node_b.get_our_node_id(), &get_event_msg!(node_b_holder, MessageSendEvent::SendAcceptChannel, node_a.get_our_node_id()));
 
                let tx;
                if let Event::FundingGenerationReady { temporary_channel_id, output_script, .. } = get_event!(node_a_holder, Event::FundingGenerationReady) {
@@ -7862,7 +8813,7 @@ pub mod bench {
                assert_eq!(&tx_broadcaster.txn_broadcasted.lock().unwrap()[..], &[tx.clone()]);
 
                let block = Block {
-                       header: BlockHeader { version: 0x20000000, prev_blockhash: genesis_hash, merkle_root: TxMerkleNode::all_zeros(), time: 42, bits: 42, nonce: 42 },
+                       header: BlockHeader { version: 0x20000000, prev_blockhash: BestBlock::from_network(network).block_hash(), merkle_root: TxMerkleNode::all_zeros(), time: 42, bits: 42, nonce: 42 },
                        txdata: vec![tx],
                };
                Listen::block_connected(&node_a, &block, 1);
@@ -7901,15 +8852,15 @@ pub mod bench {
                        _ => panic!("Unexpected event"),
                }
 
-               let dummy_graph = NetworkGraph::new(genesis_hash, &logger_a);
+               let dummy_graph = NetworkGraph::new(network, &logger_a);
 
                let mut payment_count: u64 = 0;
                macro_rules! send_payment {
                        ($node_a: expr, $node_b: expr) => {
                                let usable_channels = $node_a.list_usable_channels();
-                               let payment_params = PaymentParameters::from_node_id($node_b.get_our_node_id())
-                                       .with_features(channelmanager::provided_invoice_features());
-                               let scorer = test_utils::TestScorer::with_penalty(0);
+                               let payment_params = PaymentParameters::from_node_id($node_b.get_our_node_id(), TEST_FINAL_CLTV)
+                                       .with_features($node_b.invoice_features());
+                               let scorer = test_utils::TestScorer::new();
                                let seed = [3u8; 32];
                                let keys_manager = KeysManager::new(&seed, 42, 42);
                                let random_seed_bytes = keys_manager.get_secure_random_bytes();
@@ -7920,7 +8871,7 @@ pub mod bench {
                                payment_preimage.0[0..8].copy_from_slice(&payment_count.to_le_bytes());
                                payment_count += 1;
                                let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
-                               let payment_secret = $node_b.create_inbound_payment_for_hash(payment_hash, None, 7200).unwrap();
+                               let payment_secret = $node_b.create_inbound_payment_for_hash(payment_hash, None, 7200, None).unwrap();
 
                                $node_a.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
                                let payment_event = SendEvent::from_event($node_a.get_and_clear_pending_msg_events().pop().unwrap());
index a3c1b7f623d1f2a355516638e75432e61a04fa71..fe879a5688fedc806a137231899327ffaa5620fd 100644 (file)
 //!     (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).
+//! - `AnchorsZeroFeeHtlcTx` - requires/supports that commitment transactions include anchor outputs
+//!   and HTLC transactions are pre-signed with zero fee (see
+//!   [BOLT-3](https://github.com/lightning/bolts/blob/master/03-transactions.md) for more
+//!   information).
 //!
 //! [BOLT #9]: https://github.com/lightning/bolts/blob/master/09-features.md
 //! [messages]: crate::ln::msgs
@@ -122,7 +126,7 @@ mod sealed {
                // Byte 1
                VariableLengthOnion | StaticRemoteKey | PaymentSecret,
                // Byte 2
-               BasicMPP | Wumbo,
+               BasicMPP | Wumbo | AnchorsZeroFeeHtlcTx,
                // Byte 3
                ShutdownAnySegwit,
                // Byte 4
@@ -138,7 +142,7 @@ mod sealed {
                // Byte 1
                VariableLengthOnion | StaticRemoteKey | PaymentSecret,
                // Byte 2
-               BasicMPP | Wumbo,
+               BasicMPP | Wumbo | AnchorsZeroFeeHtlcTx,
                // Byte 3
                ShutdownAnySegwit,
                // Byte 4
@@ -176,7 +180,7 @@ mod sealed {
                // Byte 1
                StaticRemoteKey,
                // Byte 2
-               ,
+               AnchorsZeroFeeHtlcTx,
                // Byte 3
                ,
                // Byte 4
@@ -357,6 +361,9 @@ mod sealed {
        define_feature!(19, Wumbo, [InitContext, NodeContext],
                "Feature flags for `option_support_large_channel` (aka wumbo channels).", set_wumbo_optional, set_wumbo_required,
                supports_wumbo, requires_wumbo);
+       define_feature!(23, AnchorsZeroFeeHtlcTx, [InitContext, NodeContext, ChannelTypeContext],
+               "Feature flags for `option_anchors_zero_fee_htlc_tx`.", set_anchors_zero_fee_htlc_tx_optional,
+               set_anchors_zero_fee_htlc_tx_required, supports_anchors_zero_fee_htlc_tx, requires_anchors_zero_fee_htlc_tx);
        define_feature!(27, ShutdownAnySegwit, [InitContext, NodeContext],
                "Feature flags for `opt_shutdown_anysegwit`.", set_shutdown_any_segwit_optional,
                set_shutdown_any_segwit_required, supports_shutdown_anysegwit, requires_shutdown_anysegwit);
@@ -505,10 +512,10 @@ impl InvoiceFeatures {
 }
 
 impl ChannelTypeFeatures {
-       /// Constructs the implicit channel type based on the common supported types between us and our
-       /// counterparty
-       pub(crate) fn from_counterparty_init(counterparty_init: &InitFeatures) -> Self {
-               let mut ret = counterparty_init.to_context_internal();
+       // Maps the relevant `InitFeatures` to `ChannelTypeFeatures`. Any unknown features to
+       // `ChannelTypeFeatures` are not included in the result.
+       pub(crate) fn from_init(init: &InitFeatures) -> Self {
+               let mut ret = init.to_context_internal();
                // ChannelTypeFeatures must only contain required bits, so we OR the required forms of all
                // optional bits and then AND out the optional ones.
                for byte in ret.flags.iter_mut() {
@@ -678,6 +685,24 @@ impl<T: sealed::Context> Features<T> {
                        (byte & unknown_features) != 0
                })
        }
+
+       // Returns true if the features within `self` are a subset of the features within `other`.
+       pub(crate) fn is_subset(&self, other: &Self) -> bool {
+               for (idx, byte) in self.flags.iter().enumerate() {
+                       if let Some(other_byte) = other.flags.get(idx) {
+                               if byte & other_byte != *byte {
+                                       // `self` has bits set that `other` doesn't.
+                                       return false;
+                               }
+                       } else {
+                               if *byte > 0 {
+                                       // `self` has a non-zero byte that `other` doesn't.
+                                       return false;
+                               }
+                       }
+               }
+               true
+       }
 }
 
 impl<T: sealed::UpfrontShutdownScript> Features<T> {
@@ -704,6 +729,18 @@ impl<T: sealed::Wumbo> Features<T> {
        }
 }
 
+impl<T: sealed::SCIDPrivacy> Features<T> {
+       pub(crate) fn clear_scid_privacy(&mut self) {
+               <T as sealed::SCIDPrivacy>::clear_bits(&mut self.flags);
+       }
+}
+
+impl<T: sealed::AnchorsZeroFeeHtlcTx> Features<T> {
+       pub(crate) fn clear_anchors_zero_fee_htlc_tx(&mut self) {
+               <T as sealed::AnchorsZeroFeeHtlcTx>::clear_bits(&mut self.flags);
+       }
+}
+
 #[cfg(test)]
 impl<T: sealed::UnknownFeature> Features<T> {
        pub(crate) fn unknown() -> Self {
@@ -808,6 +845,7 @@ mod tests {
                init_features.set_channel_type_optional();
                init_features.set_scid_privacy_optional();
                init_features.set_zero_conf_optional();
+               init_features.set_anchors_zero_fee_htlc_tx_optional();
 
                assert!(init_features.initial_routing_sync());
                assert!(!init_features.supports_upfront_shutdown_script());
@@ -826,7 +864,7 @@ mod tests {
                        assert_eq!(node_features.flags.len(), 7);
                        assert_eq!(node_features.flags[0], 0b00000010);
                        assert_eq!(node_features.flags[1], 0b01010001);
-                       assert_eq!(node_features.flags[2], 0b00001010);
+                       assert_eq!(node_features.flags[2], 0b10001010);
                        assert_eq!(node_features.flags[3], 0b00001000);
                        assert_eq!(node_features.flags[4], 0b10000000);
                        assert_eq!(node_features.flags[5], 0b10100000);
@@ -917,7 +955,7 @@ mod tests {
                // required-StaticRemoteKey ChannelTypeFeatures.
                let mut init_features = InitFeatures::empty();
                init_features.set_static_remote_key_optional();
-               let converted_features = ChannelTypeFeatures::from_counterparty_init(&init_features);
+               let converted_features = ChannelTypeFeatures::from_init(&init_features);
                assert_eq!(converted_features, ChannelTypeFeatures::only_static_remote_key());
                assert!(!converted_features.supports_any_optional_bits());
                assert!(converted_features.requires_static_remote_key());
index a7e1f8cfd63a7e6f4e58c272a746b288abe19492..96ce9312eed3acec30cb9c7e4db7a8114fa804eb 100644 (file)
@@ -14,7 +14,7 @@ use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch
 use crate::chain::channelmonitor::ChannelMonitor;
 use crate::chain::transaction::OutPoint;
 use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
-use crate::ln::channelmanager::{self, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA};
+use crate::ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA};
 use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
 use crate::routing::router::{PaymentParameters, Route, get_route};
 use crate::ln::features::InitFeatures;
@@ -24,7 +24,7 @@ use crate::util::enforcing_trait_impls::EnforcingSigner;
 use crate::util::scid_utils;
 use crate::util::test_utils;
 use crate::util::test_utils::{panicking, TestChainMonitor};
-use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose};
+use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose};
 use crate::util::errors::APIError;
 use crate::util::config::UserConfig;
 use crate::util::ser::{ReadableArgs, Writeable};
@@ -44,7 +44,7 @@ use crate::io;
 use crate::prelude::*;
 use core::cell::RefCell;
 use alloc::rc::Rc;
-use crate::sync::{Arc, Mutex};
+use crate::sync::{Arc, Mutex, LockTestExt};
 use core::mem;
 use core::iter::repeat;
 use bitcoin::{PackedLockTime, TxMerkleNode};
@@ -61,17 +61,22 @@ pub fn confirm_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Tran
        connect_blocks(node, CHAN_CONFIRM_DEPTH - 1);
        scid
 }
-/// Mine a signle block containing the given transaction
+/// Mine a single block containing the given transaction
 pub fn mine_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) {
        let height = node.best_block_info().1 + 1;
        confirm_transaction_at(node, tx, height);
 }
+/// Mine a single block containing the given transactions
+pub fn mine_transactions<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, txn: &[&Transaction]) {
+       let height = node.best_block_info().1 + 1;
+       confirm_transactions_at(node, txn, height);
+}
 /// Mine the given transaction at the given height, mining blocks as required to build to that
 /// height
 ///
 /// Returns the SCID a channel confirmed in the given transaction will have, assuming the funding
 /// output is the 1st output in the transaction.
-pub fn confirm_transaction_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction, conf_height: u32) -> u64 {
+pub fn confirm_transactions_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, txn: &[&Transaction], conf_height: u32) -> u64 {
        let first_connect_height = node.best_block_info().1 + 1;
        assert!(first_connect_height <= conf_height);
        if conf_height > first_connect_height {
@@ -84,10 +89,15 @@ pub fn confirm_transaction_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &T
        for _ in 0..*node.network_chan_count.borrow() { // Make sure we don't end up with channels at the same short id by offsetting by chan_count
                block.txdata.push(Transaction { version: 0, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() });
        }
-       block.txdata.push(tx.clone());
+       for tx in txn {
+               block.txdata.push((*tx).clone());
+       }
        connect_block(node, &block);
        scid_utils::scid_from_parts(conf_height as u64, block.txdata.len() as u64 - 1, 0).unwrap()
 }
+pub fn confirm_transaction_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction, conf_height: u32) -> u64 {
+       confirm_transactions_at(node, &[tx], conf_height)
+}
 
 /// The possible ways we may notify a ChannelManager of a new block
 #[derive(Clone, Copy, Debug, PartialEq)]
@@ -295,6 +305,7 @@ pub struct TestChanMonCfg {
        pub persister: test_utils::TestPersister,
        pub logger: test_utils::TestLogger,
        pub keys_manager: test_utils::TestKeysInterface,
+       pub scorer: Mutex<test_utils::TestScorer>,
 }
 
 pub struct NodeCfg<'a> {
@@ -307,7 +318,7 @@ pub struct NodeCfg<'a> {
        pub logger: &'a test_utils::TestLogger,
        pub network_graph: Arc<NetworkGraph<&'a test_utils::TestLogger>>,
        pub node_seed: [u8; 32],
-       pub features: InitFeatures,
+       pub override_init_features: Rc<RefCell<Option<InitFeatures>>>,
 }
 
 pub struct Node<'a, 'b: 'a, 'c: 'b> {
@@ -317,7 +328,7 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> {
        pub router: &'b test_utils::TestRouter<'c>,
        pub chain_monitor: &'b test_utils::TestChainMonitor<'c>,
        pub keys_manager: &'b test_utils::TestKeysInterface,
-       pub node: &'a ChannelManager<&'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'b test_utils::TestRouter<'c>, &'c test_utils::TestLogger>,
+       pub node: &'a ChannelManager<&'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'b test_utils::TestKeysInterface, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'b test_utils::TestRouter<'c>, &'c test_utils::TestLogger>,
        pub network_graph: &'a NetworkGraph<&'c test_utils::TestLogger>,
        pub gossip_sync: P2PGossipSync<&'b NetworkGraph<&'c test_utils::TestLogger>, &'c test_utils::TestChainSource, &'c test_utils::TestLogger>,
        pub node_seed: [u8; 32],
@@ -326,6 +337,7 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> {
        pub logger: &'c test_utils::TestLogger,
        pub blocks: Arc<Mutex<Vec<(Block, u32)>>>,
        pub connect_style: Rc<RefCell<ConnectStyle>>,
+       pub override_init_features: Rc<RefCell<Option<InitFeatures>>>,
 }
 impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
        pub fn best_block_hash(&self) -> BlockHash {
@@ -339,6 +351,19 @@ impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
        }
 }
 
+/// If we need an unsafe pointer to a `Node` (ie to reference it in a thread
+/// pre-std::thread::scope), this provides that with `Sync`. Note that accessing some of the fields
+/// in the `Node` are not safe to use (i.e. the ones behind an `Rc`), but that's left to the caller
+/// to figure out.
+pub struct NodePtr(pub *const Node<'static, 'static, 'static>);
+impl NodePtr {
+       pub fn from_node<'a, 'b: 'a, 'c: 'b>(node: &Node<'a, 'b, 'c>) -> Self {
+               Self((node as *const Node<'a, 'b, 'c>).cast())
+       }
+}
+unsafe impl Send for NodePtr {}
+unsafe impl Sync for NodePtr {}
+
 impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
        fn drop(&mut self) {
                if !panicking() {
@@ -398,7 +423,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
                                        let mut w = test_utils::TestVecWriter(Vec::new());
                                        self.chain_monitor.chain_monitor.get_monitor(outpoint).unwrap().write(&mut w).unwrap();
                                        let (_, deserialized_monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
-                                               &mut io::Cursor::new(&w.0), self.keys_manager).unwrap();
+                                               &mut io::Cursor::new(&w.0), (self.keys_manager, self.keys_manager)).unwrap();
                                        deserialized_monitors.push(deserialized_monitor);
                                }
                        }
@@ -416,13 +441,16 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
                                        channel_monitors.insert(monitor.get_funding_txo().0, monitor);
                                }
 
+                               let scorer = Mutex::new(test_utils::TestScorer::new());
                                let mut w = test_utils::TestVecWriter(Vec::new());
                                self.node.write(&mut w).unwrap();
-                               <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>)>::read(&mut io::Cursor::new(w.0), ChannelManagerReadArgs {
+                               <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>)>::read(&mut io::Cursor::new(w.0), ChannelManagerReadArgs {
                                        default_config: *self.node.get_current_default_configuration(),
-                                       keys_manager: self.keys_manager,
+                                       entropy_source: self.keys_manager,
+                                       node_signer: self.keys_manager,
+                                       signer_provider: self.keys_manager,
                                        fee_estimator: &test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) },
-                                       router: &test_utils::TestRouter::new(Arc::new(network_graph)),
+                                       router: &test_utils::TestRouter::new(Arc::new(network_graph), &scorer),
                                        chain_monitor: self.chain_monitor,
                                        tx_broadcaster: &broadcaster,
                                        logger: &self.logger,
@@ -438,18 +466,18 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
                                        panic!();
                                }
                        }
-                       assert_eq!(*chain_source.watched_txn.lock().unwrap(), *self.chain_source.watched_txn.lock().unwrap());
-                       assert_eq!(*chain_source.watched_outputs.lock().unwrap(), *self.chain_source.watched_outputs.lock().unwrap());
+                       assert_eq!(*chain_source.watched_txn.unsafe_well_ordered_double_lock_self(), *self.chain_source.watched_txn.unsafe_well_ordered_double_lock_self());
+                       assert_eq!(*chain_source.watched_outputs.unsafe_well_ordered_double_lock_self(), *self.chain_source.watched_outputs.unsafe_well_ordered_double_lock_self());
                }
        }
 }
 
-pub fn create_chan_between_nodes<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, a_flags: InitFeatures, b_flags: InitFeatures) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
-       create_chan_between_nodes_with_value(node_a, node_b, 100000, 10001, a_flags, b_flags)
+pub fn create_chan_between_nodes<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
+       create_chan_between_nodes_with_value(node_a, node_b, 100000, 10001)
 }
 
-pub fn create_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64, a_flags: InitFeatures, b_flags: InitFeatures) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
-       let (channel_ready, channel_id, tx) = create_chan_between_nodes_with_value_a(node_a, node_b, channel_value, push_msat, a_flags, b_flags);
+pub fn create_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
+       let (channel_ready, channel_id, tx) = create_chan_between_nodes_with_value_a(node_a, node_b, channel_value, push_msat);
        let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(node_a, node_b, &channel_ready);
        (announcement, as_update, bs_update, channel_id, tx)
 }
@@ -558,22 +586,103 @@ macro_rules! get_htlc_update_msgs {
        }
 }
 
+/// Fetches the first `msg_event` to the passed `node_id` in the passed `msg_events` vec.
+/// Returns the `msg_event`.
+///
+/// Note that even though `BroadcastChannelAnnouncement` and `BroadcastChannelUpdate`
+/// `msg_events` are stored under specific peers, this function does not fetch such `msg_events` as
+/// such messages are intended to all peers.
+pub fn remove_first_msg_event_to_node(msg_node_id: &PublicKey, msg_events: &mut Vec<MessageSendEvent>) -> MessageSendEvent {
+       let ev_index = msg_events.iter().position(|e| { match e {
+               MessageSendEvent::SendAcceptChannel { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendOpenChannel { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendFundingCreated { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendFundingSigned { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendChannelReady { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendAnnouncementSignatures { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::UpdateHTLCs { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendRevokeAndACK { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendClosingSigned { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendShutdown { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendChannelReestablish { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendChannelAnnouncement { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::BroadcastChannelAnnouncement { .. } => {
+                       false
+               },
+               MessageSendEvent::BroadcastChannelUpdate { .. } => {
+                       false
+               },
+               MessageSendEvent::BroadcastNodeAnnouncement { .. } => {
+                       false
+               },
+               MessageSendEvent::SendChannelUpdate { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::HandleError { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendChannelRangeQuery { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendShortIdsQuery { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendReplyChannelRange { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendGossipTimestampFilter { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+       }});
+       if ev_index.is_some() {
+               msg_events.remove(ev_index.unwrap())
+       } else {
+               panic!("Couldn't find any MessageSendEvent to the node!")
+       }
+}
+
 #[cfg(test)]
 macro_rules! get_channel_ref {
-       ($node: expr, $lock: ident, $channel_id: expr) => {
+       ($node: expr, $counterparty_node: expr, $per_peer_state_lock: ident, $peer_state_lock: ident, $channel_id: expr) => {
                {
-                       $lock = $node.node.channel_state.lock().unwrap();
-                       $lock.by_id.get_mut(&$channel_id).unwrap()
+                       $per_peer_state_lock = $node.node.per_peer_state.read().unwrap();
+                       $peer_state_lock = $per_peer_state_lock.get(&$counterparty_node.node.get_our_node_id()).unwrap().lock().unwrap();
+                       $peer_state_lock.channel_by_id.get_mut(&$channel_id).unwrap()
                }
        }
 }
 
 #[cfg(test)]
 macro_rules! get_feerate {
-       ($node: expr, $channel_id: expr) => {
+       ($node: expr, $counterparty_node: expr, $channel_id: expr) => {
                {
-                       let mut lock;
-                       let chan = get_channel_ref!($node, lock, $channel_id);
+                       let mut per_peer_state_lock;
+                       let mut peer_state_lock;
+                       let chan = get_channel_ref!($node, $counterparty_node, per_peer_state_lock, peer_state_lock, $channel_id);
                        chan.get_feerate()
                }
        }
@@ -581,10 +690,11 @@ macro_rules! get_feerate {
 
 #[cfg(test)]
 macro_rules! get_opt_anchors {
-       ($node: expr, $channel_id: expr) => {
+       ($node: expr, $counterparty_node: expr, $channel_id: expr) => {
                {
-                       let mut lock;
-                       let chan = get_channel_ref!($node, lock, $channel_id);
+                       let mut per_peer_state_lock;
+                       let mut peer_state_lock;
+                       let chan = get_channel_ref!($node, $counterparty_node, per_peer_state_lock, peer_state_lock, $channel_id);
                        chan.opt_anchors()
                }
        }
@@ -659,12 +769,12 @@ macro_rules! check_added_monitors {
        }
 }
 
-pub fn _reload_node<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, default_config: UserConfig, chanman_encoded: &[u8], monitors_encoded: &[&[u8]]) -> ChannelManager<&'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'b test_utils::TestRouter<'c>, &'c test_utils::TestLogger> {
+pub fn _reload_node<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, default_config: UserConfig, chanman_encoded: &[u8], monitors_encoded: &[&[u8]]) -> ChannelManager<&'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'b test_utils::TestKeysInterface, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'b test_utils::TestRouter<'c>, &'c test_utils::TestLogger> {
        let mut monitors_read = Vec::with_capacity(monitors_encoded.len());
        for encoded in monitors_encoded {
                let mut monitor_read = &encoded[..];
                let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>
-                       ::read(&mut monitor_read, node.keys_manager).unwrap();
+                       ::read(&mut monitor_read, (node.keys_manager, node.keys_manager)).unwrap();
                assert!(monitor_read.is_empty());
                monitors_read.push(monitor);
        }
@@ -675,9 +785,11 @@ pub fn _reload_node<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, default_config:
                for monitor in monitors_read.iter_mut() {
                        assert!(channel_monitors.insert(monitor.get_funding_txo().0, monitor).is_none());
                }
-               <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>)>::read(&mut node_read, ChannelManagerReadArgs {
+               <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>)>::read(&mut node_read, ChannelManagerReadArgs {
                        default_config,
-                       keys_manager: node.keys_manager,
+                       entropy_source: node.keys_manager,
+                       node_signer: node.keys_manager,
+                       signer_provider: node.keys_manager,
                        fee_estimator: node.fee_estimator,
                        router: node.router,
                        chain_monitor: node.chain_monitor,
@@ -782,7 +894,7 @@ pub fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, r
        initiator.node.create_channel(receiver.node.get_our_node_id(), 100_000, 10_001, 42, initiator_config).unwrap();
        let open_channel = get_event_msg!(initiator, MessageSendEvent::SendOpenChannel, receiver.node.get_our_node_id());
 
-       receiver.node.handle_open_channel(&initiator.node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel);
+       receiver.node.handle_open_channel(&initiator.node.get_our_node_id(), &open_channel);
        let events = receiver.node.get_and_clear_pending_events();
        assert_eq!(events.len(), 1);
        match events[0] {
@@ -794,7 +906,7 @@ pub fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, r
 
        let accept_channel = get_event_msg!(receiver, MessageSendEvent::SendAcceptChannel, initiator.node.get_our_node_id());
        assert_eq!(accept_channel.minimum_depth, 0);
-       initiator.node.handle_accept_channel(&receiver.node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+       initiator.node.handle_accept_channel(&receiver.node.get_our_node_id(), &accept_channel);
 
        let (temporary_channel_id, tx, _) = create_funding_transaction(&initiator, &receiver.node.get_our_node_id(), 100_000, 42);
        initiator.node.funding_transaction_generated(&temporary_channel_id, &receiver.node.get_our_node_id(), tx.clone()).unwrap();
@@ -843,15 +955,15 @@ pub fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, r
        (tx, as_channel_ready.channel_id)
 }
 
-pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, push_msat: u64, a_flags: InitFeatures, b_flags: InitFeatures) -> Transaction {
+pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, push_msat: u64) -> Transaction {
        let create_chan_id = node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None).unwrap();
        let open_channel_msg = get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id());
        assert_eq!(open_channel_msg.temporary_channel_id, create_chan_id);
        assert_eq!(node_a.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 42);
-       node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), a_flags, &open_channel_msg);
+       node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), &open_channel_msg);
        let accept_channel_msg = get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id());
        assert_eq!(accept_channel_msg.temporary_channel_id, create_chan_id);
-       node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), b_flags, &accept_channel_msg);
+       node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), &accept_channel_msg);
        assert_ne!(node_b.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 0);
 
        sign_funding_transaction(node_a, node_b, channel_value, create_chan_id)
@@ -899,8 +1011,8 @@ pub fn create_chan_between_nodes_with_value_confirm<'a, 'b, 'c, 'd>(node_a: &'a
        create_chan_between_nodes_with_value_confirm_second(node_b, node_a)
 }
 
-pub fn create_chan_between_nodes_with_value_a<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64, a_flags: InitFeatures, b_flags: InitFeatures) -> ((msgs::ChannelReady, msgs::AnnouncementSignatures), [u8; 32], Transaction) {
-       let tx = create_chan_between_nodes_with_value_init(node_a, node_b, channel_value, push_msat, a_flags, b_flags);
+pub fn create_chan_between_nodes_with_value_a<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64) -> ((msgs::ChannelReady, msgs::AnnouncementSignatures), [u8; 32], Transaction) {
+       let tx = create_chan_between_nodes_with_value_init(node_a, node_b, channel_value, push_msat);
        let (msgs, chan_id) = create_chan_between_nodes_with_value_confirm(node_a, node_b, &tx);
        (msgs, chan_id, tx)
 }
@@ -914,7 +1026,7 @@ pub fn create_chan_between_nodes_with_value_b<'a, 'b, 'c>(node_a: &Node<'a, 'b,
        assert_eq!(events_7.len(), 1);
        let (announcement, bs_update) = match events_7[0] {
                MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
-                       (msg, update_msg)
+                       (msg, update_msg.clone().unwrap())
                },
                _ => panic!("Unexpected event"),
        };
@@ -925,6 +1037,7 @@ pub fn create_chan_between_nodes_with_value_b<'a, 'b, 'c>(node_a: &Node<'a, 'b,
        let as_update = match events_8[0] {
                MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
                        assert!(*announcement == *msg);
+                       let update_msg = update_msg.clone().unwrap();
                        assert_eq!(update_msg.contents.short_channel_id, announcement.contents.short_channel_id);
                        assert_eq!(update_msg.contents.short_channel_id, bs_update.contents.short_channel_id);
                        update_msg
@@ -935,27 +1048,27 @@ pub fn create_chan_between_nodes_with_value_b<'a, 'b, 'c>(node_a: &Node<'a, 'b,
        *node_a.network_chan_count.borrow_mut() += 1;
 
        expect_channel_ready_event(&node_b, &node_a.node.get_our_node_id());
-       ((*announcement).clone(), (*as_update).clone(), (*bs_update).clone())
+       ((*announcement).clone(), as_update, bs_update)
 }
 
-pub fn create_announced_chan_between_nodes<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize, a_flags: InitFeatures, b_flags: InitFeatures) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
-       create_announced_chan_between_nodes_with_value(nodes, a, b, 100000, 10001, a_flags, b_flags)
+pub fn create_announced_chan_between_nodes<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
+       create_announced_chan_between_nodes_with_value(nodes, a, b, 100000, 10001)
 }
 
-pub fn create_announced_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::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
-       let chan_announcement = create_chan_between_nodes_with_value(&nodes[a], &nodes[b], channel_value, push_msat, a_flags, b_flags);
+pub fn create_announced_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) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
+       let chan_announcement = create_chan_between_nodes_with_value(&nodes[a], &nodes[b], channel_value, push_msat);
        update_nodes_with_chan_announce(nodes, a, b, &chan_announcement.0, &chan_announcement.1, &chan_announcement.2);
        (chan_announcement.1, chan_announcement.2, chan_announcement.3, chan_announcement.4)
 }
 
-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) {
+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) -> (msgs::ChannelReady, Transaction) {
        let mut no_announce_cfg = test_default_channel_config();
        no_announce_cfg.channel_handshake_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);
+       nodes[b].node.handle_open_channel(&nodes[a].node.get_our_node_id(), &open_channel);
        let accept_channel = get_event_msg!(nodes[b], MessageSendEvent::SendAcceptChannel, nodes[a].node.get_our_node_id());
-       nodes[a].node.handle_accept_channel(&nodes[b].node.get_our_node_id(), b_flags, &accept_channel);
+       nodes[a].node.handle_accept_channel(&nodes[b].node.get_our_node_id(), &accept_channel);
 
        let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[a], &nodes[b].node.get_our_node_id(), channel_value, 42);
        nodes[a].node.funding_transaction_generated(&temporary_channel_id, &nodes[b].node.get_our_node_id(), tx.clone()).unwrap();
@@ -1156,7 +1269,7 @@ pub fn close_channel<'a, 'b, 'c>(outbound_node: &Node<'a, 'b, 'c>, inbound_node:
        let (tx_a, tx_b);
 
        node_a.close_channel(channel_id, &node_b.get_our_node_id()).unwrap();
-       node_b.handle_shutdown(&node_a.get_our_node_id(), &channelmanager::provided_init_features(), &get_event_msg!(struct_a, MessageSendEvent::SendShutdown, node_b.get_our_node_id()));
+       node_b.handle_shutdown(&node_a.get_our_node_id(), &get_event_msg!(struct_a, MessageSendEvent::SendShutdown, node_b.get_our_node_id()));
 
        let events_1 = node_b.get_and_clear_pending_msg_events();
        assert!(events_1.len() >= 1);
@@ -1181,7 +1294,7 @@ pub fn close_channel<'a, 'b, 'c>(outbound_node: &Node<'a, 'b, 'c>, inbound_node:
                })
        };
 
-       node_a.handle_shutdown(&node_b.get_our_node_id(), &channelmanager::provided_init_features(), &shutdown_b);
+       node_a.handle_shutdown(&node_b.get_our_node_id(), &shutdown_b);
        let (as_update, bs_update) = if close_inbound_first {
                assert!(node_a.get_and_clear_pending_msg_events().is_empty());
                node_a.handle_closing_signed(&node_b.get_our_node_id(), &closing_signed_b.unwrap());
@@ -1248,142 +1361,6 @@ impl SendEvent {
        }
 }
 
-#[macro_export]
-/// Performs the "commitment signed dance" - the series of message exchanges which occur after a
-/// commitment update.
-macro_rules! commitment_signed_dance {
-       ($node_a: expr, $node_b: expr, $commitment_signed: expr, $fail_backwards: expr, true /* skip last step */) => {
-               {
-                       check_added_monitors!($node_a, 0);
-                       assert!($node_a.node.get_and_clear_pending_msg_events().is_empty());
-                       $node_a.node.handle_commitment_signed(&$node_b.node.get_our_node_id(), &$commitment_signed);
-                       check_added_monitors!($node_a, 1);
-                       commitment_signed_dance!($node_a, $node_b, (), $fail_backwards, true, false);
-               }
-       };
-       ($node_a: expr, $node_b: expr, (), $fail_backwards: expr, true /* skip last step */, true /* return extra message */, true /* return last RAA */) => {
-               {
-                       let (as_revoke_and_ack, as_commitment_signed) = get_revoke_commit_msgs!($node_a, $node_b.node.get_our_node_id());
-                       check_added_monitors!($node_b, 0);
-                       assert!($node_b.node.get_and_clear_pending_msg_events().is_empty());
-                       $node_b.node.handle_revoke_and_ack(&$node_a.node.get_our_node_id(), &as_revoke_and_ack);
-                       assert!($node_b.node.get_and_clear_pending_msg_events().is_empty());
-                       check_added_monitors!($node_b, 1);
-                       $node_b.node.handle_commitment_signed(&$node_a.node.get_our_node_id(), &as_commitment_signed);
-                       let (bs_revoke_and_ack, extra_msg_option) = {
-                               let events = $node_b.node.get_and_clear_pending_msg_events();
-                               assert!(events.len() <= 2);
-                               (match events[0] {
-                                       MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
-                                               assert_eq!(*node_id, $node_a.node.get_our_node_id());
-                                               (*msg).clone()
-                                       },
-                                       _ => panic!("Unexpected event"),
-                               }, events.get(1).map(|e| e.clone()))
-                       };
-                       check_added_monitors!($node_b, 1);
-                       if $fail_backwards {
-                               assert!($node_a.node.get_and_clear_pending_events().is_empty());
-                               assert!($node_a.node.get_and_clear_pending_msg_events().is_empty());
-                       }
-                       (extra_msg_option, bs_revoke_and_ack)
-               }
-       };
-       ($node_a: expr, $node_b: expr, $commitment_signed: expr, $fail_backwards: expr, true /* skip last step */, false /* return extra message */, true /* return last RAA */) => {
-               {
-                       check_added_monitors!($node_a, 0);
-                       assert!($node_a.node.get_and_clear_pending_msg_events().is_empty());
-                       $node_a.node.handle_commitment_signed(&$node_b.node.get_our_node_id(), &$commitment_signed);
-                       check_added_monitors!($node_a, 1);
-                       let (extra_msg_option, bs_revoke_and_ack) = commitment_signed_dance!($node_a, $node_b, (), $fail_backwards, true, true, true);
-                       assert!(extra_msg_option.is_none());
-                       bs_revoke_and_ack
-               }
-       };
-       ($node_a: expr, $node_b: expr, (), $fail_backwards: expr, true /* skip last step */, true /* return extra message */) => {
-               {
-                       let (extra_msg_option, bs_revoke_and_ack) = commitment_signed_dance!($node_a, $node_b, (), $fail_backwards, true, true, true);
-                       $node_a.node.handle_revoke_and_ack(&$node_b.node.get_our_node_id(), &bs_revoke_and_ack);
-                       check_added_monitors!($node_a, 1);
-                       extra_msg_option
-               }
-       };
-       ($node_a: expr, $node_b: expr, (), $fail_backwards: expr, true /* skip last step */, false /* no extra message */) => {
-               {
-                       assert!(commitment_signed_dance!($node_a, $node_b, (), $fail_backwards, true, true).is_none());
-               }
-       };
-       ($node_a: expr, $node_b: expr, $commitment_signed: expr, $fail_backwards: expr) => {
-               {
-                       commitment_signed_dance!($node_a, $node_b, $commitment_signed, $fail_backwards, true);
-                       if $fail_backwards {
-                               expect_pending_htlcs_forwardable_and_htlc_handling_failed!($node_a, vec![$crate::util::events::HTLCDestination::NextHopChannel{ node_id: Some($node_b.node.get_our_node_id()), channel_id: $commitment_signed.channel_id }]);
-                               check_added_monitors!($node_a, 1);
-
-                               let channel_state = $node_a.node.channel_state.lock().unwrap();
-                               assert_eq!(channel_state.pending_msg_events.len(), 1);
-                               if let MessageSendEvent::UpdateHTLCs { ref node_id, .. } = channel_state.pending_msg_events[0] {
-                                       assert_ne!(*node_id, $node_b.node.get_our_node_id());
-                               } else { panic!("Unexpected event"); }
-                       } else {
-                               assert!($node_a.node.get_and_clear_pending_msg_events().is_empty());
-                       }
-               }
-       }
-}
-
-/// Get a payment preimage and hash.
-#[macro_export]
-macro_rules! get_payment_preimage_hash {
-       ($dest_node: expr) => {
-               {
-                       get_payment_preimage_hash!($dest_node, None)
-               }
-       };
-       ($dest_node: expr, $min_value_msat: expr) => {
-               {
-                       use bitcoin::hashes::Hash as _;
-                       let mut payment_count = $dest_node.network_payment_count.borrow_mut();
-                       let payment_preimage = $crate::ln::PaymentPreimage([*payment_count; 32]);
-                       *payment_count += 1;
-                       let payment_hash = $crate::ln::PaymentHash(
-                               bitcoin::hashes::sha256::Hash::hash(&payment_preimage.0[..]).into_inner());
-                       let payment_secret = $dest_node.node.create_inbound_payment_for_hash(payment_hash, $min_value_msat, 7200).unwrap();
-                       (payment_preimage, payment_hash, payment_secret)
-               }
-       }
-}
-
-#[macro_export]
-macro_rules! get_route {
-       ($send_node: expr, $payment_params: expr, $recv_value: expr, $cltv: expr) => {{
-               use $crate::chain::keysinterface::EntropySource;
-               let scorer = $crate::util::test_utils::TestScorer::with_penalty(0);
-               let keys_manager = $crate::util::test_utils::TestKeysInterface::new(&[0u8; 32], bitcoin::network::constants::Network::Testnet);
-               let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               $crate::routing::router::get_route(
-                       &$send_node.node.get_our_node_id(), &$payment_params, &$send_node.network_graph.read_only(),
-                       Some(&$send_node.node.list_usable_channels().iter().collect::<Vec<_>>()),
-                       $recv_value, $cltv, $send_node.logger, &scorer, &random_seed_bytes
-               )
-       }}
-}
-
-#[cfg(test)]
-#[macro_export]
-macro_rules! get_route_and_payment_hash {
-       ($send_node: expr, $recv_node: expr, $recv_value: expr) => {{
-               let payment_params = $crate::routing::router::PaymentParameters::from_node_id($recv_node.node.get_our_node_id())
-                       .with_features($crate::ln::channelmanager::provided_invoice_features());
-               $crate::get_route_and_payment_hash!($send_node, $recv_node, payment_params, $recv_value, TEST_FINAL_CLTV)
-       }};
-       ($send_node: expr, $recv_node: expr, $payment_params: expr, $recv_value: expr, $cltv: expr) => {{
-               let (payment_preimage, payment_hash, payment_secret) = $crate::get_payment_preimage_hash!($recv_node, Some($recv_value));
-               let route = $crate::get_route!($send_node, $payment_params, $recv_value, $cltv);
-               (route.unwrap(), payment_hash, payment_preimage, payment_secret)
-       }}
-}
-
 #[macro_export]
 macro_rules! expect_pending_htlcs_forwardable_conditions {
        ($node: expr, $expected_failures: expr) => {{
@@ -1474,6 +1451,164 @@ macro_rules! expect_pending_htlcs_forwardable_from_events {
                }
        }}
 }
+
+#[macro_export]
+/// Performs the "commitment signed dance" - the series of message exchanges which occur after a
+/// commitment update.
+macro_rules! commitment_signed_dance {
+       ($node_a: expr, $node_b: expr, $commitment_signed: expr, $fail_backwards: expr, true /* skip last step */) => {
+               $crate::ln::functional_test_utils::do_commitment_signed_dance(&$node_a, &$node_b, &$commitment_signed, $fail_backwards, true);
+       };
+       ($node_a: expr, $node_b: expr, (), $fail_backwards: expr, true /* skip last step */, true /* return extra message */, true /* return last RAA */) => {
+               $crate::ln::functional_test_utils::do_main_commitment_signed_dance(&$node_a, &$node_b, $fail_backwards)
+       };
+       ($node_a: expr, $node_b: expr, $commitment_signed: expr, $fail_backwards: expr, true /* skip last step */, false /* return extra message */, true /* return last RAA */) => {
+               {
+                       check_added_monitors!($node_a, 0);
+                       assert!($node_a.node.get_and_clear_pending_msg_events().is_empty());
+                       $node_a.node.handle_commitment_signed(&$node_b.node.get_our_node_id(), &$commitment_signed);
+                       check_added_monitors!($node_a, 1);
+                       let (extra_msg_option, bs_revoke_and_ack) = $crate::ln::functional_test_utils::do_main_commitment_signed_dance(&$node_a, &$node_b, $fail_backwards);
+                       assert!(extra_msg_option.is_none());
+                       bs_revoke_and_ack
+               }
+       };
+       ($node_a: expr, $node_b: expr, (), $fail_backwards: expr, true /* skip last step */, true /* return extra message */) => {
+               {
+                       let (extra_msg_option, bs_revoke_and_ack) = $crate::ln::functional_test_utils::do_main_commitment_signed_dance(&$node_a, &$node_b, $fail_backwards);
+                       $node_a.node.handle_revoke_and_ack(&$node_b.node.get_our_node_id(), &bs_revoke_and_ack);
+                       check_added_monitors!($node_a, 1);
+                       extra_msg_option
+               }
+       };
+       ($node_a: expr, $node_b: expr, (), $fail_backwards: expr, true /* skip last step */, false /* no extra message */) => {
+               assert!(commitment_signed_dance!($node_a, $node_b, (), $fail_backwards, true, true).is_none());
+       };
+       ($node_a: expr, $node_b: expr, $commitment_signed: expr, $fail_backwards: expr) => {
+               $crate::ln::functional_test_utils::do_commitment_signed_dance(&$node_a, &$node_b, &$commitment_signed, $fail_backwards, false);
+       }
+}
+
+
+pub fn do_main_commitment_signed_dance(node_a: &Node<'_, '_, '_>, node_b: &Node<'_, '_, '_>, fail_backwards: bool) -> (Option<MessageSendEvent>, msgs::RevokeAndACK) {
+       let (as_revoke_and_ack, as_commitment_signed) = get_revoke_commit_msgs!(node_a, node_b.node.get_our_node_id());
+       check_added_monitors!(node_b, 0);
+       assert!(node_b.node.get_and_clear_pending_msg_events().is_empty());
+       node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &as_revoke_and_ack);
+       assert!(node_b.node.get_and_clear_pending_msg_events().is_empty());
+       check_added_monitors!(node_b, 1);
+       node_b.node.handle_commitment_signed(&node_a.node.get_our_node_id(), &as_commitment_signed);
+       let (bs_revoke_and_ack, extra_msg_option) = {
+               let mut events = node_b.node.get_and_clear_pending_msg_events();
+               assert!(events.len() <= 2);
+               let node_a_event = remove_first_msg_event_to_node(&node_a.node.get_our_node_id(), &mut events);
+               (match node_a_event {
+                       MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
+                               assert_eq!(*node_id, node_a.node.get_our_node_id());
+                               (*msg).clone()
+                       },
+                       _ => panic!("Unexpected event"),
+               }, events.get(0).map(|e| e.clone()))
+       };
+       check_added_monitors!(node_b, 1);
+       if fail_backwards {
+               assert!(node_a.node.get_and_clear_pending_events().is_empty());
+               assert!(node_a.node.get_and_clear_pending_msg_events().is_empty());
+       }
+       (extra_msg_option, bs_revoke_and_ack)
+}
+
+pub fn do_commitment_signed_dance(node_a: &Node<'_, '_, '_>, node_b: &Node<'_, '_, '_>, commitment_signed: &msgs::CommitmentSigned, fail_backwards: bool, skip_last_step: bool) {
+       check_added_monitors!(node_a, 0);
+       assert!(node_a.node.get_and_clear_pending_msg_events().is_empty());
+       node_a.node.handle_commitment_signed(&node_b.node.get_our_node_id(), commitment_signed);
+       check_added_monitors!(node_a, 1);
+
+       commitment_signed_dance!(node_a, node_b, (), fail_backwards, true, false);
+
+       if skip_last_step { return; }
+
+       if fail_backwards {
+               expect_pending_htlcs_forwardable_and_htlc_handling_failed!(node_a,
+                       vec![crate::util::events::HTLCDestination::NextHopChannel{ node_id: Some(node_b.node.get_our_node_id()), channel_id: commitment_signed.channel_id }]);
+               check_added_monitors!(node_a, 1);
+
+               let node_a_per_peer_state = node_a.node.per_peer_state.read().unwrap();
+               let mut number_of_msg_events = 0;
+               for (cp_id, peer_state_mutex) in node_a_per_peer_state.iter() {
+                       let peer_state = peer_state_mutex.lock().unwrap();
+                       let cp_pending_msg_events = &peer_state.pending_msg_events;
+                       number_of_msg_events += cp_pending_msg_events.len();
+                       if cp_pending_msg_events.len() == 1 {
+                               if let MessageSendEvent::UpdateHTLCs { .. } = cp_pending_msg_events[0] {
+                                       assert_ne!(*cp_id, node_b.node.get_our_node_id());
+                               } else { panic!("Unexpected event"); }
+                       }
+               }
+               // Expecting the failure backwards event to the previous hop (not `node_b`)
+               assert_eq!(number_of_msg_events, 1);
+       } else {
+               assert!(node_a.node.get_and_clear_pending_msg_events().is_empty());
+       }
+}
+
+/// Get a payment preimage and hash.
+#[macro_export]
+macro_rules! get_payment_preimage_hash {
+       ($dest_node: expr) => {
+               {
+                       get_payment_preimage_hash!($dest_node, None)
+               }
+       };
+       ($dest_node: expr, $min_value_msat: expr) => {
+               {
+                       crate::get_payment_preimage_hash!($dest_node, $min_value_msat, None)
+               }
+       };
+       ($dest_node: expr, $min_value_msat: expr, $min_final_cltv_expiry_delta: expr) => {
+               {
+                       use bitcoin::hashes::Hash as _;
+                       let mut payment_count = $dest_node.network_payment_count.borrow_mut();
+                       let payment_preimage = $crate::ln::PaymentPreimage([*payment_count; 32]);
+                       *payment_count += 1;
+                       let payment_hash = $crate::ln::PaymentHash(
+                               bitcoin::hashes::sha256::Hash::hash(&payment_preimage.0[..]).into_inner());
+                       let payment_secret = $dest_node.node.create_inbound_payment_for_hash(payment_hash, $min_value_msat, 7200, $min_final_cltv_expiry_delta).unwrap();
+                       (payment_preimage, payment_hash, payment_secret)
+               }
+       };
+}
+
+#[macro_export]
+macro_rules! get_route {
+       ($send_node: expr, $payment_params: expr, $recv_value: expr, $cltv: expr) => {{
+               use $crate::chain::keysinterface::EntropySource;
+               let scorer = $crate::util::test_utils::TestScorer::new();
+               let keys_manager = $crate::util::test_utils::TestKeysInterface::new(&[0u8; 32], bitcoin::network::constants::Network::Testnet);
+               let random_seed_bytes = keys_manager.get_secure_random_bytes();
+               $crate::routing::router::get_route(
+                       &$send_node.node.get_our_node_id(), &$payment_params, &$send_node.network_graph.read_only(),
+                       Some(&$send_node.node.list_usable_channels().iter().collect::<Vec<_>>()),
+                       $recv_value, $cltv, $send_node.logger, &scorer, &random_seed_bytes
+               )
+       }}
+}
+
+#[cfg(test)]
+#[macro_export]
+macro_rules! get_route_and_payment_hash {
+       ($send_node: expr, $recv_node: expr, $recv_value: expr) => {{
+               let payment_params = $crate::routing::router::PaymentParameters::from_node_id($recv_node.node.get_our_node_id(), TEST_FINAL_CLTV)
+                       .with_features($recv_node.node.invoice_features());
+               $crate::get_route_and_payment_hash!($send_node, $recv_node, payment_params, $recv_value, TEST_FINAL_CLTV)
+       }};
+       ($send_node: expr, $recv_node: expr, $payment_params: expr, $recv_value: expr, $cltv: expr) => {{
+               let (payment_preimage, payment_hash, payment_secret) = $crate::get_payment_preimage_hash!($recv_node, Some($recv_value));
+               let route = $crate::get_route!($send_node, $payment_params, $recv_value, $cltv);
+               (route.unwrap(), payment_hash, payment_preimage, payment_secret)
+       }}
+}
+
 #[macro_export]
 #[cfg(any(test, feature = "_bench_unstable", feature = "_test_utils"))]
 macro_rules! expect_payment_claimable {
@@ -1678,17 +1813,18 @@ macro_rules! expect_payment_failed {
 }
 
 pub fn expect_payment_failed_conditions_event<'a, 'b, 'c, 'd, 'e>(
-       node: &'a Node<'b, 'c, 'd>, payment_failed_event: Event, expected_payment_hash: PaymentHash,
+       payment_failed_events: Vec<Event>, expected_payment_hash: PaymentHash,
        expected_payment_failed_permanently: bool, conditions: PaymentFailedConditions<'e>
 ) {
-       let expected_payment_id = match payment_failed_event {
-               Event::PaymentPathFailed { payment_hash, payment_failed_permanently, path, retry, payment_id, network_update, short_channel_id,
+       if conditions.expected_mpp_parts_remain { assert_eq!(payment_failed_events.len(), 1); } else { assert_eq!(payment_failed_events.len(), 2); }
+       let expected_payment_id = match &payment_failed_events[0] {
+               Event::PaymentPathFailed { payment_hash, payment_failed_permanently, path, retry, payment_id, failure, short_channel_id,
                        #[cfg(test)]
                        error_code,
                        #[cfg(test)]
                        error_data, .. } => {
-                       assert_eq!(payment_hash, expected_payment_hash, "unexpected payment_hash");
-                       assert_eq!(payment_failed_permanently, expected_payment_failed_permanently, "unexpected payment_failed_permanently value");
+                       assert_eq!(*payment_hash, expected_payment_hash, "unexpected payment_hash");
+                       assert_eq!(*payment_failed_permanently, expected_payment_failed_permanently, "unexpected payment_failed_permanently 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");
@@ -1707,23 +1843,24 @@ pub fn expect_payment_failed_conditions_event<'a, 'b, 'c, 'd, 'e>(
                        }
 
                        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"),
-                               }
+                               if let PathFailure::OnPath { network_update: Some(upd) } = failure {
+                                       match upd {
+                                               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);
+                                               },
+                                               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);
+                                               },
+                                               _ => panic!("Unexpected update type"),
+                                       }
+                               } else { panic!("Expected network update"); }
                        }
 
                        payment_id.unwrap()
@@ -1731,10 +1868,7 @@ pub fn expect_payment_failed_conditions_event<'a, 'b, 'c, 'd, 'e>(
                _ => 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] {
+               match &payment_failed_events[1] {
                        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);
@@ -1748,9 +1882,8 @@ pub fn expect_payment_failed_conditions<'a, 'b, 'c, 'd, 'e>(
        node: &'a Node<'b, 'c, 'd>, expected_payment_hash: PaymentHash, expected_payment_failed_permanently: bool,
        conditions: PaymentFailedConditions<'e>
 ) {
-       let mut events = node.node.get_and_clear_pending_events();
-       assert_eq!(events.len(), 1);
-       expect_payment_failed_conditions_event(node, events.pop().unwrap(), expected_payment_hash, expected_payment_failed_permanently, conditions);
+       let events = node.node.get_and_clear_pending_events();
+       expect_payment_failed_conditions_event(events, expected_payment_hash, expected_payment_failed_permanently, conditions);
 }
 
 pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) -> PaymentId {
@@ -1820,7 +1953,8 @@ pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path
 pub fn pass_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) {
        let mut events = origin_node.node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), expected_route.len());
-       for (path_idx, (ev, expected_path)) in events.drain(..).zip(expected_route.iter()).enumerate() {
+       for (path_idx, expected_path) in expected_route.iter().enumerate() {
+               let ev = remove_first_msg_event_to_node(&expected_path[0].node.get_our_node_id(), &mut events);
                // Once we've gotten through all the HTLCs, the last one should result in a
                // PaymentClaimable (but each previous one should not!), .
                let expect_payment = path_idx == expected_route.len() - 1;
@@ -1871,10 +2005,17 @@ pub fn do_claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>,
                }
        }
        let mut per_path_msgs: Vec<((msgs::UpdateFulfillHTLC, msgs::CommitmentSigned), PublicKey)> = Vec::with_capacity(expected_paths.len());
-       let events = expected_paths[0].last().unwrap().node.get_and_clear_pending_msg_events();
+       let mut events = expected_paths[0].last().unwrap().node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), expected_paths.len());
-       for ev in events.iter() {
-               per_path_msgs.push(msgs_from_ev!(ev));
+
+       if events.len() == 1 {
+               per_path_msgs.push(msgs_from_ev!(&events[0]));
+       } else {
+               for expected_path in expected_paths.iter() {
+                       // For MPP payments, we always want the message to the first node in the path.
+                       let ev = remove_first_msg_event_to_node(&expected_path[0].node.get_our_node_id(), &mut events);
+                       per_path_msgs.push(msgs_from_ev!(&ev));
+               }
        }
 
        for (expected_route, (path_msgs, next_hop)) in expected_paths.iter().zip(per_path_msgs.drain(..)) {
@@ -1896,9 +2037,10 @@ pub fn do_claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>,
                                {
                                        $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
                                        let fee = {
-                                               let channel_state = $node.node.channel_state.lock().unwrap();
-                                               let channel = channel_state
-                                                       .by_id.get(&next_msgs.as_ref().unwrap().0.channel_id).unwrap();
+                                               let per_peer_state = $node.node.per_peer_state.read().unwrap();
+                                               let peer_state = per_peer_state.get(&$prev_node.node.get_our_node_id())
+                                                       .unwrap().lock().unwrap();
+                                               let channel = peer_state.channel_by_id.get(&next_msgs.as_ref().unwrap().0.channel_id).unwrap();
                                                if let Some(prev_config) = channel.prev_config() {
                                                        prev_config.forwarding_fee_base_msat
                                                } else {
@@ -1974,8 +2116,8 @@ pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route:
 pub const TEST_FINAL_CLTV: u32 = 70;
 
 pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) {
-       let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features());
+       let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_features(expected_route.last().unwrap().node.invoice_features());
        let route = get_route!(origin_node, payment_params, recv_value, TEST_FINAL_CLTV).unwrap();
        assert_eq!(route.paths.len(), 1);
        assert_eq!(route.paths[0].len(), expected_route.len());
@@ -1988,10 +2130,10 @@ pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route:
 }
 
 pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64)  {
-       let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features());
+       let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_features(expected_route.last().unwrap().node.invoice_features());
        let network_graph = origin_node.network_graph.read_only();
-       let scorer = test_utils::TestScorer::with_penalty(0);
+       let scorer = test_utils::TestScorer::new();
        let seed = [0u8; 32];
        let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
        let random_seed_bytes = keys_manager.get_secure_random_bytes();
@@ -2009,9 +2151,10 @@ pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_rou
                assert!(err.contains("Cannot send value that would put us over the max HTLC value in flight our peer will accept")));
 }
 
-pub fn send_payment<'a, 'b, 'c>(origin: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64)  {
-       let our_payment_preimage = route_payment(&origin, expected_route, recv_value).0;
-       claim_payment(&origin, expected_route, our_payment_preimage);
+pub fn send_payment<'a, 'b, 'c>(origin: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) {
+       let res = route_payment(&origin, expected_route, recv_value);
+       claim_payment(&origin, expected_route, res.0);
+       res
 }
 
 pub fn fail_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_hash: PaymentHash) {
@@ -2026,22 +2169,6 @@ pub fn fail_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expe
 }
 
 pub fn pass_failed_payment_back<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths_slice: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_hash: PaymentHash) {
-       let expected_payment_id = pass_failed_payment_back_no_abandon(origin_node, expected_paths_slice, skip_last, our_payment_hash);
-       if !skip_last {
-               origin_node.node.abandon_payment(expected_payment_id.unwrap());
-               let events = origin_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, our_payment_hash, "unexpected second payment_hash");
-                               assert_eq!(*payment_id, expected_payment_id.unwrap());
-                       }
-                       _ => panic!("Unexpected second event"),
-               }
-       }
-}
-
-pub fn pass_failed_payment_back_no_abandon<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths_slice: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_hash: PaymentHash) -> Option<PaymentId> {
        let mut expected_paths: Vec<_> = expected_paths_slice.iter().collect();
        check_added_monitors!(expected_paths[0].last().unwrap(), expected_paths.len());
 
@@ -2065,8 +2192,6 @@ pub fn pass_failed_payment_back_no_abandon<'a, 'b, 'c>(origin_node: &Node<'a, 'b
        per_path_msgs.sort_unstable_by(|(_, node_id_a), (_, node_id_b)| node_id_a.cmp(node_id_b));
        expected_paths.sort_unstable_by(|path_a, path_b| path_a[path_a.len() - 2].node.get_our_node_id().cmp(&path_b[path_b.len() - 2].node.get_our_node_id()));
 
-       let mut expected_payment_id = None;
-
        for (i, (expected_route, (path_msgs, next_hop))) in expected_paths.iter().zip(per_path_msgs.drain(..)).enumerate() {
                let mut next_msgs = Some(path_msgs);
                let mut expected_next_node = next_hop;
@@ -2114,19 +2239,28 @@ pub fn pass_failed_payment_back_no_abandon<'a, 'b, 'c>(origin_node: &Node<'a, 'b
                        assert!(origin_node.node.get_and_clear_pending_msg_events().is_empty());
                        commitment_signed_dance!(origin_node, prev_node, next_msgs.as_ref().unwrap().1, false);
                        let events = origin_node.node.get_and_clear_pending_events();
-                       assert_eq!(events.len(), 1);
-                       expected_payment_id = Some(match events[0] {
-                               Event::PaymentPathFailed { payment_hash, payment_failed_permanently, all_paths_failed, ref path, ref payment_id, .. } => {
+                       if i == expected_paths.len() - 1 { assert_eq!(events.len(), 2); } else { assert_eq!(events.len(), 1); }
+
+                       let expected_payment_id = match events[0] {
+                               Event::PaymentPathFailed { payment_hash, payment_failed_permanently, ref path, ref payment_id, .. } => {
                                        assert_eq!(payment_hash, our_payment_hash);
                                        assert!(payment_failed_permanently);
-                                       assert_eq!(all_paths_failed, i == expected_paths.len() - 1);
                                        for (idx, hop) in expected_route.iter().enumerate() {
                                                assert_eq!(hop.node.get_our_node_id(), path[idx].pubkey);
                                        }
                                        payment_id.unwrap()
                                },
                                _ => panic!("Unexpected event"),
-                       });
+                       };
+                       if i == expected_paths.len() - 1 {
+                               match events[1] {
+                                       Event::PaymentFailed { ref payment_hash, ref payment_id } => {
+                                               assert_eq!(*payment_hash, our_payment_hash, "unexpected second payment_hash");
+                                               assert_eq!(*payment_id, expected_payment_id);
+                                       }
+                                       _ => panic!("Unexpected second event"),
+                               }
+                       }
                }
        }
 
@@ -2135,8 +2269,6 @@ pub fn pass_failed_payment_back_no_abandon<'a, 'b, 'c>(origin_node: &Node<'a, 'b
        assert!(expected_paths[0].last().unwrap().node.get_and_clear_pending_events().is_empty());
        assert!(expected_paths[0].last().unwrap().node.get_and_clear_pending_msg_events().is_empty());
        check_added_monitors!(expected_paths[0].last().unwrap(), 0);
-
-       expected_payment_id
 }
 
 pub fn fail_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], our_payment_hash: PaymentHash)  {
@@ -2156,8 +2288,9 @@ pub fn create_chanmon_cfgs(node_count: usize) -> Vec<TestChanMonCfg> {
                let persister = test_utils::TestPersister::new();
                let seed = [i as u8; 32];
                let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
+               let scorer = Mutex::new(test_utils::TestScorer::new());
 
-               chan_mon_cfgs.push(TestChanMonCfg { tx_broadcaster, fee_estimator, chain_source, logger, persister, keys_manager });
+               chan_mon_cfgs.push(TestChanMonCfg { tx_broadcaster, fee_estimator, chain_source, logger, persister, keys_manager, scorer });
        }
 
        chan_mon_cfgs
@@ -2168,19 +2301,19 @@ pub fn create_node_cfgs<'a>(node_count: usize, chanmon_cfgs: &'a Vec<TestChanMon
 
        for i in 0..node_count {
                let chain_monitor = test_utils::TestChainMonitor::new(Some(&chanmon_cfgs[i].chain_source), &chanmon_cfgs[i].tx_broadcaster, &chanmon_cfgs[i].logger, &chanmon_cfgs[i].fee_estimator, &chanmon_cfgs[i].persister, &chanmon_cfgs[i].keys_manager);
-               let network_graph = Arc::new(NetworkGraph::new(chanmon_cfgs[i].chain_source.genesis_hash, &chanmon_cfgs[i].logger));
+               let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &chanmon_cfgs[i].logger));
                let seed = [i as u8; 32];
                nodes.push(NodeCfg {
                        chain_source: &chanmon_cfgs[i].chain_source,
                        logger: &chanmon_cfgs[i].logger,
                        tx_broadcaster: &chanmon_cfgs[i].tx_broadcaster,
                        fee_estimator: &chanmon_cfgs[i].fee_estimator,
-                       router: test_utils::TestRouter::new(network_graph.clone()),
+                       router: test_utils::TestRouter::new(network_graph.clone(), &chanmon_cfgs[i].scorer),
                        chain_monitor,
                        keys_manager: &chanmon_cfgs[i].keys_manager,
                        node_seed: seed,
-                       features: channelmanager::provided_init_features(),
                        network_graph,
+                       override_init_features: Rc::new(RefCell::new(None)),
                });
        }
 
@@ -2203,23 +2336,23 @@ pub fn test_default_channel_config() -> UserConfig {
        default_config
 }
 
-pub fn create_node_chanmgrs<'a, 'b>(node_count: usize, cfgs: &'a Vec<NodeCfg<'b>>, node_config: &[Option<UserConfig>]) -> Vec<ChannelManager<&'a TestChainMonitor<'b>, &'b test_utils::TestBroadcaster, &'a test_utils::TestKeysInterface, &'b test_utils::TestFeeEstimator, &'a test_utils::TestRouter<'b>, &'b test_utils::TestLogger>> {
+pub fn create_node_chanmgrs<'a, 'b>(node_count: usize, cfgs: &'a Vec<NodeCfg<'b>>, node_config: &[Option<UserConfig>]) -> Vec<ChannelManager<&'a TestChainMonitor<'b>, &'b test_utils::TestBroadcaster, &'a test_utils::TestKeysInterface, &'a test_utils::TestKeysInterface, &'a test_utils::TestKeysInterface, &'b test_utils::TestFeeEstimator, &'a test_utils::TestRouter<'b>, &'b test_utils::TestLogger>> {
        let mut chanmgrs = Vec::new();
        for i in 0..node_count {
                let network = Network::Testnet;
                let params = ChainParameters {
                        network,
-                       best_block: BestBlock::from_genesis(network),
+                       best_block: BestBlock::from_network(network),
                };
                let node = ChannelManager::new(cfgs[i].fee_estimator, &cfgs[i].chain_monitor, cfgs[i].tx_broadcaster, &cfgs[i].router, cfgs[i].logger, cfgs[i].keys_manager,
-                       if node_config[i].is_some() { node_config[i].clone().unwrap() } else { test_default_channel_config() }, params);
+                       cfgs[i].keys_manager, cfgs[i].keys_manager, if node_config[i].is_some() { node_config[i].clone().unwrap() } else { test_default_channel_config() }, params);
                chanmgrs.push(node);
        }
 
        chanmgrs
 }
 
-pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeCfg<'c>>, chan_mgrs: &'a Vec<ChannelManager<&'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'c test_utils::TestRouter, &'c test_utils::TestLogger>>) -> Vec<Node<'a, 'b, 'c>> {
+pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeCfg<'c>>, chan_mgrs: &'a Vec<ChannelManager<&'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'b test_utils::TestKeysInterface, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'c test_utils::TestRouter, &'c test_utils::TestLogger>>) -> Vec<Node<'a, 'b, 'c>> {
        let mut nodes = Vec::new();
        let chan_count = Rc::new(RefCell::new(0));
        let payment_count = Rc::new(RefCell::new(0));
@@ -2236,13 +2369,14 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
                        network_payment_count: payment_count.clone(), logger: cfgs[i].logger,
                        blocks: Arc::clone(&cfgs[i].tx_broadcaster.blocks),
                        connect_style: Rc::clone(&connect_style),
+                       override_init_features: Rc::clone(&cfgs[i].override_init_features),
                })
        }
 
        for i in 0..node_count {
                for j in (i+1)..node_count {
-                       nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &msgs::Init { features: cfgs[j].features.clone(), remote_network_address: None }).unwrap();
-                       nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &msgs::Init { features: cfgs[i].features.clone(), remote_network_address: None }).unwrap();
+                       nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &msgs::Init { features: nodes[j].override_init_features.borrow().clone().unwrap_or_else(|| nodes[j].node.init_features()), remote_network_address: None }, true).unwrap();
+                       nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &msgs::Init { features: nodes[i].override_init_features.borrow().clone().unwrap_or_else(|| nodes[i].node.init_features()), remote_network_address: None }, false).unwrap();
                }
        }
 
@@ -2405,9 +2539,10 @@ pub fn get_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec<Node<'a, 'b,
 
 #[cfg(test)]
 macro_rules! get_channel_value_stat {
-       ($node: expr, $channel_id: expr) => {{
-               let chan_lock = $node.node.channel_state.lock().unwrap();
-               let chan = chan_lock.by_id.get(&$channel_id).unwrap();
+       ($node: expr, $counterparty_node: expr, $channel_id: expr) => {{
+               let peer_state_lock = $node.node.per_peer_state.read().unwrap();
+               let chan_lock = peer_state_lock.get(&$counterparty_node.node.get_our_node_id()).unwrap().lock().unwrap();
+               let chan = chan_lock.channel_by_id.get(&$channel_id).unwrap();
                chan.get_value_stat()
        }}
 }
@@ -2524,9 +2659,9 @@ macro_rules! handle_chan_reestablish_msgs {
 /// pending_htlc_adds includes both the holding cell and in-flight update_add_htlcs, whereas
 /// for claims/fails they are separated out.
 pub fn reconnect_nodes<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, send_channel_ready: (bool, bool), pending_htlc_adds: (i64, i64), pending_htlc_claims: (usize, usize), pending_htlc_fails: (usize, usize), pending_cell_htlc_claims: (usize, usize), pending_cell_htlc_fails: (usize, usize), pending_raa: (bool, bool))  {
-       node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { features: node_b.node.init_features(), remote_network_address: None }, true).unwrap();
        let reestablish_1 = get_chan_reestablish_msgs!(node_a, node_b);
-       node_b.node.peer_connected(&node_a.node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       node_b.node.peer_connected(&node_a.node.get_our_node_id(), &msgs::Init { features: node_a.node.init_features(), remote_network_address: None }, false).unwrap();
        let reestablish_2 = get_chan_reestablish_msgs!(node_b, node_a);
 
        if send_channel_ready.0 {
index c7db5d7bd983d71d08b72148e4d4a879c1739aeb..454fbe2b7819889e3246314a90ac82eed17f40f9 100644 (file)
@@ -17,7 +17,7 @@ use crate::chain::chaininterface::LowerBoundedFeeEstimator;
 use crate::chain::channelmonitor;
 use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
 use crate::chain::transaction::OutPoint;
-use crate::chain::keysinterface::{BaseSign, EntropySource, KeysInterface};
+use crate::chain::keysinterface::{ChannelSigner, EcdsaChannelSigner, EntropySource};
 use crate::ln::{PaymentPreimage, PaymentSecret, PaymentHash};
 use crate::ln::channel::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, CONCURRENT_INBOUND_HTLC_FEE_BUFFER, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MIN_AFFORDABLE_HTLC_COUNT};
 use crate::ln::channelmanager::{self, PaymentId, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA};
@@ -31,7 +31,7 @@ use crate::ln::msgs;
 use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction};
 use crate::util::enforcing_trait_impls::EnforcingSigner;
 use crate::util::test_utils;
-use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose, ClosureReason, HTLCDestination};
+use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, ClosureReason, HTLCDestination};
 use crate::util::errors::APIError;
 use crate::util::ser::{Writeable, ReadableArgs};
 use crate::util::config::UserConfig;
@@ -87,7 +87,7 @@ fn test_insane_channel_opens() {
        // Test helper that asserts we get the correct error string given a mutator
        // that supposedly makes the channel open message insane
        let insane_open_helper = |expected_error_str: &str, message_mutator: fn(msgs::OpenChannel) -> msgs::OpenChannel| {
-               nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &message_mutator(open_channel_message.clone()));
+               nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &message_mutator(open_channel_message.clone()));
                let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
                assert_eq!(msg_events.len(), 1);
                let expected_regex = regex::Regex::new(expected_error_str).unwrap();
@@ -129,7 +129,7 @@ fn test_funding_exceeds_no_wumbo_limit() {
        use crate::ln::channel::MAX_FUNDING_SATOSHIS_NO_WUMBO;
        let chanmon_cfgs = create_chanmon_cfgs(2);
        let mut node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
-       node_cfgs[1].features = channelmanager::provided_init_features().clear_wumbo();
+       *node_cfgs[1].override_init_features.borrow_mut() = Some(channelmanager::provided_init_features(&test_default_channel_config()).clear_wumbo());
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
@@ -165,7 +165,7 @@ fn do_test_counterparty_no_reserve(send_from_initiator: bool) {
                open_channel_message.channel_reserve_satoshis = 0;
                open_channel_message.max_htlc_value_in_flight_msat = 100_000_000;
        }
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel_message);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_message);
 
        // Extract the channel accept message from node1 to node0
        let mut accept_channel_message = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
@@ -173,10 +173,13 @@ fn do_test_counterparty_no_reserve(send_from_initiator: bool) {
                accept_channel_message.channel_reserve_satoshis = 0;
                accept_channel_message.max_htlc_value_in_flight_msat = 100_000_000;
        }
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel_message);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel_message);
        {
-               let mut lock;
-               let mut chan = get_channel_ref!(if send_from_initiator { &nodes[1] } else { &nodes[0] }, lock, temp_channel_id);
+               let sender_node = if send_from_initiator { &nodes[1] } else { &nodes[0] };
+               let counterparty_node = if send_from_initiator { &nodes[0] } else { &nodes[1] };
+               let mut sender_node_per_peer_lock;
+               let mut sender_node_peer_state_lock;
+               let mut chan = get_channel_ref!(sender_node, counterparty_node, sender_node_per_peer_lock, sender_node_peer_state_lock, temp_channel_id);
                chan.holder_selected_channel_reserve_satoshis = 0;
                chan.holder_max_htlc_value_in_flight_msat = 100_000_000;
        }
@@ -210,7 +213,7 @@ fn test_async_inbound_update_fee() {
        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);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // balancing
        send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
@@ -326,7 +329,7 @@ fn test_update_fee_unordered_raa() {
        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);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // balancing
        send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
@@ -382,7 +385,7 @@ fn test_multi_flight_update_fee() {
        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);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // A                                        B
        // update_fee/commitment_signed          ->
@@ -516,11 +519,11 @@ fn do_test_sanity_on_in_flight_opens(steps: u8) {
        let open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
 
        if steps & 0x0f == 1 { return; }
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
        let accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
 
        if steps & 0x0f == 2 { return; }
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
 
        let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42);
 
@@ -589,7 +592,7 @@ fn test_update_fee_vanilla() {
        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);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        {
                let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
@@ -634,7 +637,7 @@ fn test_update_fee_that_funder_cannot_afford() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
        let channel_value = 5000;
        let push_sats = 700;
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value, push_sats * 1000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value, push_sats * 1000);
        let channel_id = chan.2;
        let secp_ctx = Secp256k1::new();
        let default_config = UserConfig::default();
@@ -686,16 +689,18 @@ fn test_update_fee_that_funder_cannot_afford() {
        // Get the EnforcingSigner for each channel, which will be used to (1) get the keys
        // needed to sign the new commitment tx and (2) sign the new commitment tx.
        let (local_revocation_basepoint, local_htlc_basepoint, local_funding) = {
-               let chan_lock = nodes[0].node.channel_state.lock().unwrap();
-               let local_chan = chan_lock.by_id.get(&chan.2).unwrap();
+               let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+               let chan_lock = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
+               let local_chan = chan_lock.channel_by_id.get(&chan.2).unwrap();
                let chan_signer = local_chan.get_signer();
                let pubkeys = chan_signer.pubkeys();
                (pubkeys.revocation_basepoint, pubkeys.htlc_basepoint,
                 pubkeys.funding_pubkey)
        };
        let (remote_delayed_payment_basepoint, remote_htlc_basepoint,remote_point, remote_funding) = {
-               let chan_lock = nodes[1].node.channel_state.lock().unwrap();
-               let remote_chan = chan_lock.by_id.get(&chan.2).unwrap();
+               let per_peer_state = nodes[1].node.per_peer_state.read().unwrap();
+               let chan_lock = per_peer_state.get(&nodes[0].node.get_our_node_id()).unwrap().lock().unwrap();
+               let remote_chan = chan_lock.channel_by_id.get(&chan.2).unwrap();
                let chan_signer = remote_chan.get_signer();
                let pubkeys = chan_signer.pubkeys();
                (pubkeys.delayed_payment_basepoint, pubkeys.htlc_basepoint,
@@ -708,8 +713,9 @@ fn test_update_fee_that_funder_cannot_afford() {
                &remote_htlc_basepoint, &local_revocation_basepoint, &local_htlc_basepoint);
 
        let res = {
-               let local_chan_lock = nodes[0].node.channel_state.lock().unwrap();
-               let local_chan = local_chan_lock.by_id.get(&chan.2).unwrap();
+               let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+               let local_chan_lock = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
+               let local_chan = local_chan_lock.channel_by_id.get(&chan.2).unwrap();
                let local_chan_signer = local_chan.get_signer();
                let mut htlcs: Vec<(HTLCOutputInCommitment, ())> = vec![];
                let commitment_tx = CommitmentTransaction::new_with_auxiliary_htlc_data(
@@ -754,7 +760,7 @@ fn test_update_fee_with_fundee_update_add_htlc() {
        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);
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // balancing
        send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
@@ -853,7 +859,7 @@ fn test_update_fee() {
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
        let channel_id = chan.2;
 
        // A                                        B
@@ -954,8 +960,8 @@ fn test_update_fee() {
        check_added_monitors!(nodes[1], 1);
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
 
-       assert_eq!(get_feerate!(nodes[0], channel_id), feerate + 30);
-       assert_eq!(get_feerate!(nodes[1], channel_id), feerate + 30);
+       assert_eq!(get_feerate!(nodes[0], nodes[1], channel_id), feerate + 30);
+       assert_eq!(get_feerate!(nodes[1], nodes[0], channel_id), feerate + 30);
        close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true);
        check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure);
        check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure);
@@ -971,9 +977,9 @@ fn fake_network_test() {
        let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+       let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3);
 
        // Rebalance the network a bit by relaying one payment through all the channels...
        send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000);
@@ -991,7 +997,7 @@ fn fake_network_test() {
        fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], payment_hash_1);
 
        // Add a new channel that skips 3
-       let chan_4 = create_announced_chan_between_nodes(&nodes, 1, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_4 = create_announced_chan_between_nodes(&nodes, 1, 3);
 
        send_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], 1000000);
        send_payment(&nodes[2], &vec!(&nodes[3])[..], 1000000);
@@ -1021,9 +1027,9 @@ fn fake_network_test() {
        });
        hops.push(RouteHop {
                pubkey: nodes[1].node.get_our_node_id(),
-               node_features: channelmanager::provided_node_features(),
+               node_features: nodes[1].node.node_features(),
                short_channel_id: chan_4.0.contents.short_channel_id,
-               channel_features: channelmanager::provided_channel_features(),
+               channel_features: nodes[1].node.channel_features(),
                fee_msat: 1000000,
                cltv_expiry_delta: TEST_FINAL_CLTV,
        });
@@ -1050,9 +1056,9 @@ fn fake_network_test() {
        });
        hops.push(RouteHop {
                pubkey: nodes[1].node.get_our_node_id(),
-               node_features: channelmanager::provided_node_features(),
+               node_features: nodes[1].node.node_features(),
                short_channel_id: chan_2.0.contents.short_channel_id,
-               channel_features: channelmanager::provided_channel_features(),
+               channel_features: nodes[1].node.channel_features(),
                fee_msat: 1000000,
                cltv_expiry_delta: TEST_FINAL_CLTV,
        });
@@ -1088,8 +1094,8 @@ fn holding_cell_htlc_counting() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        let mut payments = Vec::new();
        for _ in 0..crate::ln::channel::OUR_MAX_HTLCS {
@@ -1203,11 +1209,11 @@ fn duplicate_htlc_test() {
        let mut nodes = create_network(6, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels to route via 3 to 4/5 from 0/1/2
-       create_announced_chan_between_nodes(&nodes, 0, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 1, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 2, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 3, 4, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 3, 5, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 3);
+       create_announced_chan_between_nodes(&nodes, 1, 3);
+       create_announced_chan_between_nodes(&nodes, 2, 3);
+       create_announced_chan_between_nodes(&nodes, 3, 4);
+       create_announced_chan_between_nodes(&nodes, 3, 5);
 
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[3], &nodes[4])[..], 1000000);
 
@@ -1232,7 +1238,7 @@ fn test_duplicate_htlc_different_direction_onchain() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // balancing
        send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
@@ -1240,7 +1246,7 @@ fn test_duplicate_htlc_different_direction_onchain() {
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 900_000);
 
        let (route, _, _, _) = get_route_and_payment_hash!(nodes[1], nodes[0], 800_000);
-       let node_a_payment_secret = nodes[0].node.create_inbound_payment_for_hash(payment_hash, None, 7200).unwrap();
+       let node_a_payment_secret = nodes[0].node.create_inbound_payment_for_hash(payment_hash, None, 7200, None).unwrap();
        send_along_route_with_secret(&nodes[1], route, &[&[&nodes[0]]], 800_000, payment_hash, node_a_payment_secret);
 
        // Provide preimage to node 0 by claiming payment
@@ -1319,13 +1325,13 @@ fn test_basic_channel_reserve() {
        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);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
 
-       let chan_stat = get_channel_value_stat!(nodes[0], chan.2);
+       let chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
        let channel_reserve = chan_stat.channel_reserve_msat;
 
        // The 2* and +1 are for the fee spike reserve.
-       let commit_tx_fee = 2 * commit_tx_fee_msat(get_feerate!(nodes[0], chan.2), 1 + 1, get_opt_anchors!(nodes[0], chan.2));
+       let commit_tx_fee = 2 * commit_tx_fee_msat(get_feerate!(nodes[0], nodes[1], chan.2), 1 + 1, get_opt_anchors!(nodes[0], nodes[1], chan.2));
        let max_can_send = 5000000 - channel_reserve - commit_tx_fee;
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], max_can_send + 1);
        let err = nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).err().unwrap();
@@ -1351,7 +1357,7 @@ fn test_fee_spike_violation_fails_htlc() {
        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);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
 
        let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 3460001);
        // Need to manually create the update_add_htlc message to go around the channel reserve check in send_htlc()
@@ -1378,15 +1384,16 @@ fn test_fee_spike_violation_fails_htlc() {
        // nodes[0] just sent. In the code for construction of this message, "local" refers
        // to the sender of the message, and "remote" refers to the receiver.
 
-       let feerate_per_kw = get_feerate!(nodes[0], chan.2);
+       let feerate_per_kw = get_feerate!(nodes[0], nodes[1], chan.2);
 
        const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
 
        // Get the EnforcingSigner for each channel, which will be used to (1) get the keys
        // needed to sign the new commitment tx and (2) sign the new commitment tx.
        let (local_revocation_basepoint, local_htlc_basepoint, local_secret, next_local_point, local_funding) = {
-               let chan_lock = nodes[0].node.channel_state.lock().unwrap();
-               let local_chan = chan_lock.by_id.get(&chan.2).unwrap();
+               let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+               let chan_lock = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
+               let local_chan = chan_lock.channel_by_id.get(&chan.2).unwrap();
                let chan_signer = local_chan.get_signer();
                // Make the signer believe we validated another commitment, so we can release the secret
                chan_signer.get_enforcement_state().last_holder_commitment -= 1;
@@ -1398,8 +1405,9 @@ fn test_fee_spike_violation_fails_htlc() {
                 chan_signer.pubkeys().funding_pubkey)
        };
        let (remote_delayed_payment_basepoint, remote_htlc_basepoint, remote_point, remote_funding) = {
-               let chan_lock = nodes[1].node.channel_state.lock().unwrap();
-               let remote_chan = chan_lock.by_id.get(&chan.2).unwrap();
+               let per_peer_state = nodes[1].node.per_peer_state.read().unwrap();
+               let chan_lock = per_peer_state.get(&nodes[0].node.get_our_node_id()).unwrap().lock().unwrap();
+               let remote_chan = chan_lock.channel_by_id.get(&chan.2).unwrap();
                let chan_signer = remote_chan.get_signer();
                let pubkeys = chan_signer.pubkeys();
                (pubkeys.delayed_payment_basepoint, pubkeys.htlc_basepoint,
@@ -1426,8 +1434,9 @@ fn test_fee_spike_violation_fails_htlc() {
        let commitment_number = INITIAL_COMMITMENT_NUMBER - 1;
 
        let res = {
-               let local_chan_lock = nodes[0].node.channel_state.lock().unwrap();
-               let local_chan = local_chan_lock.by_id.get(&chan.2).unwrap();
+               let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+               let local_chan_lock = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
+               let local_chan = local_chan_lock.channel_by_id.get(&chan.2).unwrap();
                let local_chan_signer = local_chan.get_signer();
                let commitment_tx = CommitmentTransaction::new_with_auxiliary_htlc_data(
                        commitment_number,
@@ -1495,7 +1504,7 @@ fn test_chan_reserve_violation_outbound_htlc_inbound_chan() {
 
        push_amt -= Channel::<EnforcingSigner>::get_holder_selected_channel_reserve_satoshis(100_000, &default_config) * 1000;
 
-       let _ = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, push_amt, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _ = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, push_amt);
 
        // Sending exactly enough to hit the reserve amount should be accepted
        for _ in 0..MIN_AFFORDABLE_HTLC_COUNT {
@@ -1526,7 +1535,7 @@ fn test_chan_reserve_violation_inbound_htlc_outbound_channel() {
        let mut push_amt = 100_000_000;
        push_amt -= commit_tx_fee_msat(feerate_per_kw, MIN_AFFORDABLE_HTLC_COUNT as u64, opt_anchors);
        push_amt -= Channel::<EnforcingSigner>::get_holder_selected_channel_reserve_satoshis(100_000, &default_config) * 1000;
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, push_amt, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, push_amt);
 
        // Send four HTLCs to cover the initial push_msat buffer we're required to include
        for _ in 0..MIN_AFFORDABLE_HTLC_COUNT {
@@ -1579,7 +1588,7 @@ fn test_chan_reserve_dust_inbound_htlcs_outbound_chan() {
        let mut push_amt = 100_000_000;
        push_amt -= commit_tx_fee_msat(feerate_per_kw, MIN_AFFORDABLE_HTLC_COUNT as u64, opt_anchors);
        push_amt -= Channel::<EnforcingSigner>::get_holder_selected_channel_reserve_satoshis(100_000, &default_config) * 1000;
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, push_amt, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, push_amt);
 
        let dust_amt = crate::ln::channel::MIN_CHAN_DUST_LIMIT_SATOSHIS * 1000
                + feerate_per_kw as u64 * htlc_success_tx_weight(opt_anchors) / 1000 * 1000 - 1;
@@ -1624,7 +1633,7 @@ fn test_chan_init_feerate_unaffordability() {
        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(), channelmanager::provided_init_features(), &open_channel_msg);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
 
        let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(msg_events.len(), 1);
@@ -1644,7 +1653,7 @@ fn test_chan_reserve_dust_inbound_htlcs_inbound_chan() {
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 98000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 98000000);
 
        let payment_amt = 46000; // Dust amount
        // In the previous code, these first four payments would succeed.
@@ -1672,14 +1681,14 @@ fn test_chan_reserve_violation_inbound_htlc_inbound_chan() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let _ = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
+       let _ = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 95000000);
 
        let feemsat = 239;
        let total_routing_fee_msat = (nodes.len() - 2) as u64 * feemsat;
-       let chan_stat = get_channel_value_stat!(nodes[0], chan.2);
-       let feerate = get_feerate!(nodes[0], chan.2);
-       let opt_anchors = get_opt_anchors!(nodes[0], chan.2);
+       let chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
+       let feerate = get_feerate!(nodes[0], nodes[1], chan.2);
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan.2);
 
        // Add a 2* and +1 for the fee spike reserve.
        let commit_tx_fee_2_htlc = 2*commit_tx_fee_msat(feerate, 2 + 1, opt_anchors);
@@ -1736,7 +1745,7 @@ fn test_inbound_outbound_capacity_is_not_zero() {
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-       let _ = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _ = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
        let channels0 = node_chanmgrs[0].list_channels();
        let channels1 = node_chanmgrs[1].list_channels();
        let default_config = UserConfig::default();
@@ -1765,14 +1774,14 @@ fn test_channel_reserve_holding_cell_htlcs() {
        config.channel_config.forwarding_fee_base_msat = 239;
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[Some(config.clone()), Some(config.clone()), Some(config.clone())]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 190000, 1001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 190000, 1001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 190000, 1001);
+       let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 190000, 1001);
 
-       let mut stat01 = get_channel_value_stat!(nodes[0], chan_1.2);
-       let mut stat11 = get_channel_value_stat!(nodes[1], chan_1.2);
+       let mut stat01 = get_channel_value_stat!(nodes[0], nodes[1], chan_1.2);
+       let mut stat11 = get_channel_value_stat!(nodes[1], nodes[0], chan_1.2);
 
-       let mut stat12 = get_channel_value_stat!(nodes[1], chan_2.2);
-       let mut stat22 = get_channel_value_stat!(nodes[2], chan_2.2);
+       let mut stat12 = get_channel_value_stat!(nodes[1], nodes[2], chan_2.2);
+       let mut stat22 = get_channel_value_stat!(nodes[2], nodes[1], chan_2.2);
 
        macro_rules! expect_forward {
                ($node: expr) => {{
@@ -1786,15 +1795,15 @@ fn test_channel_reserve_holding_cell_htlcs() {
 
        let feemsat = 239; // set above
        let total_fee_msat = (nodes.len() - 2) as u64 * feemsat;
-       let feerate = get_feerate!(nodes[0], chan_1.2);
-       let opt_anchors = get_opt_anchors!(nodes[0], chan_1.2);
+       let feerate = get_feerate!(nodes[0], nodes[1], chan_1.2);
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_1.2);
 
        let recv_value_0 = stat01.counterparty_max_htlc_value_in_flight_msat - total_fee_msat;
 
        // attempt to send amt_msat > their_max_htlc_value_in_flight_msat
        {
-               let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())
-                       .with_features(channelmanager::provided_invoice_features()).with_max_channel_saturation_power_of_half(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)
+                       .with_features(nodes[2].node.invoice_features()).with_max_channel_saturation_power_of_half(0);
                let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, recv_value_0, TEST_FINAL_CLTV);
                route.paths[0].last_mut().unwrap().fee_msat += 1;
                assert!(route.paths[0].iter().rev().skip(1).all(|h| h.fee_msat == feemsat));
@@ -1818,17 +1827,17 @@ fn test_channel_reserve_holding_cell_htlcs() {
                        break;
                }
 
-               let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())
-                       .with_features(channelmanager::provided_invoice_features()).with_max_channel_saturation_power_of_half(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)
+                       .with_features(nodes[2].node.invoice_features()).with_max_channel_saturation_power_of_half(0);
                let route = get_route!(nodes[0], payment_params, recv_value_0, TEST_FINAL_CLTV).unwrap();
                let (payment_preimage, ..) = send_along_route(&nodes[0], route, &[&nodes[1], &nodes[2]], recv_value_0);
                claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
 
                let (stat01_, stat11_, stat12_, stat22_) = (
-                       get_channel_value_stat!(nodes[0], chan_1.2),
-                       get_channel_value_stat!(nodes[1], chan_1.2),
-                       get_channel_value_stat!(nodes[1], chan_2.2),
-                       get_channel_value_stat!(nodes[2], chan_2.2),
+                       get_channel_value_stat!(nodes[0], nodes[1], chan_1.2),
+                       get_channel_value_stat!(nodes[1], nodes[0], chan_1.2),
+                       get_channel_value_stat!(nodes[1], nodes[2], chan_2.2),
+                       get_channel_value_stat!(nodes[2], nodes[1], chan_2.2),
                );
 
                assert_eq!(stat01_.value_to_self_msat, stat01.value_to_self_msat - amt_msat);
@@ -1879,7 +1888,7 @@ fn test_channel_reserve_holding_cell_htlcs() {
        let recv_value_21 = recv_value_2/2 - additional_htlc_cost_msat/2;
        let recv_value_22 = recv_value_2 - recv_value_21 - total_fee_msat - additional_htlc_cost_msat;
        {
-               let stat = get_channel_value_stat!(nodes[0], chan_1.2);
+               let stat = get_channel_value_stat!(nodes[0], nodes[1], chan_1.2);
                assert_eq!(stat.value_to_self_msat - (stat.pending_outbound_htlcs_amount_msat + recv_value_21 + recv_value_22 + total_fee_msat + total_fee_msat + commit_tx_fee_3_htlcs), stat.channel_reserve_msat);
        }
 
@@ -1995,11 +2004,11 @@ fn test_channel_reserve_holding_cell_htlcs() {
 
        let commit_tx_fee_1_htlc = 2*commit_tx_fee_msat(feerate, 1 + 1, opt_anchors);
        let expected_value_to_self = stat01.value_to_self_msat - (recv_value_1 + total_fee_msat) - (recv_value_21 + total_fee_msat) - (recv_value_22 + total_fee_msat) - (recv_value_3 + total_fee_msat);
-       let stat0 = get_channel_value_stat!(nodes[0], chan_1.2);
+       let stat0 = get_channel_value_stat!(nodes[0], nodes[1], chan_1.2);
        assert_eq!(stat0.value_to_self_msat, expected_value_to_self);
        assert_eq!(stat0.value_to_self_msat, stat0.channel_reserve_msat + commit_tx_fee_1_htlc);
 
-       let stat2 = get_channel_value_stat!(nodes[2], chan_2.2);
+       let stat2 = get_channel_value_stat!(nodes[2], nodes[1], chan_2.2);
        assert_eq!(stat2.value_to_self_msat, stat22.value_to_self_msat + recv_value_1 + recv_value_21 + recv_value_22 + recv_value_3);
 }
 
@@ -2031,9 +2040,9 @@ fn channel_reserve_in_flight_removes() {
        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);
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
-       let b_chan_values = get_channel_value_stat!(nodes[1], chan_1.2);
+       let b_chan_values = get_channel_value_stat!(nodes[1], nodes[0], chan_1.2);
        // Route the first two HTLCs.
        let payment_value_1 = b_chan_values.channel_reserve_msat - b_chan_values.value_to_self_msat - 10000;
        let (payment_preimage_1, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1]], payment_value_1);
@@ -2166,10 +2175,10 @@ fn channel_monitor_network_test() {
        let nodes = create_network(5, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_4 = create_announced_chan_between_nodes(&nodes, 3, 4, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+       let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3);
+       let chan_4 = create_announced_chan_between_nodes(&nodes, 3, 4);
 
        // Make sure all nodes are at the same starting height
        connect_blocks(&nodes[0], 4*CHAN_CONFIRM_DEPTH + 1 - nodes[0].best_block_info().1);
@@ -2363,7 +2372,7 @@ fn test_justice_tx() {
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
        *nodes[0].connect_style.borrow_mut() = ConnectStyle::FullBlockViaListen;
        // Create some new channels:
-       let chan_5 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_5 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // A pending HTLC which will be revoked:
        let payment_preimage_3 = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
@@ -2410,7 +2419,7 @@ fn test_justice_tx() {
 
        // We test justice_tx build by A on B's revoked HTLC-Success tx
        // Create some new channels:
-       let chan_6 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_6 = create_announced_chan_between_nodes(&nodes, 0, 1);
        {
                let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
                node_txn.clear();
@@ -2460,7 +2469,7 @@ fn revoked_output_claim() {
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
        // node[0] is gonna to revoke an old state thus node[1] should be able to claim the revoked output
        let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan_1.2);
        assert_eq!(revoked_local_txn.len(), 1);
@@ -2495,7 +2504,7 @@ fn claim_htlc_outputs_shared_tx() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some new channel:
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Rebalance the network to generate htlc in the two directions
        send_payment(&nodes[0], &[&nodes[1]], 8_000_000);
@@ -2561,7 +2570,7 @@ fn claim_htlc_outputs_single_tx() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Rebalance the network to generate htlc in the two directions
        send_payment(&nodes[0], &[&nodes[1]], 8_000_000);
@@ -2656,8 +2665,8 @@ fn test_htlc_on_chain_success() {
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // Ensure all nodes are at the same height
        let node_max_height = nodes.iter().map(|node| node.blocks.lock().unwrap().len()).max().unwrap() as u32;
@@ -2738,7 +2747,7 @@ fn test_htlc_on_chain_success() {
                },
                _ => panic!()
        }
-       let events = nodes[1].node.get_and_clear_pending_msg_events();
+       let mut events = nodes[1].node.get_and_clear_pending_msg_events();
        {
                let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap();
                assert_eq!(added_monitors.len(), 2);
@@ -2747,16 +2756,16 @@ fn test_htlc_on_chain_success() {
                added_monitors.clear();
        }
        assert_eq!(events.len(), 3);
-       match events[0] {
-               MessageSendEvent::BroadcastChannelUpdate { .. } => {},
-               _ => panic!("Unexpected event"),
-       }
-       match events[1] {
+
+       let nodes_2_event = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events);
+       let nodes_0_event = remove_first_msg_event_to_node(&nodes[0].node.get_our_node_id(), &mut events);
+
+       match nodes_2_event {
                MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { .. }, node_id: _ } => {},
                _ => panic!("Unexpected event"),
        }
 
-       match events[2] {
+       match nodes_0_event {
                MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, .. } } => {
                        assert!(update_add_htlcs.is_empty());
                        assert!(update_fail_htlcs.is_empty());
@@ -2766,6 +2775,13 @@ fn test_htlc_on_chain_success() {
                },
                _ => panic!("Unexpected event"),
        };
+
+       // Ensure that the last remaining message event is the BroadcastChannelUpdate msg for chan_2
+       match events[0] {
+               MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+               _ => panic!("Unexpected event"),
+       }
+
        macro_rules! check_tx_local_broadcast {
                ($node: expr, $htlc_offered: expr, $commitment_tx: expr) => { {
                        let mut node_txn = $node.tx_broadcaster.txn_broadcasted.lock().unwrap();
@@ -2877,8 +2893,8 @@ fn do_test_htlc_on_chain_timeout(connect_style: ConnectStyle) {
        *nodes[2].connect_style.borrow_mut() = connect_style;
 
        // Create some intial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // Rebalance the network a bit by relaying one payment thorugh all the channels...
        send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
@@ -2990,8 +3006,8 @@ fn test_simple_commitment_revoked_fail_backward() {
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        let (payment_preimage, _payment_hash, _payment_secret) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
        // Get the will-be-revoked local txn from nodes[2]
@@ -3049,8 +3065,8 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        let (payment_preimage, _payment_hash, _payment_secret) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], if no_to_remote { 10_000 } else { 3_000_000 });
        // Get the will-be-revoked local txn from nodes[2]
@@ -3062,7 +3078,8 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
        let value = if use_dust {
                // The dust limit applied to HTLC outputs considers the fee of the HTLC transaction as
                // well, so HTLCs at exactly the dust limit will not be included in commitment txn.
-               nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().holder_dust_limit_satoshis * 1000
+               nodes[2].node.per_peer_state.read().unwrap().get(&nodes[1].node.get_our_node_id())
+                       .unwrap().lock().unwrap().channel_by_id.get(&chan_2.2).unwrap().holder_dust_limit_satoshis * 1000
        } else { 3000000 };
 
        let (_, first_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], value);
@@ -3153,7 +3170,7 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
        connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1);
 
        let events = nodes[1].node.get_and_clear_pending_events();
-       assert_eq!(events.len(), if deliver_bs_raa { 2 + nodes.len() - 1 } else { 3 + nodes.len() });
+       assert_eq!(events.len(), if deliver_bs_raa { 3 + nodes.len() - 1 } else { 4 + nodes.len() });
        match events[0] {
                Event::ChannelClosed { reason: ClosureReason::CommitmentTxConfirmed, .. } => { },
                _ => panic!("Unexepected event"),
@@ -3164,39 +3181,22 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
                },
                _ => panic!("Unexpected event"),
        }
-       if !deliver_bs_raa {
-               match events[2] {
-                       Event::PendingHTLCsForwardable { .. } => { },
-                       _ => panic!("Unexpected event"),
-               };
-               nodes[1].node.abandon_payment(PaymentId(fourth_payment_hash.0));
-               let payment_failed_events = nodes[1].node.get_and_clear_pending_events();
-               assert_eq!(payment_failed_events.len(), 1);
-               match payment_failed_events[0] {
-                       Event::PaymentFailed { ref payment_hash, .. } => {
-                               assert_eq!(*payment_hash, fourth_payment_hash);
-                       },
-                       _ => panic!("Unexpected event"),
-               }
+       match events[2] {
+               Event::PaymentFailed { ref payment_hash, .. } => {
+                       assert_eq!(*payment_hash, fourth_payment_hash);
+               },
+               _ => panic!("Unexpected event"),
        }
+
        nodes[1].node.process_pending_htlc_forwards();
        check_added_monitors!(nodes[1], 1);
 
-       let events = nodes[1].node.get_and_clear_pending_msg_events();
+       let mut events = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), if deliver_bs_raa { 4 } else { 3 });
-       match events[if deliver_bs_raa { 1 } else { 0 }] {
-               MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { .. } } => {},
-               _ => panic!("Unexpected event"),
-       }
-       match events[if deliver_bs_raa { 2 } else { 1 }] {
-               MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { msg: msgs::ErrorMessage { channel_id, ref data } }, node_id: _ } => {
-                       assert_eq!(channel_id, chan_2.2);
-                       assert_eq!(data.as_str(), "Channel closed because commitment or closing transaction was confirmed on chain.");
-               },
-               _ => panic!("Unexpected event"),
-       }
+
        if deliver_bs_raa {
-               match events[0] {
+               let nodes_2_event = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events);
+               match nodes_2_event {
                        MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, .. } } => {
                                assert_eq!(nodes[2].node.get_our_node_id(), *node_id);
                                assert_eq!(update_add_htlcs.len(), 1);
@@ -3207,7 +3207,18 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
                        _ => panic!("Unexpected event"),
                }
        }
-       match events[if deliver_bs_raa { 3 } else { 2 }] {
+
+       let nodes_2_event = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events);
+       match nodes_2_event {
+               MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { msg: msgs::ErrorMessage { channel_id, ref data } }, node_id: _ } => {
+                       assert_eq!(channel_id, chan_2.2);
+                       assert_eq!(data.as_str(), "Channel closed because commitment or closing transaction was confirmed on chain.");
+               },
+               _ => panic!("Unexpected event"),
+       }
+
+       let nodes_0_event = remove_first_msg_event_to_node(&nodes[0].node.get_our_node_id(), &mut events);
+       match nodes_0_event {
                MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, ref commitment_signed, .. } } => {
                        assert!(update_add_htlcs.is_empty());
                        assert_eq!(update_fail_htlcs.len(), 3);
@@ -3222,29 +3233,45 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
                        commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, false, true);
 
                        let events = nodes[0].node.get_and_clear_pending_events();
-                       assert_eq!(events.len(), 3);
+                       assert_eq!(events.len(), 6);
                        match events[0] {
-                               Event::PaymentPathFailed { ref payment_hash, ref network_update, .. } => {
+                               Event::PaymentPathFailed { ref payment_hash, ref failure, .. } => {
                                        assert!(failed_htlcs.insert(payment_hash.0));
                                        // If we delivered B's RAA we got an unknown preimage error, not something
                                        // that we should update our routing table for.
                                        if !deliver_bs_raa {
-                                               assert!(network_update.is_some());
+                                               if let PathFailure::OnPath { network_update: Some(_) } = failure { } else { panic!("Unexpected path failure") }
                                        }
                                },
                                _ => panic!("Unexpected event"),
                        }
                        match events[1] {
-                               Event::PaymentPathFailed { ref payment_hash, ref network_update, .. } => {
-                                       assert!(failed_htlcs.insert(payment_hash.0));
-                                       assert!(network_update.is_some());
+                               Event::PaymentFailed { ref payment_hash, .. } => {
+                                       assert_eq!(*payment_hash, first_payment_hash);
                                },
                                _ => panic!("Unexpected event"),
                        }
                        match events[2] {
-                               Event::PaymentPathFailed { ref payment_hash, ref network_update, .. } => {
+                               Event::PaymentPathFailed { ref payment_hash, failure: PathFailure::OnPath { network_update: Some(_) }, .. } => {
                                        assert!(failed_htlcs.insert(payment_hash.0));
-                                       assert!(network_update.is_some());
+                               },
+                               _ => panic!("Unexpected event"),
+                       }
+                       match events[3] {
+                               Event::PaymentFailed { ref payment_hash, .. } => {
+                                       assert_eq!(*payment_hash, second_payment_hash);
+                               },
+                               _ => panic!("Unexpected event"),
+                       }
+                       match events[4] {
+                               Event::PaymentPathFailed { ref payment_hash, failure: PathFailure::OnPath { network_update: Some(_) }, .. } => {
+                                       assert!(failed_htlcs.insert(payment_hash.0));
+                               },
+                               _ => panic!("Unexpected event"),
+                       }
+                       match events[5] {
+                               Event::PaymentFailed { ref payment_hash, .. } => {
+                                       assert_eq!(*payment_hash, third_payment_hash);
                                },
                                _ => panic!("Unexpected event"),
                        }
@@ -3252,6 +3279,12 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
                _ => panic!("Unexpected event"),
        }
 
+       // Ensure that the last remaining message event is the BroadcastChannelUpdate msg for chan_2
+       match events[0] {
+               MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { .. } } => {},
+               _ => panic!("Unexpected event"),
+       }
+
        assert!(failed_htlcs.contains(&first_payment_hash.0));
        assert!(failed_htlcs.contains(&second_payment_hash.0));
        assert!(failed_htlcs.contains(&third_payment_hash.0));
@@ -3279,7 +3312,7 @@ fn fail_backward_pending_htlc_upon_channel_failure() {
        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);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000);
 
        // Alice -> Bob: Route a payment but without Bob sending revoke_and_ack.
        {
@@ -3328,7 +3361,7 @@ fn fail_backward_pending_htlc_upon_channel_failure() {
                nodes[0].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &update_add_htlc);
        }
        let events = nodes[0].node.get_and_clear_pending_events();
-       assert_eq!(events.len(), 2);
+       assert_eq!(events.len(), 3);
        // Check that Alice fails backward the pending HTLC from the second payment.
        match events[0] {
                Event::PaymentPathFailed { payment_hash, .. } => {
@@ -3337,6 +3370,12 @@ fn fail_backward_pending_htlc_upon_channel_failure() {
                _ => panic!("Unexpected event"),
        }
        match events[1] {
+               Event::PaymentFailed { payment_hash, .. } => {
+                       assert_eq!(payment_hash, failed_payment_hash);
+               },
+               _ => panic!("Unexpected event"),
+       }
+       match events[2] {
                Event::ChannelClosed { reason: ClosureReason::ProcessingError { ref err }, .. } => {
                        assert_eq!(err, "Remote side tried to send a 0-msat HTLC");
                },
@@ -3360,7 +3399,7 @@ fn test_htlc_ignore_latest_remote_commitment() {
                // connect_style.
                return;
        }
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        route_payment(&nodes[0], &[&nodes[1]], 10000000);
        nodes[0].node.force_close_broadcasting_latest_txn(&nodes[0].node.list_channels()[0].channel_id, &nodes[1].node.get_our_node_id()).unwrap();
@@ -3391,8 +3430,8 @@ fn test_force_close_fail_back() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       create_announced_chan_between_nodes(&nodes, 1, 2);
 
        let (route, our_payment_hash, our_payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 1000000);
 
@@ -3472,7 +3511,7 @@ fn test_dup_events_on_peer_disconnect() {
        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);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
 
@@ -3483,8 +3522,8 @@ fn test_dup_events_on_peer_disconnect() {
        nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &claim_msgs.update_fulfill_htlcs[0]);
        expect_payment_sent_without_paths!(nodes[0], payment_preimage);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (1, 0), (0, 0), (0, 0), (0, 0), (false, false));
        expect_payment_path_successful!(nodes[0]);
@@ -3503,9 +3542,9 @@ fn test_peer_disconnected_before_funding_broadcasted() {
        // broadcasted, even though it's created by `nodes[0]`.
        let expected_temporary_channel_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1_000_000, 500_000_000, 42, None).unwrap();
        let open_channel = 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(), channelmanager::provided_init_features(), &open_channel);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
        let accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
 
        let (temporary_channel_id, tx, _funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 1_000_000, 42);
        assert_eq!(temporary_channel_id, expected_temporary_channel_id);
@@ -3524,8 +3563,8 @@ fn test_peer_disconnected_before_funding_broadcasted() {
 
        // Ensure that the channel is closed with `ClosureReason::DisconnectedPeer` when the peers are
        // disconnected before the funding transaction was broadcasted.
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        check_closed_event!(nodes[0], 1, ClosureReason::DisconnectedPeer);
        check_closed_event!(nodes[1], 1, ClosureReason::DisconnectedPeer);
@@ -3538,11 +3577,11 @@ fn test_simple_peer_disconnect() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       create_announced_chan_between_nodes(&nodes, 1, 2);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
        reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
        let payment_preimage_1 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).0;
@@ -3550,8 +3589,8 @@ fn test_simple_peer_disconnect() {
        fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_hash_2);
        claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_preimage_1);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
        reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
        let (payment_preimage_3, payment_hash_3, _) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000);
@@ -3559,8 +3598,8 @@ fn test_simple_peer_disconnect() {
        let payment_hash_5 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).1;
        let payment_hash_6 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).1;
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], true, payment_preimage_3);
        fail_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], true, payment_hash_5);
@@ -3568,7 +3607,7 @@ fn test_simple_peer_disconnect() {
        reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (1, 0), (1, 0), (false, false));
        {
                let events = nodes[0].node.get_and_clear_pending_events();
-               assert_eq!(events.len(), 3);
+               assert_eq!(events.len(), 4);
                match events[0] {
                        Event::PaymentSent { payment_preimage, payment_hash, .. } => {
                                assert_eq!(payment_preimage, payment_preimage_3);
@@ -3577,14 +3616,20 @@ fn test_simple_peer_disconnect() {
                        _ => panic!("Unexpected event"),
                }
                match events[1] {
+                       Event::PaymentPathSuccessful { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               match events[2] {
                        Event::PaymentPathFailed { payment_hash, payment_failed_permanently, .. } => {
                                assert_eq!(payment_hash, payment_hash_5);
                                assert!(payment_failed_permanently);
                        },
                        _ => panic!("Unexpected event"),
                }
-               match events[2] {
-                       Event::PaymentPathSuccessful { .. } => {},
+               match events[3] {
+                       Event::PaymentFailed { payment_hash, .. } => {
+                               assert_eq!(payment_hash, payment_hash_5);
+                       },
                        _ => panic!("Unexpected event"),
                }
        }
@@ -3602,14 +3647,14 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken
 
        let mut as_channel_ready = None;
        let channel_id = if messages_delivered == 0 {
-               let (channel_ready, chan_id, _) = create_chan_between_nodes_with_value_a(&nodes[0], &nodes[1], 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let (channel_ready, chan_id, _) = create_chan_between_nodes_with_value_a(&nodes[0], &nodes[1], 100000, 10001);
                as_channel_ready = Some(channel_ready);
                // nodes[1] doesn't receive the channel_ready message (it'll be re-sent on reconnect)
                // Note that we store it so that if we're running with `simulate_broken_lnd` we can deliver
                // it before the channel_reestablish message.
                chan_id
        } else {
-               create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2
+               create_announced_chan_between_nodes(&nodes, 0, 1).2
        };
 
        let (route, payment_hash_1, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1_000_000);
@@ -3654,8 +3699,8 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken
                }
        }
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
        if messages_delivered < 3 {
                if simulate_broken_lnd {
                        // lnd has a long-standing bug where they send a channel_ready prior to a
@@ -3704,8 +3749,8 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken
                };
        }
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
        reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
        nodes[1].node.process_pending_htlc_forwards();
@@ -3787,8 +3832,8 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken
                }
        }
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
        if messages_delivered < 2 {
                reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (1, 0), (0, 0), (0, 0), (0, 0), (false, false));
                if messages_delivered < 1 {
@@ -3813,9 +3858,10 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken
        if messages_delivered == 1 || messages_delivered == 2 {
                expect_payment_path_successful!(nodes[0]);
        }
-
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       if messages_delivered <= 5 {
+               nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
+       }
        reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
        if messages_delivered > 2 {
@@ -3856,7 +3902,7 @@ fn test_channel_ready_without_best_block_updated() {
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
        *nodes[0].connect_style.borrow_mut() = ConnectStyle::BestBlockFirstSkippingBlocks;
 
-       let funding_tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let funding_tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 1_000_000, 0);
 
        let conf_height = nodes[0].best_block_info().1 + 1;
        connect_blocks(&nodes[0], CHAN_CONFIRM_DEPTH);
@@ -3878,7 +3924,7 @@ fn test_drop_messages_peer_disconnect_dual_htlc() {
        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);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (payment_preimage_1, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
 
@@ -3928,13 +3974,13 @@ fn test_drop_messages_peer_disconnect_dual_htlc() {
                _ => panic!("Unexpected event"),
        }
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
        assert_eq!(reestablish_1.len(), 1);
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
        assert_eq!(reestablish_2.len(), 1);
 
@@ -4028,7 +4074,7 @@ fn do_test_htlc_timeout(send_partial_mpp: bool) {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let our_payment_hash = if send_partial_mpp {
                let (route, our_payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], 100000);
@@ -4037,7 +4083,7 @@ fn do_test_htlc_timeout(send_partial_mpp: bool) {
                let cur_height = CHAN_CONFIRM_DEPTH + 1; // route_payment calls send_payment, which adds 1 to the current height. So we do the same here to match.
                let payment_id = PaymentId([42; 32]);
                let session_privs = nodes[0].node.test_add_new_pending_payment(our_payment_hash, Some(payment_secret), payment_id, &route).unwrap();
-               nodes[0].node.send_payment_along_path(&route.paths[0], &route.payment_params, &our_payment_hash, &Some(payment_secret), 200_000, cur_height, payment_id, &None, session_privs[0]).unwrap();
+               nodes[0].node.test_send_payment_along_path(&route.paths[0], &route.payment_params, &our_payment_hash, &Some(payment_secret), 200_000, cur_height, payment_id, &None, session_privs[0]).unwrap();
                check_added_monitors!(nodes[0], 1);
                let mut events = nodes[0].node.get_and_clear_pending_msg_events();
                assert_eq!(events.len(), 1);
@@ -4091,8 +4137,8 @@ fn do_test_holding_cell_htlc_add_timeouts(forwarded_htlc: bool) {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // Make sure all nodes are at the same starting height
        connect_blocks(&nodes[0], 2*CHAN_CONFIRM_DEPTH + 1 - nodes[0].best_block_info().1);
@@ -4185,7 +4231,7 @@ fn test_claim_sizeable_push_msat() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 98_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 98_000_000);
        nodes[1].node.force_close_broadcasting_latest_txn(&chan.2, &nodes[0].node.get_our_node_id()).unwrap();
        check_closed_broadcast!(nodes[1], true);
        check_added_monitors!(nodes[1], 1);
@@ -4214,7 +4260,7 @@ fn test_claim_on_remote_sizeable_push_msat() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 98_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 98_000_000);
        nodes[0].node.force_close_broadcasting_latest_txn(&chan.2, &nodes[1].node.get_our_node_id()).unwrap();
        check_closed_broadcast!(nodes[0], true);
        check_added_monitors!(nodes[0], 1);
@@ -4246,7 +4292,7 @@ fn test_claim_on_remote_revoked_sizeable_push_msat() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 59000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 59000000);
        let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
        let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan.2);
        assert_eq!(revoked_local_txn[0].input.len(), 1);
@@ -4277,7 +4323,7 @@ fn test_static_spendable_outputs_preimage_tx() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 3_000_000);
 
@@ -4324,7 +4370,7 @@ fn test_static_spendable_outputs_timeout_tx() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Rebalance the network a bit by relaying one payment through all the channels ...
        send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
@@ -4371,7 +4417,7 @@ fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
        let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan_1.2);
@@ -4407,7 +4453,7 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
        let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan_1.2);
@@ -4473,7 +4519,7 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
        let revoked_local_txn = get_local_commitment_txn!(nodes[1], chan_1.2);
@@ -4558,8 +4604,8 @@ fn test_onchain_to_onchain_claim() {
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // Ensure all nodes are at the same height
        let node_max_height = nodes.iter().map(|node| node.blocks.lock().unwrap().len()).max().unwrap() as u32;
@@ -4615,17 +4661,17 @@ fn test_onchain_to_onchain_claim() {
                _ => panic!("Unexpected event"),
        }
        check_added_monitors!(nodes[1], 1);
-       let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
+       let mut msg_events = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(msg_events.len(), 3);
-       match msg_events[0] {
-               MessageSendEvent::BroadcastChannelUpdate { .. } => {},
-               _ => panic!("Unexpected event"),
-       }
-       match msg_events[1] {
+       let nodes_2_event = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut msg_events);
+       let nodes_0_event = remove_first_msg_event_to_node(&nodes[0].node.get_our_node_id(), &mut msg_events);
+
+       match nodes_2_event {
                MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { .. }, node_id: _ } => {},
                _ => panic!("Unexpected event"),
        }
-       match msg_events[2] {
+
+       match nodes_0_event {
                MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, .. } } => {
                        assert!(update_add_htlcs.is_empty());
                        assert!(update_fail_htlcs.is_empty());
@@ -4635,6 +4681,13 @@ fn test_onchain_to_onchain_claim() {
                },
                _ => panic!("Unexpected event"),
        };
+
+       // Ensure that the last remaining message event is the BroadcastChannelUpdate msg for chan_2
+       match msg_events[0] {
+               MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+               _ => panic!("Unexpected event"),
+       }
+
        // Broadcast A's commitment tx on B's chain to see if we are able to claim inbound HTLC with our HTLC-Success tx
        let commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2);
        mine_transaction(&nodes[1], &commitment_tx[0]);
@@ -4667,9 +4720,9 @@ fn test_duplicate_payment_hash_one_failure_one_success() {
                &[Some(config.clone()), Some(config.clone()), Some(config.clone()), Some(config.clone())]);
        let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 2, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+       create_announced_chan_between_nodes(&nodes, 2, 3);
 
        let node_max_height = nodes.iter().map(|node| node.blocks.lock().unwrap().len()).max().unwrap() as u32;
        connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1);
@@ -4679,14 +4732,14 @@ fn test_duplicate_payment_hash_one_failure_one_success() {
 
        let (our_payment_preimage, duplicate_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 900_000);
 
-       let payment_secret = nodes[3].node.create_inbound_payment_for_hash(duplicate_payment_hash, None, 7200).unwrap();
+       let payment_secret = nodes[3].node.create_inbound_payment_for_hash(duplicate_payment_hash, None, 7200, None).unwrap();
        // We reduce the final CLTV here by a somewhat arbitrary constant to keep it under the one-byte
        // script push size limit so that the below script length checks match
        // ACCEPTED_HTLC_SCRIPT_WEIGHT.
-       let payment_params = PaymentParameters::from_node_id(nodes[3].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features());
-       let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[3], payment_params, 900000, TEST_FINAL_CLTV - 40);
-       send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2], &nodes[3]]], 900000, duplicate_payment_hash, payment_secret);
+       let payment_params = PaymentParameters::from_node_id(nodes[3].node.get_our_node_id(), TEST_FINAL_CLTV - 40)
+               .with_features(nodes[3].node.invoice_features());
+       let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[3], payment_params, 800_000, TEST_FINAL_CLTV - 40);
+       send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2], &nodes[3]]], 800_000, duplicate_payment_hash, payment_secret);
 
        let commitment_txn = get_local_commitment_txn!(nodes[2], chan_2.2);
        assert_eq!(commitment_txn[0].input.len(), 1);
@@ -4706,25 +4759,35 @@ fn test_duplicate_payment_hash_one_failure_one_success() {
 
                check_spends!(node_txn[0], commitment_txn[0]);
                assert_eq!(node_txn[0].input.len(), 1);
+               assert_eq!(node_txn[0].output.len(), 1);
 
                if node_txn.len() > 2 {
                        check_spends!(node_txn[1], commitment_txn[0]);
                        assert_eq!(node_txn[1].input.len(), 1);
+                       assert_eq!(node_txn[1].output.len(), 1);
                        assert_eq!(node_txn[0].input[0].previous_output, node_txn[1].input[0].previous_output);
 
                        check_spends!(node_txn[2], commitment_txn[0]);
+                       assert_eq!(node_txn[2].input.len(), 1);
+                       assert_eq!(node_txn[2].output.len(), 1);
                        assert_ne!(node_txn[0].input[0].previous_output, node_txn[2].input[0].previous_output);
                } else {
                        check_spends!(node_txn[1], commitment_txn[0]);
+                       assert_eq!(node_txn[1].input.len(), 1);
+                       assert_eq!(node_txn[1].output.len(), 1);
                        assert_ne!(node_txn[0].input[0].previous_output, node_txn[1].input[0].previous_output);
                }
 
                assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
                assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+               // Assign htlc_timeout_tx to the forwarded HTLC (with value ~800 sats). The received HTLC
+               // (with value 900 sats) will be claimed in the below `claim_funds` call.
                if node_txn.len() > 2 {
                        assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+                       htlc_timeout_tx = if node_txn[2].output[0].value < 900 { node_txn[2].clone() } else { node_txn[0].clone() };
+               } else {
+                       htlc_timeout_tx = if node_txn[0].output[0].value < 900 { node_txn[1].clone() } else { node_txn[0].clone() };
                }
-               htlc_timeout_tx = node_txn[0].clone();
        }
 
        nodes[2].node.claim_funds(our_payment_preimage);
@@ -4772,10 +4835,8 @@ fn test_duplicate_payment_hash_one_failure_one_success() {
        expect_payment_failed_with_update!(nodes[0], duplicate_payment_hash, false, chan_2.0.contents.short_channel_id, true);
 
        // Solve 2nd HTLC by broadcasting on B's chain HTLC-Success Tx from C
-       // Note that the fee paid is effectively double as the HTLC value (including the nodes[1] fee
-       // and nodes[2] fee) is rounded down and then claimed in full.
        mine_transaction(&nodes[1], &htlc_success_txn[1]);
-       expect_payment_forwarded!(nodes[1], nodes[0], nodes[2], Some(196*2), true, true);
+       expect_payment_forwarded!(nodes[1], nodes[0], nodes[2], Some(196), true, true);
        let updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
        assert!(updates.update_add_htlcs.is_empty());
        assert!(updates.update_fail_htlcs.is_empty());
@@ -4805,7 +4866,7 @@ fn test_dynamic_spendable_outputs_local_htlc_success_tx() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 9_000_000);
        let local_txn = get_local_commitment_txn!(nodes[1], chan_1.2);
@@ -4873,48 +4934,49 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno
                &[Some(config.clone()), Some(config.clone()), Some(config.clone()), Some(config.clone()), Some(config.clone()), Some(config.clone())]);
        let nodes = create_network(6, &node_cfgs, &node_chanmgrs);
 
-       let _chan_0_2 = create_announced_chan_between_nodes(&nodes, 0, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let _chan_1_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2_3 = create_announced_chan_between_nodes(&nodes, 2, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_3_4 = create_announced_chan_between_nodes(&nodes, 3, 4, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_3_5  = create_announced_chan_between_nodes(&nodes, 3, 5, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _chan_0_2 = create_announced_chan_between_nodes(&nodes, 0, 2);
+       let _chan_1_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+       let chan_2_3 = create_announced_chan_between_nodes(&nodes, 2, 3);
+       let chan_3_4 = create_announced_chan_between_nodes(&nodes, 3, 4);
+       let chan_3_5  = create_announced_chan_between_nodes(&nodes, 3, 5);
 
        // Rebalance and check output sanity...
        send_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 500000);
        send_payment(&nodes[1], &[&nodes[2], &nodes[3], &nodes[5]], 500000);
        assert_eq!(get_local_commitment_txn!(nodes[3], chan_2_3.2)[0].output.len(), 2);
 
-       let ds_dust_limit = nodes[3].node.channel_state.lock().unwrap().by_id.get(&chan_2_3.2).unwrap().holder_dust_limit_satoshis;
+       let ds_dust_limit = nodes[3].node.per_peer_state.read().unwrap().get(&nodes[2].node.get_our_node_id())
+               .unwrap().lock().unwrap().channel_by_id.get(&chan_2_3.2).unwrap().holder_dust_limit_satoshis;
        // 0th HTLC:
        let (_, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], ds_dust_limit*1000); // not added < dust limit + HTLC tx fee
        // 1st HTLC:
        let (_, payment_hash_2, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], ds_dust_limit*1000); // not added < dust limit + HTLC tx fee
        let (route, _, _, _) = get_route_and_payment_hash!(nodes[1], nodes[5], ds_dust_limit*1000);
        // 2nd HTLC:
-       send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_1, nodes[5].node.create_inbound_payment_for_hash(payment_hash_1, None, 7200).unwrap()); // not added < dust limit + HTLC tx fee
+       send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_1, nodes[5].node.create_inbound_payment_for_hash(payment_hash_1, None, 7200, None).unwrap()); // not added < dust limit + HTLC tx fee
        // 3rd HTLC:
-       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_2, nodes[5].node.create_inbound_payment_for_hash(payment_hash_2, None, 7200).unwrap()); // not added < dust limit + HTLC tx fee
+       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_2, nodes[5].node.create_inbound_payment_for_hash(payment_hash_2, None, 7200, None).unwrap()); // not added < dust limit + HTLC tx fee
        // 4th HTLC:
        let (_, payment_hash_3, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
        // 5th HTLC:
        let (_, payment_hash_4, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
        let (route, _, _, _) = get_route_and_payment_hash!(nodes[1], nodes[5], 1000000);
        // 6th HTLC:
-       send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_3, nodes[5].node.create_inbound_payment_for_hash(payment_hash_3, None, 7200).unwrap());
+       send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_3, nodes[5].node.create_inbound_payment_for_hash(payment_hash_3, None, 7200, None).unwrap());
        // 7th HTLC:
-       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_4, nodes[5].node.create_inbound_payment_for_hash(payment_hash_4, None, 7200).unwrap());
+       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_4, nodes[5].node.create_inbound_payment_for_hash(payment_hash_4, None, 7200, None).unwrap());
 
        // 8th HTLC:
        let (_, payment_hash_5, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
        // 9th HTLC:
        let (route, _, _, _) = get_route_and_payment_hash!(nodes[1], nodes[5], ds_dust_limit*1000);
-       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_5, nodes[5].node.create_inbound_payment_for_hash(payment_hash_5, None, 7200).unwrap()); // not added < dust limit + HTLC tx fee
+       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_5, nodes[5].node.create_inbound_payment_for_hash(payment_hash_5, None, 7200, None).unwrap()); // not added < dust limit + HTLC tx fee
 
        // 10th HTLC:
        let (_, payment_hash_6, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], ds_dust_limit*1000); // not added < dust limit + HTLC tx fee
        // 11th HTLC:
        let (route, _, _, _) = get_route_and_payment_hash!(nodes[1], nodes[5], 1000000);
-       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_6, nodes[5].node.create_inbound_payment_for_hash(payment_hash_6, None, 7200).unwrap());
+       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_6, nodes[5].node.create_inbound_payment_for_hash(payment_hash_6, None, 7200, None).unwrap());
 
        // Double-check that six of the new HTLC were added
        // We now have six HTLCs pending over the dust limit and six HTLCs under the dust limit (ie,
@@ -5080,20 +5142,21 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno
        }
 
        let as_events = nodes[0].node.get_and_clear_pending_events();
-       assert_eq!(as_events.len(), if announce_latest { 5 } else { 3 });
+       assert_eq!(as_events.len(), if announce_latest { 10 } else { 6 });
        let mut as_failds = HashSet::new();
        let mut as_updates = 0;
        for event in as_events.iter() {
-               if let &Event::PaymentPathFailed { ref payment_hash, ref payment_failed_permanently, ref network_update, .. } = event {
+               if let &Event::PaymentPathFailed { ref payment_hash, ref payment_failed_permanently, ref failure, .. } = event {
                        assert!(as_failds.insert(*payment_hash));
                        if *payment_hash != payment_hash_2 {
                                assert_eq!(*payment_failed_permanently, deliver_last_raa);
                        } else {
                                assert!(!payment_failed_permanently);
                        }
-                       if network_update.is_some() {
+                       if let PathFailure::OnPath { network_update: Some(_) } = failure {
                                as_updates += 1;
                        }
+               } else if let &Event::PaymentFailed { .. } = event {
                } else { panic!("Unexpected event"); }
        }
        assert!(as_failds.contains(&payment_hash_1));
@@ -5105,20 +5168,21 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno
        assert!(as_failds.contains(&payment_hash_6));
 
        let bs_events = nodes[1].node.get_and_clear_pending_events();
-       assert_eq!(bs_events.len(), if announce_latest { 4 } else { 3 });
+       assert_eq!(bs_events.len(), if announce_latest { 8 } else { 6 });
        let mut bs_failds = HashSet::new();
        let mut bs_updates = 0;
        for event in bs_events.iter() {
-               if let &Event::PaymentPathFailed { ref payment_hash, ref payment_failed_permanently, ref network_update, .. } = event {
+               if let &Event::PaymentPathFailed { ref payment_hash, ref payment_failed_permanently, ref failure, .. } = event {
                        assert!(bs_failds.insert(*payment_hash));
                        if *payment_hash != payment_hash_1 && *payment_hash != payment_hash_5 {
                                assert_eq!(*payment_failed_permanently, deliver_last_raa);
                        } else {
                                assert!(!payment_failed_permanently);
                        }
-                       if network_update.is_some() {
+                       if let PathFailure::OnPath { network_update: Some(_) } = failure {
                                bs_updates += 1;
                        }
+               } else if let &Event::PaymentFailed { .. } = event {
                } else { panic!("Unexpected event"); }
        }
        assert!(bs_failds.contains(&payment_hash_1));
@@ -5161,7 +5225,7 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (_, our_payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000);
        let local_txn = get_local_commitment_txn!(nodes[0], chan_1.2);
@@ -5214,9 +5278,10 @@ fn test_key_derivation_params() {
        let seed = [42; 32];
        let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
        let chain_monitor = test_utils::TestChainMonitor::new(Some(&chanmon_cfgs[0].chain_source), &chanmon_cfgs[0].tx_broadcaster, &chanmon_cfgs[0].logger, &chanmon_cfgs[0].fee_estimator, &chanmon_cfgs[0].persister, &keys_manager);
-       let network_graph = Arc::new(NetworkGraph::new(chanmon_cfgs[0].chain_source.genesis_hash, &chanmon_cfgs[0].logger));
-       let router = test_utils::TestRouter::new(network_graph.clone());
-       let node = NodeCfg { chain_source: &chanmon_cfgs[0].chain_source, logger: &chanmon_cfgs[0].logger, tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster, fee_estimator: &chanmon_cfgs[0].fee_estimator, router, chain_monitor, keys_manager: &keys_manager, network_graph, node_seed: seed, features: channelmanager::provided_init_features() };
+       let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &chanmon_cfgs[0].logger));
+       let scorer = Mutex::new(test_utils::TestScorer::new());
+       let router = test_utils::TestRouter::new(network_graph.clone(), &scorer);
+       let node = NodeCfg { chain_source: &chanmon_cfgs[0].chain_source, logger: &chanmon_cfgs[0].logger, tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster, fee_estimator: &chanmon_cfgs[0].fee_estimator, router, chain_monitor, keys_manager: &keys_manager, network_graph, node_seed: seed, override_init_features: alloc::rc::Rc::new(core::cell::RefCell::new(None)) };
        let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        node_cfgs.remove(0);
        node_cfgs.insert(0, node);
@@ -5227,8 +5292,8 @@ fn test_key_derivation_params() {
        // Create some initial channels
        // Create a dummy channel to advance index by one and thus test re-derivation correctness
        // for node 0
-       let chan_0 = create_announced_chan_between_nodes(&nodes, 0, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_0 = create_announced_chan_between_nodes(&nodes, 0, 2);
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
        assert_ne!(chan_0.3.output[0].script_pubkey, chan_1.3.output[0].script_pubkey);
 
        // Ensure all nodes are at the same height
@@ -5294,7 +5359,7 @@ fn test_static_output_closing_tx() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
        let closing_tx = close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true).2;
@@ -5321,7 +5386,7 @@ fn do_htlc_claim_local_commitment_only(use_dust: bool) {
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], if use_dust { 50000 } else { 3_000_000 });
 
@@ -5361,7 +5426,7 @@ fn do_htlc_claim_current_remote_commitment_only(use_dust: bool) {
        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);
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], if use_dust { 50000 } else { 3000000 });
        nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
@@ -5391,7 +5456,7 @@ fn do_htlc_claim_previous_remote_commitment_only(use_dust: bool, check_revoke_no
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Fail the payment, but don't deliver A's final RAA, resulting in the HTLC only being present
        // in B's previous (unrevoked) commitment transaction, but none of A's commitment transactions.
@@ -5483,7 +5548,7 @@ fn bolt2_open_channel_sending_node_checks_part1() { //This test needs to be on i
        let push_msat=10001;
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None).unwrap();
        let node0_to_1_send_open_channel = 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(), channelmanager::provided_init_features(), &node0_to_1_send_open_channel);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &node0_to_1_send_open_channel);
        get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
 
        // Create a second channel with the same random values. This used to panic due to a colliding
@@ -5550,7 +5615,7 @@ fn bolt2_open_channel_sane_dust_limit() {
        node0_to_1_send_open_channel.dust_limit_satoshis = 547;
        node0_to_1_send_open_channel.channel_reserve_satoshis = 100001;
 
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &node0_to_1_send_open_channel);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &node0_to_1_send_open_channel);
        let events = nodes[1].node.get_and_clear_pending_msg_events();
        let err_msg = match events[0] {
                MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id: _ } => {
@@ -5571,7 +5636,7 @@ fn test_fail_holding_cell_htlc_upon_free() {
        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);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
 
        // First nodes[0] generates an update_fee, setting the channel's
        // pending_update_fee.
@@ -5593,10 +5658,10 @@ fn test_fail_holding_cell_htlc_upon_free() {
 
        nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_msg.unwrap());
 
-       let mut chan_stat = get_channel_value_stat!(nodes[0], chan.2);
+       let mut chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
        let channel_reserve = chan_stat.channel_reserve_msat;
-       let feerate = get_feerate!(nodes[0], chan.2);
-       let opt_anchors = get_opt_anchors!(nodes[0], chan.2);
+       let feerate = get_feerate!(nodes[0], nodes[1], chan.2);
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan.2);
 
        // 2* and +1 HTLCs on the commit tx fee calculation for the fee spike reserve.
        let max_can_send = 5000000 - channel_reserve - 2*commit_tx_fee_msat(feerate, 1 + 1, opt_anchors);
@@ -5604,7 +5669,7 @@ fn test_fail_holding_cell_htlc_upon_free() {
 
        // Send a payment which passes reserve checks but gets stuck in the holding cell.
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
-       chan_stat = get_channel_value_stat!(nodes[0], chan.2);
+       chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
        assert_eq!(chan_stat.holding_cell_outbound_amount_msat, max_can_send);
 
        // Flush the pending fee update.
@@ -5617,7 +5682,7 @@ fn test_fail_holding_cell_htlc_upon_free() {
        // Upon receipt of the RAA, there will be an attempt to resend the holding cell
        // HTLC, but now that the fee has been raised the payment will now fail, causing
        // us to surface its failure to the user.
-       chan_stat = get_channel_value_stat!(nodes[0], chan.2);
+       chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
        assert_eq!(chan_stat.holding_cell_outbound_amount_msat, 0);
        nodes[0].logger.assert_log("lightning::ln::channel".to_string(), format!("Freeing holding cell with 1 HTLC updates in channel {}", hex::encode(chan.2)), 1);
        let failure_log = format!("Failed to send HTLC with payment_hash {} due to Cannot send value that would put our balance under counterparty-announced channel reserve value ({}) in channel {}",
@@ -5626,18 +5691,22 @@ fn test_fail_holding_cell_htlc_upon_free() {
 
        // Check that the payment failed to be sent out.
        let events = nodes[0].node.get_and_clear_pending_events();
-       assert_eq!(events.len(), 1);
+       assert_eq!(events.len(), 2);
        match &events[0] {
-               &Event::PaymentPathFailed { ref payment_id, ref payment_hash, ref payment_failed_permanently, ref network_update, ref all_paths_failed, ref short_channel_id, .. } => {
+               &Event::PaymentPathFailed { ref payment_id, ref payment_hash, ref payment_failed_permanently, failure: PathFailure::OnPath { network_update: None }, ref short_channel_id, .. } => {
                        assert_eq!(PaymentId(our_payment_hash.0), *payment_id.as_ref().unwrap());
                        assert_eq!(our_payment_hash.clone(), *payment_hash);
                        assert_eq!(*payment_failed_permanently, false);
-                       assert_eq!(*all_paths_failed, true);
-                       assert_eq!(*network_update, None);
                        assert_eq!(*short_channel_id, Some(route.paths[0][0].short_channel_id));
                },
                _ => panic!("Unexpected event"),
        }
+       match &events[1] {
+               &Event::PaymentFailed { ref payment_hash, .. } => {
+                       assert_eq!(our_payment_hash.clone(), *payment_hash);
+               },
+               _ => panic!("Unexpected event"),
+       }
 }
 
 // Test that if multiple HTLCs are released from the holding cell and one is
@@ -5649,7 +5718,7 @@ fn test_free_and_fail_holding_cell_htlcs() {
        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);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
 
        // First nodes[0] generates an update_fee, setting the channel's
        // pending_update_fee.
@@ -5671,10 +5740,10 @@ fn test_free_and_fail_holding_cell_htlcs() {
 
        nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_msg.unwrap());
 
-       let mut chan_stat = get_channel_value_stat!(nodes[0], chan.2);
+       let mut chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
        let channel_reserve = chan_stat.channel_reserve_msat;
-       let feerate = get_feerate!(nodes[0], chan.2);
-       let opt_anchors = get_opt_anchors!(nodes[0], chan.2);
+       let feerate = get_feerate!(nodes[0], nodes[1], chan.2);
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan.2);
 
        // 2* and +1 HTLCs on the commit tx fee calculation for the fee spike reserve.
        let amt_1 = 20000;
@@ -5684,11 +5753,11 @@ fn test_free_and_fail_holding_cell_htlcs() {
 
        // Send 2 payments which pass reserve checks but get stuck in the holding cell.
        nodes[0].node.send_payment(&route_1, payment_hash_1, &Some(payment_secret_1), PaymentId(payment_hash_1.0)).unwrap();
-       chan_stat = get_channel_value_stat!(nodes[0], chan.2);
+       chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
        assert_eq!(chan_stat.holding_cell_outbound_amount_msat, amt_1);
        let payment_id_2 = PaymentId(nodes[0].keys_manager.get_secure_random_bytes());
        nodes[0].node.send_payment(&route_2, payment_hash_2, &Some(payment_secret_2), payment_id_2).unwrap();
-       chan_stat = get_channel_value_stat!(nodes[0], chan.2);
+       chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
        assert_eq!(chan_stat.holding_cell_outbound_amount_msat, amt_1 + amt_2);
 
        // Flush the pending fee update.
@@ -5702,7 +5771,7 @@ fn test_free_and_fail_holding_cell_htlcs() {
        // Upon receipt of the RAA, there will be an attempt to resend the holding cell HTLCs,
        // but now that the fee has been raised the second payment will now fail, causing us
        // to surface its failure to the user. The first payment should succeed.
-       chan_stat = get_channel_value_stat!(nodes[0], chan.2);
+       chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
        assert_eq!(chan_stat.holding_cell_outbound_amount_msat, 0);
        nodes[0].logger.assert_log("lightning::ln::channel".to_string(), format!("Freeing holding cell with 2 HTLC updates in channel {}", hex::encode(chan.2)), 1);
        let failure_log = format!("Failed to send HTLC with payment_hash {} due to Cannot send value that would put our balance under counterparty-announced channel reserve value ({}) in channel {}",
@@ -5711,18 +5780,22 @@ fn test_free_and_fail_holding_cell_htlcs() {
 
        // Check that the second payment failed to be sent out.
        let events = nodes[0].node.get_and_clear_pending_events();
-       assert_eq!(events.len(), 1);
+       assert_eq!(events.len(), 2);
        match &events[0] {
-               &Event::PaymentPathFailed { ref payment_id, ref payment_hash, ref payment_failed_permanently, ref network_update, ref all_paths_failed, ref short_channel_id, .. } => {
+               &Event::PaymentPathFailed { ref payment_id, ref payment_hash, ref payment_failed_permanently, failure: PathFailure::OnPath { network_update: None }, ref short_channel_id, .. } => {
                        assert_eq!(payment_id_2, *payment_id.as_ref().unwrap());
                        assert_eq!(payment_hash_2.clone(), *payment_hash);
                        assert_eq!(*payment_failed_permanently, false);
-                       assert_eq!(*all_paths_failed, true);
-                       assert_eq!(*network_update, None);
                        assert_eq!(*short_channel_id, Some(route_2.paths[0][0].short_channel_id));
                },
                _ => panic!("Unexpected event"),
        }
+       match &events[1] {
+               &Event::PaymentFailed { ref payment_hash, .. } => {
+                       assert_eq!(payment_hash_2.clone(), *payment_hash);
+               },
+               _ => panic!("Unexpected event"),
+       }
 
        // Complete the first payment and the RAA from the fee update.
        let (payment_event, send_raa_event) = {
@@ -5775,8 +5848,8 @@ fn test_fail_holding_cell_htlc_upon_free_multihop() {
        config.channel_config.forwarding_fee_base_msat = 196;
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[Some(config.clone()), Some(config.clone()), Some(config.clone())]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan_0_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_1_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_0_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
+       let chan_1_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 95000000);
 
        // First nodes[1] generates an update_fee, setting the channel's
        // pending_update_fee.
@@ -5798,10 +5871,10 @@ fn test_fail_holding_cell_htlc_upon_free_multihop() {
 
        nodes[2].node.handle_update_fee(&nodes[1].node.get_our_node_id(), update_msg.unwrap());
 
-       let mut chan_stat = get_channel_value_stat!(nodes[0], chan_0_1.2);
+       let mut chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan_0_1.2);
        let channel_reserve = chan_stat.channel_reserve_msat;
-       let feerate = get_feerate!(nodes[0], chan_0_1.2);
-       let opt_anchors = get_opt_anchors!(nodes[0], chan_0_1.2);
+       let feerate = get_feerate!(nodes[0], nodes[1], chan_0_1.2);
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_0_1.2);
 
        // Send a payment which passes reserve checks but gets stuck in the holding cell.
        let feemsat = 239;
@@ -5822,7 +5895,7 @@ fn test_fail_holding_cell_htlc_upon_free_multihop() {
        commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
        expect_pending_htlcs_forwardable!(nodes[1]);
 
-       chan_stat = get_channel_value_stat!(nodes[1], chan_1_2.2);
+       chan_stat = get_channel_value_stat!(nodes[1], nodes[2], chan_1_2.2);
        assert_eq!(chan_stat.holding_cell_outbound_amount_msat, max_can_send);
 
        // Flush the pending fee update.
@@ -5906,7 +5979,7 @@ fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() {
        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);
-       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
 
        let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100000);
        route.paths[0][0].fee_msat = 100;
@@ -5924,7 +5997,7 @@ fn test_update_add_htlc_bolt2_sender_zero_value_msat() {
        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);
-       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
 
        let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100000);
        route.paths[0][0].fee_msat = 0;
@@ -5942,7 +6015,7 @@ fn test_update_add_htlc_bolt2_receiver_zero_value_msat() {
        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);
-       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
 
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100000);
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
@@ -5965,10 +6038,10 @@ fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() {
        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);
-       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0);
 
-       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features());
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), 0)
+               .with_features(nodes[1].node.invoice_features());
        let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], payment_params, 100000000, 0);
        route.paths[0].last_mut().unwrap().cltv_expiry_delta = 500000001;
        unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)), true, APIError::InvalidRoute { ref err },
@@ -5984,8 +6057,9 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment()
        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);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let max_accepted_htlcs = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().counterparty_max_accepted_htlcs as u64;
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0);
+       let max_accepted_htlcs = nodes[1].node.per_peer_state.read().unwrap().get(&nodes[0].node.get_our_node_id())
+               .unwrap().lock().unwrap().channel_by_id.get(&chan.2).unwrap().counterparty_max_accepted_htlcs as u64;
 
        for i in 0..max_accepted_htlcs {
                let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100000);
@@ -6025,8 +6099,8 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_value_in_flight() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
        let channel_value = 100000;
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let max_in_flight = get_channel_value_stat!(nodes[0], chan.2).counterparty_max_htlc_value_in_flight_msat;
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value, 0);
+       let max_in_flight = get_channel_value_stat!(nodes[0], nodes[1], chan.2).counterparty_max_htlc_value_in_flight_msat;
 
        send_payment(&nodes[0], &vec!(&nodes[1])[..], max_in_flight);
 
@@ -6051,11 +6125,12 @@ fn test_update_add_htlc_bolt2_receiver_check_amount_received_more_than_min() {
        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);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
        let htlc_minimum_msat: u64;
        {
-               let chan_lock = nodes[0].node.channel_state.lock().unwrap();
-               let channel = chan_lock.by_id.get(&chan.2).unwrap();
+               let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+               let chan_lock = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
+               let channel = chan_lock.channel_by_id.get(&chan.2).unwrap();
                htlc_minimum_msat = channel.get_holder_htlc_minimum_msat();
        }
 
@@ -6079,12 +6154,12 @@ fn test_update_add_htlc_bolt2_receiver_sender_can_afford_amount_sent() {
        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);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
 
-       let chan_stat = get_channel_value_stat!(nodes[0], chan.2);
+       let chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
        let channel_reserve = chan_stat.channel_reserve_msat;
-       let feerate = get_feerate!(nodes[0], chan.2);
-       let opt_anchors = get_opt_anchors!(nodes[0], chan.2);
+       let feerate = get_feerate!(nodes[0], nodes[1], chan.2);
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan.2);
        // The 2* and +1 are for the fee spike reserve.
        let commit_tx_fee_outbound = 2 * commit_tx_fee_msat(feerate, 1 + 1, opt_anchors);
 
@@ -6115,7 +6190,7 @@ fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() {
        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);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
 
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 3999999);
        let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
@@ -6154,13 +6229,13 @@ fn test_update_add_htlc_bolt2_receiver_check_max_in_flight_msat() {
        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);
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
 
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
        check_added_monitors!(nodes[0], 1);
        let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
-       updates.update_add_htlcs[0].amount_msat = get_channel_value_stat!(nodes[1], chan.2).counterparty_max_htlc_value_in_flight_msat + 1;
+       updates.update_add_htlcs[0].amount_msat = get_channel_value_stat!(nodes[1], nodes[0], chan.2).counterparty_max_htlc_value_in_flight_msat + 1;
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
 
        assert!(nodes[1].node.list_channels().is_empty());
@@ -6178,7 +6253,7 @@ fn test_update_add_htlc_bolt2_receiver_check_cltv_expiry() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
        check_added_monitors!(nodes[0], 1);
@@ -6203,7 +6278,7 @@ fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
        check_added_monitors!(nodes[0], 1);
@@ -6211,12 +6286,12 @@ fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() {
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
 
        //Disconnect and Reconnect
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
        assert_eq!(reestablish_1.len(), 1);
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
        assert_eq!(reestablish_2.len(), 1);
        nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]);
@@ -6248,7 +6323,7 @@ fn test_update_fulfill_htlc_bolt2_update_fulfill_htlc_before_commitment() {
        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);
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
        let (route, our_payment_hash, our_payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
 
@@ -6279,7 +6354,7 @@ fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() {
        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);
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
@@ -6310,7 +6385,7 @@ fn test_update_fulfill_htlc_bolt2_update_fail_malformed_htlc_before_commitment()
        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);
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
@@ -6341,7 +6416,7 @@ fn test_update_fulfill_htlc_bolt2_incorrect_htlc_id() {
        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);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (our_payment_preimage, our_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 100_000);
 
@@ -6384,7 +6459,7 @@ fn test_update_fulfill_htlc_bolt2_wrong_preimage() {
        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);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (our_payment_preimage, our_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 100_000);
 
@@ -6427,7 +6502,7 @@ fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_messag
        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);
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
 
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
@@ -6474,8 +6549,8 @@ fn test_update_fulfill_htlc_bolt2_after_malformed_htlc_message_must_forward_upda
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1000000, 1000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
+       let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1000000, 1000000);
 
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 100000);
 
@@ -6548,8 +6623,8 @@ fn test_channel_failed_after_message_with_badonion_node_perm_bits_set() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 100_000);
 
@@ -6603,13 +6678,12 @@ fn test_channel_failed_after_message_with_badonion_node_perm_bits_set() {
        }
 
        let events_5 = nodes[0].node.get_and_clear_pending_events();
-       assert_eq!(events_5.len(), 1);
+       assert_eq!(events_5.len(), 2);
 
        // Expect a PaymentPathFailed event with a ChannelFailure network update for the channel between
        // the node originating the error to its next hop.
        match events_5[0] {
-               Event::PaymentPathFailed { network_update:
-                       Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent }), error_code, ..
+               Event::PaymentPathFailed { error_code, failure: PathFailure::OnPath { network_update: Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent }) }, ..
                } => {
                        assert_eq!(short_channel_id, chan_2.0.contents.short_channel_id);
                        assert!(is_permanent);
@@ -6617,6 +6691,12 @@ fn test_channel_failed_after_message_with_badonion_node_perm_bits_set() {
                },
                _ => panic!("Unexpected event"),
        }
+       match events_5[1] {
+               Event::PaymentFailed { payment_hash, .. } => {
+                       assert_eq!(payment_hash, our_payment_hash);
+               },
+               _ => panic!("Unexpected event"),
+       }
 
        // TODO: Test actual removal of channel from NetworkGraph when it's implemented.
 }
@@ -6631,9 +6711,10 @@ fn do_test_failure_delay_dust_htlc_local_commitment(announce_latest: bool) {
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-       let chan =create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan =create_announced_chan_between_nodes(&nodes, 0, 1);
 
-       let bs_dust_limit = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().holder_dust_limit_satoshis;
+       let bs_dust_limit = nodes[1].node.per_peer_state.read().unwrap().get(&nodes[0].node.get_our_node_id())
+               .unwrap().lock().unwrap().channel_by_id.get(&chan.2).unwrap().holder_dust_limit_satoshis;
 
        // We route 2 dust-HTLCs between A and B
        let (_, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1]], bs_dust_limit*1000);
@@ -6687,7 +6768,7 @@ fn do_test_failure_delay_dust_htlc_local_commitment(announce_latest: bool) {
        connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
        let events = nodes[0].node.get_and_clear_pending_events();
        // Only 2 PaymentPathFailed events should show up, over-dust HTLC has to be failed by timeout tx
-       assert_eq!(events.len(), 2);
+       assert_eq!(events.len(), 4);
        let mut first_failed = false;
        for event in events {
                match event {
@@ -6698,7 +6779,8 @@ fn do_test_failure_delay_dust_htlc_local_commitment(announce_latest: bool) {
                                } else {
                                        assert_eq!(payment_hash, payment_hash_2);
                                }
-                       }
+                       },
+                       Event::PaymentFailed { .. } => {}
                        _ => panic!("Unexpected event"),
                }
        }
@@ -6722,9 +6804,10 @@ fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
-       let bs_dust_limit = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().holder_dust_limit_satoshis;
+       let bs_dust_limit = nodes[1].node.per_peer_state.read().unwrap().get(&nodes[0].node.get_our_node_id())
+               .unwrap().lock().unwrap().channel_by_id.get(&chan.2).unwrap().holder_dust_limit_satoshis;
 
        let (_payment_preimage_1, dust_hash, _payment_secret_1) = route_payment(&nodes[0], &[&nodes[1]], bs_dust_limit*1000);
        let (_payment_preimage_2, non_dust_hash, _payment_secret_2) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
@@ -6809,7 +6892,7 @@ fn test_user_configurable_csv_delay() {
 
        // We test config.our_to_self > BREAKDOWN_TIMEOUT is enforced in Channel::new_outbound()
        if let Err(error) = Channel::new_outbound(&LowerBoundedFeeEstimator::new(&test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }),
-               &nodes[0].keys_manager, nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), 1000000, 1000000, 0,
+               &nodes[0].keys_manager, &nodes[0].keys_manager, nodes[1].node.get_our_node_id(), &nodes[1].node.init_features(), 1000000, 1000000, 0,
                &low_our_to_self_config, 0, 42)
        {
                match error {
@@ -6823,7 +6906,7 @@ fn test_user_configurable_csv_delay() {
        let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
        open_channel.to_self_delay = 200;
        if let Err(error) = Channel::new_from_req(&LowerBoundedFeeEstimator::new(&test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }),
-               &nodes[0].keys_manager, nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &open_channel, 0,
+               &nodes[0].keys_manager, &nodes[0].keys_manager, nodes[1].node.get_our_node_id(), &nodes[0].node.channel_type_features(), &nodes[1].node.init_features(), &open_channel, 0,
                &low_our_to_self_config, 0, &nodes[0].logger, 42)
        {
                match error {
@@ -6834,10 +6917,10 @@ fn test_user_configurable_csv_delay() {
 
        // We test msg.to_self_delay <= config.their_to_self_delay is enforced in Chanel::accept_channel()
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1000000, 1000000, 42, None).unwrap();
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &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(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
        let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
        accept_channel.to_self_delay = 200;
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
        let reason_msg;
        if let MessageSendEvent::HandleError { ref action, .. } = nodes[0].node.get_and_clear_pending_msg_events()[0] {
                match action {
@@ -6855,7 +6938,7 @@ fn test_user_configurable_csv_delay() {
        let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
        open_channel.to_self_delay = 200;
        if let Err(error) = Channel::new_from_req(&LowerBoundedFeeEstimator::new(&test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }),
-               &nodes[0].keys_manager, nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &open_channel, 0,
+               &nodes[0].keys_manager, &nodes[0].keys_manager, nodes[1].node.get_our_node_id(), &nodes[0].node.channel_type_features(), &nodes[1].node.init_features(), &open_channel, 0,
                &high_their_to_self_config, 0, &nodes[0].logger, 42)
        {
                match error {
@@ -6877,14 +6960,14 @@ fn test_check_htlc_underpaying() {
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
-       let scorer = test_utils::TestScorer::with_penalty(0);
+       let scorer = test_utils::TestScorer::new();
        let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
-       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id()).with_features(channelmanager::provided_invoice_features());
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV).with_features(nodes[1].node.invoice_features());
        let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(), None, 10_000, TEST_FINAL_CLTV, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
        let (_, our_payment_hash, _) = get_payment_preimage_hash!(nodes[0]);
-       let our_payment_secret = nodes[1].node.create_inbound_payment_for_hash(our_payment_hash, Some(100_000), 7200).unwrap();
+       let our_payment_secret = nodes[1].node.create_inbound_payment_for_hash(our_payment_hash, Some(100_000), 7200, None).unwrap();
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
        check_added_monitors!(nodes[0], 1);
 
@@ -6937,13 +7020,13 @@ fn test_announce_disable_channels() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 1, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       create_announced_chan_between_nodes(&nodes, 1, 0);
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Disconnect peers
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        nodes[0].node.timer_tick_occurred(); // Enabled -> DisabledStaged
        nodes[0].node.timer_tick_occurred(); // DisabledStaged -> Disabled
@@ -6963,10 +7046,10 @@ fn test_announce_disable_channels() {
                }
        }
        // Reconnect peers
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
        assert_eq!(reestablish_1.len(), 3);
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
        assert_eq!(reestablish_2.len(), 3);
 
@@ -7019,11 +7102,11 @@ fn test_bump_penalty_txn_on_revoked_commitment() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000);
 
        let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
-       let payment_params = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features());
+       let payment_params = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id(), 30)
+               .with_features(nodes[0].node.invoice_features());
        let (route,_, _, _) = get_route_and_payment_hash!(nodes[1], nodes[0], payment_params, 3000000, 30);
        send_along_route(&nodes[1], route, &vec!(&nodes[0])[..], 3000000);
 
@@ -7126,15 +7209,15 @@ fn test_bump_penalty_txn_on_revoked_htlcs() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000);
        // Lock HTLC in both directions (using a slightly lower CLTV delay to provide timely RBF bumps)
-       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id()).with_features(channelmanager::provided_invoice_features());
-       let scorer = test_utils::TestScorer::with_penalty(0);
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), 50).with_features(nodes[1].node.invoice_features());
+       let scorer = test_utils::TestScorer::new();
        let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
        let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(), None,
                3_000_000, 50, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
        let payment_preimage = send_along_route(&nodes[0], route, &[&nodes[1]], 3_000_000).0;
-       let payment_params = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id()).with_features(channelmanager::provided_invoice_features());
+       let payment_params = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id(), 50).with_features(nodes[0].node.invoice_features());
        let route = get_route(&nodes[1].node.get_our_node_id(), &payment_params, &nodes[1].network_graph.read_only(), None,
                3_000_000, 50, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
        send_along_route(&nodes[1], route, &[&nodes[0]], 3_000_000);
@@ -7204,8 +7287,8 @@ fn test_bump_penalty_txn_on_revoked_htlcs() {
                assert_ne!(node_txn[0].input[0].previous_output, node_txn[2].input[0].previous_output);
                assert_ne!(node_txn[1].input[0].previous_output, node_txn[2].input[0].previous_output);
 
-               assert_eq!(node_txn[0].input[0].previous_output, revoked_htlc_txn[0].input[0].previous_output);
-               assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[1].input[0].previous_output);
+               assert_eq!(node_txn[0].input[0].previous_output, revoked_htlc_txn[1].input[0].previous_output);
+               assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[0].input[0].previous_output);
 
                // node_txn[3] spends the revoked outputs from the revoked_htlc_txn (which only have one
                // output, checked above).
@@ -7279,7 +7362,7 @@ fn test_bump_penalty_txn_on_remote_commitment() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000);
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 3_000_000);
        route_payment(&nodes[1], &vec!(&nodes[0])[..], 3000000).0;
 
@@ -7382,13 +7465,14 @@ fn test_counterparty_raa_skip_no_crash() {
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let per_commitment_secret;
        let next_per_commitment_point;
        {
-               let mut guard = nodes[0].node.channel_state.lock().unwrap();
-               let keys = guard.by_id.get_mut(&channel_id).unwrap().get_signer();
+               let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+               let mut guard = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
+               let keys = guard.channel_by_id.get_mut(&channel_id).unwrap().get_signer();
 
                const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
 
@@ -7422,7 +7506,7 @@ fn test_bump_txn_sanitize_tracking_maps() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000);
        // Lock HTLC in both directions
        let (payment_preimage_1, _, _) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9_000_000);
        let (_, payment_hash_2, _) = route_payment(&nodes[1], &vec!(&nodes[0])[..], 9_000_000);
@@ -7471,7 +7555,7 @@ fn test_pending_claimed_htlc_no_balance_underflow() {
        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);
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0);
 
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 1_010_000);
        nodes[1].node.claim_funds(payment_preimage);
@@ -7510,7 +7594,7 @@ fn test_channel_conf_timeout() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let _funding_tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 1_000_000, 100_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _funding_tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 1_000_000, 100_000);
 
        // The outbound node should wait forever for confirmation:
        // This matches `channel::FUNDING_CONF_DEADLINE_BLOCKS` and BOLT 2's suggested timeout, thus is
@@ -7569,7 +7653,7 @@ fn test_override_0msat_htlc_minimum() {
        let res = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
        assert_eq!(res.htlc_minimum_msat, 1);
 
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &res);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &res);
        let res = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
        assert_eq!(res.htlc_minimum_msat, 1);
 }
@@ -7606,8 +7690,8 @@ fn test_channel_update_has_correct_htlc_maximum_msat() {
        let channel_value_50_percent_msat = (channel_value_msat as f64 * 0.5) as u64;
        let channel_value_90_percent_msat = (channel_value_msat as f64 * 0.9) as u64;
 
-       let (node_0_chan_update, node_1_chan_update, _, _)  = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value_satoshis, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let (node_2_chan_update, node_3_chan_update, _, _)  = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, channel_value_satoshis, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let (node_0_chan_update, node_1_chan_update, _, _)  = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value_satoshis, 10001);
+       let (node_2_chan_update, node_3_chan_update, _, _)  = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, channel_value_satoshis, 10001);
 
        // Assert that `node[0]`'s `ChannelUpdate` is capped at 50 percent of the `channel_value`, as
        // that's the value of `node[1]`'s `holder_max_htlc_value_in_flight_msat`.
@@ -7638,7 +7722,7 @@ fn test_manually_accept_inbound_channel_request() {
        let temp_channel_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, Some(manually_accept_conf)).unwrap();
        let res = 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(), channelmanager::provided_init_features(), &res);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &res);
 
        // Assert that `nodes[1]` has no `MessageSendEvent::SendAcceptChannel` in `msg_events` before
        // accepting the inbound channel request.
@@ -7688,7 +7772,7 @@ fn test_manually_reject_inbound_channel_request() {
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, Some(manually_accept_conf)).unwrap();
        let res = 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(), channelmanager::provided_init_features(), &res);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &res);
 
        // Assert that `nodes[1]` has no `MessageSendEvent::SendAcceptChannel` in `msg_events` before
        // rejecting the inbound channel request.
@@ -7732,7 +7816,7 @@ fn test_reject_funding_before_inbound_channel_accepted() {
        let res = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
        let temp_channel_id = res.temporary_channel_id;
 
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &res);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &res);
 
        // Assert that `nodes[1]` has no `MessageSendEvent::SendAcceptChannel` in the `msg_events`.
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
@@ -7746,11 +7830,12 @@ fn test_reject_funding_before_inbound_channel_accepted() {
        // `handle_accept_channel`, which is required in order for `create_funding_transaction` to
        // succeed when `nodes[0]` is passed to it.
        let accept_chan_msg = {
-               let mut lock;
-               let channel = get_channel_ref!(&nodes[1], lock, temp_channel_id);
+               let mut node_1_per_peer_lock;
+               let mut node_1_peer_state_lock;
+               let channel =  get_channel_ref!(&nodes[1], nodes[0], node_1_per_peer_lock, node_1_peer_state_lock, temp_channel_id);
                channel.get_accept_channel_message()
        };
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_chan_msg);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_chan_msg);
 
        let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42);
 
@@ -7788,7 +7873,7 @@ fn test_can_not_accept_inbound_channel_twice() {
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, Some(manually_accept_conf)).unwrap();
        let res = 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(), channelmanager::provided_init_features(), &res);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &res);
 
        // Assert that `nodes[1]` has no `MessageSendEvent::SendAcceptChannel` in `msg_events` before
        // accepting the inbound channel request.
@@ -7833,7 +7918,7 @@ fn test_can_not_accept_unknown_inbound_channel() {
        let api_res = nodes[0].node.accept_inbound_channel(&unknown_channel_id, &nodes[1].node.get_our_node_id(), 0);
        match api_res {
                Err(APIError::ChannelUnavailable { err }) => {
-                       assert_eq!(err, "Can't accept a channel that doesn't exist");
+                       assert_eq!(err, format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(unknown_channel_id), nodes[1].node.get_our_node_id()));
                },
                Ok(_) => panic!("It shouldn't be possible to accept an unkown channel"),
                Err(_) => panic!("Unexpected Error"),
@@ -7848,10 +7933,10 @@ fn test_simple_mpp() {
        let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
        let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-       let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-       let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-       let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-       let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
+       let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+       let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2).0.contents.short_channel_id;
+       let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3).0.contents.short_channel_id;
+       let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3).0.contents.short_channel_id;
 
        let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[3], 100000);
        let path = route.paths[0].clone();
@@ -7874,10 +7959,10 @@ fn test_preimage_storage() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
+       create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
 
        {
-               let (payment_hash, payment_secret) = nodes[1].node.create_inbound_payment(Some(100_000), 7200).unwrap();
+               let (payment_hash, payment_secret) = nodes[1].node.create_inbound_payment(Some(100_000), 7200, None).unwrap();
                let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000);
                nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
                check_added_monitors!(nodes[0], 1);
@@ -7914,7 +7999,7 @@ fn test_secret_timeout() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
+       create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
 
        let (payment_hash, payment_secret_1) = nodes[1].node.create_inbound_payment_legacy(Some(100_000), 2).unwrap();
 
@@ -7979,11 +8064,11 @@ fn test_bad_secret_hash() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
+       create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
 
        let random_payment_hash = PaymentHash([42; 32]);
        let random_payment_secret = PaymentSecret([43; 32]);
-       let (our_payment_hash, our_payment_secret) = nodes[1].node.create_inbound_payment(Some(100_000), 2).unwrap();
+       let (our_payment_hash, our_payment_secret) = nodes[1].node.create_inbound_payment(Some(100_000), 2, None).unwrap();
        let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000);
 
        // All the below cases should end up being handled exactly identically, so we macro the
@@ -8051,7 +8136,7 @@ fn test_update_err_monitor_lockdown() {
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channel
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
        let outpoint = OutPoint { txid: chan_1.3.txid(), index: 0 };
 
        // Rebalance the network to generate htlc in the two directions
@@ -8065,12 +8150,13 @@ fn test_update_err_monitor_lockdown() {
        let logger = test_utils::TestLogger::with_id(format!("node {}", 0));
        let persister = test_utils::TestPersister::new();
        let watchtower = {
-               let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(outpoint).unwrap();
-               let mut w = test_utils::TestVecWriter(Vec::new());
-               monitor.write(&mut w).unwrap();
-               let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
-                               &mut io::Cursor::new(&w.0), nodes[0].keys_manager).unwrap().1;
-               assert!(new_monitor == *monitor);
+               let new_monitor = {
+                       let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(outpoint).unwrap();
+                       let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
+                                       &mut io::Cursor::new(&monitor.encode()), (nodes[0].keys_manager, nodes[0].keys_manager)).unwrap().1;
+                       assert!(new_monitor == *monitor);
+                       new_monitor
+               };
                let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
                assert_eq!(watchtower.watch_channel(outpoint, new_monitor), ChannelMonitorUpdateStatus::Completed);
                watchtower
@@ -8090,12 +8176,15 @@ fn test_update_err_monitor_lockdown() {
        let updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
        assert_eq!(updates.update_fulfill_htlcs.len(), 1);
        nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]);
-       if let Some(ref mut channel) = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2) {
-               if let Ok((_, _, update)) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].logger) {
-                       assert_eq!(watchtower.chain_monitor.update_channel(outpoint, update.clone()), ChannelMonitorUpdateStatus::PermanentFailure);
-                       assert_eq!(nodes[0].chain_monitor.update_channel(outpoint, update), ChannelMonitorUpdateStatus::Completed);
+       {
+               let mut node_0_per_peer_lock;
+               let mut node_0_peer_state_lock;
+               let mut channel = get_channel_ref!(nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, chan_1.2);
+               if let Ok(update) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].logger) {
+                       assert_eq!(watchtower.chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::PermanentFailure);
+                       assert_eq!(nodes[0].chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::Completed);
                } else { assert!(false); }
-       } else { assert!(false); };
+       }
        // Our local monitor is in-sync and hasn't processed yet timeout
        check_added_monitors!(nodes[0], 1);
        let events = nodes[0].node.get_and_clear_pending_events();
@@ -8115,7 +8204,7 @@ fn test_concurrent_monitor_claim() {
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channel
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
        let outpoint = OutPoint { txid: chan_1.3.txid(), index: 0 };
 
        // Rebalance the network to generate htlc in the two directions
@@ -8129,12 +8218,13 @@ fn test_concurrent_monitor_claim() {
        let logger = test_utils::TestLogger::with_id(format!("node {}", "Alice"));
        let persister = test_utils::TestPersister::new();
        let watchtower_alice = {
-               let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(outpoint).unwrap();
-               let mut w = test_utils::TestVecWriter(Vec::new());
-               monitor.write(&mut w).unwrap();
-               let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
-                               &mut io::Cursor::new(&w.0), nodes[0].keys_manager).unwrap().1;
-               assert!(new_monitor == *monitor);
+               let new_monitor = {
+                       let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(outpoint).unwrap();
+                       let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
+                                       &mut io::Cursor::new(&monitor.encode()), (nodes[0].keys_manager, nodes[0].keys_manager)).unwrap().1;
+                       assert!(new_monitor == *monitor);
+                       new_monitor
+               };
                let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
                assert_eq!(watchtower.watch_channel(outpoint, new_monitor), ChannelMonitorUpdateStatus::Completed);
                watchtower
@@ -8158,12 +8248,13 @@ fn test_concurrent_monitor_claim() {
        let logger = test_utils::TestLogger::with_id(format!("node {}", "Bob"));
        let persister = test_utils::TestPersister::new();
        let watchtower_bob = {
-               let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(outpoint).unwrap();
-               let mut w = test_utils::TestVecWriter(Vec::new());
-               monitor.write(&mut w).unwrap();
-               let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
-                               &mut io::Cursor::new(&w.0), nodes[0].keys_manager).unwrap().1;
-               assert!(new_monitor == *monitor);
+               let new_monitor = {
+                       let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(outpoint).unwrap();
+                       let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
+                                       &mut io::Cursor::new(&monitor.encode()), (nodes[0].keys_manager, nodes[0].keys_manager)).unwrap().1;
+                       assert!(new_monitor == *monitor);
+                       new_monitor
+               };
                let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
                assert_eq!(watchtower.watch_channel(outpoint, new_monitor), ChannelMonitorUpdateStatus::Completed);
                watchtower
@@ -8181,14 +8272,17 @@ fn test_concurrent_monitor_claim() {
        let updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
        assert_eq!(updates.update_add_htlcs.len(), 1);
        nodes[0].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &updates.update_add_htlcs[0]);
-       if let Some(ref mut channel) = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2) {
-               if let Ok((_, _, update)) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].logger) {
+       {
+               let mut node_0_per_peer_lock;
+               let mut node_0_peer_state_lock;
+               let mut channel = get_channel_ref!(nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, chan_1.2);
+               if let Ok(update) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].logger) {
                        // Watchtower Alice should already have seen the block and reject the update
-                       assert_eq!(watchtower_alice.chain_monitor.update_channel(outpoint, update.clone()), ChannelMonitorUpdateStatus::PermanentFailure);
-                       assert_eq!(watchtower_bob.chain_monitor.update_channel(outpoint, update.clone()), ChannelMonitorUpdateStatus::Completed);
-                       assert_eq!(nodes[0].chain_monitor.update_channel(outpoint, update), ChannelMonitorUpdateStatus::Completed);
+                       assert_eq!(watchtower_alice.chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::PermanentFailure);
+                       assert_eq!(watchtower_bob.chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::Completed);
+                       assert_eq!(nodes[0].chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::Completed);
                } else { assert!(false); }
-       } else { assert!(false); };
+       }
        // Our local monitor is in-sync and hasn't processed yet timeout
        check_added_monitors!(nodes[0], 1);
 
@@ -8236,9 +8330,9 @@ fn test_pre_lockin_no_chan_closed_update() {
        // Create an initial channel
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
        let mut open_chan_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(), channelmanager::provided_init_features(), &open_chan_msg);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_chan_msg);
        let accept_chan_msg = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_chan_msg);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_chan_msg);
 
        // Move the first channel through the funding flow...
        let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42);
@@ -8268,7 +8362,7 @@ fn test_htlc_no_detection() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
 
        send_payment(&nodes[0], &vec!(&nodes[1])[..], 1_000_000);
        let (_, our_payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 2_000_000);
@@ -8323,8 +8417,8 @@ fn do_test_onchain_htlc_settlement_after_close(broadcast_alice: bool, go_onchain
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_ab = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_ab = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
+       create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 10001);
 
        // Steps (1) and (2):
        // Send an HTLC Alice --> Bob --> Carol, but Carol doesn't settle the HTLC back.
@@ -8488,6 +8582,56 @@ fn test_onchain_htlc_settlement_after_close() {
        do_test_onchain_htlc_settlement_after_close(false, false);
 }
 
+#[test]
+fn test_duplicate_temporary_channel_id_from_different_peers() {
+       // Tests that we can accept two different `OpenChannel` requests with the same
+       // `temporary_channel_id`, as long as they are from different peers.
+       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, &[None, None, None]);
+       let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+       // Create an first channel channel
+       nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
+       let mut open_chan_msg_chan_1_0 = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
+
+       // Create an second channel
+       nodes[2].node.create_channel(nodes[0].node.get_our_node_id(), 100000, 10001, 43, None).unwrap();
+       let mut open_chan_msg_chan_2_0 = get_event_msg!(nodes[2], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
+
+       // Modify the `OpenChannel` from `nodes[2]` to `nodes[0]` to ensure that it uses the same
+       // `temporary_channel_id` as the `OpenChannel` from nodes[1] to nodes[0].
+       open_chan_msg_chan_2_0.temporary_channel_id = open_chan_msg_chan_1_0.temporary_channel_id;
+
+       // Assert that `nodes[0]` can accept both `OpenChannel` requests, even though they use the same
+       // `temporary_channel_id` as they are from different peers.
+       nodes[0].node.handle_open_channel(&nodes[1].node.get_our_node_id(), &open_chan_msg_chan_1_0);
+       {
+               let events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match &events[0] {
+                       MessageSendEvent::SendAcceptChannel { node_id, msg } => {
+                               assert_eq!(node_id, &nodes[1].node.get_our_node_id());
+                               assert_eq!(msg.temporary_channel_id, open_chan_msg_chan_1_0.temporary_channel_id);
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       }
+
+       nodes[0].node.handle_open_channel(&nodes[2].node.get_our_node_id(), &open_chan_msg_chan_2_0);
+       {
+               let events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match &events[0] {
+                       MessageSendEvent::SendAcceptChannel { node_id, msg } => {
+                               assert_eq!(node_id, &nodes[2].node.get_our_node_id());
+                               assert_eq!(msg.temporary_channel_id, open_chan_msg_chan_1_0.temporary_channel_id);
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       }
+}
+
 #[test]
 fn test_duplicate_chan_id() {
        // Test that if a given peer tries to open a channel with the same channel_id as one that is
@@ -8505,12 +8649,12 @@ fn test_duplicate_chan_id() {
        // Create an initial channel
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
        let mut open_chan_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(), channelmanager::provided_init_features(), &open_chan_msg);
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_chan_msg);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
 
        // Try to create a second channel with the same temporary_channel_id as the first and check
        // that it is rejected.
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_chan_msg);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_chan_msg);
        {
                let events = nodes[1].node.get_and_clear_pending_msg_events();
                assert_eq!(events.len(), 1);
@@ -8553,7 +8697,7 @@ fn test_duplicate_chan_id() {
        // Technically this is allowed by the spec, but we don't support it and there's little reason
        // to. Still, it shouldn't cause any other issues.
        open_chan_msg.temporary_channel_id = channel_id;
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_chan_msg);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_chan_msg);
        {
                let events = nodes[1].node.get_and_clear_pending_msg_events();
                assert_eq!(events.len(), 1);
@@ -8571,25 +8715,26 @@ fn test_duplicate_chan_id() {
        // Now try to create a second channel which has a duplicate funding output.
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
        let open_chan_2_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(), channelmanager::provided_init_features(), &open_chan_2_msg);
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_chan_2_msg);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
        create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); // Get and check the FundingGenerationReady event
 
        let funding_created = {
-               let mut a_channel_lock = nodes[0].node.channel_state.lock().unwrap();
+               let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+               let mut a_peer_state = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
                // Once we call `get_outbound_funding_created` the channel has a duplicate channel_id as
                // another channel in the ChannelManager - an invalid state. Thus, we'd panic later when we
                // try to create another channel. Instead, we drop the channel entirely here (leaving the
                // channelmanager in a possibly nonsense state instead).
-               let mut as_chan = a_channel_lock.by_id.remove(&open_chan_2_msg.temporary_channel_id).unwrap();
+               let mut as_chan = a_peer_state.channel_by_id.remove(&open_chan_2_msg.temporary_channel_id).unwrap();
                let logger = test_utils::TestLogger::new();
                as_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).unwrap()
        };
        check_added_monitors!(nodes[0], 0);
        nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created);
-       // At this point we'll try to add a duplicate channel monitor, which will be rejected, but
-       // still needs to be cleared here.
-       check_added_monitors!(nodes[1], 1);
+       // At this point we'll look up if the channel_id is present and immediately fail the channel
+       // without trying to persist the `ChannelMonitor`.
+       check_added_monitors!(nodes[1], 0);
 
        // ...still, nodes[1] will reject the duplicate channel.
        {
@@ -8641,9 +8786,9 @@ fn test_error_chans_closed() {
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
        // Create some initial channels
-       let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_3 = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
+       let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
+       let chan_3 = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001);
 
        assert_eq!(nodes[0].node.list_usable_channels().len(), 3);
        assert_eq!(nodes[1].node.list_usable_channels().len(), 2);
@@ -8664,7 +8809,7 @@ fn test_error_chans_closed() {
        assert!(nodes[0].node.list_usable_channels()[0].channel_id == chan_3.2 || nodes[0].node.list_usable_channels()[1].channel_id == chan_3.2);
 
        // A null channel ID should close all channels
-       let _chan_4 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _chan_4 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
        nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msgs::ErrorMessage { channel_id: [0; 32], data: "ERR".to_owned() });
        check_added_monitors!(nodes[0], 2);
        check_closed_event!(nodes[0], 2, ClosureReason::CounterpartyForceClosed { peer_msg: "ERR".to_string() });
@@ -8683,13 +8828,11 @@ fn test_error_chans_closed() {
                _ => panic!("Unexpected event"),
        }
        // Note that at this point users of a standard PeerHandler will end up calling
-       // peer_disconnected with no_connection_possible set to false, duplicating the
-       // close-all-channels logic. That's OK, we don't want to end up not force-closing channels for
-       // users with their own peer handling logic. We duplicate the call here, however.
+       // peer_disconnected.
        assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
        assert!(nodes[0].node.list_usable_channels()[0].channel_id == chan_3.2);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), true);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
        assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
        assert!(nodes[0].node.list_usable_channels()[0].channel_id == chan_3.2);
 }
@@ -8712,8 +8855,8 @@ fn test_invalid_funding_tx() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 10_000, 42, None).unwrap();
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
 
        let (temporary_channel_id, mut tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100_000, 42);
 
@@ -8802,11 +8945,11 @@ fn do_test_tx_confirmed_skipping_blocks_immediate_broadcast(test_height_before_t
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
        *nodes[0].connect_style.borrow_mut() = ConnectStyle::BestBlockFirstSkippingBlocks;
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let (chan_announce, _, channel_id, _) = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let (chan_announce, _, channel_id, _) = create_announced_chan_between_nodes(&nodes, 1, 2);
        let (_, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000);
-       nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false);
-       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id());
+       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id());
 
        nodes[1].node.force_close_broadcasting_latest_txn(&channel_id, &nodes[2].node.get_our_node_id()).unwrap();
        check_closed_broadcast!(nodes[1], true);
@@ -8869,10 +9012,10 @@ fn do_test_dup_htlc_second_rejected(test_for_second_fail_panic: bool) {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
 
-       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features());
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_features(nodes[1].node.invoice_features());
        let route = get_route!(nodes[0], payment_params, 10_000, TEST_FINAL_CLTV).unwrap();
 
        let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(&nodes[1]);
@@ -8927,9 +9070,11 @@ fn do_test_dup_htlc_second_rejected(test_for_second_fail_panic: bool) {
                commitment_signed_dance!(nodes[0], nodes[1], fail_updates_1.commitment_signed, false);
 
                let failure_events = nodes[0].node.get_and_clear_pending_events();
-               assert_eq!(failure_events.len(), 2);
+               assert_eq!(failure_events.len(), 4);
                if let Event::PaymentPathFailed { .. } = failure_events[0] {} else { panic!(); }
-               if let Event::PaymentPathFailed { .. } = failure_events[1] {} else { panic!(); }
+               if let Event::PaymentFailed { .. } = failure_events[1] {} else { panic!(); }
+               if let Event::PaymentPathFailed { .. } = failure_events[2] {} else { panic!(); }
+               if let Event::PaymentFailed { .. } = failure_events[3] {} else { panic!(); }
        } else {
                // Let the second HTLC fail and claim the first
                expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore!(nodes[1], vec![HTLCDestination::FailedPayment { payment_hash: our_payment_hash }]);
@@ -8940,7 +9085,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());
 
                claim_payment(&nodes[0], &[&nodes[1]], our_payment_preimage);
        }
@@ -8971,13 +9116,13 @@ fn test_inconsistent_mpp_params() {
        let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
        let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes_with_value(&nodes, 1, 3, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2_3 =create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0);
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100_000, 0);
+       create_announced_chan_between_nodes_with_value(&nodes, 1, 3, 100_000, 0);
+       let chan_2_3 =create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 100_000, 0);
 
-       let payment_params = PaymentParameters::from_node_id(nodes[3].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features());
+       let payment_params = PaymentParameters::from_node_id(nodes[3].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_features(nodes[3].node.invoice_features());
        let mut route = get_route!(nodes[0], payment_params, 15_000_000, TEST_FINAL_CLTV).unwrap();
        assert_eq!(route.paths.len(), 2);
        route.paths.sort_by(|path_a, _| {
@@ -8999,20 +9144,20 @@ fn test_inconsistent_mpp_params() {
                dup_route.paths.push(route.paths[1].clone());
                nodes[0].node.test_add_new_pending_payment(our_payment_hash, Some(our_payment_secret), payment_id, &dup_route).unwrap()
        };
-       {
-               nodes[0].node.send_payment_along_path(&route.paths[0], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), 15_000_000, cur_height, payment_id, &None, session_privs[0]).unwrap();
-               check_added_monitors!(nodes[0], 1);
+       nodes[0].node.test_send_payment_along_path(&route.paths[0], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), 15_000_000, cur_height, payment_id, &None, session_privs[0]).unwrap();
+       check_added_monitors!(nodes[0], 1);
 
+       {
                let mut events = nodes[0].node.get_and_clear_pending_msg_events();
                assert_eq!(events.len(), 1);
                pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 15_000_000, our_payment_hash, Some(our_payment_secret), events.pop().unwrap(), false, None);
        }
        assert!(nodes[3].node.get_and_clear_pending_events().is_empty());
 
-       {
-               nodes[0].node.send_payment_along_path(&route.paths[1], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), 14_000_000, cur_height, payment_id, &None, session_privs[1]).unwrap();
-               check_added_monitors!(nodes[0], 1);
+       nodes[0].node.test_send_payment_along_path(&route.paths[1], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), 14_000_000, cur_height, payment_id, &None, session_privs[1]).unwrap();
+       check_added_monitors!(nodes[0], 1);
 
+       {
                let mut events = nodes[0].node.get_and_clear_pending_msg_events();
                assert_eq!(events.len(), 1);
                let payment_event = SendEvent::from_event(events.pop().unwrap());
@@ -9055,14 +9200,34 @@ fn test_inconsistent_mpp_params() {
 
        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, session_privs[2]).unwrap();
+       nodes[0].node.test_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, session_privs[2]).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 1);
        pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 15_000_000, our_payment_hash, Some(our_payment_secret), events.pop().unwrap(), true, None);
 
-       claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, our_payment_preimage);
+       do_claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, our_payment_preimage);
+       let events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 3);
+       match events[0] {
+               Event::PaymentSent { payment_hash, .. } => { // The payment was abandoned earlier, so the fee paid will be None
+                       assert_eq!(payment_hash, our_payment_hash);
+               },
+               _ => panic!("Unexpected event")
+       }
+       match events[1] {
+               Event::PaymentPathSuccessful { payment_hash, .. } => {
+                       assert_eq!(payment_hash.unwrap(), our_payment_hash);
+               },
+               _ => panic!("Unexpected event")
+       }
+       match events[2] {
+               Event::PaymentPathSuccessful { payment_hash, .. } => {
+                       assert_eq!(payment_hash.unwrap(), our_payment_hash);
+               },
+               _ => panic!("Unexpected event")
+       }
 }
 
 #[test]
@@ -9072,16 +9237,15 @@ fn test_keysend_payments_to_public_node() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
        let network_graph = nodes[0].network_graph.clone();
        let payer_pubkey = nodes[0].node.get_our_node_id();
        let payee_pubkey = nodes[1].node.get_our_node_id();
        let route_params = RouteParameters {
-               payment_params: PaymentParameters::for_keysend(payee_pubkey),
+               payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
                final_value_msat: 10000,
-               final_cltv_expiry_delta: 40,
        };
-       let scorer = test_utils::TestScorer::with_penalty(0);
+       let scorer = test_utils::TestScorer::new();
        let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
        let route = find_route(&payer_pubkey, &route_params, &network_graph, None, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
 
@@ -9105,18 +9269,15 @@ fn test_keysend_payments_to_private_node() {
 
        let payer_pubkey = nodes[0].node.get_our_node_id();
        let payee_pubkey = nodes[1].node.get_our_node_id();
-       nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-       nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
 
-       let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let _chan = create_chan_between_nodes(&nodes[0], &nodes[1]);
        let route_params = RouteParameters {
-               payment_params: PaymentParameters::for_keysend(payee_pubkey),
+               payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
                final_value_msat: 10000,
-               final_cltv_expiry_delta: 40,
        };
        let network_graph = nodes[0].network_graph.clone();
        let first_hops = nodes[0].node.list_usable_channels();
-       let scorer = test_utils::TestScorer::with_penalty(0);
+       let scorer = test_utils::TestScorer::new();
        let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
        let route = find_route(
                &payer_pubkey, &route_params, &network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
@@ -9145,10 +9306,10 @@ fn test_double_partial_claim() {
        let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
        let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes_with_value(&nodes, 1, 3, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0);
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100_000, 0);
+       create_announced_chan_between_nodes_with_value(&nodes, 1, 3, 100_000, 0);
+       create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 100_000, 0);
 
        let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[3], 15_000_000);
        assert_eq!(route.paths.len(), 2);
@@ -9180,7 +9341,8 @@ fn test_double_partial_claim() {
 
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 2);
-       pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 15_000_000, payment_hash, Some(payment_secret), events.drain(..).next().unwrap(), false, None);
+       let node_1_msgs = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events);
+       pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 15_000_000, payment_hash, Some(payment_secret), node_1_msgs, false, None);
 
        // At this point nodes[3] has received one half of the payment, and the user goes to handle
        // that PaymentClaimable event they got hours ago and never handled...we should refuse to claim.
@@ -9227,18 +9389,19 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
        if on_holder_tx {
                open_channel.dust_limit_satoshis = 546;
        }
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
        let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
 
        let opt_anchors = false;
 
        let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 1_000_000, 42);
 
        if on_holder_tx {
-               if let Some(mut chan) = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&temporary_channel_id) {
-                       chan.holder_dust_limit_satoshis = 546;
-               }
+               let mut node_0_per_peer_lock;
+               let mut node_0_peer_state_lock;
+               let mut chan = get_channel_ref!(nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, temporary_channel_id);
+               chan.holder_dust_limit_satoshis = 546;
        }
 
        nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).unwrap();
@@ -9253,8 +9416,9 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
        update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &as_update, &bs_update);
 
        let dust_buffer_feerate = {
-               let chan_lock = nodes[0].node.channel_state.lock().unwrap();
-               let chan = chan_lock.by_id.get(&channel_id).unwrap();
+               let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+               let chan_lock = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
+               let chan = chan_lock.channel_by_id.get(&channel_id).unwrap();
                chan.get_dust_buffer_feerate(None) as u64
        };
        let dust_outbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_timeout_tx_weight(opt_anchors) / 1000 + open_channel.dust_limit_satoshis - 1) * 1000;
@@ -9372,9 +9536,9 @@ fn test_non_final_funding_tx() {
 
        let temp_channel_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None).unwrap();
        let open_channel_message = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel_message);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_message);
        let accept_channel_message = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel_message);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel_message);
 
        let best_height = nodes[0].node.best_block.read().unwrap().height();
 
@@ -9415,7 +9579,7 @@ fn accept_busted_but_better_fee() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_chan_between_nodes(&nodes[0], &nodes[1], channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_chan_between_nodes(&nodes[0], &nodes[1]);
 
        // Set nodes[1] to expect 5,000 sat/kW.
        {
@@ -9482,3 +9646,60 @@ fn accept_busted_but_better_fee() {
                _ => panic!("Unexpected event"),
        };
 }
+
+fn do_payment_with_custom_min_final_cltv_expiry(valid_delta: bool, use_user_hash: bool) {
+       let mut chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+       let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+       let min_final_cltv_expiry_delta = 120;
+       let final_cltv_expiry_delta = if valid_delta { min_final_cltv_expiry_delta + 2 } else {
+               min_final_cltv_expiry_delta - 2 };
+       let recv_value = 100_000;
+
+       create_chan_between_nodes(&nodes[0], &nodes[1]);
+
+       let payment_parameters = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), final_cltv_expiry_delta as u32);
+       let (payment_hash, payment_preimage, payment_secret) = if use_user_hash {
+               let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1],
+                       Some(recv_value), Some(min_final_cltv_expiry_delta));
+               (payment_hash, payment_preimage, payment_secret)
+       } else {
+               let (payment_hash, payment_secret) = nodes[1].node.create_inbound_payment(Some(recv_value), 7200, Some(min_final_cltv_expiry_delta)).unwrap();
+               (payment_hash, nodes[1].node.get_payment_preimage(payment_hash, payment_secret).unwrap(), payment_secret)
+       };
+       let route = get_route!(nodes[0], payment_parameters, recv_value, final_cltv_expiry_delta as u32).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
+       check_added_monitors!(nodes[0], 1);
+       let mut events = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(events.len(), 1);
+       let mut payment_event = SendEvent::from_event(events.pop().unwrap());
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
+       commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
+       expect_pending_htlcs_forwardable!(nodes[1]);
+
+       if valid_delta {
+               expect_payment_claimable!(nodes[1], payment_hash, payment_secret, recv_value, if use_user_hash {
+                       None } else { Some(payment_preimage) }, nodes[1].node.get_our_node_id());
+
+               claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage);
+       } else {
+               expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[1], vec![HTLCDestination::FailedPayment { payment_hash }]);
+
+               check_added_monitors!(nodes[1], 1);
+
+               let fail_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+               nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_updates.update_fail_htlcs[0]);
+               commitment_signed_dance!(nodes[0], nodes[1], fail_updates.commitment_signed, false, true);
+
+               expect_payment_failed!(nodes[0], payment_hash, true);
+       }
+}
+
+#[test]
+fn test_payment_with_custom_min_cltv_expiry_delta() {
+       do_payment_with_custom_min_final_cltv_expiry(false, false);
+       do_payment_with_custom_min_final_cltv_expiry(false, true);
+       do_payment_with_custom_min_final_cltv_expiry(true, false);
+       do_payment_with_custom_min_final_cltv_expiry(true, true);
+}
index ba1b1fe579a8cc52e30af7eb05f5ede4d6bf6a75..0c6d6f2b804bccd8cfb651c24995bf4959998a91 100644 (file)
@@ -14,7 +14,7 @@ use bitcoin::hashes::{Hash, HashEngine};
 use bitcoin::hashes::cmp::fixed_time_eq;
 use bitcoin::hashes::hmac::{Hmac, HmacEngine};
 use bitcoin::hashes::sha256::Hash as Sha256;
-use crate::chain::keysinterface::{KeyMaterial, KeysInterface, EntropySource};
+use crate::chain::keysinterface::{KeyMaterial, EntropySource};
 use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
 use crate::ln::msgs;
 use crate::ln::msgs::MAX_VALUE_MSAT;
@@ -68,6 +68,8 @@ impl ExpandedKey {
 enum Method {
        LdkPaymentHash = 0,
        UserPaymentHash = 1,
+       LdkPaymentHashCustomFinalCltv = 2,
+       UserPaymentHashCustomFinalCltv = 3,
 }
 
 impl Method {
@@ -75,11 +77,18 @@ impl Method {
                match bits {
                        bits if bits == Method::LdkPaymentHash as u8 => Ok(Method::LdkPaymentHash),
                        bits if bits == Method::UserPaymentHash as u8 => Ok(Method::UserPaymentHash),
+                       bits if bits == Method::LdkPaymentHashCustomFinalCltv as u8 => Ok(Method::LdkPaymentHashCustomFinalCltv),
+                       bits if bits == Method::UserPaymentHashCustomFinalCltv as u8 => Ok(Method::UserPaymentHashCustomFinalCltv),
                        unknown => Err(unknown),
                }
        }
 }
 
+fn min_final_cltv_expiry_delta_from_metadata(bytes: [u8; METADATA_LEN]) -> u16 {
+       let expiry_bytes = &bytes[AMT_MSAT_LEN..];
+       u16::from_be_bytes([expiry_bytes[0], expiry_bytes[1]])
+}
+
 /// Equivalent to [`crate::ln::channelmanager::ChannelManager::create_inbound_payment`], but no
 /// `ChannelManager` is required. Useful for generating invoices for [phantom node payments] without
 /// a `ChannelManager`.
@@ -90,15 +99,24 @@ impl Method {
 ///
 /// `current_time` is a Unix timestamp representing the current time.
 ///
+/// Note that if `min_final_cltv_expiry_delta` is set to some value, then the payment will not be receivable
+/// on versions of LDK prior to 0.0.114.
+///
 /// [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager
 /// [`NodeSigner::get_inbound_payment_key_material`]: crate::chain::keysinterface::NodeSigner::get_inbound_payment_key_material
-pub fn create<K: Deref>(keys: &ExpandedKey, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, keys_manager: &K, current_time: u64) -> Result<(PaymentHash, PaymentSecret), ()>
-       where K::Target: KeysInterface
+pub fn create<ES: Deref>(keys: &ExpandedKey, min_value_msat: Option<u64>,
+       invoice_expiry_delta_secs: u32, entropy_source: &ES, current_time: u64,
+       min_final_cltv_expiry_delta: Option<u16>) -> Result<(PaymentHash, PaymentSecret), ()>
+       where ES::Target: EntropySource
 {
-       let metadata_bytes = construct_metadata_bytes(min_value_msat, Method::LdkPaymentHash, invoice_expiry_delta_secs, current_time)?;
+       let metadata_bytes = construct_metadata_bytes(min_value_msat, if min_final_cltv_expiry_delta.is_some() {
+                       Method::LdkPaymentHashCustomFinalCltv
+               } else {
+                       Method::LdkPaymentHash
+               }, invoice_expiry_delta_secs, current_time, min_final_cltv_expiry_delta)?;
 
        let mut iv_bytes = [0 as u8; IV_LEN];
-       let rand_bytes = keys_manager.get_secure_random_bytes();
+       let rand_bytes = entropy_source.get_secure_random_bytes();
        iv_bytes.copy_from_slice(&rand_bytes[..IV_LEN]);
 
        let mut hmac = HmacEngine::<Sha256>::new(&keys.ldk_pmt_hash_key);
@@ -117,9 +135,17 @@ pub fn create<K: Deref>(keys: &ExpandedKey, min_value_msat: Option<u64>, invoice
 ///
 /// See [`create`] for information on the `keys` and `current_time` parameters.
 ///
+/// Note that if `min_final_cltv_expiry_delta` is set to some value, then the payment will not be receivable
+/// on versions of LDK prior to 0.0.114.
+///
 /// [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager
-pub fn create_from_hash(keys: &ExpandedKey, min_value_msat: Option<u64>, payment_hash: PaymentHash, invoice_expiry_delta_secs: u32, current_time: u64) -> Result<PaymentSecret, ()> {
-       let metadata_bytes = construct_metadata_bytes(min_value_msat, Method::UserPaymentHash, invoice_expiry_delta_secs, current_time)?;
+pub fn create_from_hash(keys: &ExpandedKey, min_value_msat: Option<u64>, payment_hash: PaymentHash,
+       invoice_expiry_delta_secs: u32, current_time: u64, min_final_cltv_expiry_delta: Option<u16>) -> Result<PaymentSecret, ()> {
+       let metadata_bytes = construct_metadata_bytes(min_value_msat, if min_final_cltv_expiry_delta.is_some() {
+                       Method::UserPaymentHashCustomFinalCltv
+               } else {
+                       Method::UserPaymentHash
+               }, invoice_expiry_delta_secs, current_time, min_final_cltv_expiry_delta)?;
 
        let mut hmac = HmacEngine::<Sha256>::new(&keys.user_pmt_hash_key);
        hmac.input(&metadata_bytes);
@@ -132,7 +158,8 @@ pub fn create_from_hash(keys: &ExpandedKey, min_value_msat: Option<u64>, payment
        Ok(construct_payment_secret(&iv_bytes, &metadata_bytes, &keys.metadata_key))
 }
 
-fn construct_metadata_bytes(min_value_msat: Option<u64>, payment_type: Method, invoice_expiry_delta_secs: u32, highest_seen_timestamp: u64) -> Result<[u8; METADATA_LEN], ()> {
+fn construct_metadata_bytes(min_value_msat: Option<u64>, payment_type: Method,
+       invoice_expiry_delta_secs: u32, highest_seen_timestamp: u64, min_final_cltv_expiry_delta: Option<u16>) -> Result<[u8; METADATA_LEN], ()> {
        if min_value_msat.is_some() && min_value_msat.unwrap() > MAX_VALUE_MSAT {
                return Err(());
        }
@@ -148,9 +175,27 @@ fn construct_metadata_bytes(min_value_msat: Option<u64>, payment_type: Method, i
        // than two hours in the future.  Thus, we add two hours here as a buffer to ensure we
        // absolutely never fail a payment too early.
        // Note that we assume that received blocks have reasonably up-to-date timestamps.
-       let expiry_bytes = (highest_seen_timestamp + invoice_expiry_delta_secs as u64 + 7200).to_be_bytes();
+       let expiry_timestamp = highest_seen_timestamp + invoice_expiry_delta_secs as u64 + 7200;
+       let mut expiry_bytes = expiry_timestamp.to_be_bytes();
+
+       // `min_value_msat` should fit in (64 bits - 3 payment type bits =) 61 bits as an unsigned integer.
+       // This should leave us with a maximum value greater than the 21M BTC supply cap anyway.
+       if min_value_msat.is_some() && min_value_msat.unwrap() > ((1u64 << 61) - 1) { return Err(()); }
+
+       // `expiry_timestamp` should fit in (64 bits - 2 delta bytes =) 48 bits as an unsigned integer.
+       // Bitcoin's block header timestamps are actually `u32`s, so we're technically already limited to
+       // the much smaller maximum timestamp of `u32::MAX` for now, but we check the u64 `expiry_timestamp`
+       // for future-proofing.
+       if min_final_cltv_expiry_delta.is_some() && expiry_timestamp > ((1u64 << 48) - 1) { return Err(()); }
+
+       if let Some(min_final_cltv_expiry_delta) = min_final_cltv_expiry_delta {
+               let bytes = min_final_cltv_expiry_delta.to_be_bytes();
+               expiry_bytes[0] |= bytes[0];
+               expiry_bytes[1] |= bytes[1];
+       }
 
        let mut metadata_bytes: [u8; METADATA_LEN] = [0; METADATA_LEN];
+
        metadata_bytes[..AMT_MSAT_LEN].copy_from_slice(&min_amt_msat_bytes);
        metadata_bytes[AMT_MSAT_LEN..].copy_from_slice(&expiry_bytes);
 
@@ -175,9 +220,13 @@ fn construct_payment_secret(iv_bytes: &[u8; IV_LEN], metadata_bytes: &[u8; METAD
 /// secret (and, if supplied by LDK, our payment preimage) to include encrypted metadata about the
 /// payment.
 ///
-/// The metadata is constructed as:
+/// For payments without a custom `min_final_cltv_expiry_delta`, the metadata is constructed as:
 ///   payment method (3 bits) || payment amount (8 bytes - 3 bits) || expiry (8 bytes)
-/// and encrypted using a key derived from [`NodeSigner::get_inbound_payment_key_material`].
+///
+/// For payments including a custom `min_final_cltv_expiry_delta`, the metadata is constructed as:
+///   payment method (3 bits) || payment amount (8 bytes - 3 bits) || min_final_cltv_expiry_delta (2 bytes) || expiry (6 bytes)
+///
+/// In both cases the result is then encrypted using a key derived from [`NodeSigner::get_inbound_payment_key_material`].
 ///
 /// Then on payment receipt, we verify in this method that the payment preimage and payment secret
 /// match what was constructed.
@@ -201,24 +250,27 @@ fn construct_payment_secret(iv_bytes: &[u8; IV_LEN], metadata_bytes: &[u8; METAD
 /// [`NodeSigner::get_inbound_payment_key_material`]: crate::chain::keysinterface::NodeSigner::get_inbound_payment_key_material
 /// [`create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment
 /// [`create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
-pub(super) fn verify<L: Deref>(payment_hash: PaymentHash, payment_data: &msgs::FinalOnionHopData, highest_seen_timestamp: u64, keys: &ExpandedKey, logger: &L) -> Result<Option<PaymentPreimage>, ()>
+pub(super) fn verify<L: Deref>(payment_hash: PaymentHash, payment_data: &msgs::FinalOnionHopData,
+       highest_seen_timestamp: u64, keys: &ExpandedKey, logger: &L) -> Result<
+       (Option<PaymentPreimage>, Option<u16>), ()>
        where L::Target: Logger
 {
        let (iv_bytes, metadata_bytes) = decrypt_metadata(payment_data.payment_secret, keys);
 
        let payment_type_res = Method::from_bits((metadata_bytes[0] & 0b1110_0000) >> METHOD_TYPE_OFFSET);
        let mut amt_msat_bytes = [0; AMT_MSAT_LEN];
+       let mut expiry_bytes = [0; METADATA_LEN - AMT_MSAT_LEN];
        amt_msat_bytes.copy_from_slice(&metadata_bytes[..AMT_MSAT_LEN]);
+       expiry_bytes.copy_from_slice(&metadata_bytes[AMT_MSAT_LEN..]);
        // Zero out the bits reserved to indicate the payment type.
        amt_msat_bytes[0] &= 0b00011111;
-       let min_amt_msat: u64 = u64::from_be_bytes(amt_msat_bytes.into());
-       let expiry = u64::from_be_bytes(metadata_bytes[AMT_MSAT_LEN..].try_into().unwrap());
+       let mut min_final_cltv_expiry_delta = None;
 
-       // Make sure to check to check the HMAC before doing the other checks below, to mitigate timing
-       // attacks.
+       // Make sure to check the HMAC before doing the other checks below, to mitigate timing attacks.
        let mut payment_preimage = None;
+
        match payment_type_res {
-               Ok(Method::UserPaymentHash) => {
+               Ok(Method::UserPaymentHash) | Ok(Method::UserPaymentHashCustomFinalCltv) => {
                        let mut hmac = HmacEngine::<Sha256>::new(&keys.user_pmt_hash_key);
                        hmac.input(&metadata_bytes[..]);
                        hmac.input(&payment_hash.0);
@@ -227,7 +279,7 @@ pub(super) fn verify<L: Deref>(payment_hash: PaymentHash, payment_data: &msgs::F
                                return Err(())
                        }
                },
-               Ok(Method::LdkPaymentHash) => {
+               Ok(Method::LdkPaymentHash) | Ok(Method::LdkPaymentHashCustomFinalCltv) => {
                        match derive_ldk_payment_preimage(payment_hash, &iv_bytes, &metadata_bytes, keys) {
                                Ok(preimage) => payment_preimage = Some(preimage),
                                Err(bad_preimage_bytes) => {
@@ -242,6 +294,19 @@ pub(super) fn verify<L: Deref>(payment_hash: PaymentHash, payment_data: &msgs::F
                }
        }
 
+       match payment_type_res {
+               Ok(Method::UserPaymentHashCustomFinalCltv) | Ok(Method::LdkPaymentHashCustomFinalCltv) => {
+                       min_final_cltv_expiry_delta = Some(min_final_cltv_expiry_delta_from_metadata(metadata_bytes));
+                       // Zero out first two bytes of expiry reserved for `min_final_cltv_expiry_delta`.
+                       expiry_bytes[0] &= 0;
+                       expiry_bytes[1] &= 0;
+               }
+               _ => {}
+       }
+
+       let min_amt_msat: u64 = u64::from_be_bytes(amt_msat_bytes.into());
+       let expiry = u64::from_be_bytes(expiry_bytes.try_into().unwrap());
+
        if payment_data.total_msat < min_amt_msat {
                log_trace!(logger, "Failing HTLC with payment_hash {} due to total_msat {} being less than the minimum amount of {} msat", log_bytes!(payment_hash.0), payment_data.total_msat, min_amt_msat);
                return Err(())
@@ -252,20 +317,20 @@ pub(super) fn verify<L: Deref>(payment_hash: PaymentHash, payment_data: &msgs::F
                return Err(())
        }
 
-       Ok(payment_preimage)
+       Ok((payment_preimage, min_final_cltv_expiry_delta))
 }
 
 pub(super) fn get_payment_preimage(payment_hash: PaymentHash, payment_secret: PaymentSecret, keys: &ExpandedKey) -> Result<PaymentPreimage, APIError> {
        let (iv_bytes, metadata_bytes) = decrypt_metadata(payment_secret, keys);
 
        match Method::from_bits((metadata_bytes[0] & 0b1110_0000) >> METHOD_TYPE_OFFSET) {
-               Ok(Method::LdkPaymentHash) => {
+               Ok(Method::LdkPaymentHash) | Ok(Method::LdkPaymentHashCustomFinalCltv) => {
                        derive_ldk_payment_preimage(payment_hash, &iv_bytes, &metadata_bytes, keys)
                                .map_err(|bad_preimage_bytes| APIError::APIMisuseError {
                                        err: format!("Payment hash {} did not match decoded preimage {}", log_bytes!(payment_hash.0), log_bytes!(bad_preimage_bytes))
                                })
                },
-               Ok(Method::UserPaymentHash) => Err(APIError::APIMisuseError {
+               Ok(Method::UserPaymentHash) | Ok(Method::UserPaymentHashCustomFinalCltv) => Err(APIError::APIMisuseError {
                        err: "Expected payment type to be LdkPaymentHash, instead got UserPaymentHash".to_string()
                }),
                Err(other) => Err(APIError::APIMisuseError { err: format!("Unknown payment type: {}", other) }),
index 1cb32bed08dc42e2cbb7371856343d14d8d21e35..c4435b470ca8c6deb8618fada682e9cd063fcc17 100644 (file)
@@ -9,17 +9,29 @@
 
 //! Further functional tests which test blockchain reorganizations.
 
+#[cfg(anchors)]
+use crate::chain::keysinterface::BaseSign;
+#[cfg(anchors)]
+use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS;
 use crate::chain::channelmonitor::{ANTI_REORG_DELAY, Balance};
 use crate::chain::transaction::OutPoint;
 use crate::chain::chaininterface::LowerBoundedFeeEstimator;
 use crate::ln::channel;
-use crate::ln::channelmanager::{self, BREAKDOWN_TIMEOUT, PaymentId};
+#[cfg(anchors)]
+use crate::ln::chan_utils;
+use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, PaymentId};
 use crate::ln::msgs::ChannelMessageHandler;
+#[cfg(anchors)]
+use crate::util::config::UserConfig;
+#[cfg(anchors)]
+use crate::util::events::BumpTransactionEvent;
 use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
 
 use bitcoin::blockdata::script::Builder;
 use bitcoin::blockdata::opcodes;
 use bitcoin::secp256k1::Secp256k1;
+#[cfg(anchors)]
+use bitcoin::{Amount, Script, TxIn, TxOut, PackedLockTime};
 use bitcoin::Transaction;
 
 use crate::prelude::*;
@@ -48,8 +60,8 @@ fn chanmon_fail_from_stale_commitment() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let (update_a, _, chan_id_2, _) = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let (update_a, _, chan_id_2, _) = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 1_000_000);
        nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
@@ -105,7 +117,7 @@ fn revoked_output_htlc_resolution_timing() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000);
 
        let payment_hash_1 = route_payment(&nodes[1], &[&nodes[0]], 1_000_000).1;
 
@@ -154,12 +166,12 @@ fn chanmon_claim_value_coop_close() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        let (_, _, chan_id, funding_tx) =
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 1_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 1_000_000);
        let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
        assert_eq!(funding_outpoint.to_channel_id(), chan_id);
 
-       let chan_feerate = get_feerate!(nodes[0], chan_id) as u64;
-       let opt_anchors = get_opt_anchors!(nodes[0], chan_id);
+       let chan_feerate = get_feerate!(nodes[0], nodes[1], chan_id) as u64;
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id);
 
        assert_eq!(vec![Balance::ClaimableOnChannelClose {
                        claimable_amount_satoshis: 1_000_000 - 1_000 - chan_feerate * channel::commitment_tx_base_weight(opt_anchors) / 1000
@@ -170,9 +182,9 @@ fn chanmon_claim_value_coop_close() {
 
        nodes[0].node.close_channel(&chan_id, &nodes[1].node.get_our_node_id()).unwrap();
        let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
        let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_shutdown);
 
        let node_0_closing_signed = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
        nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_closing_signed);
@@ -255,7 +267,7 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        let (_, _, chan_id, funding_tx) =
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 1_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 1_000_000);
        let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
        assert_eq!(funding_outpoint.to_channel_id(), chan_id);
 
@@ -269,8 +281,8 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) {
 
        let htlc_cltv_timeout = nodes[0].best_block_info().1 + TEST_FINAL_CLTV + 1; // Note ChannelManager adds one to CLTV timeouts for safety
 
-       let chan_feerate = get_feerate!(nodes[0], chan_id) as u64;
-       let opt_anchors = get_opt_anchors!(nodes[0], chan_id);
+       let chan_feerate = get_feerate!(nodes[0], nodes[1], chan_id) as u64;
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id);
 
        let remote_txn = get_local_commitment_txn!(nodes[1], chan_id);
        // Before B receives the payment preimage, it only suggests the push_msat value of 1_000 sats
@@ -594,7 +606,7 @@ fn test_balances_on_local_commitment_htlcs() {
 
        // Create a single channel with two pending HTLCs from nodes[0] to nodes[1], one which nodes[1]
        // knows the preimage for, one which it does not.
-       let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
        let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
 
        let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 10_000_000);
@@ -624,8 +636,8 @@ fn test_balances_on_local_commitment_htlcs() {
        check_added_monitors!(nodes[1], 1);
        expect_payment_claimed!(nodes[1], payment_hash_2, 20_000_000);
 
-       let chan_feerate = get_feerate!(nodes[0], chan_id) as u64;
-       let opt_anchors = get_opt_anchors!(nodes[0], chan_id);
+       let chan_feerate = get_feerate!(nodes[0], nodes[1], chan_id) as u64;
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id);
 
        // Get nodes[0]'s commitment transaction and HTLC-Timeout transactions
        let as_txn = get_local_commitment_txn!(nodes[0], chan_id);
@@ -768,7 +780,7 @@ fn test_no_preimage_inbound_htlc_balances() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000);
        let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
 
        // Send two HTLCs, one from A to B, and one from B to A.
@@ -776,8 +788,8 @@ fn test_no_preimage_inbound_htlc_balances() {
        let to_a_failed_payment_hash = route_payment(&nodes[1], &[&nodes[0]], 20_000_000).1;
        let htlc_cltv_timeout = nodes[0].best_block_info().1 + TEST_FINAL_CLTV + 1; // Note ChannelManager adds one to CLTV timeouts for safety
 
-       let chan_feerate = get_feerate!(nodes[0], chan_id) as u64;
-       let opt_anchors = get_opt_anchors!(nodes[0], chan_id);
+       let chan_feerate = get_feerate!(nodes[0], nodes[1], chan_id) as u64;
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id);
 
        // Both A and B will have an HTLC that's claimable on timeout and one that's claimable if they
        // receive the preimage. These will remain the same through the channel closure and until the
@@ -1021,7 +1033,7 @@ fn do_test_revoked_counterparty_commitment_balances(confirm_htlc_spend_first: bo
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        let (_, _, chan_id, funding_tx) =
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 100_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 100_000_000);
        let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
        assert_eq!(funding_outpoint.to_channel_id(), chan_id);
 
@@ -1052,9 +1064,9 @@ fn do_test_revoked_counterparty_commitment_balances(confirm_htlc_spend_first: bo
 
        // Get the latest commitment transaction from A and then update the fee to revoke it
        let as_revoked_txn = get_local_commitment_txn!(nodes[0], chan_id);
-       let opt_anchors = get_opt_anchors!(nodes[0], chan_id);
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id);
 
-       let chan_feerate = get_feerate!(nodes[0], chan_id) as u64;
+       let chan_feerate = get_feerate!(nodes[0], nodes[1], chan_id) as u64;
 
        let missing_htlc_cltv_timeout = nodes[0].best_block_info().1 + TEST_FINAL_CLTV + 1; // Note ChannelManager adds one to CLTV timeouts for safety
        let missing_htlc_payment_hash = route_payment(&nodes[1], &[&nodes[0]], 2_000_000).1;
@@ -1229,11 +1241,10 @@ fn do_test_revoked_counterparty_commitment_balances(confirm_htlc_spend_first: bo
        test_spendable_output(&nodes[1], &as_revoked_txn[0]);
 
        let mut payment_failed_events = nodes[1].node.get_and_clear_pending_events();
-       expect_payment_failed_conditions_event(&nodes[1], payment_failed_events.pop().unwrap(),
-               dust_payment_hash, false, PaymentFailedConditions::new());
-       expect_payment_failed_conditions_event(&nodes[1], payment_failed_events.pop().unwrap(),
+       expect_payment_failed_conditions_event(payment_failed_events[..2].to_vec(),
                missing_htlc_payment_hash, false, PaymentFailedConditions::new());
-       assert!(payment_failed_events.is_empty());
+       expect_payment_failed_conditions_event(payment_failed_events[2..].to_vec(),
+               dust_payment_hash, false, PaymentFailedConditions::new());
 
        connect_blocks(&nodes[1], 1);
        test_spendable_output(&nodes[1], &claim_txn[if confirm_htlc_spend_first { 2 } else { 3 }]);
@@ -1273,7 +1284,7 @@ fn test_revoked_counterparty_htlc_tx_balances() {
 
        // Create some initial channels
        let (_, _, chan_id, funding_tx) =
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 11_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 11_000_000);
        let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
        assert_eq!(funding_outpoint.to_channel_id(), chan_id);
 
@@ -1288,8 +1299,8 @@ fn test_revoked_counterparty_htlc_tx_balances() {
 
        claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
 
-       let chan_feerate = get_feerate!(nodes[0], chan_id) as u64;
-       let opt_anchors = get_opt_anchors!(nodes[0], chan_id);
+       let chan_feerate = get_feerate!(nodes[0], nodes[1], chan_id) as u64;
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id);
 
        // B will generate an HTLC-Success from its revoked commitment tx
        mine_transaction(&nodes[1], &revoked_local_txn[0]);
@@ -1483,7 +1494,7 @@ fn test_revoked_counterparty_aggregated_claims() {
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        let (_, _, chan_id, funding_tx) =
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 100_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 100_000_000);
        let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
        assert_eq!(funding_outpoint.to_channel_id(), chan_id);
 
@@ -1508,8 +1519,8 @@ fn test_revoked_counterparty_aggregated_claims() {
        check_spends!(as_revoked_txn[0], funding_tx);
        check_spends!(as_revoked_txn[1], as_revoked_txn[0]); // The HTLC-Claim transaction
 
-       let opt_anchors = get_opt_anchors!(nodes[0], chan_id);
-       let chan_feerate = get_feerate!(nodes[0], chan_id) as u64;
+       let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id);
+       let chan_feerate = get_feerate!(nodes[0], nodes[1], chan_id) as u64;
 
        {
                let mut feerate = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
@@ -1666,3 +1677,141 @@ fn test_revoked_counterparty_aggregated_claims() {
        assert!(nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
        assert!(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances().is_empty());
 }
+
+#[cfg(anchors)]
+#[test]
+fn test_yield_anchors_events() {
+       // Tests that two parties supporting anchor outputs can open a channel, route payments over
+       // it, and finalize its resolution uncooperatively. Once the HTLCs are locked in, one side will
+       // force close once the HTLCs expire. The force close should stem from an event emitted by LDK,
+       // allowing the consumer to provide additional fees to the commitment transaction to be
+       // broadcast. Once the commitment transaction confirms, events for the HTLC resolution should be
+       // emitted by LDK, such that the consumer can attach fees to the zero fee HTLC transactions.
+       let secp = Secp256k1::new();
+       let mut chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let mut anchors_config = UserConfig::default();
+       anchors_config.channel_handshake_config.announced_channel = true;
+       anchors_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(anchors_config), Some(anchors_config)]);
+       let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       let chan_id = create_announced_chan_between_nodes_with_value(
+               &nodes, 0, 1, 1_000_000, 500_000_000
+       ).2;
+       route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
+       let (payment_preimage, payment_hash, _) = route_payment(&nodes[1], &[&nodes[0]], 1_000_000);
+
+       assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
+
+       connect_blocks(&nodes[0], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + 1);
+       check_closed_broadcast!(&nodes[0], true);
+       assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty());
+
+       get_monitor!(nodes[0], chan_id).provide_payment_preimage(
+               &payment_hash, &payment_preimage, &node_cfgs[0].tx_broadcaster,
+               &LowerBoundedFeeEstimator::new(node_cfgs[0].fee_estimator), &nodes[0].logger
+       );
+
+       let mut holder_events = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events();
+       assert_eq!(holder_events.len(), 1);
+       let (commitment_tx, anchor_tx) = match holder_events.pop().unwrap() {
+               Event::BumpTransaction(BumpTransactionEvent::ChannelClose { commitment_tx, anchor_descriptor, .. })  => {
+                       assert_eq!(commitment_tx.input.len(), 1);
+                       assert_eq!(commitment_tx.output.len(), 6);
+                       let mut anchor_tx = Transaction {
+                               version: 2,
+                               lock_time: PackedLockTime::ZERO,
+                               input: vec![
+                                       TxIn { previous_output: anchor_descriptor.outpoint, ..Default::default() },
+                                       TxIn { ..Default::default() },
+                               ],
+                               output: vec![TxOut {
+                                       value: Amount::ONE_BTC.to_sat(),
+                                       script_pubkey: Script::new_op_return(&[]),
+                               }],
+                       };
+                       let signer = nodes[0].keys_manager.derive_channel_keys(
+                               anchor_descriptor.channel_value_satoshis, &anchor_descriptor.channel_keys_id,
+                       );
+                       let funding_sig = signer.sign_holder_anchor_input(&mut anchor_tx, 0, &secp).unwrap();
+                       anchor_tx.input[0].witness = chan_utils::build_anchor_input_witness(
+                               &signer.pubkeys().funding_pubkey, &funding_sig
+                       );
+                       (commitment_tx, anchor_tx)
+               },
+               _ => panic!("Unexpected event"),
+       };
+
+       mine_transactions(&nodes[0], &[&commitment_tx, &anchor_tx]);
+       check_added_monitors!(nodes[0], 1);
+
+       let mut holder_events = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events();
+       // Certain block `ConnectStyle`s cause an extra `ChannelClose` event to be emitted since the
+       // best block is being updated prior to the confirmed transactions.
+       match *nodes[0].connect_style.borrow() {
+               ConnectStyle::BestBlockFirst|ConnectStyle::BestBlockFirstReorgsOnlyTip|ConnectStyle::BestBlockFirstSkippingBlocks => {
+                       assert_eq!(holder_events.len(), 3);
+                       if let Event::BumpTransaction(BumpTransactionEvent::ChannelClose { .. }) = holder_events.remove(0) {}
+                       else { panic!("unexpected event"); }
+
+               },
+               _ => assert_eq!(holder_events.len(), 2),
+       };
+       let mut htlc_txs = Vec::with_capacity(2);
+       for event in holder_events {
+               match event {
+                       Event::BumpTransaction(BumpTransactionEvent::HTLCResolution { htlc_descriptors, .. }) => {
+                               assert_eq!(htlc_descriptors.len(), 1);
+                               let htlc_descriptor = &htlc_descriptors[0];
+                               let signer = nodes[0].keys_manager.derive_channel_keys(
+                                       htlc_descriptor.channel_value_satoshis, &htlc_descriptor.channel_keys_id
+                               );
+                               let per_commitment_point = signer.get_per_commitment_point(htlc_descriptor.per_commitment_number, &secp);
+                               let mut htlc_tx = Transaction {
+                                       version: 2,
+                                       lock_time: if htlc_descriptor.htlc.offered {
+                                               PackedLockTime(htlc_descriptor.htlc.cltv_expiry)
+                                       } else {
+                                               PackedLockTime::ZERO
+                                       },
+                                       input: vec![
+                                               htlc_descriptor.unsigned_tx_input(), // HTLC input
+                                               TxIn { ..Default::default() } // Fee input
+                                       ],
+                                       output: vec![
+                                               htlc_descriptor.tx_output(&per_commitment_point, &secp), // HTLC output
+                                               TxOut { // Fee input change
+                                                       value: Amount::ONE_BTC.to_sat(),
+                                                       script_pubkey: Script::new_op_return(&[]),
+                                               }
+                                       ]
+                               };
+                               let our_sig = signer.sign_holder_htlc_transaction(&mut htlc_tx, 0, htlc_descriptor, &secp).unwrap();
+                               let witness_script = htlc_descriptor.witness_script(&per_commitment_point, &secp);
+                               htlc_tx.input[0].witness = htlc_descriptor.tx_input_witness(&our_sig, &witness_script);
+                               htlc_txs.push(htlc_tx);
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       }
+
+       mine_transactions(&nodes[0], &[&htlc_txs[0], &htlc_txs[1]]);
+       connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
+
+       assert!(nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
+
+       connect_blocks(&nodes[0], BREAKDOWN_TIMEOUT as u32);
+
+       let holder_events = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events();
+       assert_eq!(holder_events.len(), 3);
+       for event in holder_events {
+               match event {
+                       Event::SpendableOutputs { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+       }
+
+       // Clear the remaining events as they're not relevant to what we're testing.
+       nodes[0].node.get_and_clear_pending_events();
+}
index 1478f8b6bfb8272795dcd06d8272db926876a959..6e49a46f08a02a25065652e28cf3895afc031fe8 100644 (file)
 //! For a normal node you probably don't need to use anything here, however, if you wish to split a
 //! node into an internet-facing route/message socket handling daemon and a separate daemon (or
 //! server entirely) which handles only channel-related messages you may wish to implement
-//! ChannelMessageHandler yourself and use it to re-serialize messages and pass them across
+//! [`ChannelMessageHandler`] yourself and use it to re-serialize messages and pass them across
 //! daemons/servers.
 //!
 //! Note that if you go with such an architecture (instead of passing raw socket events to a
 //! non-internet-facing system) you trust the frontend internet-facing system to not lie about the
-//! source node_id of the message, however this does allow you to significantly reduce bandwidth
+//! source `node_id` of the message, however this does allow you to significantly reduce bandwidth
 //! between the systems as routing messages can represent a significant chunk of bandwidth usage
 //! (especially for non-channel-publicly-announcing nodes). As an alternate design which avoids
 //! this issue, if you have sufficient bidirectional bandwidth between your systems, you may send
@@ -46,6 +46,8 @@ use crate::util::ser::{LengthReadable, Readable, ReadableArgs, Writeable, Writer
 
 use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 
+use crate::routing::gossip::NodeId;
+
 /// 21 million * 10^8 * 1000
 pub(crate) const MAX_VALUE_MSAT: u64 = 21_000_000_0000_0000_000;
 
@@ -53,37 +55,46 @@ pub(crate) const MAX_VALUE_MSAT: u64 = 21_000_000_0000_0000_000;
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum DecodeError {
        /// A version byte specified something we don't know how to handle.
-       /// Includes unknown realm byte in an OnionHopData packet
+       ///
+       /// Includes unknown realm byte in an onion hop data packet.
        UnknownVersion,
-       /// Unknown feature mandating we fail to parse message (eg TLV with an even, unknown type)
+       /// Unknown feature mandating we fail to parse message (e.g., TLV with an even, unknown type)
        UnknownRequiredFeature,
-       /// Value was invalid, eg a byte which was supposed to be a bool was something other than a 0
+       /// Value was invalid.
+       ///
+       /// For example, a byte which was supposed to be a bool was something other than a 0
        /// or 1, a public key/private key/signature was invalid, text wasn't UTF-8, TLV was
-       /// syntactically incorrect, etc
+       /// syntactically incorrect, etc.
        InvalidValue,
-       /// Buffer too short
+       /// The buffer to be read was too short.
        ShortRead,
-       /// A length descriptor in the packet didn't describe the later data correctly
+       /// A length descriptor in the packet didn't describe the later data correctly.
        BadLengthDescriptor,
-       /// Error from std::io
+       /// Error from [`std::io`].
        Io(io::ErrorKind),
        /// The message included zlib-compressed values, which we don't support.
        UnsupportedCompression,
 }
 
-/// An init message to be sent or received from a peer
+/// An [`init`] message to be sent to or received from a peer.
+///
+/// [`init`]: https://github.com/lightning/bolts/blob/master/01-messaging.md#the-init-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Init {
-       /// The relevant features which the sender supports
+       /// The relevant features which the sender supports.
        pub features: InitFeatures,
-       /// The receipient's network address. This adds the option to report a remote IP address
-       /// back to a connecting peer using the init message. A node can decide to use that information
-       /// to discover a potential update to its public IPv4 address (NAT) and use
-       /// that for a node_announcement update message containing the new address.
+       /// The receipient's network address.
+       ///
+       /// This adds the option to report a remote IP address back to a connecting peer using the init
+       /// message. A node can decide to use that information to discover a potential update to its
+       /// public IPv4 address (NAT) and use that for a [`NodeAnnouncement`] update message containing
+       /// the new address.
        pub remote_network_address: Option<NetAddress>,
 }
 
-/// An error message to be sent or received from a peer
+/// An [`error`] message to be sent to or received from a peer.
+///
+/// [`error`]: https://github.com/lightning/bolts/blob/master/01-messaging.md#the-error-and-warning-messages
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ErrorMessage {
        /// The channel ID involved in the error.
@@ -92,13 +103,16 @@ pub struct ErrorMessage {
        /// with the sending peer should be closed.
        pub channel_id: [u8; 32],
        /// A possibly human-readable error description.
-       /// The string should be sanitized before it is used (e.g. emitted to logs or printed to
-       /// stdout). Otherwise, a well crafted error message may trigger a security vulnerability in
+       ///
+       /// The string should be sanitized before it is used (e.g., emitted to logs or printed to
+       /// `stdout`). Otherwise, a well crafted error message may trigger a security vulnerability in
        /// the terminal emulator or the logging subsystem.
        pub data: String,
 }
 
-/// A warning message to be sent or received from a peer
+/// A [`warning`] message to be sent to or received from a peer.
+///
+/// [`warning`]: https://github.com/lightning/bolts/blob/master/01-messaging.md#the-error-and-warning-messages
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct WarningMessage {
        /// The channel ID involved in the warning.
@@ -106,31 +120,40 @@ pub struct WarningMessage {
        /// All-0s indicates a warning unrelated to a specific channel.
        pub channel_id: [u8; 32],
        /// A possibly human-readable warning description.
+       ///
        /// The string should be sanitized before it is used (e.g. emitted to logs or printed to
        /// stdout). Otherwise, a well crafted error message may trigger a security vulnerability in
        /// the terminal emulator or the logging subsystem.
        pub data: String,
 }
 
-/// A ping message to be sent or received from a peer
+/// A [`ping`] message to be sent to or received from a peer.
+///
+/// [`ping`]: https://github.com/lightning/bolts/blob/master/01-messaging.md#the-ping-and-pong-messages
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Ping {
-       /// The desired response length
+       /// The desired response length.
        pub ponglen: u16,
        /// The ping packet size.
+       ///
        /// This field is not sent on the wire. byteslen zeros are sent.
        pub byteslen: u16,
 }
 
-/// A pong message to be sent or received from a peer
+/// A [`pong`] message to be sent to or received from a peer.
+///
+/// [`pong`]: https://github.com/lightning/bolts/blob/master/01-messaging.md#the-ping-and-pong-messages
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Pong {
        /// The pong packet size.
+       ///
        /// This field is not sent on the wire. byteslen zeros are sent.
        pub byteslen: u16,
 }
 
-/// An open_channel message to be sent or received from a peer
+/// An [`open_channel`] message to be sent to or received from a peer.
+///
+/// [`open_channel`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-open_channel-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct OpenChannel {
        /// The genesis hash of the blockchain where the channel is to be opened
@@ -149,9 +172,11 @@ pub struct OpenChannel {
        pub channel_reserve_satoshis: u64,
        /// The minimum HTLC size incoming to sender, in milli-satoshi
        pub htlc_minimum_msat: u64,
-       /// The feerate per 1000-weight of sender generated transactions, until updated by update_fee
+       /// The feerate per 1000-weight of sender generated transactions, until updated by
+       /// [`UpdateFee`]
        pub feerate_per_kw: u32,
-       /// The number of blocks which the counterparty will have to wait to claim on-chain funds if they broadcast a commitment transaction
+       /// The number of blocks which the counterparty will have to wait to claim on-chain funds if
+       /// they broadcast a commitment transaction
        pub to_self_delay: u16,
        /// The maximum number of inbound HTLCs towards sender
        pub max_accepted_htlcs: u16,
@@ -167,17 +192,20 @@ pub struct OpenChannel {
        pub htlc_basepoint: PublicKey,
        /// The first to-be-broadcast-by-sender transaction's per commitment point
        pub first_per_commitment_point: PublicKey,
-       /// Channel flags
+       /// The channel flags to be used
        pub channel_flags: u8,
-       /// Optionally, a request to pre-set the to-sender output's scriptPubkey for when we collaboratively close
+       /// Optionally, a request to pre-set the to-sender output's `scriptPubkey` for when we collaboratively close
        pub shutdown_scriptpubkey: OptionalField<Script>,
-       /// The channel type that this channel will represent. If none is set, we derive the channel
-       /// type from the intersection of our feature bits with our counterparty's feature bits from
-       /// the Init message.
+       /// The channel type that this channel will represent
+       ///
+       /// If this is `None`, we derive the channel type from the intersection of our
+       /// feature bits with our counterparty's feature bits from the [`Init`] message.
        pub channel_type: Option<ChannelTypeFeatures>,
 }
 
-/// An accept_channel message to be sent or received from a peer
+/// An [`accept_channel`] message to be sent to or received from a peer.
+///
+/// [`accept_channel`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-accept_channel-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct AcceptChannel {
        /// A temporary channel ID, until the funding outpoint is announced
@@ -210,15 +238,17 @@ pub struct AcceptChannel {
        pub first_per_commitment_point: PublicKey,
        /// Optionally, a request to pre-set the to-sender output's scriptPubkey for when we collaboratively close
        pub shutdown_scriptpubkey: OptionalField<Script>,
-       /// The channel type that this channel will represent. If none is set, we derive the channel
-       /// type from the intersection of our feature bits with our counterparty's feature bits from
-       /// the Init message.
+       /// The channel type that this channel will represent.
        ///
+       /// If this is `None`, we derive the channel type from the intersection of
+       /// our feature bits with our counterparty's feature bits from the [`Init`] message.
        /// This is required to match the equivalent field in [`OpenChannel::channel_type`].
        pub channel_type: Option<ChannelTypeFeatures>,
 }
 
-/// A funding_created message to be sent or received from a peer
+/// A [`funding_created`] message to be sent to or received from a peer.
+///
+/// [`funding_created`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-funding_created-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct FundingCreated {
        /// A temporary channel ID, until the funding is established
@@ -231,7 +261,9 @@ pub struct FundingCreated {
        pub signature: Signature,
 }
 
-/// A funding_signed message to be sent or received from a peer
+/// A [`funding_signed`] message to be sent to or received from a peer.
+///
+/// [`funding_signed`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-funding_signed-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct FundingSigned {
        /// The channel ID
@@ -240,29 +272,37 @@ pub struct FundingSigned {
        pub signature: Signature,
 }
 
-/// A channel_ready message to be sent or received from a peer
+/// A [`channel_ready`] message to be sent to or received from a peer.
+///
+/// [`channel_ready`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-channel_ready-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelReady {
        /// The channel ID
        pub channel_id: [u8; 32],
        /// The per-commitment point of the second commitment transaction
        pub next_per_commitment_point: PublicKey,
-       /// If set, provides a short_channel_id alias for this channel. The sender will accept payments
-       /// to be forwarded over this SCID and forward them to this messages' recipient.
+       /// If set, provides a `short_channel_id` alias for this channel.
+       ///
+       /// The sender will accept payments to be forwarded over this SCID and forward them to this
+       /// messages' recipient.
        pub short_channel_id_alias: Option<u64>,
 }
 
-/// A shutdown message to be sent or received from a peer
+/// A [`shutdown`] message to be sent to or received from a peer.
+///
+/// [`shutdown`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#closing-initiation-shutdown
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Shutdown {
        /// The channel ID
        pub channel_id: [u8; 32],
        /// The destination of this peer's funds on closing.
-       /// Must be in one of these forms: p2pkh, p2sh, p2wpkh, p2wsh.
+       ///
+       /// Must be in one of these forms: P2PKH, P2SH, P2WPKH, P2WSH, P2TR.
        pub scriptpubkey: Script,
 }
 
 /// The minimum and maximum fees which the sender is willing to place on the closing transaction.
+///
 /// This is provided in [`ClosingSigned`] by both sides to indicate the fee range they are willing
 /// to use.
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -275,7 +315,9 @@ pub struct ClosingSignedFeeRange {
        pub max_fee_satoshis: u64,
 }
 
-/// A closing_signed message to be sent or received from a peer
+/// A [`closing_signed`] message to be sent to or received from a peer.
+///
+/// [`closing_signed`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#closing-negotiation-closing_signed
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ClosingSigned {
        /// The channel ID
@@ -289,7 +331,9 @@ pub struct ClosingSigned {
        pub fee_range: Option<ClosingSignedFeeRange>,
 }
 
-/// An update_add_htlc message to be sent or received from a peer
+/// An [`update_add_htlc`] message to be sent to or received from a peer.
+///
+/// [`update_add_htlc`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#adding-an-htlc-update_add_htlc
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateAddHTLC {
        /// The channel ID
@@ -305,7 +349,9 @@ pub struct UpdateAddHTLC {
        pub(crate) onion_routing_packet: OnionPacket,
 }
 
- /// An onion message to be sent or received from a peer
+ /// An onion message to be sent to or received from a peer.
+ ///
+ // TODO: update with link to OM when they are merged into the BOLTs
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct OnionMessage {
        /// Used in decrypting the onion packet's payload.
@@ -313,7 +359,9 @@ pub struct OnionMessage {
        pub(crate) onion_routing_packet: onion_message::Packet,
 }
 
-/// An update_fulfill_htlc message to be sent or received from a peer
+/// An [`update_fulfill_htlc`] message to be sent to or received from a peer.
+///
+/// [`update_fulfill_htlc`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#removing-an-htlc-update_fulfill_htlc-update_fail_htlc-and-update_fail_malformed_htlc
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFulfillHTLC {
        /// The channel ID
@@ -324,7 +372,9 @@ pub struct UpdateFulfillHTLC {
        pub payment_preimage: PaymentPreimage,
 }
 
-/// An update_fail_htlc message to be sent or received from a peer
+/// An [`update_fail_htlc`] message to be sent to or received from a peer.
+///
+/// [`update_fail_htlc`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#removing-an-htlc-update_fulfill_htlc-update_fail_htlc-and-update_fail_malformed_htlc
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFailHTLC {
        /// The channel ID
@@ -334,7 +384,9 @@ pub struct UpdateFailHTLC {
        pub(crate) reason: OnionErrorPacket,
 }
 
-/// An update_fail_malformed_htlc message to be sent or received from a peer
+/// An [`update_fail_malformed_htlc`] message to be sent to or received from a peer.
+///
+/// [`update_fail_malformed_htlc`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#removing-an-htlc-update_fulfill_htlc-update_fail_htlc-and-update_fail_malformed_htlc
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFailMalformedHTLC {
        /// The channel ID
@@ -346,7 +398,9 @@ pub struct UpdateFailMalformedHTLC {
        pub failure_code: u16,
 }
 
-/// A commitment_signed message to be sent or received from a peer
+/// A [`commitment_signed`] message to be sent to or received from a peer.
+///
+/// [`commitment_signed`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#committing-updates-so-far-commitment_signed
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct CommitmentSigned {
        /// The channel ID
@@ -357,7 +411,9 @@ pub struct CommitmentSigned {
        pub htlc_signatures: Vec<Signature>,
 }
 
-/// A revoke_and_ack message to be sent or received from a peer
+/// A [`revoke_and_ack`] message to be sent to or received from a peer.
+///
+/// [`revoke_and_ack`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#completing-the-transition-to-the-updated-state-revoke_and_ack
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct RevokeAndACK {
        /// The channel ID
@@ -368,7 +424,9 @@ pub struct RevokeAndACK {
        pub next_per_commitment_point: PublicKey,
 }
 
-/// An update_fee message to be sent or received from a peer
+/// An [`update_fee`] message to be sent to or received from a peer
+///
+/// [`update_fee`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#updating-fees-update_fee
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFee {
        /// The channel ID
@@ -379,8 +437,9 @@ pub struct UpdateFee {
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 /// Proof that the sender knows the per-commitment secret of the previous commitment transaction.
+///
 /// This is used to convince the recipient that the channel is at a certain commitment
-/// number even if they lost that data due to a local failure.  Of course, the peer may lie
+/// number even if they lost that data due to a local failure. Of course, the peer may lie
 /// and even later commitments may have been revoked.
 pub struct DataLossProtect {
        /// Proof that the sender knows the per-commitment secret of a specific commitment transaction
@@ -390,7 +449,9 @@ pub struct DataLossProtect {
        pub my_current_per_commitment_point: PublicKey,
 }
 
-/// A channel_reestablish message to be sent or received from a peer
+/// A [`channel_reestablish`] message to be sent to or received from a peer.
+///
+/// [`channel_reestablish`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#message-retransmission
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelReestablish {
        /// The channel ID
@@ -403,7 +464,9 @@ pub struct ChannelReestablish {
        pub data_loss_protect: OptionalField<DataLossProtect>,
 }
 
-/// An announcement_signatures message to be sent or received from a peer
+/// An [`announcement_signatures`] message to be sent to or received from a peer.
+///
+/// [`announcement_signatures`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-announcement_signatures-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct AnnouncementSignatures {
        /// The channel ID
@@ -416,7 +479,7 @@ pub struct AnnouncementSignatures {
        pub bitcoin_signature: Signature,
 }
 
-/// An address which can be used to connect to a remote peer
+/// An address which can be used to connect to a remote peer.
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum NetAddress {
        /// An IPv4 address/port on which the peer is listening.
@@ -439,7 +502,8 @@ pub enum NetAddress {
        /// addresses. Thus, the details are not parsed here.
        OnionV2([u8; 12]),
        /// A new-style Tor onion address/port on which the peer is listening.
-       /// To create the human-readable "hostname", concatenate ed25519_pubkey, checksum, and version,
+       ///
+       /// To create the human-readable "hostname", concatenate the ED25519 pubkey, checksum, and version,
        /// wrap as base32 and append ".onion".
        OnionV3 {
                /// The ed25519 long-term public key of the peer
@@ -460,7 +524,7 @@ pub enum NetAddress {
        },
 }
 impl NetAddress {
-       /// Gets the ID of this address type. Addresses in node_announcement messages should be sorted
+       /// Gets the ID of this address type. Addresses in [`NodeAnnouncement`] messages should be sorted
        /// by this.
        pub(crate) fn get_id(&self) -> u8 {
                match self {
@@ -570,21 +634,43 @@ impl Readable for NetAddress {
        }
 }
 
+/// Represents the set of gossip messages that require a signature from a node's identity key.
+pub enum UnsignedGossipMessage<'a> {
+       /// An unsigned channel announcement.
+       ChannelAnnouncement(&'a UnsignedChannelAnnouncement),
+       /// An unsigned channel update.
+       ChannelUpdate(&'a UnsignedChannelUpdate),
+       /// An unsigned node announcement.
+       NodeAnnouncement(&'a UnsignedNodeAnnouncement)
+}
 
-/// The unsigned part of a node_announcement
+impl<'a> Writeable for UnsignedGossipMessage<'a> {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               match self {
+                       UnsignedGossipMessage::ChannelAnnouncement(ref msg) => msg.write(writer),
+                       UnsignedGossipMessage::ChannelUpdate(ref msg) => msg.write(writer),
+                       UnsignedGossipMessage::NodeAnnouncement(ref msg) => msg.write(writer),
+               }
+       }
+}
+
+/// The unsigned part of a [`node_announcement`] message.
+///
+/// [`node_announcement`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-node_announcement-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UnsignedNodeAnnouncement {
        /// The advertised features
        pub features: NodeFeatures,
        /// A strictly monotonic announcement counter, with gaps allowed
        pub timestamp: u32,
-       /// The node_id this announcement originated from (don't rebroadcast the node_announcement back
+       /// The `node_id` this announcement originated from (don't rebroadcast the `node_announcement` back
        /// to this node).
-       pub node_id: PublicKey,
+       pub node_id: NodeId,
        /// An RGB color for UI purposes
        pub rgb: [u8; 3],
-       /// An alias, for UI purposes.  This should be sanitized before use.  There is no guarantee
-       /// of uniqueness.
+       /// An alias, for UI purposes.
+       ///
+       /// This should be sanitized before use. There is no guarantee of uniqueness.
        pub alias: [u8; 32],
        /// List of addresses on which this node is reachable
        pub addresses: Vec<NetAddress>,
@@ -592,7 +678,9 @@ pub struct UnsignedNodeAnnouncement {
        pub(crate) excess_data: Vec<u8>,
 }
 #[derive(Clone, Debug, PartialEq, Eq)]
-/// A node_announcement message to be sent or received from a peer
+/// A [`node_announcement`] message to be sent to or received from a peer.
+///
+/// [`node_announcement`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-node_announcement-message
 pub struct NodeAnnouncement {
        /// The signature by the node key
        pub signature: Signature,
@@ -600,7 +688,9 @@ pub struct NodeAnnouncement {
        pub contents: UnsignedNodeAnnouncement,
 }
 
-/// The unsigned part of a channel_announcement
+/// The unsigned part of a [`channel_announcement`] message.
+///
+/// [`channel_announcement`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-channel_announcement-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UnsignedChannelAnnouncement {
        /// The advertised channel features
@@ -609,17 +699,19 @@ pub struct UnsignedChannelAnnouncement {
        pub chain_hash: BlockHash,
        /// The short channel ID
        pub short_channel_id: u64,
-       /// One of the two node_ids which are endpoints of this channel
-       pub node_id_1: PublicKey,
-       /// The other of the two node_ids which are endpoints of this channel
-       pub node_id_2: PublicKey,
+       /// One of the two `node_id`s which are endpoints of this channel
+       pub node_id_1: NodeId,
+       /// The other of the two `node_id`s which are endpoints of this channel
+       pub node_id_2: NodeId,
        /// The funding key for the first node
-       pub bitcoin_key_1: PublicKey,
+       pub bitcoin_key_1: NodeId,
        /// The funding key for the second node
-       pub bitcoin_key_2: PublicKey,
+       pub bitcoin_key_2: NodeId,
        pub(crate) excess_data: Vec<u8>,
 }
-/// A channel_announcement message to be sent or received from a peer
+/// A [`channel_announcement`] message to be sent to or received from a peer.
+///
+/// [`channel_announcement`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-channel_announcement-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelAnnouncement {
        /// Authentication of the announcement by the first public node
@@ -634,7 +726,9 @@ pub struct ChannelAnnouncement {
        pub contents: UnsignedChannelAnnouncement,
 }
 
-/// The unsigned part of a channel_update
+/// The unsigned part of a [`channel_update`] message.
+///
+/// [`channel_update`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-channel_update-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UnsignedChannelUpdate {
        /// The genesis hash of the blockchain where the channel is to be opened
@@ -647,27 +741,32 @@ pub struct UnsignedChannelUpdate {
        pub flags: u8,
        /// The number of blocks such that if:
        /// `incoming_htlc.cltv_expiry < outgoing_htlc.cltv_expiry + cltv_expiry_delta`
-       /// then we need to fail the HTLC backwards. When forwarding an HTLC, cltv_expiry_delta determines
-       /// the outgoing HTLC's minimum cltv_expiry value -- so, if an incoming HTLC comes in with a
-       /// cltv_expiry of 100000, and the node we're forwarding to has a cltv_expiry_delta value of 10,
-       /// then we'll check that the outgoing HTLC's cltv_expiry value is at least 100010 before
+       /// then we need to fail the HTLC backwards. When forwarding an HTLC, `cltv_expiry_delta` determines
+       /// the outgoing HTLC's minimum `cltv_expiry` value -- so, if an incoming HTLC comes in with a
+       /// `cltv_expiry` of 100000, and the node we're forwarding to has a `cltv_expiry_delta` value of 10,
+       /// then we'll check that the outgoing HTLC's `cltv_expiry` value is at least 100010 before
        /// forwarding. Note that the HTLC sender is the one who originally sets this value when
        /// constructing the route.
        pub cltv_expiry_delta: u16,
        /// The minimum HTLC size incoming to sender, in milli-satoshi
        pub htlc_minimum_msat: u64,
-       /// The maximum HTLC value incoming to sender, in milli-satoshi. Used to be optional.
+       /// The maximum HTLC value incoming to sender, in milli-satoshi.
+       ///
+       /// This used to be optional.
        pub htlc_maximum_msat: u64,
        /// The base HTLC fee charged by sender, in milli-satoshi
        pub fee_base_msat: u32,
        /// The amount to fee multiplier, in micro-satoshi
        pub fee_proportional_millionths: u32,
        /// Excess data which was signed as a part of the message which we do not (yet) understand how
-       /// to decode. This is stored to ensure forward-compatibility as new fields are added to the
-       /// lightning gossip
+       /// to decode.
+       ///
+       /// This is stored to ensure forward-compatibility as new fields are added to the lightning gossip protocol.
        pub excess_data: Vec<u8>,
 }
-/// A channel_update message to be sent or received from a peer
+/// A [`channel_update`] message to be sent to or received from a peer.
+///
+/// [`channel_update`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-channel_update-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelUpdate {
        /// A signature of the channel update
@@ -676,10 +775,12 @@ pub struct ChannelUpdate {
        pub contents: UnsignedChannelUpdate,
 }
 
-/// A query_channel_range message is used to query a peer for channel
+/// A [`query_channel_range`] message is used to query a peer for channel
 /// UTXOs in a range of blocks. The recipient of a query makes a best
-/// effort to reply to the query using one or more reply_channel_range
+/// effort to reply to the query using one or more [`ReplyChannelRange`]
 /// messages.
+///
+/// [`query_channel_range`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-query_channel_range-and-reply_channel_range-messages
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct QueryChannelRange {
        /// The genesis hash of the blockchain being queried
@@ -690,13 +791,17 @@ pub struct QueryChannelRange {
        pub number_of_blocks: u32,
 }
 
-/// A reply_channel_range message is a reply to a query_channel_range
-/// message. Multiple reply_channel_range messages can be sent in reply
-/// to a single query_channel_range message. The query recipient makes a
+/// A [`reply_channel_range`] message is a reply to a [`QueryChannelRange`]
+/// message.
+///
+/// Multiple `reply_channel_range` messages can be sent in reply
+/// to a single [`QueryChannelRange`] message. The query recipient makes a
 /// best effort to respond based on their local network view which may
-/// not be a perfect view of the network. The short_channel_ids in the
-/// reply are encoded. We only support encoding_type=0 uncompressed
-/// serialization and do not support encoding_type=1 zlib serialization.
+/// not be a perfect view of the network. The `short_channel_id`s in the
+/// reply are encoded. We only support `encoding_type=0` uncompressed
+/// serialization and do not support `encoding_type=1` zlib serialization.
+///
+/// [`reply_channel_range`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-query_channel_range-and-reply_channel_range-messages
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ReplyChannelRange {
        /// The genesis hash of the blockchain being queried
@@ -707,18 +812,21 @@ pub struct ReplyChannelRange {
        pub number_of_blocks: u32,
        /// True when this is the final reply for a query
        pub sync_complete: bool,
-       /// The short_channel_ids in the channel range
+       /// The `short_channel_id`s in the channel range
        pub short_channel_ids: Vec<u64>,
 }
 
-/// A query_short_channel_ids message is used to query a peer for
-/// routing gossip messages related to one or more short_channel_ids.
+/// A [`query_short_channel_ids`] message is used to query a peer for
+/// routing gossip messages related to one or more `short_channel_id`s.
+///
 /// The query recipient will reply with the latest, if available,
-/// channel_announcement, channel_update and node_announcement messages
-/// it maintains for the requested short_channel_ids followed by a
-/// reply_short_channel_ids_end message. The short_channel_ids sent in
-/// this query are encoded. We only support encoding_type=0 uncompressed
-/// serialization and do not support encoding_type=1 zlib serialization.
+/// [`ChannelAnnouncement`], [`ChannelUpdate`] and [`NodeAnnouncement`] messages
+/// it maintains for the requested `short_channel_id`s followed by a
+/// [`ReplyShortChannelIdsEnd`] message. The `short_channel_id`s sent in
+/// this query are encoded. We only support `encoding_type=0` uncompressed
+/// serialization and do not support `encoding_type=1` zlib serialization.
+///
+/// [`query_short_channel_ids`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-query_short_channel_idsreply_short_channel_ids_end-messages
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct QueryShortChannelIds {
        /// The genesis hash of the blockchain being queried
@@ -727,22 +835,26 @@ pub struct QueryShortChannelIds {
        pub short_channel_ids: Vec<u64>,
 }
 
-/// A reply_short_channel_ids_end message is sent as a reply to a
-/// query_short_channel_ids message. The query recipient makes a best
+/// A [`reply_short_channel_ids_end`] message is sent as a reply to a
+/// message. The query recipient makes a best
 /// effort to respond based on their local network view which may not be
 /// a perfect view of the network.
+///
+/// [`reply_short_channel_ids_end`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-query_short_channel_idsreply_short_channel_ids_end-messages
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ReplyShortChannelIdsEnd {
        /// The genesis hash of the blockchain that was queried
        pub chain_hash: BlockHash,
        /// Indicates if the query recipient maintains up-to-date channel
-       /// information for the chain_hash
+       /// information for the `chain_hash`
        pub full_information: bool,
 }
 
-/// A gossip_timestamp_filter message is used by a node to request
+/// A [`gossip_timestamp_filter`] message is used by a node to request
 /// gossip relay for messages in the requested time range when the
-/// gossip_queries feature has been negotiated.
+/// `gossip_queries` feature has been negotiated.
+///
+/// [`gossip_timestamp_filter`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-gossip_timestamp_filter-message
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct GossipTimestampFilter {
        /// The genesis hash of the blockchain for channel and node information
@@ -754,12 +866,14 @@ pub struct GossipTimestampFilter {
 }
 
 /// Encoding type for data compression of collections in gossip queries.
-/// We do not support encoding_type=1 zlib serialization defined in BOLT #7.
+///
+/// We do not support `encoding_type=1` zlib serialization [defined in BOLT
+/// #7](https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#query-messages).
 enum EncodingType {
        Uncompressed = 0x00,
 }
 
-/// Used to put an error message in a LightningError
+/// Used to put an error message in a [`LightningError`].
 #[derive(Clone, Debug)]
 pub enum ErrorAction {
        /// The peer took some action which made us think they were useless. Disconnect them.
@@ -802,29 +916,30 @@ pub struct LightningError {
        pub action: ErrorAction,
 }
 
-/// Struct used to return values from revoke_and_ack messages, containing a bunch of commitment
+/// Struct used to return values from [`RevokeAndACK`] messages, containing a bunch of commitment
 /// transaction updates if they were pending.
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct CommitmentUpdate {
-       /// update_add_htlc messages which should be sent
+       /// `update_add_htlc` messages which should be sent
        pub update_add_htlcs: Vec<UpdateAddHTLC>,
-       /// update_fulfill_htlc messages which should be sent
+       /// `update_fulfill_htlc` messages which should be sent
        pub update_fulfill_htlcs: Vec<UpdateFulfillHTLC>,
-       /// update_fail_htlc messages which should be sent
+       /// `update_fail_htlc` messages which should be sent
        pub update_fail_htlcs: Vec<UpdateFailHTLC>,
-       /// update_fail_malformed_htlc messages which should be sent
+       /// `update_fail_malformed_htlc` messages which should be sent
        pub update_fail_malformed_htlcs: Vec<UpdateFailMalformedHTLC>,
-       /// An update_fee message which should be sent
+       /// An `update_fee` message which should be sent
        pub update_fee: Option<UpdateFee>,
-       /// Finally, the commitment_signed message which should be sent
+       /// A `commitment_signed` message which should be sent
        pub commitment_signed: CommitmentSigned,
 }
 
 /// Messages could have optional fields to use with extended features
-/// As we wish to serialize these differently from Option<T>s (Options get a tag byte, but
-/// OptionalFeild simply gets Present if there are enough bytes to read into it), we have a
+/// As we wish to serialize these differently from `Option<T>`s (`Options` get a tag byte, but
+/// [`OptionalField`] simply gets `Present` if there are enough bytes to read into it), we have a
 /// separate enum type for them.
-/// (C-not exported) due to a free generic in T
+///
+/// (C-not exported) due to a free generic in `T`
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum OptionalField<T> {
        /// Optional field is included in message
@@ -835,72 +950,66 @@ pub enum OptionalField<T> {
 
 /// A trait to describe an object which can receive channel messages.
 ///
-/// Messages MAY be called in parallel when they originate from different their_node_ids, however
-/// they MUST NOT be called in parallel when the two calls have the same their_node_id.
+/// Messages MAY be called in parallel when they originate from different `their_node_ids`, however
+/// they MUST NOT be called in parallel when the two calls have the same `their_node_id`.
 pub trait ChannelMessageHandler : MessageSendEventsProvider {
-       //Channel init:
-       /// Handle an incoming open_channel message from the given peer.
-       fn handle_open_channel(&self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &OpenChannel);
-       /// Handle an incoming accept_channel message from the given peer.
-       fn handle_accept_channel(&self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &AcceptChannel);
-       /// Handle an incoming funding_created message from the given peer.
+       // Channel init:
+       /// Handle an incoming `open_channel` message from the given peer.
+       fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &OpenChannel);
+       /// Handle an incoming `accept_channel` message from the given peer.
+       fn handle_accept_channel(&self, their_node_id: &PublicKey, msg: &AcceptChannel);
+       /// Handle an incoming `funding_created` message from the given peer.
        fn handle_funding_created(&self, their_node_id: &PublicKey, msg: &FundingCreated);
-       /// Handle an incoming funding_signed message from the given peer.
+       /// Handle an incoming `funding_signed` message from the given peer.
        fn handle_funding_signed(&self, their_node_id: &PublicKey, msg: &FundingSigned);
-       /// Handle an incoming channel_ready message from the given peer.
+       /// Handle an incoming `channel_ready` message from the given peer.
        fn handle_channel_ready(&self, their_node_id: &PublicKey, msg: &ChannelReady);
 
        // Channl close:
-       /// Handle an incoming shutdown message from the given peer.
-       fn handle_shutdown(&self, their_node_id: &PublicKey, their_features: &InitFeatures, msg: &Shutdown);
-       /// Handle an incoming closing_signed message from the given peer.
+       /// Handle an incoming `shutdown` message from the given peer.
+       fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &Shutdown);
+       /// Handle an incoming `closing_signed` message from the given peer.
        fn handle_closing_signed(&self, their_node_id: &PublicKey, msg: &ClosingSigned);
 
        // HTLC handling:
-       /// Handle an incoming update_add_htlc message from the given peer.
+       /// Handle an incoming `update_add_htlc` message from the given peer.
        fn handle_update_add_htlc(&self, their_node_id: &PublicKey, msg: &UpdateAddHTLC);
-       /// Handle an incoming update_fulfill_htlc message from the given peer.
+       /// Handle an incoming `update_fulfill_htlc` message from the given peer.
        fn handle_update_fulfill_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFulfillHTLC);
-       /// Handle an incoming update_fail_htlc message from the given peer.
+       /// Handle an incoming `update_fail_htlc` message from the given peer.
        fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailHTLC);
-       /// Handle an incoming update_fail_malformed_htlc message from the given peer.
+       /// Handle an incoming `update_fail_malformed_htlc` message from the given peer.
        fn handle_update_fail_malformed_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailMalformedHTLC);
-       /// Handle an incoming commitment_signed message from the given peer.
+       /// Handle an incoming `commitment_signed` message from the given peer.
        fn handle_commitment_signed(&self, their_node_id: &PublicKey, msg: &CommitmentSigned);
-       /// Handle an incoming revoke_and_ack message from the given peer.
+       /// Handle an incoming `revoke_and_ack` message from the given peer.
        fn handle_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &RevokeAndACK);
 
-       /// Handle an incoming update_fee message from the given peer.
+       /// Handle an incoming `update_fee` message from the given peer.
        fn handle_update_fee(&self, their_node_id: &PublicKey, msg: &UpdateFee);
 
        // Channel-to-announce:
-       /// Handle an incoming announcement_signatures message from the given peer.
+       /// Handle an incoming `announcement_signatures` message from the given peer.
        fn handle_announcement_signatures(&self, their_node_id: &PublicKey, msg: &AnnouncementSignatures);
 
        // Connection loss/reestablish:
-       /// Indicates a connection to the peer failed/an existing connection was lost. If no connection
-       /// is believed to be possible in the future (eg they're sending us messages we don't
-       /// understand or indicate they require unknown feature bits), no_connection_possible is set
-       /// and any outstanding channels should be failed.
-       ///
-       /// Note that in some rare cases this may be called without a corresponding
-       /// [`Self::peer_connected`].
-       fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool);
+       /// Indicates a connection to the peer failed/an existing connection was lost.
+       fn peer_disconnected(&self, their_node_id: &PublicKey);
 
-       /// Handle a peer reconnecting, possibly generating channel_reestablish message(s).
+       /// Handle a peer reconnecting, possibly generating `channel_reestablish` message(s).
        ///
        /// May return an `Err(())` if the features the peer supports are not sufficient to communicate
        /// with us. Implementors should be somewhat conservative about doing so, however, as other
        /// message handlers may still wish to communicate with this peer.
-       fn peer_connected(&self, their_node_id: &PublicKey, msg: &Init) -> Result<(), ()>;
-       /// Handle an incoming channel_reestablish message from the given peer.
+       fn peer_connected(&self, their_node_id: &PublicKey, msg: &Init, inbound: bool) -> Result<(), ()>;
+       /// Handle an incoming `channel_reestablish` message from the given peer.
        fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &ChannelReestablish);
 
-       /// Handle an incoming channel update from the given peer.
+       /// Handle an incoming `channel_update` message from the given peer.
        fn handle_channel_update(&self, their_node_id: &PublicKey, msg: &ChannelUpdate);
 
        // Error:
-       /// Handle an incoming error message from the given peer.
+       /// Handle an incoming `error` message from the given peer.
        fn handle_error(&self, their_node_id: &PublicKey, msg: &ErrorMessage);
 
        // Handler information:
@@ -921,28 +1030,28 @@ pub trait ChannelMessageHandler : MessageSendEventsProvider {
 ///
 /// # Implementor DoS Warnings
 ///
-/// For `gossip_queries` messages there are potential DoS vectors when handling
-/// inbound queries. Implementors using an on-disk network graph should be aware of
+/// For messages enabled with the `gossip_queries` feature there are potential DoS vectors when
+/// handling inbound queries. Implementors using an on-disk network graph should be aware of
 /// repeated disk I/O for queries accessing different parts of the network graph.
 pub trait RoutingMessageHandler : MessageSendEventsProvider {
-       /// Handle an incoming node_announcement message, returning true if it should be forwarded on,
-       /// false or returning an Err otherwise.
+       /// Handle an incoming `node_announcement` message, returning `true` if it should be forwarded on,
+       /// `false` or returning an `Err` otherwise.
        fn handle_node_announcement(&self, msg: &NodeAnnouncement) -> Result<bool, LightningError>;
-       /// Handle a channel_announcement message, returning true if it should be forwarded on, false
-       /// or returning an Err otherwise.
+       /// Handle a `channel_announcement` message, returning `true` if it should be forwarded on, `false`
+       /// or returning an `Err` otherwise.
        fn handle_channel_announcement(&self, msg: &ChannelAnnouncement) -> Result<bool, LightningError>;
-       /// Handle an incoming channel_update message, returning true if it should be forwarded on,
-       /// false or returning an Err otherwise.
+       /// Handle an incoming `channel_update` message, returning true if it should be forwarded on,
+       /// `false` or returning an `Err` otherwise.
        fn handle_channel_update(&self, msg: &ChannelUpdate) -> Result<bool, LightningError>;
        /// Gets channel announcements and updates required to dump our routing table to a remote node,
-       /// starting at the short_channel_id indicated by starting_point and including announcements
+       /// starting at the `short_channel_id` indicated by `starting_point` and including announcements
        /// for a single channel.
        fn get_next_channel_announcement(&self, starting_point: u64) -> Option<(ChannelAnnouncement, Option<ChannelUpdate>, Option<ChannelUpdate>)>;
        /// Gets a node announcement required to dump our routing table to a remote node, starting at
        /// the node *after* the provided pubkey and including up to one announcement immediately
-       /// higher (as defined by <PublicKey as Ord>::cmp) than starting_point.
-       /// If None is provided for starting_point, we start at the first node.
-       fn get_next_node_announcement(&self, starting_point: Option<&PublicKey>) -> Option<NodeAnnouncement>;
+       /// higher (as defined by `<PublicKey as Ord>::cmp`) than `starting_point`.
+       /// If `None` is provided for `starting_point`, we start at the first node.
+       fn get_next_node_announcement(&self, starting_point: Option<&NodeId>) -> Option<NodeAnnouncement>;
        /// Called when a connection is established with a peer. This can be used to
        /// perform routing table synchronization using a strategy defined by the
        /// implementor.
@@ -950,7 +1059,7 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider {
        /// May return an `Err(())` if the features the peer supports are not sufficient to communicate
        /// with us. Implementors should be somewhat conservative about doing so, however, as other
        /// message handlers may still wish to communicate with this peer.
-       fn peer_connected(&self, their_node_id: &PublicKey, init: &Init) -> Result<(), ()>;
+       fn peer_connected(&self, their_node_id: &PublicKey, init: &Init, inbound: bool) -> Result<(), ()>;
        /// Handles the reply of a query we initiated to learn about channels
        /// for a given range of blocks. We can expect to receive one or more
        /// replies to a single query.
@@ -960,13 +1069,20 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider {
        /// a node has completed its best effort to send us the pertaining routing
        /// gossip messages.
        fn handle_reply_short_channel_ids_end(&self, their_node_id: &PublicKey, msg: ReplyShortChannelIdsEnd) -> Result<(), LightningError>;
-       /// Handles when a peer asks us to send a list of short_channel_ids
+       /// Handles when a peer asks us to send a list of `short_channel_id`s
        /// for the requested range of blocks.
        fn handle_query_channel_range(&self, their_node_id: &PublicKey, msg: QueryChannelRange) -> Result<(), LightningError>;
        /// Handles when a peer asks us to send routing gossip messages for a
-       /// list of short_channel_ids.
+       /// list of `short_channel_id`s.
        fn handle_query_short_channel_ids(&self, their_node_id: &PublicKey, msg: QueryShortChannelIds) -> Result<(), LightningError>;
 
+       // Handler queueing status:
+       /// Indicates that there are a large number of [`ChannelAnnouncement`] (or other) messages
+       /// pending some async action. While there is no guarantee of the rate of future messages, the
+       /// caller should seek to reduce the rate of new gossip messages handled, especially
+       /// [`ChannelAnnouncement`]s.
+       fn processing_queue_high(&self) -> bool;
+
        // Handler information:
        /// Gets the node feature flags which this handler itself supports. All available handlers are
        /// queried similarly and their feature flags are OR'd together to form the [`NodeFeatures`]
@@ -982,7 +1098,7 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider {
 
 /// A trait to describe an object that can receive onion messages.
 pub trait OnionMessageHandler : OnionMessageProvider {
-       /// Handle an incoming onion_message message from the given peer.
+       /// Handle an incoming `onion_message` message from the given peer.
        fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &OnionMessage);
        /// Called when a connection is established with a peer. Can be used to track which peers
        /// advertise onion message support and are online.
@@ -990,13 +1106,10 @@ pub trait OnionMessageHandler : OnionMessageProvider {
        /// May return an `Err(())` if the features the peer supports are not sufficient to communicate
        /// with us. Implementors should be somewhat conservative about doing so, however, as other
        /// message handlers may still wish to communicate with this peer.
-       fn peer_connected(&self, their_node_id: &PublicKey, init: &Init) -> Result<(), ()>;
+       fn peer_connected(&self, their_node_id: &PublicKey, init: &Init, inbound: bool) -> Result<(), ()>;
        /// Indicates a connection to the peer failed/an existing connection was lost. Allows handlers to
        /// drop and refuse to forward onion messages to this peer.
-       ///
-       /// Note that in some rare cases this may be called without a corresponding
-       /// [`Self::peer_connected`].
-       fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool);
+       fn peer_disconnected(&self, their_node_id: &PublicKey);
 
        // Handler information:
        /// Gets the node feature flags which this handler itself supports. All available handlers are
@@ -1058,9 +1171,11 @@ pub(crate) use self::fuzzy_internal_msgs::*;
 #[derive(Clone)]
 pub(crate) struct OnionPacket {
        pub(crate) version: u8,
-       /// In order to ensure we always return an error on Onion decode in compliance with BOLT 4, we
-       /// have to deserialize OnionPackets contained in UpdateAddHTLCs even if the ephemeral public
-       /// key (here) is bogus, so we hold a Result instead of a PublicKey as we'd like.
+       /// In order to ensure we always return an error on onion decode in compliance with [BOLT
+       /// #4](https://github.com/lightning/bolts/blob/master/04-onion-routing.md), we have to
+       /// deserialize `OnionPacket`s contained in [`UpdateAddHTLC`] messages even if the ephemeral
+       /// public key (here) is bogus, so we hold a [`Result`] instead of a [`PublicKey`] as we'd
+       /// like.
        pub(crate) public_key: Result<PublicKey, secp256k1::Error>,
        pub(crate) hop_data: [u8; 20*65],
        pub(crate) hmac: [u8; 32],
@@ -1455,14 +1570,14 @@ impl Writeable for OnionHopData {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                match self.format {
                        OnionHopDataFormat::NonFinalNode { short_channel_id } => {
-                               encode_varint_length_prefixed_tlv!(w, {
+                               _encode_varint_length_prefixed_tlv!(w, {
                                        (2, HighZeroBytesDroppedBigSize(self.amt_to_forward), required),
                                        (4, HighZeroBytesDroppedBigSize(self.outgoing_cltv_value), required),
                                        (6, short_channel_id, required)
                                });
                        },
                        OnionHopDataFormat::FinalNode { ref payment_data, ref keysend_preimage } => {
-                               encode_varint_length_prefixed_tlv!(w, {
+                               _encode_varint_length_prefixed_tlv!(w, {
                                        (2, HighZeroBytesDroppedBigSize(self.amt_to_forward), required),
                                        (4, HighZeroBytesDroppedBigSize(self.outgoing_cltv_value), required),
                                        (8, payment_data, option),
@@ -1728,7 +1843,7 @@ impl Readable for UnsignedNodeAnnouncement {
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
                let features: NodeFeatures = Readable::read(r)?;
                let timestamp: u32 = Readable::read(r)?;
-               let node_id: PublicKey = Readable::read(r)?;
+               let node_id: NodeId = Readable::read(r)?;
                let mut rgb = [0; 3];
                r.read_exact(&mut rgb)?;
                let alias: [u8; 32] = Readable::read(r)?;
@@ -1850,10 +1965,9 @@ impl_writeable_msg!(ReplyShortChannelIdsEnd, {
 }, {});
 
 impl QueryChannelRange {
-       /**
-        * Calculates the overflow safe ending block height for the query.
-        * Overflow returns `0xffffffff`, otherwise returns `first_blocknum + number_of_blocks`
-        */
+       /// Calculates the overflow safe ending block height for the query.
+       ///
+       /// Overflow returns `0xffffffff`, otherwise returns `first_blocknum + number_of_blocks`.
        pub fn end_blocknum(&self) -> u32 {
                match self.first_blocknum.checked_add(self.number_of_blocks) {
                        Some(block) => block,
@@ -1939,6 +2053,7 @@ mod tests {
        use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
        use crate::ln::msgs;
        use crate::ln::msgs::{FinalOnionHopData, OptionalField, OnionErrorPacket, OnionHopDataFormat};
+       use crate::routing::gossip::NodeId;
        use crate::util::ser::{Writeable, Readable, Hostname};
 
        use bitcoin::hashes::hex::FromHex;
@@ -2046,10 +2161,10 @@ mod tests {
                        features,
                        chain_hash: BlockHash::from_hex("6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000").unwrap(),
                        short_channel_id: 2316138423780173,
-                       node_id_1: pubkey_1,
-                       node_id_2: pubkey_2,
-                       bitcoin_key_1: pubkey_3,
-                       bitcoin_key_2: pubkey_4,
+                       node_id_1: NodeId::from_pubkey(&pubkey_1),
+                       node_id_2: NodeId::from_pubkey(&pubkey_2),
+                       bitcoin_key_1: NodeId::from_pubkey(&pubkey_3),
+                       bitcoin_key_2: NodeId::from_pubkey(&pubkey_4),
                        excess_data: if excess_data { vec![10, 0, 0, 20, 0, 0, 30, 0, 0, 40] } else { Vec::new() },
                };
                let channel_announcement = msgs::ChannelAnnouncement {
@@ -2131,7 +2246,7 @@ mod tests {
                let unsigned_node_announcement = msgs::UnsignedNodeAnnouncement {
                        features,
                        timestamp: 20190119,
-                       node_id: pubkey_1,
+                       node_id: NodeId::from_pubkey(&pubkey_1),
                        rgb: [32; 3],
                        alias: [16;32],
                        addresses,
@@ -2875,7 +2990,7 @@ mod tests {
                let mut encoded_payload = Vec::new();
                let test_bytes = vec![42u8; 1000];
                if let OnionHopDataFormat::NonFinalNode { short_channel_id } = payload.format {
-                       encode_varint_length_prefixed_tlv!(&mut encoded_payload, {
+                       _encode_varint_length_prefixed_tlv!(&mut encoded_payload, {
                                (1, test_bytes, vec_type),
                                (2, HighZeroBytesDroppedBigSize(payload.amt_to_forward), required),
                                (4, HighZeroBytesDroppedBigSize(payload.outgoing_cltv_value), required),
index 4f90202fd2f5cac45ed91e395c2cefd0a8373ed5..36e9ddb067a87ad574fac2ddd9a604352e1da190 100644 (file)
 //! returned errors decode to the correct thing.
 
 use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS};
-use crate::chain::keysinterface::{EntropySource, KeysInterface, NodeSigner, Recipient};
+use crate::chain::keysinterface::{EntropySource, NodeSigner, Recipient};
 use crate::ln::{PaymentHash, PaymentSecret};
 use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS;
-use crate::ln::channelmanager::{self, HTLCForwardInfo, CLTV_FAR_FAR_AWAY, MIN_CLTV_EXPIRY_DELTA, PendingAddHTLCInfo, PendingHTLCInfo, PendingHTLCRouting, PaymentId};
+use crate::ln::channelmanager::{HTLCForwardInfo, FailureCode, CLTV_FAR_FAR_AWAY, MIN_CLTV_EXPIRY_DELTA, PendingAddHTLCInfo, PendingHTLCInfo, PendingHTLCRouting, PaymentId};
 use crate::ln::onion_utils;
 use crate::routing::gossip::{NetworkUpdate, RoutingFees};
 use crate::routing::router::{get_route, PaymentParameters, Route, RouteHint, RouteHintHop};
@@ -23,7 +23,7 @@ use crate::ln::features::{InitFeatures, InvoiceFeatures};
 use crate::ln::msgs;
 use crate::ln::msgs::{ChannelMessageHandler, ChannelUpdate};
 use crate::ln::wire::Encode;
-use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider};
+use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure};
 use crate::util::ser::{Writeable, Writer};
 use crate::util::test_utils;
 use crate::util::config::{UserConfig, ChannelConfig};
@@ -35,8 +35,7 @@ use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
 
 use bitcoin::secp256k1;
-use bitcoin::secp256k1::Secp256k1;
-use bitcoin::secp256k1::{PublicKey, SecretKey};
+use bitcoin::secp256k1::{Secp256k1, SecretKey};
 
 use crate::io;
 use crate::prelude::*;
@@ -167,10 +166,9 @@ fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case:
        commitment_signed_dance!(nodes[0], nodes[1], update_1_0.commitment_signed, false, true);
 
        let events = nodes[0].node.get_and_clear_pending_events();
-       assert_eq!(events.len(), 1);
-       if let &Event::PaymentPathFailed { ref payment_failed_permanently, ref network_update, ref all_paths_failed, ref short_channel_id, ref error_code, .. } = &events[0] {
+       assert_eq!(events.len(), 2);
+       if let &Event::PaymentPathFailed { ref payment_failed_permanently, ref short_channel_id, ref error_code, failure: PathFailure::OnPath { ref network_update }, .. } = &events[0] {
                assert_eq!(*payment_failed_permanently, !expected_retryable);
-               assert_eq!(*all_paths_failed, true);
                assert_eq!(*error_code, expected_error_code);
                if expected_channel_update.is_some() {
                        match network_update {
@@ -213,10 +211,7 @@ fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case:
        } else {
                panic!("Unexpected event");
        }
-       nodes[0].node.abandon_payment(payment_id);
-       let events = nodes[0].node.get_and_clear_pending_events();
-       assert_eq!(events.len(), 1);
-       match events[0] {
+       match events[1] {
                Event::PaymentFailed { payment_hash: ev_payment_hash, payment_id: ev_payment_id } => {
                        assert_eq!(*payment_hash, ev_payment_hash);
                        assert_eq!(payment_id, ev_payment_id);
@@ -281,7 +276,7 @@ fn test_fee_failures() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[Some(config), Some(config), Some(config)]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let channels = [create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()), create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features())];
+       let channels = [create_announced_chan_between_nodes(&nodes, 0, 1), create_announced_chan_between_nodes(&nodes, 1, 2)];
 
        // positive case
        let (route, payment_hash_success, payment_preimage_success, payment_secret_success) = get_route_and_payment_hash!(nodes[0], nodes[2], 40_000);
@@ -333,7 +328,7 @@ fn test_onion_failure() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[Some(config), Some(config), Some(node_2_cfg)]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let channels = [create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()), create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features())];
+       let channels = [create_announced_chan_between_nodes(&nodes, 0, 1), create_announced_chan_between_nodes(&nodes, 1, 2)];
        for node in nodes.iter() {
                *node.keys_manager.override_random_bytes.lock().unwrap() = Some([3; 32]);
        }
@@ -503,7 +498,9 @@ fn test_onion_failure() {
          Some(NetworkUpdate::ChannelFailure{short_channel_id, is_permanent:true}), Some(short_channel_id));
 
        let short_channel_id = channels[1].0.contents.short_channel_id;
-       let amt_to_forward = nodes[1].node.channel_state.lock().unwrap().by_id.get(&channels[1].2).unwrap().get_counterparty_htlc_minimum_msat() - 1;
+       let amt_to_forward = nodes[1].node.per_peer_state.read().unwrap().get(&nodes[2].node.get_our_node_id())
+               .unwrap().lock().unwrap().channel_by_id.get(&channels[1].2).unwrap()
+               .get_counterparty_htlc_minimum_msat() - 1;
        let mut bogus_route = route.clone();
        let route_len = bogus_route.paths[0].len();
        bogus_route.paths[0][route_len-1].fee_msat = amt_to_forward;
@@ -578,8 +575,8 @@ fn test_onion_failure() {
        let short_channel_id = channels[1].0.contents.short_channel_id;
        run_onion_failure_test("channel_disabled", 0, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || {
                // disconnect event to the channel between nodes[1] ~ nodes[2]
-               nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false);
-               nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+               nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id());
+               nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id());
        }, true, Some(UPDATE|20), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy(short_channel_id)}), Some(short_channel_id));
        reconnect_nodes(&nodes[1], &nodes[2], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
@@ -621,16 +618,16 @@ fn do_test_onion_failure_stale_channel_update(announced_channel: bool) {
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
        let other_channel = create_chan_between_nodes(
-               &nodes[0], &nodes[1], channelmanager::provided_init_features(), channelmanager::provided_init_features(),
+               &nodes[0], &nodes[1],
        );
        let channel_to_update = if announced_channel {
                let channel = create_announced_chan_between_nodes(
-                       &nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features(),
+                       &nodes, 1, 2,
                );
                (channel.2, channel.0.contents.short_channel_id)
        } else {
                let channel = create_unannounced_chan_between_nodes_with_value(
-                       &nodes, 1, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features(),
+                       &nodes, 1, 2, 100000, 10001,
                );
                (channel.0.channel_id, channel.0.short_channel_id_alias.unwrap())
        };
@@ -654,8 +651,8 @@ fn do_test_onion_failure_stale_channel_update(announced_channel: bool) {
                        htlc_maximum_msat: None,
                        htlc_minimum_msat: None,
                }])];
-               let payment_params = PaymentParameters::from_node_id(*channel_to_update_counterparty)
-                       .with_features(channelmanager::provided_invoice_features())
+               let payment_params = PaymentParameters::from_node_id(*channel_to_update_counterparty, TEST_FINAL_CLTV)
+                       .with_features(nodes[2].node.invoice_features())
                        .with_route_hints(hop_hints);
                get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, PAYMENT_AMT, TEST_FINAL_CLTV)
        };
@@ -789,20 +786,19 @@ fn test_always_create_tlv_format_onion_payloads() {
        let chanmon_cfgs = create_chanmon_cfgs(3);
        let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
 
-       // Set `node[1]`'s config features to features which return `false` for
+       // Set `node[1]`'s init features to features which return `false` for
        // `supports_variable_length_onion()`
        let mut no_variable_length_onion_features = InitFeatures::empty();
        no_variable_length_onion_features.set_static_remote_key_required();
-       let mut node_1_cfg = &mut node_cfgs[1];
-       node_1_cfg.features = no_variable_length_onion_features;
+       *node_cfgs[1].override_init_features.borrow_mut() = Some(no_variable_length_onion_features);
 
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::empty(), InitFeatures::empty());
-       create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::empty(), InitFeatures::empty());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       create_announced_chan_between_nodes(&nodes, 1, 2);
 
-       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())
+       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)
                .with_features(InvoiceFeatures::empty());
        let (route, _payment_hash, _payment_preimage, _payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 40000, TEST_FINAL_CLTV);
 
@@ -831,14 +827,79 @@ fn test_always_create_tlv_format_onion_payloads() {
        }
 }
 
+fn do_test_fail_htlc_backwards_with_reason(failure_code: FailureCode) {
+
+       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);
+
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+
+       let payment_amount = 100_000;
+       let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], payment_amount);
+       nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
+       check_added_monitors!(nodes[0], 1);
+
+       let mut events = nodes[0].node.get_and_clear_pending_msg_events();
+       let mut payment_event = SendEvent::from_event(events.pop().unwrap());
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
+       commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
+
+       expect_pending_htlcs_forwardable!(nodes[1]);
+       expect_payment_claimable!(nodes[1], payment_hash, payment_secret, payment_amount);
+       nodes[1].node.fail_htlc_backwards_with_reason(&payment_hash, failure_code);
+
+       expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[1], vec![HTLCDestination::FailedPayment { payment_hash: payment_hash }]);
+       check_added_monitors!(nodes[1], 1);
+
+       let events = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(events.len(), 1);
+       let (update_fail_htlc, commitment_signed) = match events[0] {
+               MessageSendEvent::UpdateHTLCs { node_id: _ , updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
+                       assert!(update_add_htlcs.is_empty());
+                       assert!(update_fulfill_htlcs.is_empty());
+                       assert_eq!(update_fail_htlcs.len(), 1);
+                       assert!(update_fail_malformed_htlcs.is_empty());
+                       assert!(update_fee.is_none());
+                       (update_fail_htlcs[0].clone(), commitment_signed)
+               },
+               _ => panic!("Unexpected event"),
+       };
+
+       nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &update_fail_htlc);
+       commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, false, true);
+
+       let failure_data = match failure_code {
+               FailureCode::TemporaryNodeFailure => vec![],
+               FailureCode::RequiredNodeFeatureMissing => vec![],
+               FailureCode::IncorrectOrUnknownPaymentDetails => {
+                       let mut htlc_msat_height_data = (payment_amount as u64).to_be_bytes().to_vec();
+                       htlc_msat_height_data.extend_from_slice(&CHAN_CONFIRM_DEPTH.to_be_bytes());
+                       htlc_msat_height_data
+               }
+       };
+
+       let failure_code = failure_code as u16;
+       let permanent_flag = 0x4000;
+       let permanent_fail = (failure_code & permanent_flag) != 0;
+       expect_payment_failed!(nodes[0], payment_hash, permanent_fail, failure_code, failure_data);
+
+}
+
+#[test]
+fn test_fail_htlc_backwards_with_reason() {
+       do_test_fail_htlc_backwards_with_reason(FailureCode::TemporaryNodeFailure);
+       do_test_fail_htlc_backwards_with_reason(FailureCode::RequiredNodeFeatureMissing);
+       do_test_fail_htlc_backwards_with_reason(FailureCode::IncorrectOrUnknownPaymentDetails);
+}
+
 macro_rules! get_phantom_route {
        ($nodes: expr, $amt: expr, $channel: expr) => {{
-               let secp_ctx = Secp256k1::new();
-               let phantom_secret = $nodes[1].keys_manager.get_node_secret(Recipient::PhantomNode).unwrap();
-               let phantom_pubkey = PublicKey::from_secret_key(&secp_ctx, &phantom_secret);
+               let phantom_pubkey = $nodes[1].keys_manager.get_node_id(Recipient::PhantomNode).unwrap();
                let phantom_route_hint = $nodes[1].node.get_phantom_route_hints();
-               let payment_params = PaymentParameters::from_node_id(phantom_pubkey)
-                       .with_features(channelmanager::provided_invoice_features())
+               let payment_params = PaymentParameters::from_node_id(phantom_pubkey, TEST_FINAL_CLTV)
+                       .with_features($nodes[1].node.invoice_features())
                        .with_route_hints(vec![RouteHint(vec![
                                        RouteHintHop {
                                                src_node_id: $nodes[0].node.get_our_node_id(),
@@ -863,7 +924,7 @@ macro_rules! get_phantom_route {
                                                htlc_maximum_msat: None,
                                        }
                ])]);
-               let scorer = test_utils::TestScorer::with_penalty(0);
+               let scorer = test_utils::TestScorer::new();
                let network_graph = $nodes[0].network_graph.read_only();
                (get_route(
                        &$nodes[0].node.get_our_node_id(), &payment_params, &network_graph,
@@ -880,7 +941,7 @@ fn test_phantom_onion_hmac_failure() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Get the route.
        let recv_value_msat = 10_000;
@@ -939,7 +1000,7 @@ fn test_phantom_invalid_onion_payload() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Get the route.
        let recv_value_msat = 10_000;
@@ -1012,7 +1073,7 @@ fn test_phantom_final_incorrect_cltv_expiry() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Get the route.
        let recv_value_msat = 10_000;
@@ -1068,7 +1129,7 @@ fn test_phantom_failure_too_low_cltv() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Get the route.
        let recv_value_msat = 10_000;
@@ -1118,7 +1179,7 @@ fn test_phantom_failure_modified_cltv() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Get the route.
        let recv_value_msat = 10_000;
@@ -1159,7 +1220,7 @@ fn test_phantom_failure_expires_too_soon() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Get the route.
        let recv_value_msat = 10_000;
@@ -1196,7 +1257,7 @@ fn test_phantom_failure_too_low_recv_amt() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Get the route with a too-low amount.
        let recv_amt_msat = 10_000;
@@ -1248,7 +1309,7 @@ fn test_phantom_dust_exposure_failure() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(receiver_config)]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Get the route with an amount exceeding the dust exposure threshold of nodes[1].
        let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1], Some(max_dust_exposure + 1));
@@ -1290,7 +1351,7 @@ fn test_phantom_failure_reject_payment() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Get the route with a too-low amount.
        let recv_amt_msat = 10_000;
index 1abaf5920a51d8476d56b6f65968f725bd1a781a..2916829f259ec58ee110b95fdf14fb16a702a401 100644 (file)
@@ -182,11 +182,11 @@ pub(super) fn build_onion_payloads(path: &Vec<RouteHop>, total_msat: u64, paymen
                });
                cur_value_msat += hop.fee_msat;
                if cur_value_msat >= 21000000 * 100000000 * 1000 {
-                       return Err(APIError::InvalidRoute{err: "Channel fees overflowed?"});
+                       return Err(APIError::InvalidRoute{err: "Channel fees overflowed?".to_owned()});
                }
                cur_cltv += hop.cltv_expiry_delta as u32;
                if cur_cltv >= 500000000 {
-                       return Err(APIError::InvalidRoute{err: "Channel CLTV overflowed?"});
+                       return Err(APIError::InvalidRoute{err: "Channel CLTV overflowed?".to_owned()});
                }
                last_short_channel_id = hop.short_channel_id;
        }
index 2f6431665b7ea5ec01bf4a7fe810d0ca9fc1b3c8..86b4de768f830172d1caf411b5670667be60923e 100644 (file)
@@ -13,18 +13,23 @@ use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::secp256k1::{self, Secp256k1, SecretKey};
 
-use crate::chain::keysinterface::{EntropySource, KeysInterface, NodeSigner, Recipient};
+use crate::chain::keysinterface::{EntropySource, NodeSigner, Recipient};
 use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
-use crate::ln::channelmanager::{HTLCSource, IDEMPOTENCY_TIMEOUT_TICKS, PaymentId};
-use crate::ln::msgs::DecodeError;
+use crate::ln::channelmanager::{ChannelDetails, HTLCSource, IDEMPOTENCY_TIMEOUT_TICKS, PaymentId};
 use crate::ln::onion_utils::HTLCFailReason;
-use crate::routing::router::{PaymentParameters, Route, RouteHop, RouteParameters, RoutePath};
+use crate::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters, RoutePath, Router};
 use crate::util::errors::APIError;
 use crate::util::events;
 use crate::util::logger::Logger;
+use crate::util::time::Time;
+#[cfg(all(not(feature = "no-std"), test))]
+use crate::util::time::tests::SinceEpoch;
+use crate::util::ser::ReadableArgs;
 
 use core::cmp;
+use core::fmt::{self, Display, Formatter};
 use core::ops::Deref;
+
 use crate::prelude::*;
 use crate::sync::Mutex;
 
@@ -35,9 +40,13 @@ pub(crate) enum PendingOutboundPayment {
                session_privs: HashSet<[u8; 32]>,
        },
        Retryable {
+               retry_strategy: Option<Retry>,
+               attempts: PaymentAttempts,
+               payment_params: Option<PaymentParameters>,
                session_privs: HashSet<[u8; 32]>,
                payment_hash: PaymentHash,
                payment_secret: Option<PaymentSecret>,
+               keysend_preimage: Option<PaymentPreimage>,
                pending_amt_msat: u64,
                /// Used to track the fee paid. Only present if the payment was serialized on 0.0.103+.
                pending_fee_msat: Option<u64>,
@@ -54,13 +63,8 @@ pub(crate) enum PendingOutboundPayment {
                payment_hash: Option<PaymentHash>,
                timer_ticks_without_htlcs: u8,
        },
-       /// When a payer gives up trying to retry a payment, they inform us, letting us generate a
-       /// `PaymentFailed` event when all HTLCs have irrevocably failed. This avoids a number of race
-       /// conditions in MPP-aware payment retriers (1), where the possibility of multiple
-       /// `PaymentPathFailed` events with `all_paths_failed` can be pending at once, confusing a
-       /// downstream event handler as to when a payment has actually failed.
-       ///
-       /// (1) https://github.com/lightningdevkit/rust-lightning/issues/1164
+       /// When we've decided to give up retrying a payment, we mark it as abandoned so we can eventually
+       /// generate a `PaymentFailed` event when all HTLCs have irrevocably failed.
        Abandoned {
                session_privs: HashSet<[u8; 32]>,
                payment_hash: PaymentHash,
@@ -68,6 +72,44 @@ pub(crate) enum PendingOutboundPayment {
 }
 
 impl PendingOutboundPayment {
+       fn increment_attempts(&mut self) {
+               if let PendingOutboundPayment::Retryable { attempts, .. } = self {
+                       attempts.count += 1;
+               }
+       }
+       fn is_auto_retryable_now(&self) -> bool {
+               match self {
+                       PendingOutboundPayment::Retryable { retry_strategy: Some(strategy), attempts, .. } => {
+                               strategy.is_retryable_now(&attempts)
+                       },
+                       _ => false,
+               }
+       }
+       fn is_retryable_now(&self) -> bool {
+               match self {
+                       PendingOutboundPayment::Retryable { retry_strategy: None, .. } => {
+                               // We're handling retries manually, we can always retry.
+                               true
+                       },
+                       PendingOutboundPayment::Retryable { retry_strategy: Some(strategy), attempts, .. } => {
+                               strategy.is_retryable_now(&attempts)
+                       },
+                       _ => false,
+               }
+       }
+       fn payment_parameters(&mut self) -> Option<&mut PaymentParameters> {
+               match self {
+                       PendingOutboundPayment::Retryable { payment_params: Some(ref mut params), .. } => {
+                               Some(params)
+                       },
+                       _ => None,
+               }
+       }
+       pub fn insert_previously_failed_scid(&mut self, scid: u64) {
+               if let PendingOutboundPayment::Retryable { payment_params: Some(params), .. } = self {
+                       params.previously_failed_channels.push(scid);
+               }
+       }
        pub(super) fn is_fulfilled(&self) -> bool {
                match self {
                        PendingOutboundPayment::Fulfilled { .. } => true,
@@ -114,13 +156,13 @@ impl PendingOutboundPayment {
                let our_payment_hash;
                core::mem::swap(&mut session_privs, match self {
                        PendingOutboundPayment::Legacy { .. } |
-                               PendingOutboundPayment::Fulfilled { .. } =>
+                       PendingOutboundPayment::Fulfilled { .. } =>
                                return Err(()),
-                               PendingOutboundPayment::Retryable { session_privs, payment_hash, .. } |
-                                       PendingOutboundPayment::Abandoned { session_privs, payment_hash, .. } => {
-                                               our_payment_hash = *payment_hash;
-                                               session_privs
-                                       },
+                       PendingOutboundPayment::Retryable { session_privs, payment_hash, .. } |
+                       PendingOutboundPayment::Abandoned { session_privs, payment_hash, .. } => {
+                               our_payment_hash = *payment_hash;
+                               session_privs
+                       },
                });
                *self = PendingOutboundPayment::Abandoned { session_privs, payment_hash: our_payment_hash };
                Ok(())
@@ -182,9 +224,127 @@ impl PendingOutboundPayment {
        }
 }
 
-/// If a payment fails to send, it can be in one of several states. This enum is returned as the
-/// Err() type describing which state the payment is in, see the description of individual enum
-/// states for more.
+/// Strategies available to retry payment path failures.
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+pub enum Retry {
+       /// Max number of attempts to retry payment.
+       ///
+       /// Each attempt may be multiple HTLCs along multiple paths if the router decides to split up a
+       /// retry, and may retry multiple failed HTLCs at once if they failed around the same time and
+       /// were retried along a route from a single call to [`Router::find_route`].
+       Attempts(usize),
+       #[cfg(not(feature = "no-std"))]
+       /// Time elapsed before abandoning retries for a payment. At least one attempt at payment is made;
+       /// see [`PaymentParameters::expiry_time`] to avoid any attempt at payment after a specific time.
+       ///
+       /// [`PaymentParameters::expiry_time`]: crate::routing::router::PaymentParameters::expiry_time
+       Timeout(core::time::Duration),
+}
+
+impl Retry {
+       pub(crate) fn is_retryable_now(&self, attempts: &PaymentAttempts) -> bool {
+               match (self, attempts) {
+                       (Retry::Attempts(max_retry_count), PaymentAttempts { count, .. }) => {
+                               max_retry_count > count
+                       },
+                       #[cfg(all(not(feature = "no-std"), not(test)))]
+                       (Retry::Timeout(max_duration), PaymentAttempts { first_attempted_at, .. }) =>
+                               *max_duration >= std::time::Instant::now().duration_since(*first_attempted_at),
+                       #[cfg(all(not(feature = "no-std"), test))]
+                       (Retry::Timeout(max_duration), PaymentAttempts { first_attempted_at, .. }) =>
+                               *max_duration >= SinceEpoch::now().duration_since(*first_attempted_at),
+               }
+       }
+}
+
+#[cfg(feature = "std")]
+pub(super) fn has_expired(route_params: &RouteParameters) -> bool {
+       if let Some(expiry_time) = route_params.payment_params.expiry_time {
+               if let Ok(elapsed) = std::time::SystemTime::UNIX_EPOCH.elapsed() {
+                       return elapsed > core::time::Duration::from_secs(expiry_time)
+               }
+       }
+       false
+}
+
+pub(crate) type PaymentAttempts = PaymentAttemptsUsingTime<ConfiguredTime>;
+
+/// Storing minimal payment attempts information required for determining if a outbound payment can
+/// be retried.
+pub(crate) struct PaymentAttemptsUsingTime<T: Time> {
+       /// This count will be incremented only after the result of the attempt is known. When it's 0,
+       /// it means the result of the first attempt is not known yet.
+       pub(crate) count: usize,
+       /// This field is only used when retry is `Retry::Timeout` which is only build with feature std
+       #[cfg(not(feature = "no-std"))]
+       first_attempted_at: T,
+       #[cfg(feature = "no-std")]
+       phantom: core::marker::PhantomData<T>,
+
+}
+
+#[cfg(not(any(feature = "no-std", test)))]
+type ConfiguredTime = std::time::Instant;
+#[cfg(feature = "no-std")]
+type ConfiguredTime = crate::util::time::Eternity;
+#[cfg(all(not(feature = "no-std"), test))]
+type ConfiguredTime = SinceEpoch;
+
+impl<T: Time> PaymentAttemptsUsingTime<T> {
+       pub(crate) fn new() -> Self {
+               PaymentAttemptsUsingTime {
+                       count: 0,
+                       #[cfg(not(feature = "no-std"))]
+                       first_attempted_at: T::now(),
+                       #[cfg(feature = "no-std")]
+                       phantom: core::marker::PhantomData,
+               }
+       }
+}
+
+impl<T: Time> Display for PaymentAttemptsUsingTime<T> {
+       fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
+               #[cfg(feature = "no-std")]
+               return write!(f, "attempts: {}", self.count);
+               #[cfg(not(feature = "no-std"))]
+               return write!(
+                       f,
+                       "attempts: {}, duration: {}s",
+                       self.count,
+                       T::now().duration_since(self.first_attempted_at).as_secs()
+               );
+       }
+}
+
+/// Indicates an immediate error on [`ChannelManager::send_payment_with_retry`]. Further errors
+/// may be surfaced later via [`Event::PaymentPathFailed`] and [`Event::PaymentFailed`].
+///
+/// [`ChannelManager::send_payment_with_retry`]: crate::ln::channelmanager::ChannelManager::send_payment_with_retry
+/// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
+/// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed
+#[derive(Clone, Debug)]
+pub enum RetryableSendFailure {
+       /// The provided [`PaymentParameters::expiry_time`] indicated that the payment has expired. Note
+       /// that this error is *not* caused by [`Retry::Timeout`].
+       ///
+       /// [`PaymentParameters::expiry_time`]: crate::routing::router::PaymentParameters::expiry_time
+       PaymentExpired,
+       /// We were unable to find a route to the destination.
+       RouteNotFound,
+       /// Indicates that a payment for the provided [`PaymentId`] is already in-flight and has not
+       /// yet completed (i.e. generated an [`Event::PaymentSent`] or [`Event::PaymentFailed`]).
+       ///
+       /// [`PaymentId`]: crate::ln::channelmanager::PaymentId
+       /// [`Event::PaymentSent`]: crate::util::events::Event::PaymentSent
+       /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed
+       DuplicatePayment,
+}
+
+/// If a payment fails to send with [`ChannelManager::send_payment`], it can be in one of several
+/// states. This enum is returned as the Err() type describing which state the payment is in, see
+/// the description of individual enum states for more.
+///
+/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
 #[derive(Clone, Debug)]
 pub enum PaymentSendFailure {
        /// A parameter which was passed to send_payment was invalid, preventing us from attempting to
@@ -192,68 +352,58 @@ pub enum PaymentSendFailure {
        ///
        /// You can freely resend the payment in full (with the parameter error fixed).
        ///
-       /// Because the payment failed outright, no payment tracking is done, you do not need to call
-       /// [`ChannelManager::abandon_payment`] and [`ChannelManager::retry_payment`] will *not* work
-       /// for this payment.
+       /// Because the payment failed outright, no payment tracking is done and no
+       /// [`Event::PaymentPathFailed`] or [`Event::PaymentFailed`] events will be generated.
        ///
-       /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
-       /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
+       /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
+       /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed
        ParameterError(APIError),
        /// A parameter in a single path which was passed to send_payment was invalid, preventing us
        /// from attempting to send the payment at all.
        ///
        /// You can freely resend the payment in full (with the parameter error fixed).
        ///
+       /// Because the payment failed outright, no payment tracking is done and no
+       /// [`Event::PaymentPathFailed`] or [`Event::PaymentFailed`] events will be generated.
+       ///
        /// The results here are ordered the same as the paths in the route object which was passed to
        /// send_payment.
        ///
-       /// Because the payment failed outright, no payment tracking is done, you do not need to call
-       /// [`ChannelManager::abandon_payment`] and [`ChannelManager::retry_payment`] will *not* work
-       /// for this payment.
-       ///
-       /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
-       /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
+       /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
+       /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed
        PathParameterError(Vec<Result<(), APIError>>),
        /// All paths which were attempted failed to send, with no channel state change taking place.
        /// You can freely resend the payment in full (though you probably want to do so over different
        /// paths than the ones selected).
        ///
-       /// Because the payment failed outright, no payment tracking is done, you do not need to call
-       /// [`ChannelManager::abandon_payment`] and [`ChannelManager::retry_payment`] will *not* work
-       /// for this payment.
+       /// Because the payment failed outright, no payment tracking is done and no
+       /// [`Event::PaymentPathFailed`] or [`Event::PaymentFailed`] events will be generated.
        ///
-       /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
-       /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
+       /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
+       /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed
        AllFailedResendSafe(Vec<APIError>),
        /// Indicates that a payment for the provided [`PaymentId`] is already in-flight and has not
-       /// yet completed (i.e. generated an [`Event::PaymentSent`]) or been abandoned (via
-       /// [`ChannelManager::abandon_payment`]).
+       /// yet completed (i.e. generated an [`Event::PaymentSent`] or [`Event::PaymentFailed`]).
        ///
        /// [`PaymentId`]: crate::ln::channelmanager::PaymentId
        /// [`Event::PaymentSent`]: crate::util::events::Event::PaymentSent
-       /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
+       /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed
        DuplicatePayment,
-       /// Some paths which were attempted failed to send, though possibly not all. At least some
-       /// paths have irrevocably committed to the HTLC and retrying the payment in full would result
-       /// in over-/re-payment.
+       /// Some paths that were attempted failed to send, though some paths may have succeeded. At least
+       /// some paths have irrevocably committed to the HTLC.
        ///
-       /// The results here are ordered the same as the paths in the route object which was passed to
-       /// send_payment, and any `Err`s which are not [`APIError::MonitorUpdateInProgress`] can be
-       /// safely retried via [`ChannelManager::retry_payment`].
+       /// The results here are ordered the same as the paths in the route object that was passed to
+       /// send_payment.
        ///
-       /// Any entries which contain `Err(APIError::MonitorUpdateInprogress)` or `Ok(())` MUST NOT be
-       /// retried as they will result in over-/re-payment. These HTLCs all either successfully sent
-       /// (in the case of `Ok(())`) or will send once a [`MonitorEvent::Completed`] is provided for
-       /// the next-hop channel with the latest update_id.
+       /// Any entries that contain `Err(APIError::MonitorUpdateInprogress)` will send once a
+       /// [`MonitorEvent::Completed`] is provided for the next-hop channel with the latest update_id.
        ///
-       /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
        /// [`MonitorEvent::Completed`]: crate::chain::channelmonitor::MonitorEvent::Completed
        PartialFailure {
-               /// The errors themselves, in the same order as the route hops.
+               /// The errors themselves, in the same order as the paths from the route.
                results: Vec<Result<(), APIError>>,
                /// If some paths failed without irrevocably committing to the new HTLC(s), this will
-               /// contain a [`RouteParameters`] object which can be used to calculate a new route that
-               /// will pay all remaining unpaid balance.
+               /// contain a [`RouteParameters`] object for the failing paths.
                failed_paths_retry: Option<RouteParameters>,
                /// The payment id for the payment, which is now at least partially pending.
                payment_id: PaymentId,
@@ -262,129 +412,412 @@ pub enum PaymentSendFailure {
 
 pub(super) struct OutboundPayments {
        pub(super) pending_outbound_payments: Mutex<HashMap<PaymentId, PendingOutboundPayment>>,
+       pub(super) retry_lock: Mutex<()>,
 }
 
 impl OutboundPayments {
        pub(super) fn new() -> Self {
                Self {
-                       pending_outbound_payments: Mutex::new(HashMap::new())
+                       pending_outbound_payments: Mutex::new(HashMap::new()),
+                       retry_lock: Mutex::new(()),
                }
        }
 
-       pub(super) fn send_payment_with_route<K: Deref, F>(
+       pub(super) fn send_payment<R: Deref, ES: Deref, NS: Deref, IH, SP, L: Deref>(
+               &self, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>, payment_id: PaymentId,
+               retry_strategy: Retry, route_params: RouteParameters, router: &R,
+               first_hops: Vec<ChannelDetails>, compute_inflight_htlcs: IH, entropy_source: &ES,
+               node_signer: &NS, best_block_height: u32, logger: &L,
+               pending_events: &Mutex<Vec<events::Event>>, send_payment_along_path: SP,
+       ) -> Result<(), RetryableSendFailure>
+       where
+               R::Target: Router,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               L::Target: Logger,
+               IH: Fn() -> InFlightHtlcs,
+               SP: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
+                        u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>,
+       {
+               self.send_payment_internal(payment_id, payment_hash, payment_secret, None, retry_strategy,
+                       route_params, router, first_hops, &compute_inflight_htlcs, entropy_source, node_signer,
+                       best_block_height, logger, pending_events, &send_payment_along_path)
+       }
+
+       pub(super) fn send_payment_with_route<ES: Deref, NS: Deref, F>(
                &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
-               payment_id: PaymentId, keys_manager: &K, best_block_height: u32, send_payment_along_path: F
+               payment_id: PaymentId, entropy_source: &ES, node_signer: &NS, best_block_height: u32,
+               send_payment_along_path: F
        ) -> Result<(), PaymentSendFailure>
        where
-               K::Target: KeysInterface,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
                F: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
                   u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>
        {
-               let onion_session_privs = self.add_new_pending_payment(payment_hash, *payment_secret, payment_id, route, keys_manager, best_block_height)?;
-               self.send_payment_internal(route, payment_hash, payment_secret, None, payment_id, None, onion_session_privs, keys_manager, best_block_height, send_payment_along_path)
+               let onion_session_privs = self.add_new_pending_payment(payment_hash, *payment_secret, payment_id, None, route, None, None, entropy_source, best_block_height)?;
+               self.pay_route_internal(route, payment_hash, payment_secret, None, payment_id, None,
+                       onion_session_privs, node_signer, best_block_height, &send_payment_along_path)
+                       .map_err(|e| { self.remove_outbound_if_all_failed(payment_id, &e); e })
        }
 
-       pub(super) fn send_spontaneous_payment<K: Deref, F>(
+       pub(super) fn send_spontaneous_payment<R: Deref, ES: Deref, NS: Deref, IH, SP, L: Deref>(
+               &self, payment_preimage: Option<PaymentPreimage>, payment_id: PaymentId,
+               retry_strategy: Retry, route_params: RouteParameters, router: &R,
+               first_hops: Vec<ChannelDetails>, inflight_htlcs: IH, entropy_source: &ES,
+               node_signer: &NS, best_block_height: u32, logger: &L,
+               pending_events: &Mutex<Vec<events::Event>>, send_payment_along_path: SP
+       ) -> Result<PaymentHash, RetryableSendFailure>
+       where
+               R::Target: Router,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               L::Target: Logger,
+               IH: Fn() -> InFlightHtlcs,
+               SP: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
+                        u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>,
+       {
+               let preimage = payment_preimage
+                       .unwrap_or_else(|| PaymentPreimage(entropy_source.get_secure_random_bytes()));
+               let payment_hash = PaymentHash(Sha256::hash(&preimage.0).into_inner());
+               self.send_payment_internal(payment_id, payment_hash, &None, Some(preimage), retry_strategy,
+                       route_params, router, first_hops, inflight_htlcs, entropy_source, node_signer,
+                       best_block_height, logger, pending_events, send_payment_along_path)
+                       .map(|()| payment_hash)
+       }
+
+       pub(super) fn send_spontaneous_payment_with_route<ES: Deref, NS: Deref, F>(
                &self, route: &Route, payment_preimage: Option<PaymentPreimage>, payment_id: PaymentId,
-               keys_manager: &K, best_block_height: u32, send_payment_along_path: F
+               entropy_source: &ES, node_signer: &NS, best_block_height: u32, send_payment_along_path: F
        ) -> Result<PaymentHash, PaymentSendFailure>
        where
-               K::Target: KeysInterface,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
                F: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
                   u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>
        {
-               let preimage = match payment_preimage {
-                       Some(p) => p,
-                       None => PaymentPreimage(keys_manager.get_secure_random_bytes()),
-               };
+               let preimage = payment_preimage
+                       .unwrap_or_else(|| PaymentPreimage(entropy_source.get_secure_random_bytes()));
                let payment_hash = PaymentHash(Sha256::hash(&preimage.0).into_inner());
-               let onion_session_privs = self.add_new_pending_payment(payment_hash, None, payment_id, &route, keys_manager, best_block_height)?;
+               let onion_session_privs = self.add_new_pending_payment(payment_hash, None, payment_id, Some(preimage), &route, None, None, entropy_source, best_block_height)?;
 
-               match self.send_payment_internal(route, payment_hash, &None, Some(preimage), payment_id, None, onion_session_privs, keys_manager, best_block_height, send_payment_along_path) {
+               match self.pay_route_internal(route, payment_hash, &None, Some(preimage), payment_id, None, onion_session_privs, node_signer, best_block_height, &send_payment_along_path) {
                        Ok(()) => Ok(payment_hash),
-                       Err(e) => Err(e)
+                       Err(e) => {
+                               self.remove_outbound_if_all_failed(payment_id, &e);
+                               Err(e)
+                       }
                }
        }
 
-       pub(super) fn retry_payment_with_route<K: Deref, F>(
-               &self, route: &Route, payment_id: PaymentId, keys_manager: &K, best_block_height: u32,
-               send_payment_along_path: F
-       ) -> Result<(), PaymentSendFailure>
+       pub(super) fn check_retry_payments<R: Deref, ES: Deref, NS: Deref, SP, IH, FH, L: Deref>(
+               &self, router: &R, first_hops: FH, inflight_htlcs: IH, entropy_source: &ES, node_signer: &NS,
+               best_block_height: u32, pending_events: &Mutex<Vec<events::Event>>, logger: &L,
+               send_payment_along_path: SP,
+       )
        where
-               K::Target: KeysInterface,
-               F: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
-                  u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>
+               R::Target: Router,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               SP: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
+                  u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>,
+               IH: Fn() -> InFlightHtlcs,
+               FH: Fn() -> Vec<ChannelDetails>,
+               L::Target: Logger,
        {
-               const RETRY_OVERFLOW_PERCENTAGE: u64 = 10;
+               let _single_thread = self.retry_lock.lock().unwrap();
+               loop {
+                       let mut outbounds = self.pending_outbound_payments.lock().unwrap();
+                       let mut retry_id_route_params = None;
+                       for (pmt_id, pmt) in outbounds.iter_mut() {
+                               if pmt.is_auto_retryable_now() {
+                                       if let PendingOutboundPayment::Retryable { pending_amt_msat, total_msat, payment_params: Some(params), .. } = pmt {
+                                               if pending_amt_msat < total_msat {
+                                                       retry_id_route_params = Some((*pmt_id, RouteParameters {
+                                                               final_value_msat: *total_msat - *pending_amt_msat,
+                                                               payment_params: params.clone(),
+                                                       }));
+                                                       break
+                                               }
+                                       }
+                               }
+                       }
+                       core::mem::drop(outbounds);
+                       if let Some((payment_id, route_params)) = retry_id_route_params {
+                               self.retry_payment_internal(payment_id, route_params, router, first_hops(), &inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, &send_payment_along_path)
+                       } else { break }
+               }
+
+               let mut outbounds = self.pending_outbound_payments.lock().unwrap();
+               outbounds.retain(|pmt_id, pmt| {
+                       let mut retain = true;
+                       if !pmt.is_auto_retryable_now() && pmt.remaining_parts() == 0 {
+                               if pmt.mark_abandoned().is_ok() {
+                                       pending_events.lock().unwrap().push(events::Event::PaymentFailed {
+                                               payment_id: *pmt_id,
+                                               payment_hash: pmt.payment_hash().expect("PendingOutboundPayments::Retryable always has a payment hash set"),
+                                       });
+                                       retain = false;
+                               }
+                       }
+                       retain
+               });
+       }
+
+       pub(super) fn needs_abandon(&self) -> bool {
+               let outbounds = self.pending_outbound_payments.lock().unwrap();
+               outbounds.iter().any(|(_, pmt)|
+                       !pmt.is_auto_retryable_now() && pmt.remaining_parts() == 0 && !pmt.is_fulfilled())
+       }
+
+       /// Errors immediately on [`RetryableSendFailure`] error conditions. Otherwise, further errors may
+       /// be surfaced asynchronously via [`Event::PaymentPathFailed`] and [`Event::PaymentFailed`].
+       ///
+       /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
+       /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed
+       fn send_payment_internal<R: Deref, NS: Deref, ES: Deref, IH, SP, L: Deref>(
+               &self, payment_id: PaymentId, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
+               keysend_preimage: Option<PaymentPreimage>, retry_strategy: Retry, route_params: RouteParameters,
+               router: &R, first_hops: Vec<ChannelDetails>, inflight_htlcs: IH, entropy_source: &ES,
+               node_signer: &NS, best_block_height: u32, logger: &L,
+               pending_events: &Mutex<Vec<events::Event>>, send_payment_along_path: SP,
+       ) -> Result<(), RetryableSendFailure>
+       where
+               R::Target: Router,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               L::Target: Logger,
+               IH: Fn() -> InFlightHtlcs,
+               SP: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
+                   u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>
+       {
+               #[cfg(feature = "std")] {
+                       if has_expired(&route_params) {
+                               return Err(RetryableSendFailure::PaymentExpired)
+                       }
+               }
+
+               let route = router.find_route(
+                       &node_signer.get_node_id(Recipient::Node).unwrap(), &route_params,
+                       Some(&first_hops.iter().collect::<Vec<_>>()), &inflight_htlcs()
+               ).map_err(|_| RetryableSendFailure::RouteNotFound)?;
+
+               let onion_session_privs = self.add_new_pending_payment(payment_hash, *payment_secret,
+                       payment_id, keysend_preimage, &route, Some(retry_strategy),
+                       Some(route_params.payment_params.clone()), entropy_source, best_block_height)
+                       .map_err(|_| RetryableSendFailure::DuplicatePayment)?;
+
+               let res = self.pay_route_internal(&route, payment_hash, payment_secret, None, payment_id, None,
+                       onion_session_privs, node_signer, best_block_height, &send_payment_along_path);
+               log_info!(logger, "Result sending payment with id {}: {:?}", log_bytes!(payment_id.0), res);
+               if let Err(e) = res {
+                       self.handle_pay_route_err(e, payment_id, payment_hash, route, route_params, router, first_hops, &inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, &send_payment_along_path);
+               }
+               Ok(())
+       }
+
+       fn retry_payment_internal<R: Deref, NS: Deref, ES: Deref, IH, SP, L: Deref>(
+               &self, payment_id: PaymentId, route_params: RouteParameters, router: &R,
+               first_hops: Vec<ChannelDetails>, inflight_htlcs: &IH, entropy_source: &ES, node_signer: &NS,
+               best_block_height: u32, logger: &L, pending_events: &Mutex<Vec<events::Event>>,
+               send_payment_along_path: &SP,
+       )
+       where
+               R::Target: Router,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               L::Target: Logger,
+               IH: Fn() -> InFlightHtlcs,
+               SP: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
+                   u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>
+       {
+               #[cfg(feature = "std")] {
+                       if has_expired(&route_params) {
+                               log_error!(logger, "Payment params expired on retry, abandoning payment {}", log_bytes!(payment_id.0));
+                               self.abandon_payment(payment_id, pending_events);
+                               return
+                       }
+               }
+
+               let route = match router.find_route(
+                       &node_signer.get_node_id(Recipient::Node).unwrap(), &route_params,
+                       Some(&first_hops.iter().collect::<Vec<_>>()), &inflight_htlcs()
+               ) {
+                       Ok(route) => route,
+                       Err(e) => {
+                               log_error!(logger, "Failed to find a route on retry, abandoning payment {}: {:#?}", log_bytes!(payment_id.0), e);
+                               self.abandon_payment(payment_id, pending_events);
+                               return
+                       }
+               };
                for path in route.paths.iter() {
                        if path.len() == 0 {
-                               return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError {
-                                       err: "length-0 path in route".to_string()
-                               }))
+                               log_error!(logger, "length-0 path in route");
+                               self.abandon_payment(payment_id, pending_events);
+                               return
                        }
                }
 
+               const RETRY_OVERFLOW_PERCENTAGE: u64 = 10;
                let mut onion_session_privs = Vec::with_capacity(route.paths.len());
                for _ in 0..route.paths.len() {
-                       onion_session_privs.push(keys_manager.get_secure_random_bytes());
+                       onion_session_privs.push(entropy_source.get_secure_random_bytes());
                }
 
-               let (total_msat, payment_hash, payment_secret) = {
+               macro_rules! abandon_with_entry {
+                       ($payment_id: expr, $payment_hash: expr, $payment: expr, $pending_events: expr) => {
+                               if $payment.get_mut().mark_abandoned().is_ok() && $payment.get().remaining_parts() == 0 {
+                                       $pending_events.lock().unwrap().push(events::Event::PaymentFailed {
+                                               payment_id: $payment_id,
+                                               payment_hash: $payment_hash,
+                                       });
+                                       $payment.remove();
+                               }
+                       }
+               }
+               let (total_msat, payment_hash, payment_secret, keysend_preimage) = {
                        let mut outbounds = self.pending_outbound_payments.lock().unwrap();
-                       match outbounds.get_mut(&payment_id) {
-                               Some(payment) => {
-                                       let res = match payment {
+                       match outbounds.entry(payment_id) {
+                               hash_map::Entry::Occupied(mut payment) => {
+                                       let res = match payment.get() {
                                                PendingOutboundPayment::Retryable {
-                                                       total_msat, payment_hash, payment_secret, pending_amt_msat, ..
+                                                       total_msat, payment_hash, keysend_preimage, payment_secret, pending_amt_msat, ..
                                                } => {
                                                        let retry_amt_msat: u64 = route.paths.iter().map(|path| path.last().unwrap().fee_msat).sum();
                                                        if retry_amt_msat + *pending_amt_msat > *total_msat * (100 + RETRY_OVERFLOW_PERCENTAGE) / 100 {
-                                                               return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError {
-                                                                       err: format!("retry_amt_msat of {} will put pending_amt_msat (currently: {}) more than 10% over total_payment_amt_msat of {}", retry_amt_msat, pending_amt_msat, total_msat).to_string()
-                                                               }))
+                                                               log_error!(logger, "retry_amt_msat of {} will put pending_amt_msat (currently: {}) more than 10% over total_payment_amt_msat of {}", retry_amt_msat, pending_amt_msat, total_msat);
+                                                               let payment_hash = *payment_hash;
+                                                               abandon_with_entry!(payment_id, payment_hash, payment, pending_events);
+                                                               return
                                                        }
-                                                       (*total_msat, *payment_hash, *payment_secret)
+                                                       (*total_msat, *payment_hash, *payment_secret, *keysend_preimage)
                                                },
                                                PendingOutboundPayment::Legacy { .. } => {
-                                                       return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError {
-                                                               err: "Unable to retry payments that were initially sent on LDK versions prior to 0.0.102".to_string()
-                                                       }))
+                                                       log_error!(logger, "Unable to retry payments that were initially sent on LDK versions prior to 0.0.102");
+                                                       return
                                                },
                                                PendingOutboundPayment::Fulfilled { .. } => {
-                                                       return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError {
-                                                               err: "Payment already completed".to_owned()
-                                                       }));
+                                                       log_error!(logger, "Payment already completed");
+                                                       return
                                                },
                                                PendingOutboundPayment::Abandoned { .. } => {
-                                                       return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError {
-                                                               err: "Payment already abandoned (with some HTLCs still pending)".to_owned()
-                                                       }));
+                                                       log_error!(logger, "Payment already abandoned (with some HTLCs still pending)");
+                                                       return
                                                },
                                        };
+                                       if !payment.get().is_retryable_now() {
+                                               log_error!(logger, "Retries exhausted for payment id {}", log_bytes!(payment_id.0));
+                                               abandon_with_entry!(payment_id, res.1, payment, pending_events);
+                                               return
+                                       }
+                                       payment.get_mut().increment_attempts();
                                        for (path, session_priv_bytes) in route.paths.iter().zip(onion_session_privs.iter()) {
-                                               assert!(payment.insert(*session_priv_bytes, path));
+                                               assert!(payment.get_mut().insert(*session_priv_bytes, path));
                                        }
                                        res
                                },
-                               None =>
-                                       return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError {
-                                               err: format!("Payment with ID {} not found", log_bytes!(payment_id.0)),
-                                       })),
+                               hash_map::Entry::Vacant(_) => {
+                                       log_error!(logger, "Payment with ID {} not found", log_bytes!(payment_id.0));
+                                       return
+                               }
                        }
                };
-               self.send_payment_internal(route, payment_hash, &payment_secret, None, payment_id, Some(total_msat), onion_session_privs, keys_manager, best_block_height, send_payment_along_path)
+               let res = self.pay_route_internal(&route, payment_hash, &payment_secret, keysend_preimage,
+                       payment_id, Some(total_msat), onion_session_privs, node_signer, best_block_height,
+                       &send_payment_along_path);
+               log_info!(logger, "Result retrying payment id {}: {:?}", log_bytes!(payment_id.0), res);
+               if let Err(e) = res {
+                       self.handle_pay_route_err(e, payment_id, payment_hash, route, route_params, router, first_hops, inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, send_payment_along_path);
+               }
        }
 
-       pub(super) fn send_probe<K: Deref, F>(
-               &self, hops: Vec<RouteHop>, probing_cookie_secret: [u8; 32], keys_manager: &K,
-               best_block_height: u32, send_payment_along_path: F
+       fn handle_pay_route_err<R: Deref, NS: Deref, ES: Deref, IH, SP, L: Deref>(
+               &self, err: PaymentSendFailure, payment_id: PaymentId, payment_hash: PaymentHash, route: Route,
+               mut route_params: RouteParameters, router: &R, first_hops: Vec<ChannelDetails>,
+               inflight_htlcs: &IH, entropy_source: &ES, node_signer: &NS, best_block_height: u32, logger: &L,
+               pending_events: &Mutex<Vec<events::Event>>, send_payment_along_path: &SP,
+       )
+       where
+               R::Target: Router,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
+               L::Target: Logger,
+               IH: Fn() -> InFlightHtlcs,
+               SP: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
+                   u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>
+       {
+               match err {
+                       PaymentSendFailure::AllFailedResendSafe(errs) => {
+                               Self::push_path_failed_evs_and_scids(payment_id, payment_hash, &mut route_params, route.paths, errs.into_iter().map(|e| Err(e)), pending_events);
+                               self.retry_payment_internal(payment_id, route_params, router, first_hops, inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, send_payment_along_path);
+                       },
+                       PaymentSendFailure::PartialFailure { failed_paths_retry: Some(mut retry), results, .. } => {
+                               Self::push_path_failed_evs_and_scids(payment_id, payment_hash, &mut retry, route.paths, results.into_iter(), pending_events);
+                               // Some paths were sent, even if we failed to send the full MPP value our recipient may
+                               // misbehave and claim the funds, at which point we have to consider the payment sent, so
+                               // return `Ok()` here, ignoring any retry errors.
+                               self.retry_payment_internal(payment_id, retry, router, first_hops, inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, send_payment_along_path);
+                       },
+                       PaymentSendFailure::PartialFailure { failed_paths_retry: None, .. } => {
+                               // This may happen if we send a payment and some paths fail, but only due to a temporary
+                               // monitor failure or the like, implying they're really in-flight, but we haven't sent the
+                               // initial HTLC-Add messages yet.
+                       },
+                       PaymentSendFailure::PathParameterError(results) => {
+                               Self::push_path_failed_evs_and_scids(payment_id, payment_hash, &mut route_params, route.paths, results.into_iter(), pending_events);
+                               self.abandon_payment(payment_id, pending_events);
+                       },
+                       PaymentSendFailure::ParameterError(e) => {
+                               log_error!(logger, "Failed to send to route due to parameter error: {:?}. Your router is buggy", e);
+                               self.abandon_payment(payment_id, pending_events);
+                       },
+                       PaymentSendFailure::DuplicatePayment => debug_assert!(false), // unreachable
+               }
+       }
+
+       fn push_path_failed_evs_and_scids<I: ExactSizeIterator + Iterator<Item = Result<(), APIError>>>(
+               payment_id: PaymentId, payment_hash: PaymentHash, route_params: &mut RouteParameters,
+               paths: Vec<Vec<RouteHop>>, path_results: I, pending_events: &Mutex<Vec<events::Event>>
+       ) {
+               let mut events = pending_events.lock().unwrap();
+               debug_assert_eq!(paths.len(), path_results.len());
+               for (path, path_res) in paths.into_iter().zip(path_results) {
+                       if let Err(e) = path_res {
+                               if let APIError::MonitorUpdateInProgress = e { continue }
+                               let mut failed_scid = None;
+                               if let APIError::ChannelUnavailable { .. } = e {
+                                       let scid = path[0].short_channel_id;
+                                       failed_scid = Some(scid);
+                                       route_params.payment_params.previously_failed_channels.push(scid);
+                               }
+                               events.push(events::Event::PaymentPathFailed {
+                                       payment_id: Some(payment_id),
+                                       payment_hash,
+                                       payment_failed_permanently: false,
+                                       failure: events::PathFailure::InitialSend { err: e },
+                                       path,
+                                       short_channel_id: failed_scid,
+                                       retry: None,
+                                       #[cfg(test)]
+                                       error_code: None,
+                                       #[cfg(test)]
+                                       error_data: None,
+                               });
+                       }
+               }
+       }
+
+       pub(super) fn send_probe<ES: Deref, NS: Deref, F>(
+               &self, hops: Vec<RouteHop>, probing_cookie_secret: [u8; 32], entropy_source: &ES,
+               node_signer: &NS, best_block_height: u32, send_payment_along_path: F
        ) -> Result<(PaymentHash, PaymentId), PaymentSendFailure>
        where
-               K::Target: KeysInterface,
+               ES::Target: EntropySource,
+               NS::Target: NodeSigner,
                F: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
                   u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>
        {
-               let payment_id = PaymentId(keys_manager.get_secure_random_bytes());
+               let payment_id = PaymentId(entropy_source.get_secure_random_bytes());
 
                let payment_hash = probing_cookie_from_id(&payment_id, probing_cookie_secret);
 
@@ -395,29 +828,33 @@ impl OutboundPayments {
                }
 
                let route = Route { paths: vec![hops], payment_params: None };
-               let onion_session_privs = self.add_new_pending_payment(payment_hash, None, payment_id, &route, keys_manager, best_block_height)?;
+               let onion_session_privs = self.add_new_pending_payment(payment_hash, None, payment_id, None, &route, None, None, entropy_source, best_block_height)?;
 
-               match self.send_payment_internal(&route, payment_hash, &None, None, payment_id, None, onion_session_privs, keys_manager, best_block_height, send_payment_along_path) {
+               match self.pay_route_internal(&route, payment_hash, &None, None, payment_id, None, onion_session_privs, node_signer, best_block_height, &send_payment_along_path) {
                        Ok(()) => Ok((payment_hash, payment_id)),
-                       Err(e) => Err(e)
+                       Err(e) => {
+                               self.remove_outbound_if_all_failed(payment_id, &e);
+                               Err(e)
+                       }
                }
        }
 
        #[cfg(test)]
-       pub(super) fn test_add_new_pending_payment<K: Deref>(
+       pub(super) fn test_add_new_pending_payment<ES: Deref>(
                &self, payment_hash: PaymentHash, payment_secret: Option<PaymentSecret>, payment_id: PaymentId,
-               route: &Route, keys_manager: &K, best_block_height: u32
-       ) -> Result<Vec<[u8; 32]>, PaymentSendFailure> where K::Target: KeysInterface {
-               self.add_new_pending_payment(payment_hash, payment_secret, payment_id, route, keys_manager, best_block_height)
+               route: &Route, retry_strategy: Option<Retry>, entropy_source: &ES, best_block_height: u32
+       ) -> Result<Vec<[u8; 32]>, PaymentSendFailure> where ES::Target: EntropySource {
+               self.add_new_pending_payment(payment_hash, payment_secret, payment_id, None, route, retry_strategy, None, entropy_source, best_block_height)
        }
 
-       fn add_new_pending_payment<K: Deref>(
+       pub(super) fn add_new_pending_payment<ES: Deref>(
                &self, payment_hash: PaymentHash, payment_secret: Option<PaymentSecret>, payment_id: PaymentId,
-               route: &Route, keys_manager: &K, best_block_height: u32
-       ) -> Result<Vec<[u8; 32]>, PaymentSendFailure> where K::Target: KeysInterface {
+               keysend_preimage: Option<PaymentPreimage>, route: &Route, retry_strategy: Option<Retry>,
+               payment_params: Option<PaymentParameters>, entropy_source: &ES, best_block_height: u32
+       ) -> Result<Vec<[u8; 32]>, PaymentSendFailure> where ES::Target: EntropySource {
                let mut onion_session_privs = Vec::with_capacity(route.paths.len());
                for _ in 0..route.paths.len() {
-                       onion_session_privs.push(keys_manager.get_secure_random_bytes());
+                       onion_session_privs.push(entropy_source.get_secure_random_bytes());
                }
 
                let mut pending_outbounds = self.pending_outbound_payments.lock().unwrap();
@@ -425,11 +862,15 @@ impl OutboundPayments {
                        hash_map::Entry::Occupied(_) => Err(PaymentSendFailure::DuplicatePayment),
                        hash_map::Entry::Vacant(entry) => {
                                let payment = entry.insert(PendingOutboundPayment::Retryable {
+                                       retry_strategy,
+                                       attempts: PaymentAttempts::new(),
+                                       payment_params,
                                        session_privs: HashSet::new(),
                                        pending_amt_msat: 0,
                                        pending_fee_msat: Some(0),
                                        payment_hash,
                                        payment_secret,
+                                       keysend_preimage,
                                        starting_block_height: best_block_height,
                                        total_msat: route.get_total_amount(),
                                });
@@ -443,34 +884,34 @@ impl OutboundPayments {
                }
        }
 
-       fn send_payment_internal<K: Deref, F>(
+       fn pay_route_internal<NS: Deref, F>(
                &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
                keysend_preimage: Option<PaymentPreimage>, payment_id: PaymentId, recv_value_msat: Option<u64>,
-               onion_session_privs: Vec<[u8; 32]>, keys_manager: &K, best_block_height: u32,
-               send_payment_along_path: F
+               onion_session_privs: Vec<[u8; 32]>, node_signer: &NS, best_block_height: u32,
+               send_payment_along_path: &F
        ) -> Result<(), PaymentSendFailure>
        where
-               K::Target: KeysInterface,
+               NS::Target: NodeSigner,
                F: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
                   u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>
        {
                if route.paths.len() < 1 {
-                       return Err(PaymentSendFailure::ParameterError(APIError::InvalidRoute{err: "There must be at least one path to send over"}));
+                       return Err(PaymentSendFailure::ParameterError(APIError::InvalidRoute{err: "There must be at least one path to send over".to_owned()}));
                }
                if payment_secret.is_none() && route.paths.len() > 1 {
-                       return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError{err: "Payment secret is required for multi-path payments".to_string()}));
+                       return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError{err: "Payment secret is required for multi-path payments".to_owned()}));
                }
                let mut total_value = 0;
-               let our_node_id = keys_manager.get_node_id(Recipient::Node).unwrap(); // TODO no unwrap
+               let our_node_id = node_signer.get_node_id(Recipient::Node).unwrap(); // TODO no unwrap
                let mut path_errs = Vec::with_capacity(route.paths.len());
                'path_check: for path in route.paths.iter() {
                        if path.len() < 1 || path.len() > 20 {
-                               path_errs.push(Err(APIError::InvalidRoute{err: "Path didn't go anywhere/had bogus size"}));
+                               path_errs.push(Err(APIError::InvalidRoute{err: "Path didn't go anywhere/had bogus size".to_owned()}));
                                continue 'path_check;
                        }
                        for (idx, hop) in path.iter().enumerate() {
                                if idx != path.len() - 1 && hop.pubkey == our_node_id {
-                                       path_errs.push(Err(APIError::InvalidRoute{err: "Path went through us but wasn't a simple rebalance loop to us"}));
+                                       path_errs.push(Err(APIError::InvalidRoute{err: "Path went through us but wasn't a simple rebalance loop to us".to_owned()}));
                                        continue 'path_check;
                                }
                        }
@@ -536,16 +977,11 @@ impl OutboundPayments {
                                                Some(RouteParameters {
                                                        payment_params: payment_params.clone(),
                                                        final_value_msat: pending_amt_unsent,
-                                                       final_cltv_expiry_delta: max_unsent_cltv_delta,
                                                })
                                        } else { None }
                                } else { None },
                        })
                } else if has_err {
-                       // If we failed to send any paths, we should remove the new PaymentId from the
-                       // `pending_outbound_payments` map, as the user isn't expected to `abandon_payment`.
-                       let removed = self.pending_outbound_payments.lock().unwrap().remove(&payment_id).is_some();
-                       debug_assert!(removed, "We should always have a pending payment to remove here");
                        Err(PaymentSendFailure::AllFailedResendSafe(results.drain(..).map(|r| r.unwrap_err()).collect()))
                } else {
                        Ok(())
@@ -553,20 +989,30 @@ impl OutboundPayments {
        }
 
        #[cfg(test)]
-       pub(super) fn test_send_payment_internal<K: Deref, F>(
+       pub(super) fn test_send_payment_internal<NS: Deref, F>(
                &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
                keysend_preimage: Option<PaymentPreimage>, payment_id: PaymentId, recv_value_msat: Option<u64>,
-               onion_session_privs: Vec<[u8; 32]>, keys_manager: &K, best_block_height: u32,
+               onion_session_privs: Vec<[u8; 32]>, node_signer: &NS, best_block_height: u32,
                send_payment_along_path: F
        ) -> Result<(), PaymentSendFailure>
        where
-               K::Target: KeysInterface,
+               NS::Target: NodeSigner,
                F: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
                   u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>
        {
-               self.send_payment_internal(route, payment_hash, payment_secret, keysend_preimage, payment_id,
-                       recv_value_msat, onion_session_privs, keys_manager, best_block_height,
-                       send_payment_along_path)
+               self.pay_route_internal(route, payment_hash, payment_secret, keysend_preimage, payment_id,
+                       recv_value_msat, onion_session_privs, node_signer, best_block_height,
+                       &send_payment_along_path)
+                       .map_err(|e| { self.remove_outbound_if_all_failed(payment_id, &e); e })
+       }
+
+       // If we failed to send any paths, remove the new PaymentId from the `pending_outbound_payments`
+       // map as the payment is free to be resent.
+       fn remove_outbound_if_all_failed(&self, payment_id: PaymentId, err: &PaymentSendFailure) {
+               if let &PaymentSendFailure::AllFailedResendSafe(_) = err {
+                       let removed = self.pending_outbound_payments.lock().unwrap().remove(&payment_id).is_some();
+                       debug_assert!(removed, "We should always have a pending payment to remove here");
+               }
        }
 
        pub(super) fn claim_htlc<L: Deref>(
@@ -677,57 +1123,96 @@ impl OutboundPayments {
                });
        }
 
+       // Returns a bool indicating whether a PendingHTLCsForwardable event should be generated.
        pub(super) fn fail_htlc<L: Deref>(
                &self, source: &HTLCSource, payment_hash: &PaymentHash, onion_error: &HTLCFailReason,
                path: &Vec<RouteHop>, session_priv: &SecretKey, payment_id: &PaymentId,
                payment_params: &Option<PaymentParameters>, probing_cookie_secret: [u8; 32],
                secp_ctx: &Secp256k1<secp256k1::All>, pending_events: &Mutex<Vec<events::Event>>, logger: &L
-       ) where L::Target: Logger {
+       ) -> bool where L::Target: Logger {
+               #[cfg(test)]
+               let (network_update, short_channel_id, payment_retryable, onion_error_code, onion_error_data) = onion_error.decode_onion_failure(secp_ctx, logger, &source);
+               #[cfg(not(test))]
+               let (network_update, short_channel_id, payment_retryable, _, _) = onion_error.decode_onion_failure(secp_ctx, logger, &source);
+
+               let payment_is_probe = payment_is_probe(payment_hash, &payment_id, probing_cookie_secret);
                let mut session_priv_bytes = [0; 32];
                session_priv_bytes.copy_from_slice(&session_priv[..]);
                let mut outbounds = self.pending_outbound_payments.lock().unwrap();
-               let mut all_paths_failed = false;
+
+               // If any payments already need retry, there's no need to generate a redundant
+               // `PendingHTLCsForwardable`.
+               let already_awaiting_retry = outbounds.iter().any(|(_, pmt)| {
+                       let mut awaiting_retry = false;
+                       if pmt.is_auto_retryable_now() {
+                               if let PendingOutboundPayment::Retryable { pending_amt_msat, total_msat, .. } = pmt {
+                                       if pending_amt_msat < total_msat {
+                                               awaiting_retry = true;
+                                       }
+                               }
+                       }
+                       awaiting_retry
+               });
+
                let mut full_failure_ev = None;
-               if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(*payment_id) {
+               let mut pending_retry_ev = false;
+               let mut retry = None;
+               let attempts_remaining = if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(*payment_id) {
                        if !payment.get_mut().remove(&session_priv_bytes, Some(&path)) {
                                log_trace!(logger, "Received duplicative fail for HTLC with payment_hash {}", log_bytes!(payment_hash.0));
-                               return
+                               return false
                        }
                        if payment.get().is_fulfilled() {
                                log_trace!(logger, "Received failure of HTLC with payment_hash {} after payment completion", log_bytes!(payment_hash.0));
-                               return
+                               return false
+                       }
+                       let mut is_retryable_now = payment.get().is_auto_retryable_now();
+                       if let Some(scid) = short_channel_id {
+                               payment.get_mut().insert_previously_failed_scid(scid);
+                       }
+
+                       // We want to move towards only using the `PaymentParameters` in the outbound payments
+                       // map. However, for backwards-compatibility, we still need to support passing the
+                       // `PaymentParameters` data that was shoved in the HTLC (and given to us via
+                       // `payment_params`) back to the user.
+                       let path_last_hop = path.last().expect("Outbound payments must have had a valid path");
+                       if let Some(params) = payment.get_mut().payment_parameters() {
+                               retry = Some(RouteParameters {
+                                       payment_params: params.clone(),
+                                       final_value_msat: path_last_hop.fee_msat,
+                               });
+                       } else if let Some(params) = payment_params {
+                               retry = Some(RouteParameters {
+                                       payment_params: params.clone(),
+                                       final_value_msat: path_last_hop.fee_msat,
+                               });
+                       }
+
+                       if payment_is_probe || !is_retryable_now || !payment_retryable || retry.is_none() {
+                               let _ = payment.get_mut().mark_abandoned(); // we'll only Err if it's a legacy payment
+                               is_retryable_now = false;
                        }
                        if payment.get().remaining_parts() == 0 {
-                               all_paths_failed = true;
                                if payment.get().abandoned() {
-                                       full_failure_ev = Some(events::Event::PaymentFailed {
-                                               payment_id: *payment_id,
-                                               payment_hash: payment.get().payment_hash().expect("PendingOutboundPayments::RetriesExceeded always has a payment hash set"),
-                                       });
+                                       if !payment_is_probe {
+                                               full_failure_ev = Some(events::Event::PaymentFailed {
+                                                       payment_id: *payment_id,
+                                                       payment_hash: payment.get().payment_hash().expect("PendingOutboundPayments::RetriesExceeded always has a payment hash set"),
+                                               });
+                                       }
                                        payment.remove();
                                }
                        }
+                       is_retryable_now
                } else {
                        log_trace!(logger, "Received duplicative fail for HTLC with payment_hash {}", log_bytes!(payment_hash.0));
-                       return
-               }
-               let mut retry = if let Some(payment_params_data) = payment_params {
-                       let path_last_hop = path.last().expect("Outbound payments must have had a valid path");
-                       Some(RouteParameters {
-                               payment_params: payment_params_data.clone(),
-                               final_value_msat: path_last_hop.fee_msat,
-                               final_cltv_expiry_delta: path_last_hop.cltv_expiry_delta,
-                       })
-               } else { None };
+                       return false
+               };
+               core::mem::drop(outbounds);
                log_trace!(logger, "Failing outbound payment HTLC with payment_hash {}", log_bytes!(payment_hash.0));
 
                let path_failure = {
-                       #[cfg(test)]
-                       let (network_update, short_channel_id, payment_retryable, onion_error_code, onion_error_data) = onion_error.decode_onion_failure(secp_ctx, logger, &source);
-                       #[cfg(not(test))]
-                       let (network_update, short_channel_id, payment_retryable, _, _) = onion_error.decode_onion_failure(secp_ctx, logger, &source);
-
-                       if payment_is_probe(payment_hash, &payment_id, probing_cookie_secret) {
+                       if payment_is_probe {
                                if !payment_retryable {
                                        events::Event::ProbeSuccessful {
                                                payment_id: *payment_id,
@@ -749,12 +1234,17 @@ impl OutboundPayments {
                                if let Some(scid) = short_channel_id {
                                        retry.as_mut().map(|r| r.payment_params.previously_failed_channels.push(scid));
                                }
+                               // If we miss abandoning the payment above, we *must* generate an event here or else the
+                               // payment will sit in our outbounds forever.
+                               if attempts_remaining && !already_awaiting_retry {
+                                       debug_assert!(full_failure_ev.is_none());
+                                       pending_retry_ev = true;
+                               }
                                events::Event::PaymentPathFailed {
                                        payment_id: Some(*payment_id),
                                        payment_hash: payment_hash.clone(),
                                        payment_failed_permanently: !payment_retryable,
-                                       network_update,
-                                       all_paths_failed,
+                                       failure: events::PathFailure::OnPath { network_update },
                                        path: path.clone(),
                                        short_channel_id,
                                        retry,
@@ -768,15 +1258,17 @@ impl OutboundPayments {
                let mut pending_events = pending_events.lock().unwrap();
                pending_events.push(path_failure);
                if let Some(ev) = full_failure_ev { pending_events.push(ev); }
+               pending_retry_ev
        }
 
-       pub(super) fn abandon_payment(&self, payment_id: PaymentId) -> Option<events::Event> {
-               let mut failed_ev = None;
+       pub(super) fn abandon_payment(
+               &self, payment_id: PaymentId, pending_events: &Mutex<Vec<events::Event>>
+       ) {
                let mut outbounds = self.pending_outbound_payments.lock().unwrap();
                if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(payment_id) {
                        if let Ok(()) = payment.get_mut().mark_abandoned() {
                                if payment.get().remaining_parts() == 0 {
-                                       failed_ev = Some(events::Event::PaymentFailed {
+                                       pending_events.lock().unwrap().push(events::Event::PaymentFailed {
                                                payment_id,
                                                payment_hash: payment.get().payment_hash().expect("PendingOutboundPayments::RetriesExceeded always has a payment hash set"),
                                        });
@@ -784,7 +1276,6 @@ impl OutboundPayments {
                                }
                        }
                }
-               failed_ev
        }
 
        #[cfg(test)]
@@ -828,13 +1319,214 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
                (0, session_privs, required),
                (1, pending_fee_msat, option),
                (2, payment_hash, required),
+               // Note that while we "default" payment_param's final CLTV expiry delta to 0 we should
+               // never see it - `payment_params` was added here after the field was added/required.
+               (3, payment_params, (option: ReadableArgs, 0)),
                (4, payment_secret, option),
+               (5, keysend_preimage, option),
                (6, total_msat, required),
                (8, pending_amt_msat, required),
                (10, starting_block_height, required),
+               (not_written, retry_strategy, (static_value, None)),
+               (not_written, attempts, (static_value, PaymentAttempts::new())),
        },
        (3, Abandoned) => {
                (0, session_privs, required),
                (2, payment_hash, required),
        },
 );
+
+#[cfg(test)]
+mod tests {
+       use bitcoin::network::constants::Network;
+       use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
+
+       use crate::ln::PaymentHash;
+       use crate::ln::channelmanager::PaymentId;
+       use crate::ln::features::{ChannelFeatures, NodeFeatures};
+       use crate::ln::msgs::{ErrorAction, LightningError};
+       use crate::ln::outbound_payment::{OutboundPayments, Retry, RetryableSendFailure};
+       use crate::routing::gossip::NetworkGraph;
+       use crate::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters};
+       use crate::sync::{Arc, Mutex};
+       use crate::util::errors::APIError;
+       use crate::util::events::{Event, PathFailure};
+       use crate::util::test_utils;
+
+       #[test]
+       #[cfg(feature = "std")]
+       fn fails_paying_after_expiration() {
+               do_fails_paying_after_expiration(false);
+               do_fails_paying_after_expiration(true);
+       }
+       #[cfg(feature = "std")]
+       fn do_fails_paying_after_expiration(on_retry: bool) {
+               let outbound_payments = OutboundPayments::new();
+               let logger = test_utils::TestLogger::new();
+               let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
+               let scorer = Mutex::new(test_utils::TestScorer::new());
+               let router = test_utils::TestRouter::new(network_graph, &scorer);
+               let secp_ctx = Secp256k1::new();
+               let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
+
+               let past_expiry_time = std::time::SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() - 2;
+               let payment_params = PaymentParameters::from_node_id(
+                               PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()),
+                               0
+                       ).with_expiry_time(past_expiry_time);
+               let expired_route_params = RouteParameters {
+                       payment_params,
+                       final_value_msat: 0,
+               };
+               let pending_events = Mutex::new(Vec::new());
+               if on_retry {
+                       outbound_payments.add_new_pending_payment(PaymentHash([0; 32]), None, PaymentId([0; 32]), None,
+                       &Route { paths: vec![], payment_params: None }, Some(Retry::Attempts(1)),
+                       Some(expired_route_params.payment_params.clone()), &&keys_manager, 0).unwrap();
+                       outbound_payments.retry_payment_internal(
+                               PaymentId([0; 32]), expired_route_params, &&router, vec![], &|| InFlightHtlcs::new(),
+                               &&keys_manager, &&keys_manager, 0, &&logger, &pending_events,
+                               &|_, _, _, _, _, _, _, _, _| Ok(()));
+                       let events = pending_events.lock().unwrap();
+                       assert_eq!(events.len(), 1);
+                       if let Event::PaymentFailed { .. } = events[0] { } else { panic!("Unexpected event"); }
+               } else {
+                       let err = outbound_payments.send_payment(
+                               PaymentHash([0; 32]), &None, PaymentId([0; 32]), Retry::Attempts(0), expired_route_params,
+                               &&router, vec![], || InFlightHtlcs::new(), &&keys_manager, &&keys_manager, 0, &&logger,
+                               &pending_events, |_, _, _, _, _, _, _, _, _| Ok(())).unwrap_err();
+                       if let RetryableSendFailure::PaymentExpired = err { } else { panic!("Unexpected error"); }
+               }
+       }
+
+       #[test]
+       fn find_route_error() {
+               do_find_route_error(false);
+               do_find_route_error(true);
+       }
+       fn do_find_route_error(on_retry: bool) {
+               let outbound_payments = OutboundPayments::new();
+               let logger = test_utils::TestLogger::new();
+               let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
+               let scorer = Mutex::new(test_utils::TestScorer::new());
+               let router = test_utils::TestRouter::new(network_graph, &scorer);
+               let secp_ctx = Secp256k1::new();
+               let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
+
+               let payment_params = PaymentParameters::from_node_id(
+                       PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0);
+               let route_params = RouteParameters {
+                       payment_params,
+                       final_value_msat: 0,
+               };
+               router.expect_find_route(route_params.clone(),
+                       Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError }));
+
+               let pending_events = Mutex::new(Vec::new());
+               if on_retry {
+                       outbound_payments.add_new_pending_payment(PaymentHash([0; 32]), None, PaymentId([0; 32]), None,
+                               &Route { paths: vec![], payment_params: None }, Some(Retry::Attempts(1)),
+                               Some(route_params.payment_params.clone()), &&keys_manager, 0).unwrap();
+                       outbound_payments.retry_payment_internal(
+                               PaymentId([0; 32]), route_params, &&router, vec![], &|| InFlightHtlcs::new(),
+                               &&keys_manager, &&keys_manager, 0, &&logger, &pending_events,
+                               &|_, _, _, _, _, _, _, _, _| Ok(()));
+                       let events = pending_events.lock().unwrap();
+                       assert_eq!(events.len(), 1);
+                       if let Event::PaymentFailed { .. } = events[0] { } else { panic!("Unexpected event"); }
+               } else {
+                       let err = outbound_payments.send_payment(
+                               PaymentHash([0; 32]), &None, PaymentId([0; 32]), Retry::Attempts(0), route_params,
+                               &&router, vec![], || InFlightHtlcs::new(), &&keys_manager, &&keys_manager, 0, &&logger,
+                               &pending_events, |_, _, _, _, _, _, _, _, _| Ok(())).unwrap_err();
+                       if let RetryableSendFailure::RouteNotFound = err {
+                       } else { panic!("Unexpected error"); }
+               }
+       }
+
+       #[test]
+       fn initial_send_payment_path_failed_evs() {
+               let outbound_payments = OutboundPayments::new();
+               let logger = test_utils::TestLogger::new();
+               let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
+               let scorer = Mutex::new(test_utils::TestScorer::new());
+               let router = test_utils::TestRouter::new(network_graph, &scorer);
+               let secp_ctx = Secp256k1::new();
+               let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
+
+               let sender_pk = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
+               let receiver_pk = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap());
+               let payment_params = PaymentParameters::from_node_id(sender_pk, 0);
+               let route_params = RouteParameters {
+                       payment_params: payment_params.clone(),
+                       final_value_msat: 0,
+               };
+               let failed_scid = 42;
+               let route = Route {
+                       paths: vec![vec![RouteHop {
+                               pubkey: receiver_pk,
+                               node_features: NodeFeatures::empty(),
+                               short_channel_id: failed_scid,
+                               channel_features: ChannelFeatures::empty(),
+                               fee_msat: 0,
+                               cltv_expiry_delta: 0,
+                       }]],
+                       payment_params: Some(payment_params),
+               };
+               router.expect_find_route(route_params.clone(), Ok(route.clone()));
+               let mut route_params_w_failed_scid = route_params.clone();
+               route_params_w_failed_scid.payment_params.previously_failed_channels.push(failed_scid);
+               router.expect_find_route(route_params_w_failed_scid, Ok(route.clone()));
+               router.expect_find_route(route_params.clone(), Ok(route.clone()));
+               router.expect_find_route(route_params.clone(), Ok(route.clone()));
+
+               // Ensure that a ChannelUnavailable error will result in blaming an scid in the
+               // PaymentPathFailed event.
+               let pending_events = Mutex::new(Vec::new());
+               outbound_payments.send_payment(
+                       PaymentHash([0; 32]), &None, PaymentId([0; 32]), Retry::Attempts(0), route_params.clone(),
+                       &&router, vec![], || InFlightHtlcs::new(), &&keys_manager, &&keys_manager, 0, &&logger,
+                       &pending_events,
+                       |_, _, _, _, _, _, _, _, _| Err(APIError::ChannelUnavailable { err: "test".to_owned() }))
+                       .unwrap();
+               let mut events = pending_events.lock().unwrap();
+               assert_eq!(events.len(), 2);
+               if let Event::PaymentPathFailed {
+                       short_channel_id,
+                       failure: PathFailure::InitialSend { err: APIError::ChannelUnavailable { .. }}, .. } = events[0]
+               {
+                       assert_eq!(short_channel_id, Some(failed_scid));
+               } else { panic!("Unexpected event"); }
+               if let Event::PaymentFailed { .. } = events[1] { } else { panic!("Unexpected event"); }
+               events.clear();
+               core::mem::drop(events);
+
+               // Ensure that a MonitorUpdateInProgress "error" will not result in a PaymentPathFailed event.
+               outbound_payments.send_payment(
+                       PaymentHash([0; 32]), &None, PaymentId([0; 32]), Retry::Attempts(0), route_params.clone(),
+                       &&router, vec![], || InFlightHtlcs::new(), &&keys_manager, &&keys_manager, 0, &&logger,
+                       &pending_events, |_, _, _, _, _, _, _, _, _| Err(APIError::MonitorUpdateInProgress))
+                       .unwrap();
+               {
+                       let events = pending_events.lock().unwrap();
+                       assert_eq!(events.len(), 0);
+               }
+
+               // Ensure that any other error will result in a PaymentPathFailed event but no blamed scid.
+               outbound_payments.send_payment(
+                       PaymentHash([0; 32]), &None, PaymentId([1; 32]), Retry::Attempts(0), route_params.clone(),
+                       &&router, vec![], || InFlightHtlcs::new(), &&keys_manager, &&keys_manager, 0, &&logger,
+                       &pending_events,
+                       |_, _, _, _, _, _, _, _, _| Err(APIError::APIMisuseError { err: "test".to_owned() }))
+                       .unwrap();
+               let events = pending_events.lock().unwrap();
+               assert_eq!(events.len(), 2);
+               if let Event::PaymentPathFailed {
+                       short_channel_id,
+                       failure: PathFailure::InitialSend { err: APIError::APIMisuseError { .. }}, .. } = events[0]
+               {
+                       assert_eq!(short_channel_id, None);
+               } else { panic!("Unexpected event"); }
+               if let Event::PaymentFailed { .. } = events[1] { } else { panic!("Unexpected event"); }
+       }
+}
index 6c3f98df406d99ec331053d0289c91f0dbd24952..15361b98ad71fd9ee1193891aa71f4d45ef5d9a3 100644 (file)
 
 use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Listen, Watch};
 use crate::chain::channelmonitor::{ANTI_REORG_DELAY, LATENCY_GRACE_PERIOD_BLOCKS};
+use crate::chain::keysinterface::EntropySource;
 use crate::chain::transaction::OutPoint;
-use crate::chain::keysinterface::{EntropySource, KeysInterface};
 use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS;
-use crate::ln::channelmanager::{self, BREAKDOWN_TIMEOUT, ChannelManager, MPP_TIMEOUT_TICKS, MIN_CLTV_EXPIRY_DELTA, PaymentId, PaymentSendFailure, IDEMPOTENCY_TIMEOUT_TICKS};
+use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, MPP_TIMEOUT_TICKS, MIN_CLTV_EXPIRY_DELTA, PaymentId, PaymentSendFailure, IDEMPOTENCY_TIMEOUT_TICKS, RecentPaymentDetails};
+use crate::ln::features::InvoiceFeatures;
 use crate::ln::msgs;
 use crate::ln::msgs::ChannelMessageHandler;
-use crate::routing::gossip::RoutingFees;
-use crate::routing::router::{get_route, PaymentParameters, RouteHint, RouteHintHop, RouteParameters};
-use crate::util::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider};
+use crate::ln::outbound_payment::Retry;
+use crate::routing::gossip::{EffectiveCapacity, RoutingFees};
+use crate::routing::router::{get_route, PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RouteParameters};
+use crate::routing::scoring::ChannelUsage;
+use crate::util::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure};
 use crate::util::test_utils;
 use crate::util::errors::APIError;
 use crate::util::ser::Writeable;
@@ -34,60 +37,11 @@ use crate::prelude::*;
 
 use crate::ln::functional_test_utils::*;
 use crate::routing::gossip::NodeId;
-
-#[test]
-fn retry_single_path_payment() {
-       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, &[None, None, None]);
-       let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-
-       let _chan_0 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 2, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       // Rebalance to find a route
-       send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000);
-
-       let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 100_000);
-
-       // Rebalance so that the first hop fails.
-       send_payment(&nodes[1], &vec!(&nodes[2])[..], 2_000_000);
-
-       // Make sure the payment fails on the first hop.
-       let payment_id = PaymentId(payment_hash.0);
-       nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), payment_id).unwrap();
-       check_added_monitors!(nodes[0], 1);
-       let mut events = nodes[0].node.get_and_clear_pending_msg_events();
-       assert_eq!(events.len(), 1);
-       let mut payment_event = SendEvent::from_event(events.pop().unwrap());
-       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
-       check_added_monitors!(nodes[1], 0);
-       commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
-       expect_pending_htlcs_forwardable!(nodes[1]);
-       expect_pending_htlcs_forwardable_and_htlc_handling_failed!(&nodes[1], vec![HTLCDestination::NextHopChannel { node_id: Some(nodes[2].node.get_our_node_id()), channel_id: chan_1.2 }]);
-       let htlc_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
-       assert!(htlc_updates.update_add_htlcs.is_empty());
-       assert_eq!(htlc_updates.update_fail_htlcs.len(), 1);
-       assert!(htlc_updates.update_fulfill_htlcs.is_empty());
-       assert!(htlc_updates.update_fail_malformed_htlcs.is_empty());
-       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());
-
-       // Rebalance the channel so the retry succeeds.
-       send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000);
-
-       // Mine two blocks (we expire retries after 3, so this will check that we don't expire early)
-       connect_blocks(&nodes[0], 2);
-
-       // Retry the payment and make sure it succeeds.
-       nodes[0].node.retry_payment(&route, payment_id).unwrap();
-       check_added_monitors!(nodes[0], 1);
-       let mut events = nodes[0].node.get_and_clear_pending_msg_events();
-       assert_eq!(events.len(), 1);
-       pass_along_path(&nodes[0], &[&nodes[1], &nodes[2]], 100_000, payment_hash, Some(payment_secret), events.pop().unwrap(), true, None);
-       claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage);
-}
+#[cfg(feature = "std")]
+use {
+       crate::util::time::tests::SinceEpoch,
+       std::time::{SystemTime, Instant, Duration}
+};
 
 #[test]
 fn mpp_failure() {
@@ -96,10 +50,10 @@ fn mpp_failure() {
        let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
        let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-       let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-       let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-       let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
-       let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
+       let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+       let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2).0.contents.short_channel_id;
+       let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3).0.contents.short_channel_id;
+       let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3).0.contents.short_channel_id;
 
        let (mut route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[3], 100000);
        let path = route.paths[0].clone();
@@ -121,14 +75,15 @@ fn mpp_retry() {
        let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
        let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-       let (chan_1_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let (chan_2_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 0, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let (chan_3_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 1, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let (chan_4_update, _, chan_4_id, _) = create_announced_chan_between_nodes(&nodes, 3, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let (chan_1_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let (chan_2_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 0, 2);
+       let (chan_3_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 1, 3);
+       let (chan_4_update, _, chan_4_id, _) = create_announced_chan_between_nodes(&nodes, 3, 2);
        // Rebalance
        send_payment(&nodes[3], &vec!(&nodes[2])[..], 1_500_000);
 
-       let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[3], 1_000_000);
+       let amt_msat = 1_000_000;
+       let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[3], amt_msat);
        let path = route.paths[0].clone();
        route.paths.push(path);
        route.paths[0][0].pubkey = nodes[1].node.get_our_node_id();
@@ -140,17 +95,23 @@ fn mpp_retry() {
 
        // Initiate the MPP payment.
        let payment_id = PaymentId(payment_hash.0);
-       nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), payment_id).unwrap();
+       let mut route_params = RouteParameters {
+               payment_params: route.payment_params.clone().unwrap(),
+               final_value_msat: amt_msat,
+       };
+
+       nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
+       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), payment_id, route_params.clone(), Retry::Attempts(1)).unwrap();
        check_added_monitors!(nodes[0], 2); // one monitor per path
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 2);
 
        // Pass half of the payment along the success path.
-       let success_path_msgs = events.remove(0);
+       let success_path_msgs = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events);
        pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 2_000_000, payment_hash, Some(payment_secret), success_path_msgs, false, None);
 
        // Add the HTLC along the first hop.
-       let fail_path_msgs_1 = events.remove(0);
+       let fail_path_msgs_1 = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events);
        let (update_add, commitment_signed) = match fail_path_msgs_1 {
                MessageSendEvent::UpdateHTLCs { node_id: _, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
                        assert_eq!(update_add_htlcs.len(), 1);
@@ -176,25 +137,23 @@ 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());
+       let mut events = nodes[0].node.get_and_clear_pending_events();
+       match events[1] {
+               Event::PendingHTLCsForwardable { .. } => {},
+               _ => panic!("Unexpected event")
+       }
+       events.remove(1);
+       expect_payment_failed_conditions_event(events, 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);
 
-       // Make sure it errors as expected given a too-large amount.
-       if let Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError { err })) = nodes[0].node.retry_payment(&route, payment_id) {
-               assert!(err.contains("over total_payment_amt_msat"));
-       } else { panic!("Unexpected error"); }
-
-       // Make sure it errors as expected given the wrong payment_id.
-       if let Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError { err })) = nodes[0].node.retry_payment(&route, PaymentId([0; 32])) {
-               assert!(err.contains("not found"));
-       } else { panic!("Unexpected error"); }
-
        // Retry the second half of the payment and make sure it succeeds.
-       let mut path = route.clone();
-       path.paths.remove(0);
-       nodes[0].node.retry_payment(&path, payment_id).unwrap();
+       route.paths.remove(0);
+       route_params.final_value_msat = 1_000_000;
+       route_params.payment_params.previously_failed_channels.push(chan_4_update.contents.short_channel_id);
+       nodes[0].router.expect_find_route(route_params, Ok(route));
+       nodes[0].node.process_pending_htlc_forwards();
        check_added_monitors!(nodes[0], 1);
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 1);
@@ -208,10 +167,10 @@ fn do_mpp_receive_timeout(send_partial_mpp: bool) {
        let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
        let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-       let (chan_1_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let (chan_2_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 0, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let (chan_3_update, _, chan_3_id, _) = create_announced_chan_between_nodes(&nodes, 1, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let (chan_4_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 2, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let (chan_1_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let (chan_2_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 0, 2);
+       let (chan_3_update, _, chan_3_id, _) = create_announced_chan_between_nodes(&nodes, 1, 3);
+       let (chan_4_update, _, _, _) = create_announced_chan_between_nodes(&nodes, 2, 3);
 
        let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[3], 100_000);
        let path = route.paths[0].clone();
@@ -230,7 +189,8 @@ fn do_mpp_receive_timeout(send_partial_mpp: bool) {
        assert_eq!(events.len(), 2);
 
        // Pass half of the payment along the first path.
-       pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 200_000, payment_hash, Some(payment_secret), events.remove(0), false, None);
+       let node_1_msgs = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events);
+       pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 200_000, payment_hash, Some(payment_secret), node_1_msgs, false, None);
 
        if send_partial_mpp {
                // Time out the partial MPP
@@ -257,7 +217,8 @@ fn do_mpp_receive_timeout(send_partial_mpp: bool) {
                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);
+               let node_2_msgs = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events);
+               pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash, Some(payment_secret), node_2_msgs, true, None);
 
                // Even after MPP_TIMEOUT_TICKS we should not timeout the MPP if we have all the parts
                for _ in 0..MPP_TIMEOUT_TICKS {
@@ -274,55 +235,6 @@ fn mpp_receive_timeout() {
        do_mpp_receive_timeout(false);
 }
 
-#[test]
-fn retry_expired_payment() {
-       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, &[None, None, None]);
-       let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-
-       let _chan_0 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 2, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       // Rebalance to find a route
-       send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000);
-
-       let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 100_000);
-
-       // Rebalance so that the first hop fails.
-       send_payment(&nodes[1], &vec!(&nodes[2])[..], 2_000_000);
-
-       // Make sure the payment fails on the first hop.
-       nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
-       check_added_monitors!(nodes[0], 1);
-       let mut events = nodes[0].node.get_and_clear_pending_msg_events();
-       assert_eq!(events.len(), 1);
-       let mut payment_event = SendEvent::from_event(events.pop().unwrap());
-       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
-       check_added_monitors!(nodes[1], 0);
-       commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
-       expect_pending_htlcs_forwardable!(nodes[1]);
-       expect_pending_htlcs_forwardable_and_htlc_handling_failed!(&nodes[1], vec![HTLCDestination::NextHopChannel { node_id: Some(nodes[2].node.get_our_node_id()), channel_id: chan_1.2 }]);
-       let htlc_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
-       assert!(htlc_updates.update_add_htlcs.is_empty());
-       assert_eq!(htlc_updates.update_fail_htlcs.len(), 1);
-       assert!(htlc_updates.update_fulfill_htlcs.is_empty());
-       assert!(htlc_updates.update_fail_malformed_htlcs.is_empty());
-       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!(nodes[0], payment_hash, false);
-
-       // Mine blocks so the payment will have expired.
-       connect_blocks(&nodes[0], 3);
-
-       // Retry the payment and make sure it errors as expected.
-       if let Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError { err })) = nodes[0].node.retry_payment(&route, PaymentId(payment_hash.0)) {
-               assert!(err.contains("not found"));
-       } else {
-               panic!("Unexpected error");
-       }
-}
-
 #[test]
 fn no_pending_leak_on_initial_send_failure() {
        // In an earlier version of our payment tracking, we'd have a retry entry even when the initial
@@ -336,16 +248,16 @@ fn no_pending_leak_on_initial_send_failure() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)),
                true, APIError::ChannelUnavailable { ref err },
-               assert_eq!(err, "Peer for first hop currently disconnected/pending monitor update!"));
+               assert_eq!(err, "Peer for first hop currently disconnected"));
 
        assert!(!nodes[0].node.has_pending_payments());
 }
@@ -367,20 +279,25 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
-       let (_, _, chan_id_2, _) = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
+       let (_, _, chan_id_2, _) = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // Serialize the ChannelManager prior to sending payments
        let nodes_0_serialized = nodes[0].node.encode();
 
        // Send two payments - one which will get to nodes[2] and will be claimed, one which we'll time
        // out and retry.
-       let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 1_000_000);
+       let amt_msat = 1_000_000;
+       let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat);
        let (payment_preimage_1, payment_hash_1, _, payment_id_1) = send_along_route(&nodes[0], route.clone(), &[&nodes[1], &nodes[2]], 1_000_000);
-       nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
+       let route_params = RouteParameters {
+               payment_params: route.payment_params.clone().unwrap(),
+               final_value_msat: amt_msat,
+       };
+       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -391,8 +308,8 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
        // We relay the payment to nodes[1] while its disconnected from nodes[2], causing the payment
        // to be returned immediately to nodes[0], without having nodes[2] fail the inbound payment
        // which would prevent retry.
-       nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false);
-       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id());
+       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id());
 
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
        commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false, true);
@@ -421,13 +338,13 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
        assert_eq!(as_broadcasted_txn.len(), 1);
        assert_eq!(as_broadcasted_txn[0], as_commitment_tx);
 
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
        // Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an
        // error, as the channel has hit the chain.
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
        nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
        let as_err = nodes[0].node.get_and_clear_pending_msg_events();
@@ -436,7 +353,7 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
                MessageSendEvent::HandleError { node_id, action: msgs::ErrorAction::SendErrorMessage { ref msg } } => {
                        assert_eq!(node_id, nodes[1].node.get_our_node_id());
                        nodes[1].node.handle_error(&nodes[0].node.get_our_node_id(), msg);
-                       check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: "Failed to find corresponding channel".to_string() });
+                       check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", &nodes[1].node.get_our_node_id()) });
                        check_added_monitors!(nodes[1], 1);
                        assert_eq!(nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0).len(), 1);
                },
@@ -464,7 +381,7 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
        // Create a new channel on which to retry the payment before we fail the payment via the
        // HTLC-Timeout transaction. This avoids ChannelManager timing out the payment due to us
        // connecting several blocks while creating the channel (implying time has passed).
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
        assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
 
        mine_transaction(&nodes[1], &as_commitment_tx);
@@ -489,7 +406,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());
 
        // 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
@@ -500,8 +417,10 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
        // and not the original fee. We also update node[1]'s relevant config as
        // do_claim_payment_along_route expects us to never overpay.
        {
-               let mut channel_state = nodes[1].node.channel_state.lock().unwrap();
-               let mut channel = channel_state.by_id.get_mut(&chan_id_2).unwrap();
+               let per_peer_state = nodes[1].node.per_peer_state.read().unwrap();
+               let mut peer_state = per_peer_state.get(&nodes[2].node.get_our_node_id())
+                       .unwrap().lock().unwrap();
+               let mut channel = peer_state.channel_by_id.get_mut(&chan_id_2).unwrap();
                let mut new_config = channel.config();
                new_config.forwarding_fee_base_msat += 100_000;
                channel.update_config(&new_config);
@@ -513,8 +432,8 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
                nodes[1].node.timer_tick_occurred();
        }
 
-       assert!(nodes[0].node.retry_payment(&new_route, payment_id_1).is_err()); // Shouldn't be allowed to retry a fulfilled payment
-       nodes[0].node.retry_payment(&new_route, PaymentId(payment_hash.0)).unwrap();
+       assert!(nodes[0].node.send_payment(&new_route, payment_hash, &Some(payment_secret), payment_id_1).is_err()); // Shouldn't be allowed to retry a fulfilled payment
+       nodes[0].node.send_payment(&new_route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
        check_added_monitors!(nodes[0], 1);
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 1);
@@ -545,13 +464,13 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) {
 
        let first_persister: test_utils::TestPersister;
        let first_new_chain_monitor: test_utils::TestChainMonitor;
-       let first_nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let first_nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let second_persister: test_utils::TestPersister;
        let second_new_chain_monitor: test_utils::TestChainMonitor;
-       let second_nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let second_nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let third_persister: test_utils::TestPersister;
        let third_new_chain_monitor: test_utils::TestChainMonitor;
-       let third_nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let third_nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
 
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
@@ -562,7 +481,7 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) {
        // Ignore the announcement_signatures messages
        nodes[0].node.get_and_clear_pending_msg_events();
        nodes[1].node.get_and_clear_pending_msg_events();
-       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
 
        // Serialize the ChannelManager prior to sending payments
        let mut nodes_0_serialized = nodes[0].node.encode();
@@ -575,7 +494,7 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) {
        let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
 
        reload_node!(nodes[0], test_default_channel_config(), nodes_0_serialized, &[&chan_0_monitor_serialized], first_persister, first_new_chain_monitor, first_nodes_0_deserialized);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        // On reload, the ChannelManager should realize it is stale compared to the ChannelMonitor and
        // force-close the channel.
@@ -584,12 +503,12 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) {
        assert!(nodes[0].node.has_pending_payments());
        assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0).len(), 1);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
        // Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an
        // error, as the channel has hit the chain.
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
        nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
        let as_err = nodes[0].node.get_and_clear_pending_msg_events();
@@ -599,7 +518,7 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) {
                MessageSendEvent::HandleError { node_id, action: msgs::ErrorAction::SendErrorMessage { ref msg } } => {
                        assert_eq!(node_id, nodes[1].node.get_our_node_id());
                        nodes[1].node.handle_error(&nodes[0].node.get_our_node_id(), msg);
-                       check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: "Failed to find corresponding channel".to_string() });
+                       check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", &nodes[1].node.get_our_node_id()) });
                        check_added_monitors!(nodes[1], 1);
                        bs_commitment_tx = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
                },
@@ -648,7 +567,10 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) {
        // If we attempt to retry prior to the HTLC-Timeout (or commitment transaction, for dust HTLCs)
        // confirming, we will fail as it's considered still-pending...
        let (new_route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[2], if use_dust { 1_000 } else { 1_000_000 });
-       assert!(nodes[0].node.retry_payment(&new_route, payment_id).is_err());
+       match nodes[0].node.send_payment(&new_route, payment_hash, &Some(payment_secret), payment_id) {
+               Err(PaymentSendFailure::DuplicatePayment) => {},
+               _ => panic!("Unexpected error")
+       }
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
        // After ANTI_REORG_DELAY confirmations, the HTLC should be failed and we can try the payment
@@ -656,42 +578,49 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) {
        // (which should also still work).
        connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
        connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1);
-       // We set mpp_parts_remain to avoid having abandon_payment called
-       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());
 
        let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
        let chan_1_monitor_serialized = get_monitor!(nodes[0], chan_id_3).encode();
        nodes_0_serialized = nodes[0].node.encode();
 
-       assert!(nodes[0].node.retry_payment(&new_route, payment_id).is_ok());
+       // After the payment failed, we're free to send it again.
+       assert!(nodes[0].node.send_payment(&new_route, payment_hash, &Some(payment_secret), payment_id).is_ok());
        assert!(!nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
        reload_node!(nodes[0], test_default_channel_config(), nodes_0_serialized, &[&chan_0_monitor_serialized, &chan_1_monitor_serialized], second_persister, second_new_chain_monitor, second_nodes_0_deserialized);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
        // Now resend the payment, delivering the HTLC and actually claiming it this time. This ensures
        // the payment is not (spuriously) listed as still pending.
-       assert!(nodes[0].node.retry_payment(&new_route, payment_id).is_ok());
+       assert!(nodes[0].node.send_payment(&new_route, payment_hash, &Some(payment_secret), payment_id).is_ok());
        check_added_monitors!(nodes[0], 1);
        pass_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], if use_dust { 1_000 } else { 1_000_000 }, payment_hash, payment_secret);
        claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
 
-       assert!(nodes[0].node.retry_payment(&new_route, payment_id).is_err());
+       match nodes[0].node.send_payment(&new_route, payment_hash, &Some(payment_secret), payment_id) {
+               Err(PaymentSendFailure::DuplicatePayment) => {},
+               _ => panic!("Unexpected error")
+       }
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
        let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
        let chan_1_monitor_serialized = get_monitor!(nodes[0], chan_id_3).encode();
        nodes_0_serialized = nodes[0].node.encode();
 
-       // Ensure that after reload we cannot retry the payment.
+       // Check that after reload we can send the payment again (though we shouldn't, since it was
+       // claimed previously).
        reload_node!(nodes[0], test_default_channel_config(), nodes_0_serialized, &[&chan_0_monitor_serialized, &chan_1_monitor_serialized], third_persister, third_new_chain_monitor, third_nodes_0_deserialized);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
-       assert!(nodes[0].node.retry_payment(&new_route, payment_id).is_err());
+       match nodes[0].node.send_payment(&new_route, payment_hash, &Some(payment_secret), payment_id) {
+               Err(PaymentSendFailure::DuplicatePayment) => {},
+               _ => panic!("Unexpected error")
+       }
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 }
 
@@ -716,10 +645,10 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        // Route a payment, but force-close the channel before the HTLC fulfill message arrives at
        // nodes[0].
@@ -729,8 +658,8 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co
        check_added_monitors!(nodes[0], 1);
        check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        // Connect blocks until the CLTV timeout is up so that we get an HTLC-Timeout transaction
        connect_blocks(&nodes[0], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + 1);
@@ -859,10 +788,10 @@ fn test_fulfill_restart_failure() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_1_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_1_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 100_000);
 
        // The simplest way to get a failure after a fulfill is to reload nodes[1] from a state
@@ -881,7 +810,7 @@ fn test_fulfill_restart_failure() {
        // Now reload nodes[1]...
        reload_node!(nodes[1], &chan_manager_serialized, &[&chan_0_monitor_serialized], persister, new_chain_monitor, nodes_1_deserialized);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
        reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
        nodes[1].node.fail_htlc_backwards(&payment_hash);
@@ -902,15 +831,15 @@ fn get_ldk_payment_preimage() {
        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);
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
 
        let amt_msat = 60_000;
        let expiry_secs = 60 * 60;
-       let (payment_hash, payment_secret) = nodes[1].node.create_inbound_payment(Some(amt_msat), expiry_secs).unwrap();
+       let (payment_hash, payment_secret) = nodes[1].node.create_inbound_payment(Some(amt_msat), expiry_secs, None).unwrap();
 
-       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features());
-       let scorer = test_utils::TestScorer::with_penalty(0);
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_features(nodes[1].node.invoice_features());
+       let scorer = test_utils::TestScorer::new();
        let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
        let random_seed_bytes = keys_manager.get_secure_random_bytes();
        let route = get_route(
@@ -935,8 +864,8 @@ fn sent_probe_is_probe_of_sending_node() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None, None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // First check we refuse to build a single-hop probe
        let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[1], 100_000);
@@ -965,8 +894,8 @@ fn successful_probe_yields_event() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None, None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       create_announced_chan_between_nodes(&nodes, 1, 2);
 
        let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[2], 100_000);
 
@@ -1010,6 +939,7 @@ fn successful_probe_yields_event() {
                },
                _ => panic!(),
        };
+       assert!(!nodes[0].node.has_pending_payments());
 }
 
 #[test]
@@ -1019,10 +949,10 @@ fn failed_probe_yields_event() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None, None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 90000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 90000000);
 
-       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id());
+       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42);
 
        let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[2], &payment_params, 9_998_000, 42);
 
@@ -1055,6 +985,7 @@ fn failed_probe_yields_event() {
                },
                _ => panic!(),
        };
+       assert!(!nodes[0].node.has_pending_payments());
 }
 
 #[test]
@@ -1066,10 +997,10 @@ fn onchain_failed_probe_yields_event() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
-       create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
+       create_announced_chan_between_nodes(&nodes, 1, 2);
 
-       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id());
+       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42);
 
        // Send a dust HTLC, which will be treated as if it timed out once the channel hits the chain.
        let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[2], &payment_params, 1_000, 42);
@@ -1109,6 +1040,7 @@ fn onchain_failed_probe_yields_event() {
                }
        }
        assert!(found_probe_failed);
+       assert!(!nodes[0].node.has_pending_payments());
 }
 
 #[test]
@@ -1119,7 +1051,7 @@ fn claimed_send_payment_idempotent() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let (route, second_payment_hash, second_payment_preimage, second_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000);
        let (first_payment_preimage, _, _, payment_id) = send_along_route(&nodes[0], route.clone(), &[&nodes[1]], 100_000);
@@ -1191,7 +1123,7 @@ fn abandoned_send_payment_idempotent() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let (route, second_payment_hash, second_payment_preimage, second_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000);
        let (_, first_payment_hash, _, payment_id) = send_along_route(&nodes[0], route.clone(), &[&nodes[1]], 100_000);
@@ -1221,20 +1153,17 @@ fn abandoned_send_payment_idempotent() {
        nodes[1].node.fail_htlc_backwards(&first_payment_hash);
        expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[1], [HTLCDestination::FailedPayment { payment_hash: first_payment_hash }]);
 
-       pass_failed_payment_back_no_abandon(&nodes[0], &[&[&nodes[1]]], false, first_payment_hash);
-       check_send_rejected!();
-
-       // Until we abandon the payment, no matter how many timer ticks pass, we still cannot reuse the
+       // Until we abandon the payment upon path failure, no matter how many timer ticks pass, we still cannot reuse the
        // PaymentId.
        for _ in 0..=IDEMPOTENCY_TIMEOUT_TICKS {
                nodes[0].node.timer_tick_occurred();
        }
        check_send_rejected!();
 
-       nodes[0].node.abandon_payment(payment_id);
-       get_event!(nodes[0], Event::PaymentFailed);
+       pass_failed_payment_back(&nodes[0], &[&[&nodes[1]]], false, first_payment_hash);
 
-       // However, we can reuse the PaymentId immediately after we `abandon_payment`.
+       // However, we can reuse the PaymentId immediately after we `abandon_payment` upon passing the
+       // failed payment back.
        nodes[0].node.send_payment(&route, second_payment_hash, &Some(second_payment_secret), payment_id).unwrap();
        check_added_monitors!(nodes[0], 1);
        pass_along_route(&nodes[0], &[&[&nodes[1]]], 100_000, second_payment_hash, second_payment_secret);
@@ -1259,84 +1188,115 @@ fn test_trivial_inflight_htlc_tracking(){
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       let (_, _, chan_1_id, _) = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let (_, _, chan_2_id, _) = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let (_, _, chan_1_id, _) = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let (_, _, chan_2_id, _) = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // Send and claim the payment. Inflight HTLCs should be empty.
-       send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 500000);
+       let payment_hash = send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 500000).1;
+       let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
        {
-               let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
-
-               let node_0_channel_lock = nodes[0].node.channel_state.lock().unwrap();
-               let node_1_channel_lock = nodes[1].node.channel_state.lock().unwrap();
-               let channel_1 = node_0_channel_lock.by_id.get(&chan_1_id).unwrap();
-               let channel_2 = node_1_channel_lock.by_id.get(&chan_2_id).unwrap();
+               let mut node_0_per_peer_lock;
+               let mut node_0_peer_state_lock;
+               let channel_1 =  get_channel_ref!(&nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, chan_1_id);
 
                let chan_1_used_liquidity = inflight_htlcs.used_liquidity_msat(
                        &NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) ,
                        &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()),
                        channel_1.get_short_channel_id().unwrap()
                );
+               assert_eq!(chan_1_used_liquidity, None);
+       }
+       {
+               let mut node_1_per_peer_lock;
+               let mut node_1_peer_state_lock;
+               let channel_2 =  get_channel_ref!(&nodes[1], nodes[2], node_1_per_peer_lock, node_1_peer_state_lock, chan_2_id);
+
                let chan_2_used_liquidity = inflight_htlcs.used_liquidity_msat(
                        &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()) ,
                        &NodeId::from_pubkey(&nodes[2].node.get_our_node_id()),
                        channel_2.get_short_channel_id().unwrap()
                );
 
-               assert_eq!(chan_1_used_liquidity, None);
                assert_eq!(chan_2_used_liquidity, None);
        }
+       let pending_payments = nodes[0].node.list_recent_payments();
+       assert_eq!(pending_payments.len(), 1);
+       assert_eq!(pending_payments[0], RecentPaymentDetails::Fulfilled { payment_hash: Some(payment_hash) });
+
+       // Remove fulfilled payment
+       for _ in 0..=IDEMPOTENCY_TIMEOUT_TICKS {
+               nodes[0].node.timer_tick_occurred();
+       }
 
        // Send the payment, but do not claim it. Our inflight HTLCs should contain the pending payment.
-       let (payment_preimage, _,  _) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 500000);
+       let (payment_preimage, payment_hash,  _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 500000);
+       let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
        {
-               let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
-
-               let node_0_channel_lock = nodes[0].node.channel_state.lock().unwrap();
-               let node_1_channel_lock = nodes[1].node.channel_state.lock().unwrap();
-               let channel_1 = node_0_channel_lock.by_id.get(&chan_1_id).unwrap();
-               let channel_2 = node_1_channel_lock.by_id.get(&chan_2_id).unwrap();
+               let mut node_0_per_peer_lock;
+               let mut node_0_peer_state_lock;
+               let channel_1 =  get_channel_ref!(&nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, chan_1_id);
 
                let chan_1_used_liquidity = inflight_htlcs.used_liquidity_msat(
                        &NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) ,
                        &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()),
                        channel_1.get_short_channel_id().unwrap()
                );
+               // First hop accounts for expected 1000 msat fee
+               assert_eq!(chan_1_used_liquidity, Some(501000));
+       }
+       {
+               let mut node_1_per_peer_lock;
+               let mut node_1_peer_state_lock;
+               let channel_2 =  get_channel_ref!(&nodes[1], nodes[2], node_1_per_peer_lock, node_1_peer_state_lock, chan_2_id);
+
                let chan_2_used_liquidity = inflight_htlcs.used_liquidity_msat(
                        &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()) ,
                        &NodeId::from_pubkey(&nodes[2].node.get_our_node_id()),
                        channel_2.get_short_channel_id().unwrap()
                );
 
-               // First hop accounts for expected 1000 msat fee
-               assert_eq!(chan_1_used_liquidity, Some(501000));
                assert_eq!(chan_2_used_liquidity, Some(500000));
        }
+       let pending_payments = nodes[0].node.list_recent_payments();
+       assert_eq!(pending_payments.len(), 1);
+       assert_eq!(pending_payments[0], RecentPaymentDetails::Pending { payment_hash, total_msat: 500000 });
 
        // Now, let's claim the payment. This should result in the used liquidity to return `None`.
        claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
-       {
-               let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
 
-               let node_0_channel_lock = nodes[0].node.channel_state.lock().unwrap();
-               let node_1_channel_lock = nodes[1].node.channel_state.lock().unwrap();
-               let channel_1 = node_0_channel_lock.by_id.get(&chan_1_id).unwrap();
-               let channel_2 = node_1_channel_lock.by_id.get(&chan_2_id).unwrap();
+       // Remove fulfilled payment
+       for _ in 0..=IDEMPOTENCY_TIMEOUT_TICKS {
+               nodes[0].node.timer_tick_occurred();
+       }
+
+       let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
+       {
+               let mut node_0_per_peer_lock;
+               let mut node_0_peer_state_lock;
+               let channel_1 =  get_channel_ref!(&nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, chan_1_id);
 
                let chan_1_used_liquidity = inflight_htlcs.used_liquidity_msat(
                        &NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) ,
                        &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()),
                        channel_1.get_short_channel_id().unwrap()
                );
+               assert_eq!(chan_1_used_liquidity, None);
+       }
+       {
+               let mut node_1_per_peer_lock;
+               let mut node_1_peer_state_lock;
+               let channel_2 =  get_channel_ref!(&nodes[1], nodes[2], node_1_per_peer_lock, node_1_peer_state_lock, chan_2_id);
+
                let chan_2_used_liquidity = inflight_htlcs.used_liquidity_msat(
                        &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()) ,
                        &NodeId::from_pubkey(&nodes[2].node.get_our_node_id()),
                        channel_2.get_short_channel_id().unwrap()
                );
-
-               assert_eq!(chan_1_used_liquidity, None);
                assert_eq!(chan_2_used_liquidity, None);
        }
+
+       let pending_payments = nodes[0].node.list_recent_payments();
+       assert_eq!(pending_payments.len(), 0);
 }
 
 #[test]
@@ -1345,7 +1305,7 @@ fn test_holding_cell_inflight_htlcs() {
        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);
-       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let (route, payment_hash_1, _, payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
        let (_, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
@@ -1362,8 +1322,9 @@ fn test_holding_cell_inflight_htlcs() {
        let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
 
        {
-               let channel_lock = nodes[0].node.channel_state.lock().unwrap();
-               let channel = channel_lock.by_id.get(&channel_id).unwrap();
+               let mut node_0_per_peer_lock;
+               let mut node_0_peer_state_lock;
+               let channel =  get_channel_ref!(&nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, channel_id);
 
                let used_liquidity = inflight_htlcs.used_liquidity_msat(
                        &NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) ,
@@ -1400,14 +1361,14 @@ fn do_test_intercepted_payment(test: InterceptTest) {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, Some(intercept_forwards_config), Some(zero_conf_chan_config)]);
 
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let scorer = test_utils::TestScorer::with_penalty(0);
+       let scorer = test_utils::TestScorer::new();
        let random_seed_bytes = chanmon_cfgs[0].keys_manager.get_secure_random_bytes();
 
-       let _ = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let _ = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let amt_msat = 100_000;
        let intercept_scid = nodes[1].node.get_intercept_scid();
-       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())
+       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)
                .with_route_hints(vec![
                        RouteHint(vec![RouteHintHop {
                                src_node_id: nodes[1].node.get_our_node_id(),
@@ -1421,19 +1382,19 @@ fn do_test_intercepted_payment(test: InterceptTest) {
                                htlc_maximum_msat: None,
                        }])
                ])
-               .with_features(channelmanager::provided_invoice_features());
+               .with_features(nodes[2].node.invoice_features());
        let route_params = RouteParameters {
                payment_params,
                final_value_msat: amt_msat,
-               final_cltv_expiry_delta: TEST_FINAL_CLTV,
        };
        let route = get_route(
                &nodes[0].node.get_our_node_id(), &route_params.payment_params,
                &nodes[0].network_graph.read_only(), None, route_params.final_value_msat,
-               route_params.final_cltv_expiry_delta, nodes[0].logger, &scorer, &random_seed_bytes
+               route_params.payment_params.final_cltv_expiry_delta, nodes[0].logger, &scorer,
+               &random_seed_bytes,
        ).unwrap();
 
-       let (payment_hash, payment_secret) = nodes[2].node.create_inbound_payment(Some(amt_msat), 60 * 60).unwrap();
+       let (payment_hash, payment_secret) = nodes[2].node.create_inbound_payment(Some(amt_msat), 60 * 60, None).unwrap();
        nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
        let payment_event = {
                {
@@ -1465,7 +1426,7 @@ fn do_test_intercepted_payment(test: InterceptTest) {
 
        // Check for unknown channel id error.
        let unknown_chan_id_err = nodes[1].node.forward_intercepted_htlc(intercept_id, &[42; 32], nodes[2].node.get_our_node_id(), expected_outbound_amount_msat).unwrap_err();
-       assert_eq!(unknown_chan_id_err , APIError::ChannelUnavailable  { err: format!("Channel with id {} not found", log_bytes!([42; 32])) });
+       assert_eq!(unknown_chan_id_err , APIError::ChannelUnavailable  { err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!([42; 32]), nodes[2].node.get_our_node_id()) });
 
        if test == InterceptTest::Fail {
                // Ensure we can fail the intercepted payment back.
@@ -1564,3 +1525,1306 @@ fn do_test_intercepted_payment(test: InterceptTest) {
                assert_eq!(unknown_intercept_id_err , APIError::APIMisuseError { err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0)) });
        }
 }
+
+#[derive(PartialEq)]
+enum AutoRetry {
+       Success,
+       Spontaneous,
+       FailAttempts,
+       FailTimeout,
+       FailOnRestart,
+       FailOnRetry,
+}
+
+#[test]
+fn automatic_retries() {
+       do_automatic_retries(AutoRetry::Success);
+       do_automatic_retries(AutoRetry::Spontaneous);
+       do_automatic_retries(AutoRetry::FailAttempts);
+       do_automatic_retries(AutoRetry::FailTimeout);
+       do_automatic_retries(AutoRetry::FailOnRestart);
+       do_automatic_retries(AutoRetry::FailOnRetry);
+}
+fn do_automatic_retries(test: AutoRetry) {
+       // Test basic automatic payment retries in ChannelManager. See individual `test` variant comments
+       // below.
+       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, &[None, None, None]);
+
+       let persister;
+       let new_chain_monitor;
+       let node_0_deserialized;
+
+       let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+       let channel_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
+       let channel_id_2 = create_announced_chan_between_nodes(&nodes, 2, 1).2;
+
+       // Marshall data to send the payment
+       #[cfg(feature = "std")]
+       let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
+       #[cfg(not(feature = "std"))]
+       let payment_expiry_secs = 60 * 60;
+       let amt_msat = 1000;
+       let mut invoice_features = InvoiceFeatures::empty();
+       invoice_features.set_variable_length_onion_required();
+       invoice_features.set_payment_secret_required();
+       invoice_features.set_basic_mpp_optional();
+       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_expiry_time(payment_expiry_secs as u64)
+               .with_features(invoice_features);
+       let route_params = RouteParameters {
+               payment_params,
+               final_value_msat: amt_msat,
+       };
+       let (_, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat);
+
+       macro_rules! pass_failed_attempt_with_retry_along_path {
+               ($failing_channel_id: expr, $expect_pending_htlcs_forwardable: expr) => {
+                       // Send a payment attempt that fails due to lack of liquidity on the second hop
+                       check_added_monitors!(nodes[0], 1);
+                       let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
+                       let mut update_add = update_0.update_add_htlcs[0].clone();
+                       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
+                       commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
+                       expect_pending_htlcs_forwardable_ignore!(nodes[1]);
+                       nodes[1].node.process_pending_htlc_forwards();
+                       expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore!(nodes[1],
+                               vec![HTLCDestination::NextHopChannel {
+                                       node_id: Some(nodes[2].node.get_our_node_id()),
+                                       channel_id: $failing_channel_id,
+                               }]);
+                       nodes[1].node.process_pending_htlc_forwards();
+                       let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+                       check_added_monitors!(&nodes[1], 1);
+                       assert!(update_1.update_fail_htlcs.len() == 1);
+                       let fail_msg = update_1.update_fail_htlcs[0].clone();
+                       nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg);
+                       commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
+
+                       // Ensure the attempt fails and a new PendingHTLCsForwardable event is generated for the retry
+                       let mut events = nodes[0].node.get_and_clear_pending_events();
+                       assert_eq!(events.len(), 2);
+                       match events[0] {
+                               Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently, ..  } => {
+                                       assert_eq!(payment_hash, ev_payment_hash);
+                                       assert_eq!(payment_failed_permanently, false);
+                               },
+                               _ => panic!("Unexpected event"),
+                       }
+                       if $expect_pending_htlcs_forwardable {
+                               match events[1] {
+                                       Event::PendingHTLCsForwardable { .. } => {},
+                                       _ => panic!("Unexpected event"),
+                               }
+                       } else {
+                               match events[1] {
+                                       Event::PaymentFailed { payment_hash: ev_payment_hash, .. } => {
+                                               assert_eq!(payment_hash, ev_payment_hash);
+                                       },
+                                       _ => panic!("Unexpected event"),
+                               }
+                       }
+               }
+       }
+
+       if test == AutoRetry::Success {
+               // Test that we can succeed on the first retry.
+               nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+               pass_failed_attempt_with_retry_along_path!(channel_id_2, true);
+
+               // Open a new channel with liquidity on the second hop so we can find a route for the retry
+               // attempt, since the initial second hop channel will be excluded from pathfinding
+               create_announced_chan_between_nodes(&nodes, 1, 2);
+
+               // We retry payments in `process_pending_htlc_forwards`
+               nodes[0].node.process_pending_htlc_forwards();
+               check_added_monitors!(nodes[0], 1);
+               let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(msg_events.len(), 1);
+               pass_along_path(&nodes[0], &[&nodes[1], &nodes[2]], amt_msat, payment_hash, Some(payment_secret), msg_events.pop().unwrap(), true, None);
+               claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage);
+       } else if test == AutoRetry::Spontaneous {
+               nodes[0].node.send_spontaneous_payment_with_retry(Some(payment_preimage), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+               pass_failed_attempt_with_retry_along_path!(channel_id_2, true);
+
+               // Open a new channel with liquidity on the second hop so we can find a route for the retry
+               // attempt, since the initial second hop channel will be excluded from pathfinding
+               create_announced_chan_between_nodes(&nodes, 1, 2);
+
+               // We retry payments in `process_pending_htlc_forwards`
+               nodes[0].node.process_pending_htlc_forwards();
+               check_added_monitors!(nodes[0], 1);
+               let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(msg_events.len(), 1);
+               pass_along_path(&nodes[0], &[&nodes[1], &nodes[2]], amt_msat, payment_hash, None, msg_events.pop().unwrap(), true, Some(payment_preimage));
+               claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage);
+       } else if test == AutoRetry::FailAttempts {
+               // Ensure ChannelManager will not retry a payment if it has run out of payment attempts.
+               nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+               pass_failed_attempt_with_retry_along_path!(channel_id_2, true);
+
+               // Open a new channel with no liquidity on the second hop so we can find a (bad) route for
+               // the retry attempt, since the initial second hop channel will be excluded from pathfinding
+               let channel_id_3 = create_announced_chan_between_nodes(&nodes, 2, 1).2;
+
+               // We retry payments in `process_pending_htlc_forwards`
+               nodes[0].node.process_pending_htlc_forwards();
+               pass_failed_attempt_with_retry_along_path!(channel_id_3, false);
+
+               // Ensure we won't retry a second time.
+               nodes[0].node.process_pending_htlc_forwards();
+               let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(msg_events.len(), 0);
+       } else if test == AutoRetry::FailTimeout {
+               #[cfg(not(feature = "no-std"))] {
+                       // Ensure ChannelManager will not retry a payment if it times out due to Retry::Timeout.
+                       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Timeout(Duration::from_secs(60))).unwrap();
+                       pass_failed_attempt_with_retry_along_path!(channel_id_2, true);
+
+                       // Advance the time so the second attempt fails due to timeout.
+                       SinceEpoch::advance(Duration::from_secs(61));
+
+                       // Make sure we don't retry again.
+                       nodes[0].node.process_pending_htlc_forwards();
+                       let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+                       assert_eq!(msg_events.len(), 0);
+
+                       let mut events = nodes[0].node.get_and_clear_pending_events();
+                       assert_eq!(events.len(), 1);
+                       match events[0] {
+                               Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id } => {
+                                       assert_eq!(payment_hash, *ev_payment_hash);
+                                       assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
+                               },
+                               _ => panic!("Unexpected event"),
+                       }
+               }
+       } else if test == AutoRetry::FailOnRestart {
+               // Ensure ChannelManager will not retry a payment after restart, even if there were retry
+               // attempts remaining prior to restart.
+               nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(2)).unwrap();
+               pass_failed_attempt_with_retry_along_path!(channel_id_2, true);
+
+               // Open a new channel with no liquidity on the second hop so we can find a (bad) route for
+               // the retry attempt, since the initial second hop channel will be excluded from pathfinding
+               let channel_id_3 = create_announced_chan_between_nodes(&nodes, 2, 1).2;
+
+               // Ensure the first retry attempt fails, with 1 retry attempt remaining
+               nodes[0].node.process_pending_htlc_forwards();
+               pass_failed_attempt_with_retry_along_path!(channel_id_3, true);
+
+               // Restart the node and ensure that ChannelManager does not use its remaining retry attempt
+               let node_encoded = nodes[0].node.encode();
+               let chan_1_monitor_serialized = get_monitor!(nodes[0], channel_id_1).encode();
+               reload_node!(nodes[0], node_encoded, &[&chan_1_monitor_serialized], persister, new_chain_monitor, node_0_deserialized);
+
+               let mut events = nodes[0].node.get_and_clear_pending_events();
+               expect_pending_htlcs_forwardable_from_events!(nodes[0], events, true);
+               // Make sure we don't retry again.
+               let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(msg_events.len(), 0);
+
+               let mut events = nodes[0].node.get_and_clear_pending_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id } => {
+                               assert_eq!(payment_hash, *ev_payment_hash);
+                               assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       } else if test == AutoRetry::FailOnRetry {
+               nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+               pass_failed_attempt_with_retry_along_path!(channel_id_2, true);
+
+               // We retry payments in `process_pending_htlc_forwards`. Since our channel closed, we should
+               // fail to find a route.
+               nodes[0].node.process_pending_htlc_forwards();
+               let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(msg_events.len(), 0);
+
+               let mut events = nodes[0].node.get_and_clear_pending_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id } => {
+                               assert_eq!(payment_hash, *ev_payment_hash);
+                               assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       }
+}
+
+#[test]
+fn auto_retry_partial_failure() {
+       // Test that we'll retry appropriately on send partial failure and retry partial failure.
+       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 mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+       let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+       let chan_3_id = create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+
+       // Marshall data to send the payment
+       let amt_msat = 20_000;
+       let (_, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
+       #[cfg(feature = "std")]
+       let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
+       #[cfg(not(feature = "std"))]
+       let payment_expiry_secs = 60 * 60;
+       let mut invoice_features = InvoiceFeatures::empty();
+       invoice_features.set_variable_length_onion_required();
+       invoice_features.set_payment_secret_required();
+       invoice_features.set_basic_mpp_optional();
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_expiry_time(payment_expiry_secs as u64)
+               .with_features(invoice_features);
+       let route_params = RouteParameters {
+               payment_params,
+               final_value_msat: amt_msat,
+       };
+
+       // Ensure the first monitor update (for the initial send path1 over chan_1) succeeds, but the
+       // second (for the initial send path2 over chan_2) fails.
+       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
+       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
+       // Ensure third monitor update (for the retry1's path1 over chan_1) succeeds, but the fourth (for
+       // the retry1's path2 over chan_3) fails, and monitor updates succeed after that.
+       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
+       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
+       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
+
+       // Configure the initial send, retry1 and retry2's paths.
+       let send_route = Route {
+               paths: vec![
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_1_id,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: amt_msat / 2,
+                               cltv_expiry_delta: 100,
+                       }],
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_2_id,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: amt_msat / 2,
+                               cltv_expiry_delta: 100,
+                       }],
+               ],
+               payment_params: Some(route_params.payment_params.clone()),
+       };
+       let retry_1_route = Route {
+               paths: vec![
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_1_id,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: amt_msat / 4,
+                               cltv_expiry_delta: 100,
+                       }],
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_3_id,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: amt_msat / 4,
+                               cltv_expiry_delta: 100,
+                       }],
+               ],
+               payment_params: Some(route_params.payment_params.clone()),
+       };
+       let retry_2_route = Route {
+               paths: vec![
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_1_id,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: amt_msat / 4,
+                               cltv_expiry_delta: 100,
+                       }],
+               ],
+               payment_params: Some(route_params.payment_params.clone()),
+       };
+       nodes[0].router.expect_find_route(route_params.clone(), Ok(send_route));
+       let mut payment_params = route_params.payment_params.clone();
+       payment_params.previously_failed_channels.push(chan_2_id);
+       nodes[0].router.expect_find_route(RouteParameters {
+                       payment_params, final_value_msat: amt_msat / 2,
+               }, Ok(retry_1_route));
+       let mut payment_params = route_params.payment_params.clone();
+       payment_params.previously_failed_channels.push(chan_3_id);
+       nodes[0].router.expect_find_route(RouteParameters {
+                       payment_params, final_value_msat: amt_msat / 4,
+               }, Ok(retry_2_route));
+
+       // Send a payment that will partially fail on send, then partially fail on retry, then succeed.
+       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(3)).unwrap();
+       let closed_chan_events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(closed_chan_events.len(), 4);
+       match closed_chan_events[0] {
+               Event::ChannelClosed { .. } => {},
+               _ => panic!("Unexpected event"),
+       }
+       match closed_chan_events[1] {
+               Event::PaymentPathFailed { .. } => {},
+               _ => panic!("Unexpected event"),
+       }
+       match closed_chan_events[2] {
+               Event::ChannelClosed { .. } => {},
+               _ => panic!("Unexpected event"),
+       }
+       match closed_chan_events[3] {
+               Event::PaymentPathFailed { .. } => {},
+               _ => panic!("Unexpected event"),
+       }
+
+       // Pass the first part of the payment along the path.
+       check_added_monitors!(nodes[0], 5); // three outbound channel updates succeeded, two permanently failed
+       let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+
+       // First message is the first update_add, remaining messages are broadcasting channel updates and
+       // errors for the permfailed channels
+       assert_eq!(msg_events.len(), 5);
+       let mut payment_event = SendEvent::from_event(msg_events.remove(0));
+
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event.commitment_msg);
+       check_added_monitors!(nodes[1], 1);
+       let (bs_first_raa, bs_first_cs) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_first_raa);
+       check_added_monitors!(nodes[0], 1);
+       let as_second_htlc_updates = SendEvent::from_node(&nodes[0]);
+
+       nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_first_cs);
+       check_added_monitors!(nodes[0], 1);
+       let as_first_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id());
+
+       nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_first_raa);
+       check_added_monitors!(nodes[1], 1);
+
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &as_second_htlc_updates.msgs[0]);
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &as_second_htlc_updates.msgs[1]);
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_second_htlc_updates.commitment_msg);
+       check_added_monitors!(nodes[1], 1);
+       let (bs_second_raa, bs_second_cs) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_raa);
+       check_added_monitors!(nodes[0], 1);
+
+       nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_cs);
+       check_added_monitors!(nodes[0], 1);
+       let as_second_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id());
+
+       nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_second_raa);
+       check_added_monitors!(nodes[1], 1);
+
+       expect_pending_htlcs_forwardable_ignore!(nodes[1]);
+       nodes[1].node.process_pending_htlc_forwards();
+       expect_payment_claimable!(nodes[1], payment_hash, payment_secret, amt_msat);
+       nodes[1].node.claim_funds(payment_preimage);
+       expect_payment_claimed!(nodes[1], payment_hash, amt_msat);
+       let bs_claim_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+       assert_eq!(bs_claim_update.update_fulfill_htlcs.len(), 1);
+
+       nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_claim_update.update_fulfill_htlcs[0]);
+       nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_claim_update.commitment_signed);
+       check_added_monitors!(nodes[0], 1);
+       let (as_third_raa, as_third_cs) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
+
+       nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_third_raa);
+       check_added_monitors!(nodes[1], 4);
+       let bs_second_claim_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_third_cs);
+       check_added_monitors!(nodes[1], 1);
+       let bs_third_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_third_raa);
+       check_added_monitors!(nodes[0], 1);
+
+       nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_second_claim_update.update_fulfill_htlcs[0]);
+       nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_second_claim_update.update_fulfill_htlcs[1]);
+       nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_claim_update.commitment_signed);
+       check_added_monitors!(nodes[0], 1);
+       let (as_fourth_raa, as_fourth_cs) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
+
+       nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_fourth_raa);
+       check_added_monitors!(nodes[1], 1);
+
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_fourth_cs);
+       check_added_monitors!(nodes[1], 1);
+       let bs_second_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_raa);
+       check_added_monitors!(nodes[0], 1);
+       expect_payment_sent!(nodes[0], payment_preimage);
+}
+
+#[test]
+fn auto_retry_zero_attempts_send_error() {
+       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 mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+       create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+
+       // Marshall data to send the payment
+       let amt_msat = 20_000;
+       let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
+       #[cfg(feature = "std")]
+       let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
+       #[cfg(not(feature = "std"))]
+       let payment_expiry_secs = 60 * 60;
+       let mut invoice_features = InvoiceFeatures::empty();
+       invoice_features.set_variable_length_onion_required();
+       invoice_features.set_payment_secret_required();
+       invoice_features.set_basic_mpp_optional();
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_expiry_time(payment_expiry_secs as u64)
+               .with_features(invoice_features);
+       let route_params = RouteParameters {
+               payment_params,
+               final_value_msat: amt_msat,
+       };
+
+       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
+       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap();
+       assert_eq!(nodes[0].node.get_and_clear_pending_msg_events().len(), 2); // channel close messages
+       let events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 3);
+       if let Event::ChannelClosed { .. } = events[0] { } else { panic!(); }
+       if let Event::PaymentPathFailed { .. } = events[1] { } else { panic!(); }
+       if let Event::PaymentFailed { .. } = events[2] { } else { panic!(); }
+       check_added_monitors!(nodes[0], 2);
+}
+
+#[test]
+fn fails_paying_after_rejected_by_payee() {
+       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 mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+
+       // Marshall data to send the payment
+       let amt_msat = 20_000;
+       let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
+       #[cfg(feature = "std")]
+       let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
+       #[cfg(not(feature = "std"))]
+       let payment_expiry_secs = 60 * 60;
+       let mut invoice_features = InvoiceFeatures::empty();
+       invoice_features.set_variable_length_onion_required();
+       invoice_features.set_payment_secret_required();
+       invoice_features.set_basic_mpp_optional();
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_expiry_time(payment_expiry_secs as u64)
+               .with_features(invoice_features);
+       let route_params = RouteParameters {
+               payment_params,
+               final_value_msat: amt_msat,
+       };
+
+       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+       check_added_monitors!(nodes[0], 1);
+       let mut events = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(events.len(), 1);
+       let mut payment_event = SendEvent::from_event(events.pop().unwrap());
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
+       check_added_monitors!(nodes[1], 0);
+       commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
+       expect_pending_htlcs_forwardable!(nodes[1]);
+       expect_payment_claimable!(&nodes[1], payment_hash, payment_secret, amt_msat);
+
+       nodes[1].node.fail_htlc_backwards(&payment_hash);
+       expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[1], [HTLCDestination::FailedPayment { payment_hash }]);
+       pass_failed_payment_back(&nodes[0], &[&[&nodes[1]]], false, payment_hash);
+}
+
+#[test]
+fn retry_multi_path_single_failed_payment() {
+       // Tests that we can/will retry after a single path of an MPP payment failed immediately
+       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, None]);
+       let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
+
+       let amt_msat = 100_010_000;
+
+       let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
+       #[cfg(feature = "std")]
+       let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
+       #[cfg(not(feature = "std"))]
+       let payment_expiry_secs = 60 * 60;
+       let mut invoice_features = InvoiceFeatures::empty();
+       invoice_features.set_variable_length_onion_required();
+       invoice_features.set_payment_secret_required();
+       invoice_features.set_basic_mpp_optional();
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_expiry_time(payment_expiry_secs as u64)
+               .with_features(invoice_features);
+       let route_params = RouteParameters {
+               payment_params: payment_params.clone(),
+               final_value_msat: amt_msat,
+       };
+
+       let chans = nodes[0].node.list_usable_channels();
+       let mut route = Route {
+               paths: vec![
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chans[0].short_channel_id.unwrap(),
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: 10_000,
+                               cltv_expiry_delta: 100,
+                       }],
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chans[1].short_channel_id.unwrap(),
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: 100_000_001, // Our default max-HTLC-value is 10% of the channel value, which this is one more than
+                               cltv_expiry_delta: 100,
+                       }],
+               ],
+               payment_params: Some(payment_params),
+       };
+       nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
+       // On retry, split the payment across both channels.
+       route.paths[0][0].fee_msat = 50_000_001;
+       route.paths[1][0].fee_msat = 50_000_000;
+       let mut pay_params = route.payment_params.clone().unwrap();
+       pay_params.previously_failed_channels.push(chans[1].short_channel_id.unwrap());
+       nodes[0].router.expect_find_route(RouteParameters {
+                       payment_params: pay_params,
+                       // Note that the second request here requests the amount we originally failed to send,
+                       // not the amount remaining on the full payment, which should be changed.
+                       final_value_msat: 100_000_001,
+               }, Ok(route.clone()));
+
+       {
+               let scorer = chanmon_cfgs[0].scorer.lock().unwrap();
+               // The initial send attempt, 2 paths
+               scorer.expect_usage(chans[0].short_channel_id.unwrap(), ChannelUsage { amount_msat: 10_000, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown });
+               scorer.expect_usage(chans[1].short_channel_id.unwrap(), ChannelUsage { amount_msat: 100_000_001, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown });
+               // The retry, 2 paths. Ensure that the in-flight HTLC amount is factored in.
+               scorer.expect_usage(chans[0].short_channel_id.unwrap(), ChannelUsage { amount_msat: 50_000_001, inflight_htlc_msat: 10_000, effective_capacity: EffectiveCapacity::Unknown });
+               scorer.expect_usage(chans[1].short_channel_id.unwrap(), ChannelUsage { amount_msat: 50_000_000, inflight_htlc_msat: 0, effective_capacity: EffectiveCapacity::Unknown });
+       }
+
+       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+       let events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 1);
+       match events[0] {
+               Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently: false,
+                       failure: PathFailure::InitialSend { err: APIError::ChannelUnavailable { err: ref err_msg }},
+                       short_channel_id: Some(expected_scid), .. } =>
+               {
+                       assert_eq!(payment_hash, ev_payment_hash);
+                       assert_eq!(expected_scid, route.paths[1][0].short_channel_id);
+                       assert!(err_msg.contains("max HTLC"));
+               },
+               _ => panic!("Unexpected event"),
+       }
+       let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(htlc_msgs.len(), 2);
+       check_added_monitors!(nodes[0], 2);
+}
+
+#[test]
+fn immediate_retry_on_failure() {
+       // Tests that we can/will retry immediately after a failure
+       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, None]);
+       let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
+
+       let amt_msat = 100_000_001;
+       let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
+       #[cfg(feature = "std")]
+       let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
+       #[cfg(not(feature = "std"))]
+       let payment_expiry_secs = 60 * 60;
+       let mut invoice_features = InvoiceFeatures::empty();
+       invoice_features.set_variable_length_onion_required();
+       invoice_features.set_payment_secret_required();
+       invoice_features.set_basic_mpp_optional();
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_expiry_time(payment_expiry_secs as u64)
+               .with_features(invoice_features);
+       let route_params = RouteParameters {
+               payment_params,
+               final_value_msat: amt_msat,
+       };
+
+       let chans = nodes[0].node.list_usable_channels();
+       let mut route = Route {
+               paths: vec![
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chans[0].short_channel_id.unwrap(),
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: 100_000_001, // Our default max-HTLC-value is 10% of the channel value, which this is one more than
+                               cltv_expiry_delta: 100,
+                       }],
+               ],
+               payment_params: Some(PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)),
+       };
+       nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
+       // On retry, split the payment across both channels.
+       route.paths.push(route.paths[0].clone());
+       route.paths[0][0].short_channel_id = chans[1].short_channel_id.unwrap();
+       route.paths[0][0].fee_msat = 50_000_000;
+       route.paths[1][0].fee_msat = 50_000_001;
+       let mut pay_params = route_params.payment_params.clone();
+       pay_params.previously_failed_channels.push(chans[0].short_channel_id.unwrap());
+       nodes[0].router.expect_find_route(RouteParameters {
+                       payment_params: pay_params, final_value_msat: amt_msat,
+               }, Ok(route.clone()));
+
+       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+       let events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 1);
+       match events[0] {
+               Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently: false,
+                       failure: PathFailure::InitialSend { err: APIError::ChannelUnavailable { err: ref err_msg }},
+                       short_channel_id: Some(expected_scid), .. } =>
+               {
+                       assert_eq!(payment_hash, ev_payment_hash);
+                       assert_eq!(expected_scid, route.paths[1][0].short_channel_id);
+                       assert!(err_msg.contains("max HTLC"));
+               },
+               _ => panic!("Unexpected event"),
+       }
+       let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(htlc_msgs.len(), 2);
+       check_added_monitors!(nodes[0], 2);
+}
+
+#[test]
+fn no_extra_retries_on_back_to_back_fail() {
+       // In a previous release, we had a race where we may exceed the payment retry count if we
+       // get two failures in a row with the second indicating that all paths had failed (this field,
+       // `all_paths_failed`, has since been removed).
+       // Generally, when we give up trying to retry a payment, we don't know for sure what the
+       // current state of the ChannelManager event queue is. Specifically, we cannot be sure that
+       // there are not multiple additional `PaymentPathFailed` or even `PaymentSent` events
+       // pending which we will see later. Thus, when we previously removed the retry tracking map
+       // entry after a `all_paths_failed` `PaymentPathFailed` event, we may have dropped the
+       // retry entry even though more events for the same payment were still pending. This led to
+       // us retrying a payment again even though we'd already given up on it.
+       //
+       // We now have a separate event - `PaymentFailed` which indicates no HTLCs remain and which
+       // is used to remove the payment retry counter entries instead. This tests for the specific
+       // excess-retry case while also testing `PaymentFailed` generation.
+
+       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, &[None, None, None]);
+       let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+       let chan_1_scid = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0).0.contents.short_channel_id;
+       let chan_2_scid = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 10_000_000, 0).0.contents.short_channel_id;
+
+       let amt_msat = 200_000_000;
+       let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
+       #[cfg(feature = "std")]
+       let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
+       #[cfg(not(feature = "std"))]
+       let payment_expiry_secs = 60 * 60;
+       let mut invoice_features = InvoiceFeatures::empty();
+       invoice_features.set_variable_length_onion_required();
+       invoice_features.set_payment_secret_required();
+       invoice_features.set_basic_mpp_optional();
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_expiry_time(payment_expiry_secs as u64)
+               .with_features(invoice_features);
+       let route_params = RouteParameters {
+               payment_params,
+               final_value_msat: amt_msat,
+       };
+
+       let mut route = Route {
+               paths: vec![
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_1_scid,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: 0, // nodes[1] will fail the payment as we don't pay its fee
+                               cltv_expiry_delta: 100,
+                       }, RouteHop {
+                               pubkey: nodes[2].node.get_our_node_id(),
+                               node_features: nodes[2].node.node_features(),
+                               short_channel_id: chan_2_scid,
+                               channel_features: nodes[2].node.channel_features(),
+                               fee_msat: 100_000_000,
+                               cltv_expiry_delta: 100,
+                       }],
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_1_scid,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: 0, // nodes[1] will fail the payment as we don't pay its fee
+                               cltv_expiry_delta: 100,
+                       }, RouteHop {
+                               pubkey: nodes[2].node.get_our_node_id(),
+                               node_features: nodes[2].node.node_features(),
+                               short_channel_id: chan_2_scid,
+                               channel_features: nodes[2].node.channel_features(),
+                               fee_msat: 100_000_000,
+                               cltv_expiry_delta: 100,
+                       }]
+               ],
+               payment_params: Some(PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)),
+       };
+       nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
+       let mut second_payment_params = route_params.payment_params.clone();
+       second_payment_params.previously_failed_channels = vec![chan_2_scid, chan_2_scid];
+       // On retry, we'll only return one path
+       route.paths.remove(1);
+       route.paths[0][1].fee_msat = amt_msat;
+       nodes[0].router.expect_find_route(RouteParameters {
+                       payment_params: second_payment_params,
+                       final_value_msat: amt_msat,
+               }, Ok(route.clone()));
+
+       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+       let htlc_updates = SendEvent::from_node(&nodes[0]);
+       check_added_monitors!(nodes[0], 1);
+       assert_eq!(htlc_updates.msgs.len(), 1);
+
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &htlc_updates.msgs[0]);
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &htlc_updates.commitment_msg);
+       check_added_monitors!(nodes[1], 1);
+       let (bs_first_raa, bs_first_cs) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_first_raa);
+       check_added_monitors!(nodes[0], 1);
+       let second_htlc_updates = SendEvent::from_node(&nodes[0]);
+
+       nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_first_cs);
+       check_added_monitors!(nodes[0], 1);
+       let as_first_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id());
+
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &second_htlc_updates.msgs[0]);
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &second_htlc_updates.commitment_msg);
+       check_added_monitors!(nodes[1], 1);
+       let bs_second_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
+
+       nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_first_raa);
+       check_added_monitors!(nodes[1], 1);
+       let bs_fail_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_raa);
+       check_added_monitors!(nodes[0], 1);
+
+       nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_fail_update.update_fail_htlcs[0]);
+       nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_fail_update.commitment_signed);
+       check_added_monitors!(nodes[0], 1);
+       let (as_second_raa, as_third_cs) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
+
+       nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_second_raa);
+       check_added_monitors!(nodes[1], 1);
+       let bs_second_fail_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_third_cs);
+       check_added_monitors!(nodes[1], 1);
+       let bs_third_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_second_fail_update.update_fail_htlcs[0]);
+       nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_fail_update.commitment_signed);
+       check_added_monitors!(nodes[0], 1);
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_third_raa);
+       check_added_monitors!(nodes[0], 1);
+       let (as_third_raa, as_fourth_cs) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
+
+       nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_third_raa);
+       check_added_monitors!(nodes[1], 1);
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_fourth_cs);
+       check_added_monitors!(nodes[1], 1);
+       let bs_fourth_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_fourth_raa);
+       check_added_monitors!(nodes[0], 1);
+
+       // At this point A has sent two HTLCs which both failed due to lack of fee. It now has two
+       // pending `PaymentPathFailed` events, one with `all_paths_failed` unset, and the second
+       // with it set.
+       //
+       // Previously, we retried payments in an event consumer, which would retry each
+       // `PaymentPathFailed` individually. In that setup, we had retried the payment in response to
+       // the first `PaymentPathFailed`, then seen the second `PaymentPathFailed` with
+       // `all_paths_failed` set and assumed the payment was completely failed. We ultimately fixed it
+       // by adding the `PaymentFailed` event.
+       //
+       // Because we now retry payments as a batch, we simply return a single-path route in the
+       // second, batched, request, have that fail, ensure the payment was abandoned.
+       let mut events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 3);
+       match events[0] {
+               Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently, ..  } => {
+                       assert_eq!(payment_hash, ev_payment_hash);
+                       assert_eq!(payment_failed_permanently, false);
+               },
+               _ => panic!("Unexpected event"),
+       }
+       match events[1] {
+               Event::PendingHTLCsForwardable { .. } => {},
+               _ => panic!("Unexpected event"),
+       }
+       match events[2] {
+               Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently, ..  } => {
+                       assert_eq!(payment_hash, ev_payment_hash);
+                       assert_eq!(payment_failed_permanently, false);
+               },
+               _ => panic!("Unexpected event"),
+       }
+
+       nodes[0].node.process_pending_htlc_forwards();
+       let retry_htlc_updates = SendEvent::from_node(&nodes[0]);
+       check_added_monitors!(nodes[0], 1);
+
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &retry_htlc_updates.msgs[0]);
+       commitment_signed_dance!(nodes[1], nodes[0], &retry_htlc_updates.commitment_msg, false, true);
+       let bs_fail_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+       nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_fail_update.update_fail_htlcs[0]);
+       commitment_signed_dance!(nodes[0], nodes[1], &bs_fail_update.commitment_signed, false, true);
+
+       let mut events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 2);
+       match events[0] {
+               Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently, ..  } => {
+                       assert_eq!(payment_hash, ev_payment_hash);
+                       assert_eq!(payment_failed_permanently, false);
+               },
+               _ => panic!("Unexpected event"),
+       }
+       match events[1] {
+               Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id } => {
+                       assert_eq!(payment_hash, *ev_payment_hash);
+                       assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
+               },
+               _ => panic!("Unexpected event"),
+       }
+}
+
+#[test]
+fn test_simple_partial_retry() {
+       // In the first version of the in-`ChannelManager` payment retries, retries were sent for the
+       // full amount of the payment, rather than only the missing amount. Here we simply test for
+       // this by sending a payment with two parts, failing one, and retrying the second. Note that
+       // `TestRouter` will check that the `RouteParameters` (which contain the amount) matches the
+       // request.
+       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, &[None, None, None]);
+       let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+       let chan_1_scid = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0).0.contents.short_channel_id;
+       let chan_2_scid = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 10_000_000, 0).0.contents.short_channel_id;
+
+       let amt_msat = 200_000_000;
+       let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[2], amt_msat);
+       #[cfg(feature = "std")]
+       let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
+       #[cfg(not(feature = "std"))]
+       let payment_expiry_secs = 60 * 60;
+       let mut invoice_features = InvoiceFeatures::empty();
+       invoice_features.set_variable_length_onion_required();
+       invoice_features.set_payment_secret_required();
+       invoice_features.set_basic_mpp_optional();
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_expiry_time(payment_expiry_secs as u64)
+               .with_features(invoice_features);
+       let route_params = RouteParameters {
+               payment_params,
+               final_value_msat: amt_msat,
+       };
+
+       let mut route = Route {
+               paths: vec![
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_1_scid,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: 0, // nodes[1] will fail the payment as we don't pay its fee
+                               cltv_expiry_delta: 100,
+                       }, RouteHop {
+                               pubkey: nodes[2].node.get_our_node_id(),
+                               node_features: nodes[2].node.node_features(),
+                               short_channel_id: chan_2_scid,
+                               channel_features: nodes[2].node.channel_features(),
+                               fee_msat: 100_000_000,
+                               cltv_expiry_delta: 100,
+                       }],
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_1_scid,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: 100_000,
+                               cltv_expiry_delta: 100,
+                       }, RouteHop {
+                               pubkey: nodes[2].node.get_our_node_id(),
+                               node_features: nodes[2].node.node_features(),
+                               short_channel_id: chan_2_scid,
+                               channel_features: nodes[2].node.channel_features(),
+                               fee_msat: 100_000_000,
+                               cltv_expiry_delta: 100,
+                       }]
+               ],
+               payment_params: Some(PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)),
+       };
+       nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
+       let mut second_payment_params = route_params.payment_params.clone();
+       second_payment_params.previously_failed_channels = vec![chan_2_scid];
+       // On retry, we'll only be asked for one path (or 100k sats)
+       route.paths.remove(0);
+       nodes[0].router.expect_find_route(RouteParameters {
+                       payment_params: second_payment_params,
+                       final_value_msat: amt_msat / 2,
+               }, Ok(route.clone()));
+
+       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+       let htlc_updates = SendEvent::from_node(&nodes[0]);
+       check_added_monitors!(nodes[0], 1);
+       assert_eq!(htlc_updates.msgs.len(), 1);
+
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &htlc_updates.msgs[0]);
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &htlc_updates.commitment_msg);
+       check_added_monitors!(nodes[1], 1);
+       let (bs_first_raa, bs_first_cs) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_first_raa);
+       check_added_monitors!(nodes[0], 1);
+       let second_htlc_updates = SendEvent::from_node(&nodes[0]);
+
+       nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_first_cs);
+       check_added_monitors!(nodes[0], 1);
+       let as_first_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id());
+
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &second_htlc_updates.msgs[0]);
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &second_htlc_updates.commitment_msg);
+       check_added_monitors!(nodes[1], 1);
+       let bs_second_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
+
+       nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_first_raa);
+       check_added_monitors!(nodes[1], 1);
+       let bs_fail_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_raa);
+       check_added_monitors!(nodes[0], 1);
+
+       nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_fail_update.update_fail_htlcs[0]);
+       nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_fail_update.commitment_signed);
+       check_added_monitors!(nodes[0], 1);
+       let (as_second_raa, as_third_cs) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
+
+       nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_second_raa);
+       check_added_monitors!(nodes[1], 1);
+
+       nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_third_cs);
+       check_added_monitors!(nodes[1], 1);
+
+       let bs_third_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_third_raa);
+       check_added_monitors!(nodes[0], 1);
+
+       let mut events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 2);
+       match events[0] {
+               Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently, ..  } => {
+                       assert_eq!(payment_hash, ev_payment_hash);
+                       assert_eq!(payment_failed_permanently, false);
+               },
+               _ => panic!("Unexpected event"),
+       }
+       match events[1] {
+               Event::PendingHTLCsForwardable { .. } => {},
+               _ => panic!("Unexpected event"),
+       }
+
+       nodes[0].node.process_pending_htlc_forwards();
+       let retry_htlc_updates = SendEvent::from_node(&nodes[0]);
+       check_added_monitors!(nodes[0], 1);
+
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &retry_htlc_updates.msgs[0]);
+       commitment_signed_dance!(nodes[1], nodes[0], &retry_htlc_updates.commitment_msg, false, true);
+
+       expect_pending_htlcs_forwardable!(nodes[1]);
+       check_added_monitors!(nodes[1], 1);
+
+       let bs_forward_update = get_htlc_update_msgs!(nodes[1], nodes[2].node.get_our_node_id());
+       nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &bs_forward_update.update_add_htlcs[0]);
+       nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &bs_forward_update.update_add_htlcs[1]);
+       commitment_signed_dance!(nodes[2], nodes[1], &bs_forward_update.commitment_signed, false);
+
+       expect_pending_htlcs_forwardable!(nodes[2]);
+       expect_payment_claimable!(nodes[2], payment_hash, payment_secret, amt_msat);
+}
+
+#[test]
+#[cfg(feature = "std")]
+fn test_threaded_payment_retries() {
+       // In the first version of the in-`ChannelManager` payment retries, retries weren't limited to
+       // a single thread and would happily let multiple threads run retries at the same time. Because
+       // retries are done by first calculating the amount we need to retry, then dropping the
+       // relevant lock, then actually sending, we would happily let multiple threads retry the same
+       // amount at the same time, overpaying our original HTLC!
+       let chanmon_cfgs = create_chanmon_cfgs(4);
+       let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
+       let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
+
+       // There is one mitigating guardrail when retrying payments - we can never over-pay by more
+       // than 10% of the original value. Thus, we want all our retries to be below that. In order to
+       // keep things simple, we route one HTLC for 0.1% of the payment over channel 1 and the rest
+       // out over channel 3+4. This will let us ignore 99% of the payment value and deal with only
+       // our channel.
+       let chan_1_scid = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0).0.contents.short_channel_id;
+       create_announced_chan_between_nodes_with_value(&nodes, 1, 3, 10_000_000, 0);
+       let chan_3_scid = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 10_000_000, 0).0.contents.short_channel_id;
+       let chan_4_scid = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 10_000_000, 0).0.contents.short_channel_id;
+
+       let amt_msat = 100_000_000;
+       let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[2], amt_msat);
+       #[cfg(feature = "std")]
+       let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
+       #[cfg(not(feature = "std"))]
+       let payment_expiry_secs = 60 * 60;
+       let mut invoice_features = InvoiceFeatures::empty();
+       invoice_features.set_variable_length_onion_required();
+       invoice_features.set_payment_secret_required();
+       invoice_features.set_basic_mpp_optional();
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_expiry_time(payment_expiry_secs as u64)
+               .with_features(invoice_features);
+       let mut route_params = RouteParameters {
+               payment_params,
+               final_value_msat: amt_msat,
+       };
+
+       let mut route = Route {
+               paths: vec![
+                       vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_1_scid,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: 0,
+                               cltv_expiry_delta: 100,
+                       }, RouteHop {
+                               pubkey: nodes[3].node.get_our_node_id(),
+                               node_features: nodes[2].node.node_features(),
+                               short_channel_id: 42, // Set a random SCID which nodes[1] will fail as unknown
+                               channel_features: nodes[2].node.channel_features(),
+                               fee_msat: amt_msat / 1000,
+                               cltv_expiry_delta: 100,
+                       }],
+                       vec![RouteHop {
+                               pubkey: nodes[2].node.get_our_node_id(),
+                               node_features: nodes[2].node.node_features(),
+                               short_channel_id: chan_3_scid,
+                               channel_features: nodes[2].node.channel_features(),
+                               fee_msat: 100_000,
+                               cltv_expiry_delta: 100,
+                       }, RouteHop {
+                               pubkey: nodes[3].node.get_our_node_id(),
+                               node_features: nodes[3].node.node_features(),
+                               short_channel_id: chan_4_scid,
+                               channel_features: nodes[3].node.channel_features(),
+                               fee_msat: amt_msat - amt_msat / 1000,
+                               cltv_expiry_delta: 100,
+                       }]
+               ],
+               payment_params: Some(PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)),
+       };
+       nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
+
+       nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params.clone(), Retry::Attempts(0xdeadbeef)).unwrap();
+       check_added_monitors!(nodes[0], 2);
+       let mut send_msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(send_msg_events.len(), 2);
+       send_msg_events.retain(|msg|
+               if let MessageSendEvent::UpdateHTLCs { node_id, .. } = msg {
+                       // Drop the commitment update for nodes[2], we can just let that one sit pending
+                       // forever.
+                       *node_id == nodes[1].node.get_our_node_id()
+               } else { panic!(); }
+       );
+
+       // from here on out, the retry `RouteParameters` amount will be amt/1000
+       route_params.final_value_msat /= 1000;
+       route.paths.pop();
+
+       let end_time = Instant::now() + Duration::from_secs(1);
+       macro_rules! thread_body { () => { {
+               // We really want std::thread::scope, but its not stable until 1.63. Until then, we get unsafe.
+               let node_ref = NodePtr::from_node(&nodes[0]);
+               move || {
+                       let node_a = unsafe { &*node_ref.0 };
+                       while Instant::now() < end_time {
+                               node_a.node.get_and_clear_pending_events(); // wipe the PendingHTLCsForwardable
+                               // Ignore if we have any pending events, just always pretend we just got a
+                               // PendingHTLCsForwardable
+                               node_a.node.process_pending_htlc_forwards();
+                       }
+               }
+       } } }
+       let mut threads = Vec::new();
+       for _ in 0..16 { threads.push(std::thread::spawn(thread_body!())); }
+
+       // Back in the main thread, poll pending messages and make sure that we never have more than
+       // one HTLC pending at a time. Note that the commitment_signed_dance will fail horribly if
+       // there are HTLC messages shoved in while its running. This allows us to test that we never
+       // generate an additional update_add_htlc until we've fully failed the first.
+       let mut previously_failed_channels = Vec::new();
+       loop {
+               assert_eq!(send_msg_events.len(), 1);
+               let send_event = SendEvent::from_event(send_msg_events.pop().unwrap());
+               assert_eq!(send_event.msgs.len(), 1);
+
+               nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &send_event.msgs[0]);
+               commitment_signed_dance!(nodes[1], nodes[0], send_event.commitment_msg, false, true);
+
+               // Note that we only push one route into `expect_find_route` at a time, because that's all
+               // the retries (should) need. If the bug is reintroduced "real" routes may be selected, but
+               // we should still ultimately fail for the same reason - because we're trying to send too
+               // many HTLCs at once.
+               let mut new_route_params = route_params.clone();
+               previously_failed_channels.push(route.paths[0][1].short_channel_id);
+               new_route_params.payment_params.previously_failed_channels = previously_failed_channels.clone();
+               route.paths[0][1].short_channel_id += 1;
+               nodes[0].router.expect_find_route(new_route_params, Ok(route.clone()));
+
+               let bs_fail_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+               nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_fail_updates.update_fail_htlcs[0]);
+               // The "normal" commitment_signed_dance delivers the final RAA and then calls
+               // `check_added_monitors` to ensure only the one RAA-generated monitor update was created.
+               // This races with our other threads which may generate an add-HTLCs commitment update via
+               // `process_pending_htlc_forwards`. Instead, we defer the monitor update check until after
+               // *we've* called `process_pending_htlc_forwards` when its guaranteed to have two updates.
+               let last_raa = commitment_signed_dance!(nodes[0], nodes[1], bs_fail_updates.commitment_signed, false, true, false, true);
+               nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &last_raa);
+
+               let cur_time = Instant::now();
+               if cur_time > end_time {
+                       for thread in threads.drain(..) { thread.join().unwrap(); }
+               }
+
+               // Make sure we have some events to handle when we go around...
+               nodes[0].node.get_and_clear_pending_events(); // wipe the PendingHTLCsForwardable
+               nodes[0].node.process_pending_htlc_forwards();
+               send_msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+               check_added_monitors!(nodes[0], 2);
+
+               if cur_time > end_time {
+                       break;
+               }
+       }
+}
+
+fn do_no_missing_sent_on_midpoint_reload(persist_manager_with_payment: bool) {
+       // Test that if we reload in the middle of an HTLC claim commitment signed dance we'll still
+       // receive the PaymentSent event even if the ChannelManager had no idea about the payment when
+       // it was last persisted.
+       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 (persister_a, persister_b, persister_c);
+       let (chain_monitor_a, chain_monitor_b, chain_monitor_c);
+       let (nodes_0_deserialized, nodes_0_deserialized_b, nodes_0_deserialized_c);
+       let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
+
+       let mut nodes_0_serialized = Vec::new();
+       if !persist_manager_with_payment {
+               nodes_0_serialized = nodes[0].node.encode();
+       }
+
+       let (our_payment_preimage, our_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
+
+       if persist_manager_with_payment {
+               nodes_0_serialized = nodes[0].node.encode();
+       }
+
+       nodes[1].node.claim_funds(our_payment_preimage);
+       check_added_monitors!(nodes[1], 1);
+       expect_payment_claimed!(nodes[1], our_payment_hash, 1_000_000);
+
+       let updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+       nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]);
+       nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &updates.commitment_signed);
+       check_added_monitors!(nodes[0], 1);
+
+       // The ChannelMonitor should always be the latest version, as we're required to persist it
+       // during the commitment signed handling.
+       let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
+       reload_node!(nodes[0], test_default_channel_config(), &nodes_0_serialized, &[&chan_0_monitor_serialized], persister_a, chain_monitor_a, nodes_0_deserialized);
+
+       let events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 2);
+       if let Event::ChannelClosed { reason: ClosureReason::OutdatedChannelManager, .. } = events[0] {} else { panic!(); }
+       if let Event::PaymentSent { payment_preimage, .. } = events[1] { assert_eq!(payment_preimage, our_payment_preimage); } else { panic!(); }
+       // Note that we don't get a PaymentPathSuccessful here as we leave the HTLC pending to avoid
+       // the double-claim that would otherwise appear at the end of this test.
+       let as_broadcasted_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
+       assert_eq!(as_broadcasted_txn.len(), 1);
+
+       // Ensure that, even after some time, if we restart we still include *something* in the current
+       // `ChannelManager` which prevents a `PaymentFailed` when we restart even if pending resolved
+       // payments have since been timed out thanks to `IDEMPOTENCY_TIMEOUT_TICKS`.
+       // A naive implementation of the fix here would wipe the pending payments set, causing a
+       // failure event when we restart.
+       for _ in 0..(IDEMPOTENCY_TIMEOUT_TICKS * 2) { nodes[0].node.timer_tick_occurred(); }
+
+       let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
+       reload_node!(nodes[0], test_default_channel_config(), &nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister_b, chain_monitor_b, nodes_0_deserialized_b);
+       let events = nodes[0].node.get_and_clear_pending_events();
+       assert!(events.is_empty());
+
+       // Ensure that we don't generate any further events even after the channel-closing commitment
+       // transaction is confirmed on-chain.
+       confirm_transaction(&nodes[0], &as_broadcasted_txn[0]);
+       for _ in 0..(IDEMPOTENCY_TIMEOUT_TICKS * 2) { nodes[0].node.timer_tick_occurred(); }
+
+       let events = nodes[0].node.get_and_clear_pending_events();
+       assert!(events.is_empty());
+
+       let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
+       reload_node!(nodes[0], test_default_channel_config(), &nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister_c, chain_monitor_c, nodes_0_deserialized_c);
+       let events = nodes[0].node.get_and_clear_pending_events();
+       assert!(events.is_empty());
+}
+
+#[test]
+fn no_missing_sent_on_midpoint_reload() {
+       do_no_missing_sent_on_midpoint_reload(false);
+       do_no_missing_sent_on_midpoint_reload(true);
+}
index 277b0faf6a0d4e81f488a40b440de9d09940caad..4632007a0adcc04ce2273d7aacf216786fea0336 100644 (file)
@@ -9,6 +9,7 @@
 
 use crate::prelude::*;
 
+use crate::chain::keysinterface::{NodeSigner, Recipient};
 use crate::ln::msgs::LightningError;
 use crate::ln::msgs;
 use crate::ln::wire;
@@ -26,6 +27,8 @@ use crate::util::crypto::hkdf_extract_expand_twice;
 use crate::util::ser::VecWriter;
 use bitcoin::hashes::hex::ToHex;
 
+use core::ops::Deref;
+
 /// Maximum Lightning message data length according to
 /// [BOLT-8](https://github.com/lightning/bolts/blob/v1.0/08-transport.md#lightning-message-specification)
 /// and [BOLT-1](https://github.com/lightning/bolts/blob/master/01-messaging.md#lightning-message-format):
@@ -36,6 +39,11 @@ const NOISE_CK: [u8; 32] = [0x26, 0x40, 0xf5, 0x2e, 0xeb, 0xcd, 0x9e, 0x88, 0x29
 // Sha256(NOISE_CK || "lightning")
 const NOISE_H: [u8; 32] = [0xd1, 0xfb, 0xf6, 0xde, 0xe4, 0xf6, 0x86, 0xf1, 0x32, 0xfd, 0x70, 0x2c, 0x4a, 0xbf, 0x8f, 0xba, 0x4b, 0xb4, 0x20, 0xd8, 0x9d, 0x2a, 0x04, 0x8a, 0x3c, 0x4f, 0x4c, 0x09, 0x2e, 0x37, 0xb6, 0x76];
 
+enum NoiseSecretKey<'a, 'b, NS: Deref> where NS::Target: NodeSigner {
+       InMemory(&'a SecretKey),
+       NodeSigner(&'b NS)
+}
+
 pub enum NextNoiseStep {
        ActOne,
        ActTwo,
@@ -109,10 +117,10 @@ impl PeerChannelEncryptor {
                }
        }
 
-       pub fn new_inbound<C: secp256k1::Signing>(our_node_secret: &SecretKey, secp_ctx: &Secp256k1<C>) -> PeerChannelEncryptor {
+       pub fn new_inbound<NS: Deref>(node_signer: &NS) -> PeerChannelEncryptor where NS::Target: NodeSigner {
                let mut sha = Sha256::engine();
                sha.input(&NOISE_H);
-               let our_node_id = PublicKey::from_secret_key(&secp_ctx, our_node_secret);
+               let our_node_id = node_signer.get_node_id(Recipient::Node).unwrap();
                sha.input(&our_node_id.serialize()[..]);
                let h = Sha256::from_engine(sha).into_inner();
 
@@ -201,7 +209,9 @@ impl PeerChannelEncryptor {
        }
 
        #[inline]
-       fn inbound_noise_act(state: &mut BidirectionalNoiseState, act: &[u8], our_key: &SecretKey) -> Result<(PublicKey, [u8; 32]), LightningError> {
+       fn inbound_noise_act<'a, 'b, NS: Deref>(
+               state: &mut BidirectionalNoiseState, act: &[u8], secret_key: NoiseSecretKey<'a, 'b, NS>
+       ) -> Result<(PublicKey, [u8; 32]), LightningError> where NS::Target: NodeSigner {
                assert_eq!(act.len(), 50);
 
                if act[0] != 0 {
@@ -218,7 +228,15 @@ impl PeerChannelEncryptor {
                sha.input(&their_pub.serialize()[..]);
                state.h = Sha256::from_engine(sha).into_inner();
 
-               let ss = SharedSecret::new(&their_pub, &our_key);
+               let ss = match secret_key {
+                       NoiseSecretKey::InMemory(secret_key) => SharedSecret::new(&their_pub, secret_key),
+                       NoiseSecretKey::NodeSigner(node_signer) => node_signer
+                               .ecdh(Recipient::Node, &their_pub, None)
+                               .map_err(|_| LightningError {
+                                       err: "Failed to derive shared secret".to_owned(),
+                                       action: msgs::ErrorAction::DisconnectPeer { msg: None }
+                               })?,
+               };
                let temp_k = PeerChannelEncryptor::hkdf(state, ss);
 
                let mut dec = [0; 0];
@@ -251,9 +269,9 @@ impl PeerChannelEncryptor {
                }
        }
 
-       pub fn process_act_one_with_keys<C: secp256k1::Signing>(
-               &mut self, act_one: &[u8], our_node_secret: &SecretKey, our_ephemeral: SecretKey, secp_ctx: &Secp256k1<C>)
-       -> Result<[u8; 50], LightningError> {
+       pub fn process_act_one_with_keys<C: secp256k1::Signing, NS: Deref>(
+               &mut self, act_one: &[u8], node_signer: &NS, our_ephemeral: SecretKey, secp_ctx: &Secp256k1<C>)
+       -> Result<[u8; 50], LightningError> where NS::Target: NodeSigner {
                assert_eq!(act_one.len(), 50);
 
                match self.noise_state {
@@ -264,7 +282,7 @@ impl PeerChannelEncryptor {
                                                        panic!("Requested act at wrong step");
                                                }
 
-                                               let (their_pub, _) = PeerChannelEncryptor::inbound_noise_act(bidirectional_state, act_one, &our_node_secret)?;
+                                               let (their_pub, _) = PeerChannelEncryptor::inbound_noise_act(bidirectional_state, act_one, NoiseSecretKey::NodeSigner(node_signer))?;
                                                ie.get_or_insert(their_pub);
 
                                                re.get_or_insert(our_ephemeral);
@@ -281,9 +299,9 @@ impl PeerChannelEncryptor {
                }
        }
 
-       pub fn process_act_two<C: secp256k1::Signing>(
-               &mut self, act_two: &[u8], our_node_secret: &SecretKey, secp_ctx: &Secp256k1<C>)
-       -> Result<([u8; 66], PublicKey), LightningError> {
+       pub fn process_act_two<NS: Deref>(
+               &mut self, act_two: &[u8], node_signer: &NS)
+       -> Result<([u8; 66], PublicKey), LightningError> where NS::Target: NodeSigner {
                assert_eq!(act_two.len(), 50);
 
                let final_hkdf;
@@ -296,10 +314,13 @@ impl PeerChannelEncryptor {
                                                        panic!("Requested act at wrong step");
                                                }
 
-                                               let (re, temp_k2) = PeerChannelEncryptor::inbound_noise_act(bidirectional_state, act_two, &ie)?;
+                                               let (re, temp_k2) = PeerChannelEncryptor::inbound_noise_act(bidirectional_state, act_two, NoiseSecretKey::<NS>::InMemory(&ie))?;
 
                                                let mut res = [0; 66];
-                                               let our_node_id = PublicKey::from_secret_key(secp_ctx, &our_node_secret);
+                                               let our_node_id = node_signer.get_node_id(Recipient::Node).map_err(|_| LightningError {
+                                                       err: "Failed to encrypt message".to_owned(),
+                                                       action: msgs::ErrorAction::DisconnectPeer { msg: None }
+                                               })?;
 
                                                PeerChannelEncryptor::encrypt_with_ad(&mut res[1..50], 1, &temp_k2, &bidirectional_state.h, &our_node_id.serialize()[..]);
 
@@ -308,7 +329,10 @@ impl PeerChannelEncryptor {
                                                sha.input(&res[1..50]);
                                                bidirectional_state.h = Sha256::from_engine(sha).into_inner();
 
-                                               let ss = SharedSecret::new(&re, our_node_secret);
+                                               let ss = node_signer.ecdh(Recipient::Node, &re, None).map_err(|_| LightningError {
+                                                       err: "Failed to derive shared secret".to_owned(),
+                                                       action: msgs::ErrorAction::DisconnectPeer { msg: None }
+                                               })?;
                                                let temp_k = PeerChannelEncryptor::hkdf(bidirectional_state, ss);
 
                                                PeerChannelEncryptor::encrypt_with_ad(&mut res[50..], 0, &temp_k, &bidirectional_state.h, &[0; 0]);
@@ -522,12 +546,13 @@ impl PeerChannelEncryptor {
 mod tests {
        use super::LN_MAX_MSG_LEN;
 
-       use bitcoin::secp256k1::{PublicKey,SecretKey};
+       use bitcoin::secp256k1::{PublicKey, SecretKey};
        use bitcoin::secp256k1::Secp256k1;
 
        use hex;
 
        use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor,NoiseState};
+       use crate::util::test_utils::TestNodeSigner;
 
        fn get_outbound_peer_for_initiator_test_vectors() -> PeerChannelEncryptor {
                let their_node_id = PublicKey::from_slice(&hex::decode("028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7").unwrap()[..]).unwrap();
@@ -542,12 +567,13 @@ mod tests {
                // transport-responder successful handshake
                let our_node_id = SecretKey::from_slice(&hex::decode("2121212121212121212121212121212121212121212121212121212121212121").unwrap()[..]).unwrap();
                let our_ephemeral = SecretKey::from_slice(&hex::decode("2222222222222222222222222222222222222222222222222222222222222222").unwrap()[..]).unwrap();
-               let secp_ctx = Secp256k1::signing_only();
+               let secp_ctx = Secp256k1::new();
+               let node_signer = TestNodeSigner::new(our_node_id);
 
-               let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
+               let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
 
                let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
-               assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
+               assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
 
                let act_three = hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap().to_vec();
                // test vector doesn't specify the initiator static key, but it's the same as the one
@@ -572,14 +598,14 @@ mod tests {
        #[test]
        fn noise_initiator_test_vectors() {
                let our_node_id = SecretKey::from_slice(&hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap();
-               let secp_ctx = Secp256k1::signing_only();
+               let node_signer = TestNodeSigner::new(our_node_id);
 
                {
                        // transport-initiator successful handshake
                        let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors();
 
                        let act_two = hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap().to_vec();
-                       assert_eq!(outbound_peer.process_act_two(&act_two[..], &our_node_id, &secp_ctx).unwrap().0[..], hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap()[..]);
+                       assert_eq!(outbound_peer.process_act_two(&act_two[..], &&node_signer).unwrap().0[..], hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap()[..]);
 
                        match outbound_peer.noise_state {
                                NoiseState::Finished { sk, sn, sck, rk, rn, rck } => {
@@ -602,7 +628,7 @@ mod tests {
                        let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors();
 
                        let act_two = hex::decode("0102466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap().to_vec();
-                       assert!(outbound_peer.process_act_two(&act_two[..], &our_node_id, &secp_ctx).is_err());
+                       assert!(outbound_peer.process_act_two(&act_two[..], &&node_signer).is_err());
                }
 
                {
@@ -610,7 +636,7 @@ mod tests {
                        let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors();
 
                        let act_two = hex::decode("0004466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap().to_vec();
-                       assert!(outbound_peer.process_act_two(&act_two[..], &our_node_id, &secp_ctx).is_err());
+                       assert!(outbound_peer.process_act_two(&act_two[..], &&node_signer).is_err());
                }
 
                {
@@ -618,7 +644,7 @@ mod tests {
                        let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors();
 
                        let act_two = hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730af").unwrap().to_vec();
-                       assert!(outbound_peer.process_act_two(&act_two[..], &our_node_id, &secp_ctx).is_err());
+                       assert!(outbound_peer.process_act_two(&act_two[..], &&node_signer).is_err());
                }
        }
 
@@ -626,7 +652,8 @@ mod tests {
        fn noise_responder_test_vectors() {
                let our_node_id = SecretKey::from_slice(&hex::decode("2121212121212121212121212121212121212121212121212121212121212121").unwrap()[..]).unwrap();
                let our_ephemeral = SecretKey::from_slice(&hex::decode("2222222222222222222222222222222222222222222222222222222222222222").unwrap()[..]).unwrap();
-               let secp_ctx = Secp256k1::signing_only();
+               let secp_ctx = Secp256k1::new();
+               let node_signer = TestNodeSigner::new(our_node_id);
 
                {
                        let _ = get_inbound_peer_for_test_vectors();
@@ -637,31 +664,31 @@ mod tests {
                }
                {
                        // transport-responder act1 bad version test
-                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
+                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
 
                        let act_one = hex::decode("01036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
-                       assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).is_err());
+                       assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).is_err());
                }
                {
                        // transport-responder act1 bad key serialization test
-                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
+                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
 
                        let act_one =hex::decode("00046360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
-                       assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).is_err());
+                       assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).is_err());
                }
                {
                        // transport-responder act1 bad MAC test
-                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
+                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
 
                        let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6b").unwrap().to_vec();
-                       assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).is_err());
+                       assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).is_err());
                }
                {
                        // transport-responder act3 bad version test
-                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
+                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
 
                        let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
-                       assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
+                       assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
 
                        let act_three = hex::decode("01b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap().to_vec();
                        assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
@@ -672,30 +699,30 @@ mod tests {
                }
                {
                        // transport-responder act3 bad MAC for ciphertext test
-                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
+                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
 
                        let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
-                       assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
+                       assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
 
                        let act_three = hex::decode("00c9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap().to_vec();
                        assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
                }
                {
                        // transport-responder act3 bad rs test
-                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
+                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
 
                        let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
-                       assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
+                       assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
 
                        let act_three = hex::decode("00bfe3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa2235536ad09a8ee351870c2bb7f78b754a26c6cef79a98d25139c856d7efd252c2ae73c").unwrap().to_vec();
                        assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
                }
                {
                        // transport-responder act3 bad MAC test
-                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
+                       let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
 
                        let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
-                       assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
+                       assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
 
                        let act_three = hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139bb").unwrap().to_vec();
                        assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
@@ -708,13 +735,13 @@ mod tests {
                // We use the same keys as the initiator and responder test vectors, so we copy those tests
                // here and use them to encrypt.
                let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors();
-               let secp_ctx = Secp256k1::signing_only();
 
                {
                        let our_node_id = SecretKey::from_slice(&hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap();
+                       let node_signer = TestNodeSigner::new(our_node_id);
 
                        let act_two = hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap().to_vec();
-                       assert_eq!(outbound_peer.process_act_two(&act_two[..], &our_node_id, &secp_ctx).unwrap().0[..], hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap()[..]);
+                       assert_eq!(outbound_peer.process_act_two(&act_two[..], &&node_signer).unwrap().0[..], hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap()[..]);
 
                        match outbound_peer.noise_state {
                                NoiseState::Finished { sk, sn, sck, rk, rn, rck } => {
index d851d29d46cd80e9d608fb951bc535e0c231649b..41bbf5b4908bba966f83d274dce8b2f3a2bb8ebf 100644 (file)
@@ -17,6 +17,7 @@
 
 use bitcoin::secp256k1::{self, Secp256k1, SecretKey, PublicKey};
 
+use crate::chain::keysinterface::{KeysManager, NodeSigner, Recipient};
 use crate::ln::features::{InitFeatures, NodeFeatures};
 use crate::ln::msgs;
 use crate::ln::msgs::{ChannelMessageHandler, LightningError, NetAddress, OnionMessageHandler, RoutingMessageHandler};
@@ -26,9 +27,8 @@ use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
 use crate::ln::wire;
 use crate::ln::wire::Encode;
 use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
-use crate::routing::gossip::{NetworkGraph, P2PGossipSync};
+use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId};
 use crate::util::atomic_counter::AtomicCounter;
-use crate::util::crypto::sign;
 use crate::util::events::{MessageSendEvent, MessageSendEventsProvider, OnionMessageProvider};
 use crate::util::logger::Logger;
 
@@ -43,20 +43,26 @@ use core::convert::Infallible;
 #[cfg(feature = "std")] use std::error;
 
 use bitcoin::hashes::sha256::Hash as Sha256;
-use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hashes::sha256::HashEngine as Sha256Engine;
 use bitcoin::hashes::{HashEngine, Hash};
 
-/// Handler for BOLT1-compliant messages.
+/// A handler provided to [`PeerManager`] for reading and handling custom messages.
+///
+/// [BOLT 1] specifies a custom message type range for use with experimental or application-specific
+/// messages. `CustomMessageHandler` allows for user-defined handling of such types. See the
+/// [`lightning_custom_message`] crate for tools useful in composing more than one custom handler.
+///
+/// [BOLT 1]: https://github.com/lightning/bolts/blob/master/01-messaging.md
+/// [`lightning_custom_message`]: https://docs.rs/lightning_custom_message/latest/lightning_custom_message
 pub trait CustomMessageHandler: wire::CustomMessageReader {
-       /// Called with the message type that was received and the buffer to be read.
-       /// Can return a `MessageHandlingError` if the message could not be handled.
+       /// Handles the given message sent from `sender_node_id`, possibly producing messages for
+       /// [`CustomMessageHandler::get_and_clear_pending_msg`] to return and thus for [`PeerManager`]
+       /// to send.
        fn handle_custom_message(&self, msg: Self::CustomMessage, sender_node_id: &PublicKey) -> Result<(), LightningError>;
 
-       /// Gets the list of pending messages which were generated by the custom message
-       /// handler, clearing the list in the process. The first tuple element must
-       /// correspond to the intended recipients node ids. If no connection to one of the
-       /// specified node does not exist, the message is simply not sent to it.
+       /// Returns the list of pending messages that were generated by the handler, clearing the list
+       /// in the process. Each message is paired with the node id of the intended recipient. If no
+       /// connection to the node exists, then the message is simply not sent.
        fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)>;
 }
 
@@ -72,8 +78,8 @@ impl RoutingMessageHandler for IgnoringMessageHandler {
        fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result<bool, LightningError> { Ok(false) }
        fn get_next_channel_announcement(&self, _starting_point: u64) ->
                Option<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> { None }
-       fn get_next_node_announcement(&self, _starting_point: Option<&PublicKey>) -> Option<msgs::NodeAnnouncement> { None }
-       fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init) -> Result<(), ()> { Ok(()) }
+       fn get_next_node_announcement(&self, _starting_point: Option<&NodeId>) -> Option<msgs::NodeAnnouncement> { None }
+       fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init, _inbound: bool) -> Result<(), ()> { Ok(()) }
        fn handle_reply_channel_range(&self, _their_node_id: &PublicKey, _msg: msgs::ReplyChannelRange) -> Result<(), LightningError> { Ok(()) }
        fn handle_reply_short_channel_ids_end(&self, _their_node_id: &PublicKey, _msg: msgs::ReplyShortChannelIdsEnd) -> Result<(), LightningError> { Ok(()) }
        fn handle_query_channel_range(&self, _their_node_id: &PublicKey, _msg: msgs::QueryChannelRange) -> Result<(), LightningError> { Ok(()) }
@@ -82,14 +88,15 @@ impl RoutingMessageHandler for IgnoringMessageHandler {
        fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
                InitFeatures::empty()
        }
+       fn processing_queue_high(&self) -> bool { false }
 }
 impl OnionMessageProvider for IgnoringMessageHandler {
        fn next_onion_message_for_peer(&self, _peer_node_id: PublicKey) -> Option<msgs::OnionMessage> { None }
 }
 impl OnionMessageHandler for IgnoringMessageHandler {
        fn handle_onion_message(&self, _their_node_id: &PublicKey, _msg: &msgs::OnionMessage) {}
-       fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init) -> Result<(), ()> { Ok(()) }
-       fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {}
+       fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init, _inbound: bool) -> Result<(), ()> { Ok(()) }
+       fn peer_disconnected(&self, _their_node_id: &PublicKey) {}
        fn provided_node_features(&self) -> NodeFeatures { NodeFeatures::empty() }
        fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
                InitFeatures::empty()
@@ -173,10 +180,10 @@ impl MessageSendEventsProvider for ErroringMessageHandler {
 impl ChannelMessageHandler for ErroringMessageHandler {
        // Any messages which are related to a specific channel generate an error message to let the
        // peer know we don't care about channels.
-       fn handle_open_channel(&self, their_node_id: &PublicKey, _their_features: InitFeatures, msg: &msgs::OpenChannel) {
+       fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) {
                ErroringMessageHandler::push_error(self, their_node_id, msg.temporary_channel_id);
        }
-       fn handle_accept_channel(&self, their_node_id: &PublicKey, _their_features: InitFeatures, msg: &msgs::AcceptChannel) {
+       fn handle_accept_channel(&self, their_node_id: &PublicKey, msg: &msgs::AcceptChannel) {
                ErroringMessageHandler::push_error(self, their_node_id, msg.temporary_channel_id);
        }
        fn handle_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) {
@@ -188,7 +195,7 @@ impl ChannelMessageHandler for ErroringMessageHandler {
        fn handle_channel_ready(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReady) {
                ErroringMessageHandler::push_error(self, their_node_id, msg.channel_id);
        }
-       fn handle_shutdown(&self, their_node_id: &PublicKey, _their_features: &InitFeatures, msg: &msgs::Shutdown) {
+       fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &msgs::Shutdown) {
                ErroringMessageHandler::push_error(self, their_node_id, msg.channel_id);
        }
        fn handle_closing_signed(&self, their_node_id: &PublicKey, msg: &msgs::ClosingSigned) {
@@ -223,8 +230,8 @@ impl ChannelMessageHandler for ErroringMessageHandler {
        }
        // msgs::ChannelUpdate does not contain the channel_id field, so we just drop them.
        fn handle_channel_update(&self, _their_node_id: &PublicKey, _msg: &msgs::ChannelUpdate) {}
-       fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {}
-       fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init) -> Result<(), ()> { Ok(()) }
+       fn peer_disconnected(&self, _their_node_id: &PublicKey) {}
+       fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init, _inbound: bool) -> Result<(), ()> { Ok(()) }
        fn handle_error(&self, _their_node_id: &PublicKey, _msg: &msgs::ErrorMessage) {}
        fn provided_node_features(&self) -> NodeFeatures { NodeFeatures::empty() }
        fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
@@ -315,16 +322,7 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
 /// generate no further read_event/write_buffer_space_avail/socket_disconnected calls for the
 /// descriptor.
 #[derive(Clone)]
-pub struct PeerHandleError {
-       /// Used to indicate that we probably can't make any future connections to this peer (e.g.
-       /// because we required features that our peer was missing, or vice versa).
-       ///
-       /// While LDK's [`ChannelManager`] will not do it automatically, you likely wish to force-close
-       /// any channels with this peer or check for new versions of LDK.
-       ///
-       /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
-       pub no_connection_possible: bool,
-}
+pub struct PeerHandleError { }
 impl fmt::Debug for PeerHandleError {
        fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
                formatter.write_str("Peer Sent Invalid Data")
@@ -346,7 +344,7 @@ impl error::Error for PeerHandleError {
 enum InitSyncTracker{
        NoSyncRequested,
        ChannelsSyncing(u64),
-       NodesSyncing(PublicKey),
+       NodesSyncing(NodeId),
 }
 
 /// The ratio between buffer sizes at which we stop sending initial sync messages vs when we stop
@@ -390,7 +388,15 @@ const BUFFER_DRAIN_MSGS_PER_TICK: usize = 32;
 
 struct Peer {
        channel_encryptor: PeerChannelEncryptor,
-       their_node_id: Option<PublicKey>,
+       /// We cache a `NodeId` here to avoid serializing peers' keys every time we forward gossip
+       /// messages in `PeerManager`. Use `Peer::set_their_node_id` to modify this field.
+       their_node_id: Option<(PublicKey, NodeId)>,
+       /// The features provided in the peer's [`msgs::Init`] message.
+       ///
+       /// This is set only after we've processed the [`msgs::Init`] message and called relevant
+       /// `peer_connected` handler methods. Thus, this field is set *iff* we've finished our
+       /// handshake and can talk to this peer normally (though use [`Peer::handshake_complete`] to
+       /// check this.
        their_features: Option<InitFeatures>,
        their_net_address: Option<NetAddress>,
 
@@ -413,9 +419,24 @@ struct Peer {
        awaiting_pong_timer_tick_intervals: i8,
        received_message_since_timer_tick: bool,
        sent_gossip_timestamp_filter: bool,
+
+       /// Indicates we've received a `channel_announcement` since the last time we had
+       /// [`PeerManager::gossip_processing_backlogged`] set (or, really, that we've received a
+       /// `channel_announcement` at all - we set this unconditionally but unset it every time we
+       /// check if we're gossip-processing-backlogged).
+       received_channel_announce_since_backlogged: bool,
+
+       inbound_connection: bool,
 }
 
 impl Peer {
+       /// True after we've processed the [`msgs::Init`] message and called relevant `peer_connected`
+       /// handler methods. Thus, this implies we've finished our handshake and can talk to this peer
+       /// normally.
+       fn handshake_complete(&self) -> bool {
+               self.their_features.is_some()
+       }
+
        /// Returns true if the channel announcements/updates for the given channel should be
        /// forwarded to this peer.
        /// If we are sending our routing table to this peer and we have not yet sent channel
@@ -423,6 +444,7 @@ impl Peer {
        /// point and we shouldn't send it yet to avoid sending duplicate updates. If we've already
        /// sent the old versions, we should send the update, and so return true here.
        fn should_forward_channel_announcement(&self, channel_id: u64) -> bool {
+               if !self.handshake_complete() { return false; }
                if self.their_features.as_ref().unwrap().supports_gossip_queries() &&
                        !self.sent_gossip_timestamp_filter {
                                return false;
@@ -435,7 +457,8 @@ impl Peer {
        }
 
        /// Similar to the above, but for node announcements indexed by node_id.
-       fn should_forward_node_announcement(&self, node_id: PublicKey) -> bool {
+       fn should_forward_node_announcement(&self, node_id: NodeId) -> bool {
+               if !self.handshake_complete() { return false; }
                if self.their_features.as_ref().unwrap().supports_gossip_queries() &&
                        !self.sent_gossip_timestamp_filter {
                                return false;
@@ -443,14 +466,18 @@ impl Peer {
                match self.sync_status {
                        InitSyncTracker::NoSyncRequested => true,
                        InitSyncTracker::ChannelsSyncing(_) => false,
-                       InitSyncTracker::NodesSyncing(pk) => pk < node_id,
+                       InitSyncTracker::NodesSyncing(sync_node_id) => sync_node_id.as_slice() < node_id.as_slice(),
                }
        }
 
        /// Returns whether we should be reading bytes from this peer, based on whether its outbound
        /// buffer still has space and we don't need to pause reads to get some writes out.
-       fn should_read(&self) -> bool {
-               self.pending_outbound_buffer.len() < OUTBOUND_BUFFER_LIMIT_READ_PAUSE
+       fn should_read(&mut self, gossip_processing_backlogged: bool) -> bool {
+               if !gossip_processing_backlogged {
+                       self.received_channel_announce_since_backlogged = false;
+               }
+               self.pending_outbound_buffer.len() < OUTBOUND_BUFFER_LIMIT_READ_PAUSE &&
+                       (!gossip_processing_backlogged || !self.received_channel_announce_since_backlogged)
        }
 
        /// Determines if we should push additional gossip background sync (aka "backfill") onto a peer's
@@ -458,19 +485,20 @@ impl Peer {
        fn should_buffer_gossip_backfill(&self) -> bool {
                self.pending_outbound_buffer.is_empty() && self.gossip_broadcast_buffer.is_empty()
                        && self.msgs_sent_since_pong < BUFFER_DRAIN_MSGS_PER_TICK
+                       && self.handshake_complete()
        }
 
        /// Determines if we should push an onion message onto a peer's outbound buffer. This is checked
        /// every time the peer's buffer may have been drained.
        fn should_buffer_onion_message(&self) -> bool {
-               self.pending_outbound_buffer.is_empty()
+               self.pending_outbound_buffer.is_empty() && self.handshake_complete()
                        && self.msgs_sent_since_pong < BUFFER_DRAIN_MSGS_PER_TICK
        }
 
        /// Determines if we should push additional gossip broadcast messages onto a peer's outbound
        /// buffer. This is checked every time the peer's buffer may have been drained.
        fn should_buffer_gossip_broadcast(&self) -> bool {
-               self.pending_outbound_buffer.is_empty()
+               self.pending_outbound_buffer.is_empty() && self.handshake_complete()
                        && self.msgs_sent_since_pong < BUFFER_DRAIN_MSGS_PER_TICK
        }
 
@@ -482,6 +510,10 @@ impl Peer {
                total_outbound_buffered > OUTBOUND_BUFFER_LIMIT_DROP_GOSSIP ||
                        self.msgs_sent_since_pong > BUFFER_DRAIN_MSGS_PER_TICK * FORWARD_INIT_SYNC_BUFFER_LIMIT_RATIO
        }
+
+       fn set_their_node_id(&mut self, node_id: PublicKey) {
+               self.their_node_id = Some((node_id, NodeId::from_pubkey(&node_id)));
+       }
 }
 
 /// SimpleArcPeerManager is useful when you need a PeerManager with a static lifetime, e.g.
@@ -491,7 +523,7 @@ impl Peer {
 /// issues such as overly long function definitions.
 ///
 /// (C-not exported) as `Arc`s don't make sense in bindings.
-pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>, Arc<SimpleArcOnionMessenger<L>>, Arc<L>, IgnoringMessageHandler>;
+pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>, Arc<SimpleArcOnionMessenger<L>>, Arc<L>, IgnoringMessageHandler, Arc<KeysManager>>;
 
 /// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference
 /// counterpart to the SimpleArcPeerManager type alias. Use this type by default when you don't
@@ -501,7 +533,7 @@ pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArc
 /// helps with issues such as long function definitions.
 ///
 /// (C-not exported) as general type aliases don't make sense in bindings.
-pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, M, T, F, L>, &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, &'i SimpleRefOnionMessenger<'j, 'k, L>, &'f L, IgnoringMessageHandler>;
+pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, M, T, F, L>, &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, &'i SimpleRefOnionMessenger<'j, 'k, L>, &'f L, IgnoringMessageHandler, &'c KeysManager>;
 
 /// A PeerManager manages a set of peers, described by their [`SocketDescriptor`] and marshalls
 /// socket events into messages which it passes on to its [`MessageHandler`].
@@ -522,12 +554,13 @@ pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm
 /// you're using lightning-net-tokio.
 ///
 /// [`read_event`]: PeerManager::read_event
-pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref> where
+pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref, NS: Deref> where
                CM::Target: ChannelMessageHandler,
                RM::Target: RoutingMessageHandler,
                OM::Target: OnionMessageHandler,
                L::Target: Logger,
-               CMH::Target: CustomMessageHandler {
+               CMH::Target: CustomMessageHandler,
+               NS::Target: NodeSigner {
        message_handler: MessageHandler<CM, RM, OM>,
        /// Connection state for each connected peer - we have an outer read-write lock which is taken
        /// as read while we're doing processing for a peer and taken write when a peer is being added
@@ -557,12 +590,16 @@ pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: D
        /// value increases strictly since we don't assume access to a time source.
        last_node_announcement_serial: AtomicU32,
 
-       our_node_secret: SecretKey,
        ephemeral_key_midstate: Sha256Engine,
        custom_message_handler: CMH,
 
        peer_counter: AtomicCounter,
 
+       gossip_processing_backlogged: AtomicBool,
+       gossip_processing_backlog_lifted: AtomicBool,
+
+       node_signer: NS,
+
        logger: L,
        secp_ctx: Secp256k1<secp256k1::SignOnly>
 }
@@ -592,10 +629,11 @@ macro_rules! encode_msg {
        }}
 }
 
-impl<Descriptor: SocketDescriptor, CM: Deref, OM: Deref, L: Deref> PeerManager<Descriptor, CM, IgnoringMessageHandler, OM, L, IgnoringMessageHandler> where
+impl<Descriptor: SocketDescriptor, CM: Deref, OM: Deref, L: Deref, NS: Deref> PeerManager<Descriptor, CM, IgnoringMessageHandler, OM, L, IgnoringMessageHandler, NS> where
                CM::Target: ChannelMessageHandler,
                OM::Target: OnionMessageHandler,
-               L::Target: Logger {
+               L::Target: Logger,
+               NS::Target: NodeSigner {
        /// Constructs a new `PeerManager` with the given `ChannelMessageHandler` and
        /// `OnionMessageHandler`. No routing message handler is used and network graph messages are
        /// ignored.
@@ -609,18 +647,19 @@ impl<Descriptor: SocketDescriptor, CM: Deref, OM: Deref, L: Deref> PeerManager<D
        /// minute should suffice.
        ///
        /// (C-not exported) as we can't export a PeerManager with a dummy route handler
-       pub fn new_channel_only(channel_message_handler: CM, onion_message_handler: OM, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L) -> Self {
+       pub fn new_channel_only(channel_message_handler: CM, onion_message_handler: OM, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, node_signer: NS) -> Self {
                Self::new(MessageHandler {
                        chan_handler: channel_message_handler,
                        route_handler: IgnoringMessageHandler{},
                        onion_message_handler,
-               }, our_node_secret, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{})
+               }, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{}, node_signer)
        }
 }
 
-impl<Descriptor: SocketDescriptor, RM: Deref, L: Deref> PeerManager<Descriptor, ErroringMessageHandler, RM, IgnoringMessageHandler, L, IgnoringMessageHandler> where
+impl<Descriptor: SocketDescriptor, RM: Deref, L: Deref, NS: Deref> PeerManager<Descriptor, ErroringMessageHandler, RM, IgnoringMessageHandler, L, IgnoringMessageHandler, NS> where
                RM::Target: RoutingMessageHandler,
-               L::Target: Logger {
+               L::Target: Logger,
+               NS::Target: NodeSigner {
        /// Constructs a new `PeerManager` with the given `RoutingMessageHandler`. No channel message
        /// handler or onion message handler is used and onion and channel messages will be ignored (or
        /// generate error messages). Note that some other lightning implementations time-out connections
@@ -635,29 +674,29 @@ impl<Descriptor: SocketDescriptor, RM: Deref, L: Deref> PeerManager<Descriptor,
        /// cryptographically secure random bytes.
        ///
        /// (C-not exported) as we can't export a PeerManager with a dummy channel handler
-       pub fn new_routing_only(routing_message_handler: RM, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L) -> Self {
+       pub fn new_routing_only(routing_message_handler: RM, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, node_signer: NS) -> Self {
                Self::new(MessageHandler {
                        chan_handler: ErroringMessageHandler::new(),
                        route_handler: routing_message_handler,
                        onion_message_handler: IgnoringMessageHandler{},
-               }, our_node_secret, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{})
+               }, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{}, node_signer)
        }
 }
 
-/// A simple wrapper that optionally prints " from <pubkey>" for an optional pubkey.
+/// A simple wrapper that optionally prints ` from <pubkey>` for an optional pubkey.
 /// This works around `format!()` taking a reference to each argument, preventing
 /// `if let Some(node_id) = peer.their_node_id { format!(.., node_id) } else { .. }` from compiling
 /// due to lifetime errors.
-struct OptionalFromDebugger<'a>(&'a Option<PublicKey>);
+struct OptionalFromDebugger<'a>(&'a Option<(PublicKey, NodeId)>);
 impl core::fmt::Display for OptionalFromDebugger<'_> {
        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
-               if let Some(node_id) = self.0 { write!(f, " from {}", log_pubkey!(node_id)) } else { Ok(()) }
+               if let Some((node_id, _)) = self.0 { write!(f, " from {}", log_pubkey!(node_id)) } else { Ok(()) }
        }
 }
 
 /// A function used to filter out local or private addresses
-/// https://www.iana.org./assignments/ipv4-address-space/ipv4-address-space.xhtml
-/// https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
+/// <https://www.iana.org./assignments/ipv4-address-space/ipv4-address-space.xhtml>
+/// <https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml>
 fn filter_addresses(ip_address: Option<NetAddress>) -> Option<NetAddress> {
        match ip_address{
                // For IPv4 range 10.0.0.0 - 10.255.255.255 (10/8)
@@ -685,12 +724,14 @@ fn filter_addresses(ip_address: Option<NetAddress>) -> Option<NetAddress> {
        }
 }
 
-impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref> PeerManager<Descriptor, CM, RM, OM, L, CMH> where
+impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref, NS: Deref> PeerManager<Descriptor, CM, RM, OM, L, CMH, NS> where
                CM::Target: ChannelMessageHandler,
                RM::Target: RoutingMessageHandler,
                OM::Target: OnionMessageHandler,
                L::Target: Logger,
-               CMH::Target: CustomMessageHandler {
+               CMH::Target: CustomMessageHandler,
+               NS::Target: NodeSigner
+{
        /// Constructs a new PeerManager with the given message handlers and node_id secret key
        /// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
        /// cryptographically secure random bytes.
@@ -699,7 +740,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
        /// incremented irregularly internally. In general it is best to simply use the current UNIX
        /// timestamp, however if it is not available a persistent counter that increases once per
        /// minute should suffice.
-       pub fn new(message_handler: MessageHandler<CM, RM, OM>, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, custom_message_handler: CMH) -> Self {
+       pub fn new(message_handler: MessageHandler<CM, RM, OM>, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, custom_message_handler: CMH, node_signer: NS) -> Self {
                let mut ephemeral_key_midstate = Sha256::engine();
                ephemeral_key_midstate.input(ephemeral_random_data);
 
@@ -713,29 +754,36 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                        node_id_to_descriptor: Mutex::new(HashMap::new()),
                        event_processing_lock: Mutex::new(()),
                        blocked_event_processors: AtomicBool::new(false),
-                       our_node_secret,
                        ephemeral_key_midstate,
                        peer_counter: AtomicCounter::new(),
+                       gossip_processing_backlogged: AtomicBool::new(false),
+                       gossip_processing_backlog_lifted: AtomicBool::new(false),
                        last_node_announcement_serial: AtomicU32::new(current_time),
                        logger,
                        custom_message_handler,
+                       node_signer,
                        secp_ctx,
                }
        }
 
-       /// Get the list of node ids for peers which have completed the initial handshake.
+       /// Get a list of tuples mapping from node id to network addresses for peers which have
+       /// completed the initial handshake.
+       ///
+       /// For outbound connections, the [`PublicKey`] will be the same as the `their_node_id` parameter
+       /// passed in to [`Self::new_outbound_connection`], however entries will only appear once the initial
+       /// handshake has completed and we are sure the remote peer has the private key for the given
+       /// [`PublicKey`].
        ///
-       /// For outbound connections, this will be the same as the their_node_id parameter passed in to
-       /// new_outbound_connection, however entries will only appear once the initial handshake has
-       /// completed and we are sure the remote peer has the private key for the given node_id.
-       pub fn get_peer_node_ids(&self) -> Vec<PublicKey> {
+       /// The returned `Option`s will only be `Some` if an address had been previously given via
+       /// [`Self::new_outbound_connection`] or [`Self::new_inbound_connection`].
+       pub fn get_peer_node_ids(&self) -> Vec<(PublicKey, Option<NetAddress>)> {
                let peers = self.peers.read().unwrap();
                peers.values().filter_map(|peer_mutex| {
                        let p = peer_mutex.lock().unwrap();
-                       if !p.channel_encryptor.is_ready_for_encryption() || p.their_features.is_none() {
+                       if !p.handshake_complete() {
                                return None;
                        }
-                       p.their_node_id
+                       Some((p.their_node_id.unwrap().0, p.their_net_address.clone()))
                }).collect()
        }
 
@@ -746,7 +794,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                SecretKey::from_slice(&Sha256::from_engine(ephemeral_hash).into_inner()).expect("You broke SHA-256!")
        }
 
-       /// Indicates a new outbound connection has been established to a node with the given node_id
+       /// Indicates a new outbound connection has been established to a node with the given `node_id`
        /// and an optional remote network address.
        ///
        /// The remote network address adds the option to report a remote IP address back to a connecting
@@ -767,31 +815,40 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                let pending_read_buffer = [0; 50].to_vec(); // Noise act two is 50 bytes
 
                let mut peers = self.peers.write().unwrap();
-               if peers.insert(descriptor, Mutex::new(Peer {
-                       channel_encryptor: peer_encryptor,
-                       their_node_id: None,
-                       their_features: None,
-                       their_net_address: remote_network_address,
-
-                       pending_outbound_buffer: LinkedList::new(),
-                       pending_outbound_buffer_first_msg_offset: 0,
-                       gossip_broadcast_buffer: LinkedList::new(),
-                       awaiting_write_event: false,
-
-                       pending_read_buffer,
-                       pending_read_buffer_pos: 0,
-                       pending_read_is_header: false,
-
-                       sync_status: InitSyncTracker::NoSyncRequested,
-
-                       msgs_sent_since_pong: 0,
-                       awaiting_pong_timer_tick_intervals: 0,
-                       received_message_since_timer_tick: false,
-                       sent_gossip_timestamp_filter: false,
-               })).is_some() {
-                       panic!("PeerManager driver duplicated descriptors!");
-               };
-               Ok(res)
+               match peers.entry(descriptor) {
+                       hash_map::Entry::Occupied(_) => {
+                               debug_assert!(false, "PeerManager driver duplicated descriptors!");
+                               Err(PeerHandleError {})
+                       },
+                       hash_map::Entry::Vacant(e) => {
+                               e.insert(Mutex::new(Peer {
+                                       channel_encryptor: peer_encryptor,
+                                       their_node_id: None,
+                                       their_features: None,
+                                       their_net_address: remote_network_address,
+
+                                       pending_outbound_buffer: LinkedList::new(),
+                                       pending_outbound_buffer_first_msg_offset: 0,
+                                       gossip_broadcast_buffer: LinkedList::new(),
+                                       awaiting_write_event: false,
+
+                                       pending_read_buffer,
+                                       pending_read_buffer_pos: 0,
+                                       pending_read_is_header: false,
+
+                                       sync_status: InitSyncTracker::NoSyncRequested,
+
+                                       msgs_sent_since_pong: 0,
+                                       awaiting_pong_timer_tick_intervals: 0,
+                                       received_message_since_timer_tick: false,
+                                       sent_gossip_timestamp_filter: false,
+
+                                       received_channel_announce_since_backlogged: false,
+                                       inbound_connection: false,
+                               }));
+                               Ok(res)
+                       }
+               }
        }
 
        /// Indicates a new inbound connection has been established to a node with an optional remote
@@ -810,41 +867,63 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
        ///
        /// [`socket_disconnected()`]: PeerManager::socket_disconnected
        pub fn new_inbound_connection(&self, descriptor: Descriptor, remote_network_address: Option<NetAddress>) -> Result<(), PeerHandleError> {
-               let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret, &self.secp_ctx);
+               let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.node_signer);
                let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
 
                let mut peers = self.peers.write().unwrap();
-               if peers.insert(descriptor, Mutex::new(Peer {
-                       channel_encryptor: peer_encryptor,
-                       their_node_id: None,
-                       their_features: None,
-                       their_net_address: remote_network_address,
-
-                       pending_outbound_buffer: LinkedList::new(),
-                       pending_outbound_buffer_first_msg_offset: 0,
-                       gossip_broadcast_buffer: LinkedList::new(),
-                       awaiting_write_event: false,
-
-                       pending_read_buffer,
-                       pending_read_buffer_pos: 0,
-                       pending_read_is_header: false,
-
-                       sync_status: InitSyncTracker::NoSyncRequested,
-
-                       msgs_sent_since_pong: 0,
-                       awaiting_pong_timer_tick_intervals: 0,
-                       received_message_since_timer_tick: false,
-                       sent_gossip_timestamp_filter: false,
-               })).is_some() {
-                       panic!("PeerManager driver duplicated descriptors!");
-               };
-               Ok(())
+               match peers.entry(descriptor) {
+                       hash_map::Entry::Occupied(_) => {
+                               debug_assert!(false, "PeerManager driver duplicated descriptors!");
+                               Err(PeerHandleError {})
+                       },
+                       hash_map::Entry::Vacant(e) => {
+                               e.insert(Mutex::new(Peer {
+                                       channel_encryptor: peer_encryptor,
+                                       their_node_id: None,
+                                       their_features: None,
+                                       their_net_address: remote_network_address,
+
+                                       pending_outbound_buffer: LinkedList::new(),
+                                       pending_outbound_buffer_first_msg_offset: 0,
+                                       gossip_broadcast_buffer: LinkedList::new(),
+                                       awaiting_write_event: false,
+
+                                       pending_read_buffer,
+                                       pending_read_buffer_pos: 0,
+                                       pending_read_is_header: false,
+
+                                       sync_status: InitSyncTracker::NoSyncRequested,
+
+                                       msgs_sent_since_pong: 0,
+                                       awaiting_pong_timer_tick_intervals: 0,
+                                       received_message_since_timer_tick: false,
+                                       sent_gossip_timestamp_filter: false,
+
+                                       received_channel_announce_since_backlogged: false,
+                                       inbound_connection: true,
+                               }));
+                               Ok(())
+                       }
+               }
+       }
+
+       fn peer_should_read(&self, peer: &mut Peer) -> bool {
+               peer.should_read(self.gossip_processing_backlogged.load(Ordering::Relaxed))
        }
 
-       fn do_attempt_write_data(&self, descriptor: &mut Descriptor, peer: &mut Peer) {
+       fn update_gossip_backlogged(&self) {
+               let new_state = self.message_handler.route_handler.processing_queue_high();
+               let prev_state = self.gossip_processing_backlogged.swap(new_state, Ordering::Relaxed);
+               if prev_state && !new_state {
+                       self.gossip_processing_backlog_lifted.store(true, Ordering::Relaxed);
+               }
+       }
+
+       fn do_attempt_write_data(&self, descriptor: &mut Descriptor, peer: &mut Peer, force_one_write: bool) {
+               let mut have_written = false;
                while !peer.awaiting_write_event {
                        if peer.should_buffer_onion_message() {
-                               if let Some(peer_node_id) = peer.their_node_id {
+                               if let Some((peer_node_id, _)) = peer.their_node_id {
                                        if let Some(next_onion_message) =
                                                self.message_handler.onion_message_handler.next_onion_message_for_peer(peer_node_id) {
                                                        self.enqueue_message(peer, &next_onion_message);
@@ -884,8 +963,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                }
                                        },
                                        InitSyncTracker::ChannelsSyncing(_) => unreachable!(),
-                                       InitSyncTracker::NodesSyncing(key) => {
-                                               if let Some(msg) = self.message_handler.route_handler.get_next_node_announcement(Some(&key)) {
+                                       InitSyncTracker::NodesSyncing(sync_node_id) => {
+                                               if let Some(msg) = self.message_handler.route_handler.get_next_node_announcement(Some(&sync_node_id)) {
                                                        self.enqueue_message(peer, &msg);
                                                        peer.sync_status = InitSyncTracker::NodesSyncing(msg.contents.node_id);
                                                } else {
@@ -898,13 +977,23 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                self.maybe_send_extra_ping(peer);
                        }
 
+                       let should_read = self.peer_should_read(peer);
                        let next_buff = match peer.pending_outbound_buffer.front() {
-                               None => return,
+                               None => {
+                                       if force_one_write && !have_written {
+                                               if should_read {
+                                                       let data_sent = descriptor.send_data(&[], should_read);
+                                                       debug_assert_eq!(data_sent, 0, "Can't write more than no data");
+                                               }
+                                       }
+                                       return
+                               },
                                Some(buff) => buff,
                        };
 
                        let pending = &next_buff[peer.pending_outbound_buffer_first_msg_offset..];
-                       let data_sent = descriptor.send_data(pending, peer.should_read());
+                       let data_sent = descriptor.send_data(pending, should_read);
+                       have_written = true;
                        peer.pending_outbound_buffer_first_msg_offset += data_sent;
                        if peer.pending_outbound_buffer_first_msg_offset == next_buff.len() {
                                peer.pending_outbound_buffer_first_msg_offset = 0;
@@ -934,12 +1023,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                // This is most likely a simple race condition where the user found that the socket
                                // was writeable, then we told the user to `disconnect_socket()`, then they called
                                // this method. Return an error to make sure we get disconnected.
-                               return Err(PeerHandleError { no_connection_possible: false });
+                               return Err(PeerHandleError { });
                        },
                        Some(peer_mutex) => {
                                let mut peer = peer_mutex.lock().unwrap();
                                peer.awaiting_write_event = false;
-                               self.do_attempt_write_data(descriptor, &mut peer);
+                               self.do_attempt_write_data(descriptor, &mut peer, false);
                        }
                };
                Ok(())
@@ -957,6 +1046,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
        /// [`send_data`] call on this descriptor has `resume_read` set (preventing DoS issues in the
        /// send buffer).
        ///
+       /// In order to avoid processing too many messages at once per peer, `data` should be on the
+       /// order of 4KiB.
+       ///
        /// [`send_data`]: SocketDescriptor::send_data
        /// [`process_events`]: PeerManager::process_events
        pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: &[u8]) -> Result<bool, PeerHandleError> {
@@ -964,7 +1056,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                        Ok(res) => Ok(res),
                        Err(e) => {
                                log_trace!(self.logger, "Peer sent invalid data or we decided to disconnect due to a protocol error");
-                               self.disconnect_event_internal(peer_descriptor, e.no_connection_possible);
+                               self.disconnect_event_internal(peer_descriptor);
                                Err(e)
                        }
                }
@@ -973,9 +1065,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
        /// Append a message to a peer's pending outbound/write buffer
        fn enqueue_message<M: wire::Type>(&self, peer: &mut Peer, message: &M) {
                if is_gossip_msg(message.type_id()) {
-                       log_gossip!(self.logger, "Enqueueing message {:?} to {}", message, log_pubkey!(peer.their_node_id.unwrap()));
+                       log_gossip!(self.logger, "Enqueueing message {:?} to {}", message, log_pubkey!(peer.their_node_id.unwrap().0));
                } else {
-                       log_trace!(self.logger, "Enqueueing message {:?} to {}", message, log_pubkey!(peer.their_node_id.unwrap()))
+                       log_trace!(self.logger, "Enqueueing message {:?} to {}", message, log_pubkey!(peer.their_node_id.unwrap().0))
                }
                peer.msgs_sent_since_pong += 1;
                peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(message));
@@ -997,7 +1089,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                // This is most likely a simple race condition where the user read some bytes
                                // from the socket, then we told the user to `disconnect_socket()`, then they
                                // called this method. Return an error to make sure we get disconnected.
-                               return Err(PeerHandleError { no_connection_possible: false });
+                               return Err(PeerHandleError { });
                        },
                        Some(peer_mutex) => {
                                let mut read_pos = 0;
@@ -1011,7 +1103,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                                                msgs::ErrorAction::DisconnectPeer { msg: _ } => {
                                                                                        //TODO: Try to push msg
                                                                                        log_debug!(self.logger, "Error handling message{}; disconnecting peer with: {}", OptionalFromDebugger(&peer_node_id), e.err);
-                                                                                       return Err(PeerHandleError{ no_connection_possible: false });
+                                                                                       return Err(PeerHandleError { });
                                                                                },
                                                                                msgs::ErrorAction::IgnoreAndLog(level) => {
                                                                                        log_given_level!(self.logger, level, "Error handling message{}; ignoring: {}", OptionalFromDebugger(&peer_node_id), e.err);
@@ -1060,14 +1152,18 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
 
                                                macro_rules! insert_node_id {
                                                        () => {
-                                                               match self.node_id_to_descriptor.lock().unwrap().entry(peer.their_node_id.unwrap()) {
-                                                                       hash_map::Entry::Occupied(_) => {
-                                                                               log_trace!(self.logger, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap()));
+                                                               match self.node_id_to_descriptor.lock().unwrap().entry(peer.their_node_id.unwrap().0) {
+                                                                       hash_map::Entry::Occupied(e) => {
+                                                                               log_trace!(self.logger, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap().0));
                                                                                peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event
-                                                                               return Err(PeerHandleError{ no_connection_possible: false })
+                                                                               // Check that the peers map is consistent with the
+                                                                               // node_id_to_descriptor map, as this has been broken
+                                                                               // before.
+                                                                               debug_assert!(peers.get(e.get()).is_some());
+                                                                               return Err(PeerHandleError { })
                                                                        },
                                                                        hash_map::Entry::Vacant(entry) => {
-                                                                               log_debug!(self.logger, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap()));
+                                                                               log_debug!(self.logger, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap().0));
                                                                                entry.insert(peer_descriptor.clone())
                                                                        },
                                                                };
@@ -1079,19 +1175,19 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                        NextNoiseStep::ActOne => {
                                                                let act_two = try_potential_handleerror!(peer, peer.channel_encryptor
                                                                        .process_act_one_with_keys(&peer.pending_read_buffer[..],
-                                                                               &self.our_node_secret, self.get_ephemeral_key(), &self.secp_ctx)).to_vec();
+                                                                               &self.node_signer, self.get_ephemeral_key(), &self.secp_ctx)).to_vec();
                                                                peer.pending_outbound_buffer.push_back(act_two);
                                                                peer.pending_read_buffer = [0; 66].to_vec(); // act three is 66 bytes long
                                                        },
                                                        NextNoiseStep::ActTwo => {
                                                                let (act_three, their_node_id) = try_potential_handleerror!(peer,
                                                                        peer.channel_encryptor.process_act_two(&peer.pending_read_buffer[..],
-                                                                               &self.our_node_secret, &self.secp_ctx));
+                                                                               &self.node_signer));
                                                                peer.pending_outbound_buffer.push_back(act_three.to_vec());
                                                                peer.pending_read_buffer = [0; 18].to_vec(); // Message length header is 18 bytes
                                                                peer.pending_read_is_header = true;
 
-                                                               peer.their_node_id = Some(their_node_id);
+                                                               peer.set_their_node_id(their_node_id);
                                                                insert_node_id!();
                                                                let features = self.message_handler.chan_handler.provided_init_features(&their_node_id)
                                                                        .or(self.message_handler.route_handler.provided_init_features(&their_node_id))
@@ -1105,7 +1201,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                                        peer.channel_encryptor.process_act_three(&peer.pending_read_buffer[..]));
                                                                peer.pending_read_buffer = [0; 18].to_vec(); // Message length header is 18 bytes
                                                                peer.pending_read_is_header = true;
-                                                               peer.their_node_id = Some(their_node_id);
+                                                               peer.set_their_node_id(their_node_id);
                                                                insert_node_id!();
                                                                let features = self.message_handler.chan_handler.provided_init_features(&their_node_id)
                                                                        .or(self.message_handler.route_handler.provided_init_features(&their_node_id))
@@ -1121,7 +1217,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                                        if peer.pending_read_buffer.capacity() > 8192 { peer.pending_read_buffer = Vec::new(); }
                                                                        peer.pending_read_buffer.resize(msg_len as usize + 16, 0);
                                                                        if msg_len < 2 { // Need at least the message type tag
-                                                                               return Err(PeerHandleError{ no_connection_possible: false });
+                                                                               return Err(PeerHandleError { });
                                                                        }
                                                                        peer.pending_read_is_header = false;
                                                                } else {
@@ -1164,19 +1260,19 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                                                                (msgs::DecodeError::UnknownRequiredFeature, ty) => {
                                                                                                        log_gossip!(self.logger, "Received a message with an unknown required feature flag or TLV, you may want to update!");
                                                                                                        self.enqueue_message(peer, &msgs::WarningMessage { channel_id: [0; 32], data: format!("Received an unknown required feature/TLV in message type {:?}", ty) });
-                                                                                                       return Err(PeerHandleError { no_connection_possible: false });
+                                                                                                       return Err(PeerHandleError { });
                                                                                                }
-                                                                                               (msgs::DecodeError::UnknownVersion, _) => return Err(PeerHandleError { no_connection_possible: false }),
+                                                                                               (msgs::DecodeError::UnknownVersion, _) => return Err(PeerHandleError { }),
                                                                                                (msgs::DecodeError::InvalidValue, _) => {
                                                                                                        log_debug!(self.logger, "Got an invalid value while deserializing message");
-                                                                                                       return Err(PeerHandleError { no_connection_possible: false });
+                                                                                                       return Err(PeerHandleError { });
                                                                                                }
                                                                                                (msgs::DecodeError::ShortRead, _) => {
                                                                                                        log_debug!(self.logger, "Deserialization failed due to shortness of message");
-                                                                                                       return Err(PeerHandleError { no_connection_possible: false });
+                                                                                                       return Err(PeerHandleError { });
                                                                                                }
-                                                                                               (msgs::DecodeError::BadLengthDescriptor, _) => return Err(PeerHandleError { no_connection_possible: false }),
-                                                                                               (msgs::DecodeError::Io(_), _) => return Err(PeerHandleError { no_connection_possible: false }),
+                                                                                               (msgs::DecodeError::BadLengthDescriptor, _) => return Err(PeerHandleError { }),
+                                                                                               (msgs::DecodeError::Io(_), _) => return Err(PeerHandleError { }),
                                                                                        }
                                                                                }
                                                                        };
@@ -1186,7 +1282,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                        }
                                                }
                                        }
-                                       pause_read = !peer.should_read();
+                                       pause_read = !self.peer_should_read(peer);
 
                                        if let Some(message) = msg_to_handle {
                                                match self.handle_message(&peer_mutex, peer_lock, message) {
@@ -1207,7 +1303,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                }
 
                for msg in msgs_to_forward.drain(..) {
-                       self.forward_broadcast_msg(&*peers, &msg, peer_node_id.as_ref());
+                       self.forward_broadcast_msg(&*peers, &msg, peer_node_id.as_ref().map(|(pk, _)| pk));
                }
 
                Ok(pause_read)
@@ -1221,17 +1317,17 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                mut peer_lock: MutexGuard<Peer>,
                message: wire::Message<<<CMH as core::ops::Deref>::Target as wire::CustomMessageReader>::CustomMessage>
        ) -> Result<Option<wire::Message<<<CMH as core::ops::Deref>::Target as wire::CustomMessageReader>::CustomMessage>>, MessageHandlingError> {
-               let their_node_id = peer_lock.their_node_id.clone().expect("We know the peer's public key by the time we receive messages");
+               let their_node_id = peer_lock.their_node_id.clone().expect("We know the peer's public key by the time we receive messages").0;
                peer_lock.received_message_since_timer_tick = true;
 
                // Need an Init as first message
                if let wire::Message::Init(msg) = message {
                        if msg.features.requires_unknown_bits() {
                                log_debug!(self.logger, "Peer features required unknown version bits");
-                               return Err(PeerHandleError{ no_connection_possible: true }.into());
+                               return Err(PeerHandleError { }.into());
                        }
                        if peer_lock.their_features.is_some() {
-                               return Err(PeerHandleError{ no_connection_possible: false }.into());
+                               return Err(PeerHandleError { }.into());
                        }
 
                        log_info!(self.logger, "Received peer Init message from {}: {}", log_pubkey!(their_node_id), msg.features);
@@ -1241,24 +1337,24 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                peer_lock.sync_status = InitSyncTracker::ChannelsSyncing(0);
                        }
 
-                       if let Err(()) = self.message_handler.route_handler.peer_connected(&their_node_id, &msg) {
+                       if let Err(()) = self.message_handler.route_handler.peer_connected(&their_node_id, &msg, peer_lock.inbound_connection) {
                                log_debug!(self.logger, "Route Handler decided we couldn't communicate with peer {}", log_pubkey!(their_node_id));
-                               return Err(PeerHandleError{ no_connection_possible: true }.into());
+                               return Err(PeerHandleError { }.into());
                        }
-                       if let Err(()) = self.message_handler.chan_handler.peer_connected(&their_node_id, &msg) {
+                       if let Err(()) = self.message_handler.chan_handler.peer_connected(&their_node_id, &msg, peer_lock.inbound_connection) {
                                log_debug!(self.logger, "Channel Handler decided we couldn't communicate with peer {}", log_pubkey!(their_node_id));
-                               return Err(PeerHandleError{ no_connection_possible: true }.into());
+                               return Err(PeerHandleError { }.into());
                        }
-                       if let Err(()) = self.message_handler.onion_message_handler.peer_connected(&their_node_id, &msg) {
+                       if let Err(()) = self.message_handler.onion_message_handler.peer_connected(&their_node_id, &msg, peer_lock.inbound_connection) {
                                log_debug!(self.logger, "Onion Message Handler decided we couldn't communicate with peer {}", log_pubkey!(their_node_id));
-                               return Err(PeerHandleError{ no_connection_possible: true }.into());
+                               return Err(PeerHandleError { }.into());
                        }
 
                        peer_lock.their_features = Some(msg.features);
                        return Ok(None);
                } else if peer_lock.their_features.is_none() {
                        log_debug!(self.logger, "Peer {} sent non-Init first message", log_pubkey!(their_node_id));
-                       return Err(PeerHandleError{ no_connection_possible: false }.into());
+                       return Err(PeerHandleError { }.into());
                }
 
                if let wire::Message::GossipTimestampFilter(_msg) = message {
@@ -1272,7 +1368,10 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                        return Ok(None);
                }
 
-               let their_features = peer_lock.their_features.clone();
+               if let wire::Message::ChannelAnnouncement(ref _msg) = message {
+                       peer_lock.received_channel_announce_since_backlogged = true;
+               }
+
                mem::drop(peer_lock);
 
                if is_gossip_msg(message.type_id()) {
@@ -1307,7 +1406,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                }
                                self.message_handler.chan_handler.handle_error(&their_node_id, &msg);
                                if msg.channel_id == [0; 32] {
-                                       return Err(PeerHandleError{ no_connection_possible: true }.into());
+                                       return Err(PeerHandleError { }.into());
                                }
                        },
                        wire::Message::Warning(msg) => {
@@ -1340,10 +1439,10 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
 
                        // Channel messages:
                        wire::Message::OpenChannel(msg) => {
-                               self.message_handler.chan_handler.handle_open_channel(&their_node_id, their_features.clone().unwrap(), &msg);
+                               self.message_handler.chan_handler.handle_open_channel(&their_node_id, &msg);
                        },
                        wire::Message::AcceptChannel(msg) => {
-                               self.message_handler.chan_handler.handle_accept_channel(&their_node_id, their_features.clone().unwrap(), &msg);
+                               self.message_handler.chan_handler.handle_accept_channel(&their_node_id, &msg);
                        },
 
                        wire::Message::FundingCreated(msg) => {
@@ -1357,7 +1456,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                        },
 
                        wire::Message::Shutdown(msg) => {
-                               self.message_handler.chan_handler.handle_shutdown(&their_node_id, their_features.as_ref().unwrap(), &msg);
+                               self.message_handler.chan_handler.handle_shutdown(&their_node_id, &msg);
                        },
                        wire::Message::ClosingSigned(msg) => {
                                self.message_handler.chan_handler.handle_closing_signed(&their_node_id, &msg);
@@ -1399,12 +1498,14 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                .map_err(|e| -> MessageHandlingError { e.into() })? {
                                        should_forward = Some(wire::Message::ChannelAnnouncement(msg));
                                }
+                               self.update_gossip_backlogged();
                        },
                        wire::Message::NodeAnnouncement(msg) => {
                                if self.message_handler.route_handler.handle_node_announcement(&msg)
                                                .map_err(|e| -> MessageHandlingError { e.into() })? {
                                        should_forward = Some(wire::Message::NodeAnnouncement(msg));
                                }
+                               self.update_gossip_backlogged();
                        },
                        wire::Message::ChannelUpdate(msg) => {
                                self.message_handler.chan_handler.handle_channel_update(&their_node_id, &msg);
@@ -1412,6 +1513,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                .map_err(|e| -> MessageHandlingError { e.into() })? {
                                        should_forward = Some(wire::Message::ChannelUpdate(msg));
                                }
+                               self.update_gossip_backlogged();
                        },
                        wire::Message::QueryShortChannelIds(msg) => {
                                self.message_handler.route_handler.handle_query_short_channel_ids(&their_node_id, msg)?;
@@ -1434,8 +1536,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                        // Unknown messages:
                        wire::Message::Unknown(type_id) if message.is_even() => {
                                log_debug!(self.logger, "Received unknown even message of type {}, disconnecting peer!", type_id);
-                               // Fail the channel if message is an even, unknown type as per BOLT #1.
-                               return Err(PeerHandleError{ no_connection_possible: true }.into());
+                               return Err(PeerHandleError { }.into());
                        },
                        wire::Message::Unknown(type_id) => {
                                log_trace!(self.logger, "Received unknown odd message of type {}, ignoring", type_id);
@@ -1455,19 +1556,22 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
 
                                for (_, peer_mutex) in peers.iter() {
                                        let mut peer = peer_mutex.lock().unwrap();
-                                       if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_features.is_none() ||
+                                       if !peer.handshake_complete() ||
                                                        !peer.should_forward_channel_announcement(msg.contents.short_channel_id) {
                                                continue
                                        }
+                                       debug_assert!(peer.their_node_id.is_some());
+                                       debug_assert!(peer.channel_encryptor.is_ready_for_encryption());
                                        if peer.buffer_full_drop_gossip_broadcast() {
                                                log_gossip!(self.logger, "Skipping broadcast message to {:?} as its outbound buffer is full", peer.their_node_id);
                                                continue;
                                        }
-                                       if peer.their_node_id.as_ref() == Some(&msg.contents.node_id_1) ||
-                                          peer.their_node_id.as_ref() == Some(&msg.contents.node_id_2) {
-                                               continue;
+                                       if let Some((_, their_node_id)) = peer.their_node_id {
+                                               if their_node_id == msg.contents.node_id_1 || their_node_id == msg.contents.node_id_2 {
+                                                       continue;
+                                               }
                                        }
-                                       if except_node.is_some() && peer.their_node_id.as_ref() == except_node {
+                                       if except_node.is_some() && peer.their_node_id.as_ref().map(|(pk, _)| pk) == except_node {
                                                continue;
                                        }
                                        self.enqueue_encoded_gossip_broadcast(&mut *peer, encoded_msg.clone());
@@ -1479,18 +1583,22 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
 
                                for (_, peer_mutex) in peers.iter() {
                                        let mut peer = peer_mutex.lock().unwrap();
-                                       if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_features.is_none() ||
+                                       if !peer.handshake_complete() ||
                                                        !peer.should_forward_node_announcement(msg.contents.node_id) {
                                                continue
                                        }
+                                       debug_assert!(peer.their_node_id.is_some());
+                                       debug_assert!(peer.channel_encryptor.is_ready_for_encryption());
                                        if peer.buffer_full_drop_gossip_broadcast() {
                                                log_gossip!(self.logger, "Skipping broadcast message to {:?} as its outbound buffer is full", peer.their_node_id);
                                                continue;
                                        }
-                                       if peer.their_node_id.as_ref() == Some(&msg.contents.node_id) {
-                                               continue;
+                                       if let Some((_, their_node_id)) = peer.their_node_id {
+                                               if their_node_id == msg.contents.node_id {
+                                                       continue;
+                                               }
                                        }
-                                       if except_node.is_some() && peer.their_node_id.as_ref() == except_node {
+                                       if except_node.is_some() && peer.their_node_id.as_ref().map(|(pk, _)| pk) == except_node {
                                                continue;
                                        }
                                        self.enqueue_encoded_gossip_broadcast(&mut *peer, encoded_msg.clone());
@@ -1502,15 +1610,17 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
 
                                for (_, peer_mutex) in peers.iter() {
                                        let mut peer = peer_mutex.lock().unwrap();
-                                       if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_features.is_none() ||
+                                       if !peer.handshake_complete() ||
                                                        !peer.should_forward_channel_announcement(msg.contents.short_channel_id)  {
                                                continue
                                        }
+                                       debug_assert!(peer.their_node_id.is_some());
+                                       debug_assert!(peer.channel_encryptor.is_ready_for_encryption());
                                        if peer.buffer_full_drop_gossip_broadcast() {
                                                log_gossip!(self.logger, "Skipping broadcast message to {:?} as its outbound buffer is full", peer.their_node_id);
                                                continue;
                                        }
-                                       if except_node.is_some() && peer.their_node_id.as_ref() == except_node {
+                                       if except_node.is_some() && peer.their_node_id.as_ref().map(|(pk, _)| pk) == except_node {
                                                continue;
                                        }
                                        self.enqueue_encoded_gossip_broadcast(&mut *peer, encoded_msg.clone());
@@ -1559,6 +1669,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                        }
                }
 
+               self.update_gossip_backlogged();
+               let flush_read_disabled = self.gossip_processing_backlog_lifted.swap(false, Ordering::Relaxed);
+
                let mut peers_to_disconnect = HashMap::new();
                let mut events_generated = self.message_handler.chan_handler.get_and_clear_pending_msg_events();
                events_generated.append(&mut self.message_handler.route_handler.get_and_clear_pending_msg_events());
@@ -1582,7 +1695,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                        Some(descriptor) => match peers.get(&descriptor) {
                                                                Some(peer_mutex) => {
                                                                        let peer_lock = peer_mutex.lock().unwrap();
-                                                                       if peer_lock.their_features.is_none() {
+                                                                       if !peer_lock.handshake_complete() {
                                                                                continue;
                                                                        }
                                                                        peer_lock
@@ -1703,10 +1816,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                                self.forward_broadcast_msg(peers, &wire::Message::ChannelAnnouncement(msg), None),
                                                        _ => {},
                                                }
-                                               match self.message_handler.route_handler.handle_channel_update(&update_msg) {
-                                                       Ok(_) | Err(LightningError { action: msgs::ErrorAction::IgnoreDuplicateGossip, .. }) =>
-                                                               self.forward_broadcast_msg(peers, &wire::Message::ChannelUpdate(update_msg), None),
-                                                       _ => {},
+                                               if let Some(msg) = update_msg {
+                                                       match self.message_handler.route_handler.handle_channel_update(&msg) {
+                                                               Ok(_) | Err(LightningError { action: msgs::ErrorAction::IgnoreDuplicateGossip, .. }) =>
+                                                                       self.forward_broadcast_msg(peers, &wire::Message::ChannelUpdate(msg), None),
+                                                               _ => {},
+                                                       }
                                                }
                                        },
                                        MessageSendEvent::BroadcastChannelUpdate { msg } => {
@@ -1717,6 +1832,14 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                        _ => {},
                                                }
                                        },
+                                       MessageSendEvent::BroadcastNodeAnnouncement { msg } => {
+                                               log_debug!(self.logger, "Handling BroadcastNodeAnnouncement event in peer_handler for node {}", msg.contents.node_id);
+                                               match self.message_handler.route_handler.handle_node_announcement(&msg) {
+                                                       Ok(_) | Err(LightningError { action: msgs::ErrorAction::IgnoreDuplicateGossip, .. }) =>
+                                                               self.forward_broadcast_msg(peers, &wire::Message::NodeAnnouncement(msg), None),
+                                                       _ => {},
+                                               }
+                                       },
                                        MessageSendEvent::SendChannelUpdate { ref node_id, ref msg } => {
                                                log_trace!(self.logger, "Handling SendChannelUpdate event in peer_handler for node {} for channel {}",
                                                                log_pubkey!(node_id), msg.contents.short_channel_id);
@@ -1778,7 +1901,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                        }
 
                        for (descriptor, peer_mutex) in peers.iter() {
-                               self.do_attempt_write_data(&mut (*descriptor).clone(), &mut *peer_mutex.lock().unwrap());
+                               let mut peer = peer_mutex.lock().unwrap();
+                               if flush_read_disabled { peer.received_channel_announce_since_backlogged = false; }
+                               self.do_attempt_write_data(&mut (*descriptor).clone(), &mut *peer, flush_read_disabled);
                        }
                }
                if !peers_to_disconnect.is_empty() {
@@ -1790,24 +1915,21 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                // thread can be holding the peer lock if we have the global write
                                // lock).
 
-                               if let Some(mut descriptor) = self.node_id_to_descriptor.lock().unwrap().remove(&node_id) {
+                               let descriptor_opt = self.node_id_to_descriptor.lock().unwrap().remove(&node_id);
+                               if let Some(mut descriptor) = descriptor_opt {
                                        if let Some(peer_mutex) = peers.remove(&descriptor) {
+                                               let mut peer = peer_mutex.lock().unwrap();
                                                if let Some(msg) = msg {
                                                        log_trace!(self.logger, "Handling DisconnectPeer HandleError event in peer_handler for node {} with message {}",
                                                                        log_pubkey!(node_id),
                                                                        msg.data);
-                                                       let mut peer = peer_mutex.lock().unwrap();
                                                        self.enqueue_message(&mut *peer, &msg);
                                                        // This isn't guaranteed to work, but if there is enough free
                                                        // room in the send buffer, put the error message there...
-                                                       self.do_attempt_write_data(&mut descriptor, &mut *peer);
-                                               } else {
-                                                       log_trace!(self.logger, "Handling DisconnectPeer HandleError event in peer_handler for node {} with no message", log_pubkey!(node_id));
+                                                       self.do_attempt_write_data(&mut descriptor, &mut *peer, false);
                                                }
-                                       }
-                                       descriptor.disconnect_socket();
-                                       self.message_handler.chan_handler.peer_disconnected(&node_id, false);
-                                       self.message_handler.onion_message_handler.peer_disconnected(&node_id, false);
+                                               self.do_disconnect(descriptor, &*peer, "DisconnectPeer HandleError");
+                                       } else { debug_assert!(false, "Missing connection for peer"); }
                                }
                        }
                }
@@ -1815,10 +1937,26 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
 
        /// Indicates that the given socket descriptor's connection is now closed.
        pub fn socket_disconnected(&self, descriptor: &Descriptor) {
-               self.disconnect_event_internal(descriptor, false);
+               self.disconnect_event_internal(descriptor);
        }
 
-       fn disconnect_event_internal(&self, descriptor: &Descriptor, no_connection_possible: bool) {
+       fn do_disconnect(&self, mut descriptor: Descriptor, peer: &Peer, reason: &'static str) {
+               if !peer.handshake_complete() {
+                       log_trace!(self.logger, "Disconnecting peer which hasn't completed handshake due to {}", reason);
+                       descriptor.disconnect_socket();
+                       return;
+               }
+
+               debug_assert!(peer.their_node_id.is_some());
+               if let Some((node_id, _)) = peer.their_node_id {
+                       log_trace!(self.logger, "Disconnecting peer with id {} due to {}", node_id, reason);
+                       self.message_handler.chan_handler.peer_disconnected(&node_id);
+                       self.message_handler.onion_message_handler.peer_disconnected(&node_id);
+               }
+               descriptor.disconnect_socket();
+       }
+
+       fn disconnect_event_internal(&self, descriptor: &Descriptor) {
                let mut peers = self.peers.write().unwrap();
                let peer_option = peers.remove(descriptor);
                match peer_option {
@@ -1829,13 +1967,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                        },
                        Some(peer_lock) => {
                                let peer = peer_lock.lock().unwrap();
-                               if let Some(node_id) = peer.their_node_id {
-                                       log_trace!(self.logger,
-                                               "Handling disconnection of peer {}, with {}future connection to the peer possible.",
-                                               log_pubkey!(node_id), if no_connection_possible { "no " } else { "" });
-                                       self.node_id_to_descriptor.lock().unwrap().remove(&node_id);
-                                       self.message_handler.chan_handler.peer_disconnected(&node_id, no_connection_possible);
-                                       self.message_handler.onion_message_handler.peer_disconnected(&node_id, no_connection_possible);
+                               if let Some((node_id, _)) = peer.their_node_id {
+                                       log_trace!(self.logger, "Handling disconnection of peer {}", log_pubkey!(node_id));
+                                       let removed = self.node_id_to_descriptor.lock().unwrap().remove(&node_id);
+                                       debug_assert!(removed.is_some(), "descriptor maps should be consistent");
+                                       if !peer.handshake_complete() { return; }
+                                       self.message_handler.chan_handler.peer_disconnected(&node_id);
+                                       self.message_handler.onion_message_handler.peer_disconnected(&node_id);
                                }
                        }
                };
@@ -1843,21 +1981,17 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
 
        /// Disconnect a peer given its node id.
        ///
-       /// Set `no_connection_possible` to true to prevent any further connection with this peer,
-       /// force-closing any channels we have with it.
-       ///
        /// If a peer is connected, this will call [`disconnect_socket`] on the descriptor for the
        /// peer. Thus, be very careful about reentrancy issues.
        ///
        /// [`disconnect_socket`]: SocketDescriptor::disconnect_socket
-       pub fn disconnect_by_node_id(&self, node_id: PublicKey, no_connection_possible: bool) {
+       pub fn disconnect_by_node_id(&self, node_id: PublicKey) {
                let mut peers_lock = self.peers.write().unwrap();
-               if let Some(mut descriptor) = self.node_id_to_descriptor.lock().unwrap().remove(&node_id) {
-                       log_trace!(self.logger, "Disconnecting peer with id {} due to client request", node_id);
-                       peers_lock.remove(&descriptor);
-                       self.message_handler.chan_handler.peer_disconnected(&node_id, no_connection_possible);
-                       self.message_handler.onion_message_handler.peer_disconnected(&node_id, no_connection_possible);
-                       descriptor.disconnect_socket();
+               if let Some(descriptor) = self.node_id_to_descriptor.lock().unwrap().remove(&node_id) {
+                       let peer_opt = peers_lock.remove(&descriptor);
+                       if let Some(peer_mutex) = peer_opt {
+                               self.do_disconnect(descriptor, &*peer_mutex.lock().unwrap(), "client request");
+                       } else { debug_assert!(false, "node_id_to_descriptor thought we had a peer"); }
                }
        }
 
@@ -1868,13 +2002,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                let mut peers_lock = self.peers.write().unwrap();
                self.node_id_to_descriptor.lock().unwrap().clear();
                let peers = &mut *peers_lock;
-               for (mut descriptor, peer) in peers.drain() {
-                       if let Some(node_id) = peer.lock().unwrap().their_node_id {
-                               log_trace!(self.logger, "Disconnecting peer with id {} due to client request to disconnect all peers", node_id);
-                               self.message_handler.chan_handler.peer_disconnected(&node_id, false);
-                               self.message_handler.onion_message_handler.peer_disconnected(&node_id, false);
-                       }
-                       descriptor.disconnect_socket();
+               for (descriptor, peer_mutex) in peers.drain() {
+                       self.do_disconnect(descriptor, &*peer_mutex.lock().unwrap(), "client request to disconnect all peers");
                }
        }
 
@@ -1908,9 +2037,14 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                {
                        let peers_lock = self.peers.read().unwrap();
 
+                       self.update_gossip_backlogged();
+                       let flush_read_disabled = self.gossip_processing_backlog_lifted.swap(false, Ordering::Relaxed);
+
                        for (descriptor, peer_mutex) in peers_lock.iter() {
                                let mut peer = peer_mutex.lock().unwrap();
-                               if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_node_id.is_none() {
+                               if flush_read_disabled { peer.received_channel_announce_since_backlogged = false; }
+
+                               if !peer.handshake_complete() {
                                        // The peer needs to complete its handshake before we can exchange messages. We
                                        // give peers one timer tick to complete handshake, reusing
                                        // `awaiting_pong_timer_tick_intervals` to track number of timer ticks taken
@@ -1922,56 +2056,56 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                        }
                                        continue;
                                }
+                               debug_assert!(peer.channel_encryptor.is_ready_for_encryption());
+                               debug_assert!(peer.their_node_id.is_some());
 
-                               if peer.awaiting_pong_timer_tick_intervals == -1 {
-                                       // Magic value set in `maybe_send_extra_ping`.
-                                       peer.awaiting_pong_timer_tick_intervals = 1;
+                               loop { // Used as a `goto` to skip writing a Ping message.
+                                       if peer.awaiting_pong_timer_tick_intervals == -1 {
+                                               // Magic value set in `maybe_send_extra_ping`.
+                                               peer.awaiting_pong_timer_tick_intervals = 1;
+                                               peer.received_message_since_timer_tick = false;
+                                               break;
+                                       }
+
+                                       if (peer.awaiting_pong_timer_tick_intervals > 0 && !peer.received_message_since_timer_tick)
+                                               || peer.awaiting_pong_timer_tick_intervals as u64 >
+                                                       MAX_BUFFER_DRAIN_TICK_INTERVALS_PER_PEER as u64 * peers_lock.len() as u64
+                                       {
+                                               descriptors_needing_disconnect.push(descriptor.clone());
+                                               break;
+                                       }
                                        peer.received_message_since_timer_tick = false;
-                                       continue;
-                               }
 
-                               if (peer.awaiting_pong_timer_tick_intervals > 0 && !peer.received_message_since_timer_tick)
-                                       || peer.awaiting_pong_timer_tick_intervals as u64 >
-                                               MAX_BUFFER_DRAIN_TICK_INTERVALS_PER_PEER as u64 * peers_lock.len() as u64
-                               {
-                                       descriptors_needing_disconnect.push(descriptor.clone());
-                                       continue;
-                               }
-                               peer.received_message_since_timer_tick = false;
+                                       if peer.awaiting_pong_timer_tick_intervals > 0 {
+                                               peer.awaiting_pong_timer_tick_intervals += 1;
+                                               break;
+                                       }
 
-                               if peer.awaiting_pong_timer_tick_intervals > 0 {
-                                       peer.awaiting_pong_timer_tick_intervals += 1;
-                                       continue;
+                                       peer.awaiting_pong_timer_tick_intervals = 1;
+                                       let ping = msgs::Ping {
+                                               ponglen: 0,
+                                               byteslen: 64,
+                                       };
+                                       self.enqueue_message(&mut *peer, &ping);
+                                       break;
                                }
-
-                               peer.awaiting_pong_timer_tick_intervals = 1;
-                               let ping = msgs::Ping {
-                                       ponglen: 0,
-                                       byteslen: 64,
-                               };
-                               self.enqueue_message(&mut *peer, &ping);
-                               self.do_attempt_write_data(&mut (descriptor.clone()), &mut *peer);
+                               self.do_attempt_write_data(&mut (descriptor.clone()), &mut *peer, flush_read_disabled);
                        }
                }
 
                if !descriptors_needing_disconnect.is_empty() {
                        {
                                let mut peers_lock = self.peers.write().unwrap();
-                               for descriptor in descriptors_needing_disconnect.iter() {
-                                       if let Some(peer) = peers_lock.remove(descriptor) {
-                                               if let Some(node_id) = peer.lock().unwrap().their_node_id {
-                                                       log_trace!(self.logger, "Disconnecting peer with id {} due to ping timeout", node_id);
+                               for descriptor in descriptors_needing_disconnect {
+                                       if let Some(peer_mutex) = peers_lock.remove(&descriptor) {
+                                               let peer = peer_mutex.lock().unwrap();
+                                               if let Some((node_id, _)) = peer.their_node_id {
                                                        self.node_id_to_descriptor.lock().unwrap().remove(&node_id);
-                                                       self.message_handler.chan_handler.peer_disconnected(&node_id, false);
-                                                       self.message_handler.onion_message_handler.peer_disconnected(&node_id, false);
                                                }
+                                               self.do_disconnect(descriptor, &*peer, "ping timeout");
                                        }
                                }
                        }
-
-                       for mut descriptor in descriptors_needing_disconnect.drain(..) {
-                               descriptor.disconnect_socket();
-                       }
                }
        }
 
@@ -2017,13 +2151,20 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                let announcement = msgs::UnsignedNodeAnnouncement {
                        features,
                        timestamp: self.last_node_announcement_serial.fetch_add(1, Ordering::AcqRel),
-                       node_id: PublicKey::from_secret_key(&self.secp_ctx, &self.our_node_secret),
+                       node_id: NodeId::from_pubkey(&self.node_signer.get_node_id(Recipient::Node).unwrap()),
                        rgb, alias, addresses,
                        excess_address_data: Vec::new(),
                        excess_data: Vec::new(),
                };
-               let msghash = hash_to_message!(&Sha256dHash::hash(&announcement.encode()[..])[..]);
-               let node_announce_sig = sign(&self.secp_ctx, &msghash, &self.our_node_secret);
+               let node_announce_sig = match self.node_signer.sign_gossip_message(
+                       msgs::UnsignedGossipMessage::NodeAnnouncement(&announcement)
+               ) {
+                       Ok(sig) => sig,
+                       Err(_) => {
+                               log_error!(self.logger, "Failed to generate signature for node_announcement");
+                               return;
+                       },
+               };
 
                let msg = msgs::NodeAnnouncement {
                        signature: node_announce_sig,
@@ -2051,23 +2192,25 @@ fn is_gossip_msg(type_id: u16) -> bool {
 
 #[cfg(test)]
 mod tests {
+       use crate::chain::keysinterface::{NodeSigner, Recipient};
+       use crate::ln::peer_channel_encryptor::PeerChannelEncryptor;
        use crate::ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler, filter_addresses};
        use crate::ln::{msgs, wire};
        use crate::ln::msgs::NetAddress;
        use crate::util::events;
        use crate::util::test_utils;
 
-       use bitcoin::secp256k1::Secp256k1;
-       use bitcoin::secp256k1::{SecretKey, PublicKey};
+       use bitcoin::secp256k1::SecretKey;
 
        use crate::prelude::*;
        use crate::sync::{Arc, Mutex};
-       use core::sync::atomic::Ordering;
+       use core::sync::atomic::{AtomicBool, Ordering};
 
        #[derive(Clone)]
        struct FileDescriptor {
                fd: u16,
                outbound_data: Arc<Mutex<Vec<u8>>>,
+               disconnect: Arc<AtomicBool>,
        }
        impl PartialEq for FileDescriptor {
                fn eq(&self, other: &Self) -> bool {
@@ -2087,23 +2230,26 @@ mod tests {
                        data.len()
                }
 
-               fn disconnect_socket(&mut self) {}
+               fn disconnect_socket(&mut self) { self.disconnect.store(true, Ordering::Release); }
        }
 
        struct PeerManagerCfg {
                chan_handler: test_utils::TestChannelMessageHandler,
                routing_handler: test_utils::TestRoutingMessageHandler,
                logger: test_utils::TestLogger,
+               node_signer: test_utils::TestNodeSigner,
        }
 
        fn create_peermgr_cfgs(peer_count: usize) -> Vec<PeerManagerCfg> {
                let mut cfgs = Vec::new();
-               for _ in 0..peer_count {
+               for i in 0..peer_count {
+                       let node_secret = SecretKey::from_slice(&[42 + i as u8; 32]).unwrap();
                        cfgs.push(
                                PeerManagerCfg{
                                        chan_handler: test_utils::TestChannelMessageHandler::new(),
                                        logger: test_utils::TestLogger::new(),
                                        routing_handler: test_utils::TestRoutingMessageHandler::new(),
+                                       node_signer: test_utils::TestNodeSigner::new(node_secret),
                                }
                        );
                }
@@ -2111,26 +2257,33 @@ mod tests {
                cfgs
        }
 
-       fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler>> {
+       fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler, &'a test_utils::TestNodeSigner>> {
                let mut peers = Vec::new();
                for i in 0..peer_count {
-                       let node_secret = SecretKey::from_slice(&[42 + i as u8; 32]).unwrap();
                        let ephemeral_bytes = [i as u8; 32];
                        let msg_handler = MessageHandler { chan_handler: &cfgs[i].chan_handler, route_handler: &cfgs[i].routing_handler, onion_message_handler: IgnoringMessageHandler {} };
-                       let peer = PeerManager::new(msg_handler, node_secret, 0, &ephemeral_bytes, &cfgs[i].logger, IgnoringMessageHandler {});
+                       let peer = PeerManager::new(msg_handler, 0, &ephemeral_bytes, &cfgs[i].logger, IgnoringMessageHandler {}, &cfgs[i].node_signer);
                        peers.push(peer);
                }
 
                peers
        }
 
-       fn establish_connection<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler>) -> (FileDescriptor, FileDescriptor) {
-               let secp_ctx = Secp256k1::new();
-               let a_id = PublicKey::from_secret_key(&secp_ctx, &peer_a.our_node_secret);
-               let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
-               let mut fd_b = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
-               let initial_data = peer_b.new_outbound_connection(a_id, fd_b.clone(), None).unwrap();
-               peer_a.new_inbound_connection(fd_a.clone(), None).unwrap();
+       fn establish_connection<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler, &'a test_utils::TestNodeSigner>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler, &'a test_utils::TestNodeSigner>) -> (FileDescriptor, FileDescriptor) {
+               let id_a = peer_a.node_signer.get_node_id(Recipient::Node).unwrap();
+               let mut fd_a = FileDescriptor {
+                       fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())),
+                       disconnect: Arc::new(AtomicBool::new(false)),
+               };
+               let addr_a = NetAddress::IPv4{addr: [127, 0, 0, 1], port: 1000};
+               let id_b = peer_b.node_signer.get_node_id(Recipient::Node).unwrap();
+               let mut fd_b = FileDescriptor {
+                       fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())),
+                       disconnect: Arc::new(AtomicBool::new(false)),
+               };
+               let addr_b = NetAddress::IPv4{addr: [127, 0, 0, 1], port: 1001};
+               let initial_data = peer_b.new_outbound_connection(id_a, fd_b.clone(), Some(addr_a.clone())).unwrap();
+               peer_a.new_inbound_connection(fd_a.clone(), Some(addr_b.clone())).unwrap();
                assert_eq!(peer_a.read_event(&mut fd_a, &initial_data).unwrap(), false);
                peer_a.process_events();
 
@@ -2145,28 +2298,104 @@ mod tests {
                let a_data = fd_a.outbound_data.lock().unwrap().split_off(0);
                assert_eq!(peer_b.read_event(&mut fd_b, &a_data).unwrap(), false);
 
+               assert!(peer_a.get_peer_node_ids().contains(&(id_b, Some(addr_b))));
+               assert!(peer_b.get_peer_node_ids().contains(&(id_a, Some(addr_a))));
+
                (fd_a.clone(), fd_b.clone())
        }
 
+       #[test]
+       #[cfg(feature = "std")]
+       fn fuzz_threaded_connections() {
+               // Spawn two threads which repeatedly connect two peers together, leading to "got second
+               // connection with peer" disconnections and rapid reconnect. This previously found an issue
+               // with our internal map consistency, and is a generally good smoke test of disconnection.
+               let cfgs = Arc::new(create_peermgr_cfgs(2));
+               // Until we have std::thread::scoped we have to unsafe { turn off the borrow checker }.
+               let peers = Arc::new(create_network(2, unsafe { &*(&*cfgs as *const _) as &'static _ }));
+
+               let start_time = std::time::Instant::now();
+               macro_rules! spawn_thread { ($id: expr) => { {
+                       let peers = Arc::clone(&peers);
+                       let cfgs = Arc::clone(&cfgs);
+                       std::thread::spawn(move || {
+                               let mut ctr = 0;
+                               while start_time.elapsed() < std::time::Duration::from_secs(1) {
+                                       let id_a = peers[0].node_signer.get_node_id(Recipient::Node).unwrap();
+                                       let mut fd_a = FileDescriptor {
+                                               fd: $id  + ctr * 3, outbound_data: Arc::new(Mutex::new(Vec::new())),
+                                               disconnect: Arc::new(AtomicBool::new(false)),
+                                       };
+                                       let addr_a = NetAddress::IPv4{addr: [127, 0, 0, 1], port: 1000};
+                                       let mut fd_b = FileDescriptor {
+                                               fd: $id + ctr * 3, outbound_data: Arc::new(Mutex::new(Vec::new())),
+                                               disconnect: Arc::new(AtomicBool::new(false)),
+                                       };
+                                       let addr_b = NetAddress::IPv4{addr: [127, 0, 0, 1], port: 1001};
+                                       let initial_data = peers[1].new_outbound_connection(id_a, fd_b.clone(), Some(addr_a.clone())).unwrap();
+                                       peers[0].new_inbound_connection(fd_a.clone(), Some(addr_b.clone())).unwrap();
+                                       assert_eq!(peers[0].read_event(&mut fd_a, &initial_data).unwrap(), false);
+
+                                       while start_time.elapsed() < std::time::Duration::from_secs(1) {
+                                               peers[0].process_events();
+                                               if fd_a.disconnect.load(Ordering::Acquire) { break; }
+                                               let a_data = fd_a.outbound_data.lock().unwrap().split_off(0);
+                                               if peers[1].read_event(&mut fd_b, &a_data).is_err() { break; }
+
+                                               peers[1].process_events();
+                                               if fd_b.disconnect.load(Ordering::Acquire) { break; }
+                                               let b_data = fd_b.outbound_data.lock().unwrap().split_off(0);
+                                               if peers[0].read_event(&mut fd_a, &b_data).is_err() { break; }
+
+                                               cfgs[0].chan_handler.pending_events.lock().unwrap()
+                                                       .push(crate::util::events::MessageSendEvent::SendShutdown {
+                                                               node_id: peers[1].node_signer.get_node_id(Recipient::Node).unwrap(),
+                                                               msg: msgs::Shutdown {
+                                                                       channel_id: [0; 32],
+                                                                       scriptpubkey: bitcoin::Script::new(),
+                                                               },
+                                                       });
+                                               cfgs[1].chan_handler.pending_events.lock().unwrap()
+                                                       .push(crate::util::events::MessageSendEvent::SendShutdown {
+                                                               node_id: peers[0].node_signer.get_node_id(Recipient::Node).unwrap(),
+                                                               msg: msgs::Shutdown {
+                                                                       channel_id: [0; 32],
+                                                                       scriptpubkey: bitcoin::Script::new(),
+                                                               },
+                                                       });
+
+                                               peers[0].timer_tick_occurred();
+                                               peers[1].timer_tick_occurred();
+                                       }
+
+                                       peers[0].socket_disconnected(&fd_a);
+                                       peers[1].socket_disconnected(&fd_b);
+                                       ctr += 1;
+                                       std::thread::sleep(std::time::Duration::from_micros(1));
+                               }
+                       })
+               } } }
+               let thrd_a = spawn_thread!(1);
+               let thrd_b = spawn_thread!(2);
+
+               thrd_a.join().unwrap();
+               thrd_b.join().unwrap();
+       }
+
        #[test]
        fn test_disconnect_peer() {
                // Simple test which builds a network of PeerManager, connects and brings them to NoiseState::Finished and
                // push a DisconnectPeer event to remove the node flagged by id
                let cfgs = create_peermgr_cfgs(2);
-               let chan_handler = test_utils::TestChannelMessageHandler::new();
-               let mut peers = create_network(2, &cfgs);
+               let peers = create_network(2, &cfgs);
                establish_connection(&peers[0], &peers[1]);
                assert_eq!(peers[0].peers.read().unwrap().len(), 1);
 
-               let secp_ctx = Secp256k1::new();
-               let their_id = PublicKey::from_secret_key(&secp_ctx, &peers[1].our_node_secret);
-
-               chan_handler.pending_events.lock().unwrap().push(events::MessageSendEvent::HandleError {
+               let their_id = peers[1].node_signer.get_node_id(Recipient::Node).unwrap();
+               cfgs[0].chan_handler.pending_events.lock().unwrap().push(events::MessageSendEvent::HandleError {
                        node_id: their_id,
                        action: msgs::ErrorAction::DisconnectPeer { msg: None },
                });
-               assert_eq!(chan_handler.pending_events.lock().unwrap().len(), 1);
-               peers[0].message_handler.chan_handler = &chan_handler;
 
                peers[0].process_events();
                assert_eq!(peers[0].peers.read().unwrap().len(), 0);
@@ -2183,8 +2412,7 @@ mod tests {
                let (fd_a, mut fd_b) = establish_connection(&peers[0], &peers[1]);
                assert_eq!(peers[0].peers.read().unwrap().len(), 1);
 
-               let secp_ctx = Secp256k1::new();
-               let their_id = PublicKey::from_secret_key(&secp_ctx, &peers[1].our_node_secret);
+               let their_id = peers[1].node_signer.get_node_id(Recipient::Node).unwrap();
 
                let msg = msgs::Shutdown { channel_id: [42; 32], scriptpubkey: bitcoin::Script::new() };
                a_chan_handler.pending_events.lock().unwrap().push(events::MessageSendEvent::SendShutdown {
@@ -2201,6 +2429,38 @@ mod tests {
                assert_eq!(peers[1].read_event(&mut fd_b, &a_data).unwrap(), false);
        }
 
+       #[test]
+       fn test_non_init_first_msg() {
+               // Simple test of the first message received over a connection being something other than
+               // Init. This results in an immediate disconnection, which previously included a spurious
+               // peer_disconnected event handed to event handlers (which would panic in
+               // `TestChannelMessageHandler` here).
+               let cfgs = create_peermgr_cfgs(2);
+               let peers = create_network(2, &cfgs);
+
+               let mut fd_dup = FileDescriptor {
+                       fd: 3, outbound_data: Arc::new(Mutex::new(Vec::new())),
+                       disconnect: Arc::new(AtomicBool::new(false)),
+               };
+               let addr_dup = NetAddress::IPv4{addr: [127, 0, 0, 1], port: 1003};
+               let id_a = cfgs[0].node_signer.get_node_id(Recipient::Node).unwrap();
+               peers[0].new_inbound_connection(fd_dup.clone(), Some(addr_dup.clone())).unwrap();
+
+               let mut dup_encryptor = PeerChannelEncryptor::new_outbound(id_a, SecretKey::from_slice(&[42; 32]).unwrap());
+               let initial_data = dup_encryptor.get_act_one(&peers[1].secp_ctx);
+               assert_eq!(peers[0].read_event(&mut fd_dup, &initial_data).unwrap(), false);
+               peers[0].process_events();
+
+               let a_data = fd_dup.outbound_data.lock().unwrap().split_off(0);
+               let (act_three, _) =
+                       dup_encryptor.process_act_two(&a_data[..], &&cfgs[1].node_signer).unwrap();
+               assert_eq!(peers[0].read_event(&mut fd_dup, &act_three).unwrap(), false);
+
+               let not_init_msg = msgs::Ping { ponglen: 4, byteslen: 0 };
+               let msg_bytes = dup_encryptor.encrypt_message(&not_init_msg);
+               assert!(peers[0].read_event(&mut fd_dup, &msg_bytes).is_err());
+       }
+
        #[test]
        fn test_disconnect_all_peer() {
                // Simple test which builds a network of PeerManager, connects and brings them to NoiseState::Finished and
@@ -2284,10 +2544,15 @@ mod tests {
                cfgs[1].routing_handler.request_full_sync.store(true, Ordering::Release);
                let peers = create_network(2, &cfgs);
 
-               let secp_ctx = Secp256k1::new();
-               let a_id = PublicKey::from_secret_key(&secp_ctx, &peers[0].our_node_secret);
-               let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
-               let mut fd_b = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
+               let a_id = peers[0].node_signer.get_node_id(Recipient::Node).unwrap();
+               let mut fd_a = FileDescriptor {
+                       fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())),
+                       disconnect: Arc::new(AtomicBool::new(false)),
+               };
+               let mut fd_b = FileDescriptor {
+                       fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())),
+                       disconnect: Arc::new(AtomicBool::new(false)),
+               };
                let initial_data = peers[1].new_outbound_connection(a_id, fd_b.clone(), None).unwrap();
                peers[0].new_inbound_connection(fd_a.clone(), None).unwrap();
 
index 44d4cd9cd569176f60045610431a577c950a3a78..f563a63cfd1a41b2363ac5421c53d39b3effa7a2 100644 (file)
@@ -12,8 +12,8 @@
 //! LSP).
 
 use crate::chain::ChannelMonitorUpdateStatus;
-use crate::chain::keysinterface::{Recipient, KeysInterface, NodeSigner};
-use crate::ln::channelmanager::{self, ChannelManager, MIN_CLTV_EXPIRY_DELTA, PaymentId};
+use crate::chain::keysinterface::NodeSigner;
+use crate::ln::channelmanager::{ChannelManager, MIN_CLTV_EXPIRY_DELTA, PaymentId};
 use crate::routing::gossip::RoutingFees;
 use crate::routing::router::{PaymentParameters, RouteHint, RouteHintHop};
 use crate::ln::features::ChannelTypeFeatures;
@@ -31,10 +31,7 @@ use core::default::Default;
 use crate::ln::functional_test_utils::*;
 
 use bitcoin::blockdata::constants::genesis_block;
-use bitcoin::hashes::Hash;
-use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::network::constants::Network;
-use bitcoin::secp256k1::Secp256k1;
 
 #[test]
 fn test_priv_forwarding_rejection() {
@@ -48,11 +45,11 @@ fn test_priv_forwarding_rejection() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, Some(no_announce_cfg), None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_1_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_1_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       let chan_id_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
-       let chan_id_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 500_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.channel_id;
+       let chan_id_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000).2;
+       let chan_id_2 = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 500_000_000).0.channel_id;
 
        // We should always be able to forward through nodes[1] as long as its out through a public
        // channel:
@@ -69,8 +66,8 @@ fn test_priv_forwarding_rejection() {
                htlc_maximum_msat: None,
        }]);
        let last_hops = vec![route_hint];
-       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features())
+       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_features(nodes[2].node.invoice_features())
                .with_route_hints(last_hops);
        let (route, our_payment_hash, our_payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 10_000, TEST_FINAL_CLTV);
 
@@ -93,8 +90,8 @@ fn test_priv_forwarding_rejection() {
        // Now disconnect nodes[1] from its peers and restart with accept_forwards_to_priv_channels set
        // to true. Sadly there is currently no way to change it at runtime.
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id());
 
        let nodes_1_serialized = nodes[1].node.encode();
        let monitor_a_serialized = get_monitor!(nodes[1], chan_id_1).encode();
@@ -103,8 +100,8 @@ fn test_priv_forwarding_rejection() {
        no_announce_cfg.accept_forwards_to_priv_channels = true;
        reload_node!(nodes[1], no_announce_cfg, &nodes_1_serialized, &[&monitor_a_serialized, &monitor_b_serialized], persister, new_chain_monitor, nodes_1_deserialized);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), 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(), remote_network_address: None }, false).unwrap();
        let as_reestablish = get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap();
        let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_reestablish);
@@ -112,8 +109,8 @@ fn test_priv_forwarding_rejection() {
        get_event_msg!(nodes[0], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id());
        get_event_msg!(nodes[1], MessageSendEvent::SendChannelUpdate, nodes[0].node.get_our_node_id());
 
-       nodes[1].node.peer_connected(&nodes[2].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-       nodes[2].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[2].node.get_our_node_id(), &msgs::Init { features: nodes[2].node.init_features(), remote_network_address: None }, true).unwrap();
+       nodes[2].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, false).unwrap();
        let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[2]).pop().unwrap();
        let cs_reestablish = get_chan_reestablish_msgs!(nodes[2], nodes[1]).pop().unwrap();
        nodes[2].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
@@ -144,7 +141,7 @@ fn do_test_1_conf_open(connect_style: ConnectStyle) {
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
        *nodes[0].connect_style.borrow_mut() = connect_style;
 
-       let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001);
        mine_transaction(&nodes[1], &tx);
        nodes[0].node.handle_channel_ready(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendChannelReady, nodes[0].node.get_our_node_id()));
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
@@ -187,14 +184,14 @@ fn do_test_1_conf_open(connect_style: ConnectStyle) {
                msg.clone()
        } else { panic!("Unexpected event"); };
        let (bs_announcement, bs_update) = if let MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } = bs_announce_events[1] {
-               (msg.clone(), update_msg.clone())
+               (msg.clone(), update_msg.clone().unwrap())
        } else { panic!("Unexpected event"); };
 
        nodes[0].node.handle_announcement_signatures(&nodes[1].node.get_our_node_id(), &bs_announcement_sigs);
        let as_announce_events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(as_announce_events.len(), 1);
        let (announcement, as_update) = if let MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } = as_announce_events[0] {
-               (msg.clone(), update_msg.clone())
+               (msg.clone(), update_msg.clone().unwrap())
        } else { panic!("Unexpected event"); };
        assert_eq!(announcement, bs_announcement);
 
@@ -221,8 +218,8 @@ fn test_routed_scid_alias() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, Some(no_announce_cfg), None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
-       let mut as_channel_ready = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 500_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0;
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000).2;
+       let mut as_channel_ready = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 500_000_000).0;
 
        let last_hop = nodes[2].node.list_usable_channels();
        let hop_hints = vec![RouteHint(vec![RouteHintHop {
@@ -236,8 +233,8 @@ fn test_routed_scid_alias() {
                htlc_maximum_msat: None,
                htlc_minimum_msat: None,
        }])];
-       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features())
+       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42)
+               .with_features(nodes[2].node.invoice_features())
                .with_route_hints(hop_hints);
        let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 100_000, 42);
        assert_eq!(route.paths[0][1].short_channel_id, last_hop[0].inbound_scid_alias.unwrap());
@@ -287,7 +284,7 @@ fn test_scid_privacy_on_pub_channel() {
        open_channel.channel_type.as_mut().unwrap().set_scid_privacy_required();
        assert_eq!(open_channel.channel_flags & 1, 1); // The `announce_channel` bit is set.
 
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
        let err = get_err_msg!(nodes[1], nodes[0].node.get_our_node_id());
        assert_eq!(err.data, "SCID Alias/Privacy Channel Type cannot be set on a public channel");
 }
@@ -320,8 +317,8 @@ fn test_scid_privacy_negotiation() {
 
        let second_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
        assert!(!second_open_channel.channel_type.as_ref().unwrap().supports_scid_privacy());
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &second_open_channel);
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &second_open_channel);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
 
        let events = nodes[0].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 1);
@@ -345,7 +342,7 @@ fn test_inbound_scid_privacy() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, Some(accept_forward_cfg), None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
 
        let mut no_announce_cfg = test_default_channel_config();
        no_announce_cfg.channel_handshake_config.announced_channel = false;
@@ -355,9 +352,9 @@ fn test_inbound_scid_privacy() {
 
        assert!(open_channel.channel_type.as_ref().unwrap().requires_scid_privacy());
 
-       nodes[2].node.handle_open_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel);
+       nodes[2].node.handle_open_channel(&nodes[1].node.get_our_node_id(), &open_channel);
        let accept_channel = get_event_msg!(nodes[2], MessageSendEvent::SendAcceptChannel, nodes[1].node.get_our_node_id());
-       nodes[1].node.handle_accept_channel(&nodes[2].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+       nodes[1].node.handle_accept_channel(&nodes[2].node.get_our_node_id(), &accept_channel);
 
        let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[1], &nodes[2].node.get_our_node_id(), 100_000, 42);
        nodes[1].node.funding_transaction_generated(&temporary_channel_id, &nodes[2].node.get_our_node_id(), tx.clone()).unwrap();
@@ -398,8 +395,8 @@ fn test_inbound_scid_privacy() {
                htlc_maximum_msat: None,
                htlc_minimum_msat: None,
        }])];
-       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features())
+       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42)
+               .with_features(nodes[2].node.invoice_features())
                .with_route_hints(hop_hints.clone());
        let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 100_000, 42);
        assert_eq!(route.paths[0][1].short_channel_id, last_hop[0].inbound_scid_alias.unwrap());
@@ -413,8 +410,8 @@ fn test_inbound_scid_privacy() {
        // what channel we're talking about.
        hop_hints[0].0[0].short_channel_id = last_hop[0].short_channel_id.unwrap();
 
-       let payment_params_2 = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features())
+       let payment_params_2 = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42)
+               .with_features(nodes[2].node.invoice_features())
                .with_route_hints(hop_hints);
        let (route_2, payment_hash_2, _, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params_2, 100_000, 42);
        assert_eq!(route_2.paths[0][1].short_channel_id, last_hop[0].short_channel_id.unwrap());
@@ -449,8 +446,8 @@ fn test_scid_alias_returned() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, Some(accept_forward_cfg), None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 2, 10_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0);
+       let chan = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 2, 10_000, 0);
 
        let last_hop = nodes[2].node.list_usable_channels();
        let mut hop_hints = vec![RouteHint(vec![RouteHintHop {
@@ -464,8 +461,8 @@ fn test_scid_alias_returned() {
                htlc_maximum_msat: None,
                htlc_minimum_msat: None,
        }])];
-       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())
-               .with_features(channelmanager::provided_invoice_features())
+       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42)
+               .with_features(nodes[2].node.invoice_features())
                .with_route_hints(hop_hints);
        let (mut route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 10_000, 42);
        assert_eq!(route.paths[0][1].short_channel_id, nodes[2].node.list_usable_channels()[0].inbound_scid_alias.unwrap());
@@ -500,8 +497,7 @@ fn test_scid_alias_returned() {
                fee_proportional_millionths: last_hop[0].counterparty.forwarding_info.as_ref().unwrap().fee_proportional_millionths,
                excess_data: Vec::new(),
        };
-       let msg_hash = Sha256dHash::hash(&contents.encode()[..]);
-       let signature = Secp256k1::new().sign_ecdsa(&hash_to_message!(&msg_hash[..]), &nodes[1].keys_manager.get_node_secret(Recipient::Node).unwrap());
+       let signature = nodes[1].keys_manager.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelUpdate(&contents)).unwrap();
        let msg = msgs::ChannelUpdate { signature, contents };
 
        let mut err_data = Vec::new();
@@ -572,13 +568,13 @@ fn test_0conf_channel_with_async_monitor() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, Some(chan_config), None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0);
 
        chan_config.channel_handshake_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());
 
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
        let events = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 1);
        match events[0] {
@@ -590,7 +586,7 @@ fn test_0conf_channel_with_async_monitor() {
 
        let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
        assert_eq!(accept_channel.minimum_depth, 0);
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
 
        let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42);
        nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).unwrap();
@@ -768,7 +764,7 @@ fn test_public_0conf_channel() {
        match bs_announcement[0] {
                MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
                        announcement = msg.clone();
-                       bs_update = update_msg.clone();
+                       bs_update = update_msg.clone().unwrap();
                },
                _ => panic!("Unexpected event"),
        };
@@ -778,6 +774,7 @@ fn test_public_0conf_channel() {
        match as_announcement[0] {
                MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
                        assert!(announcement == *msg);
+                       let update_msg = update_msg.as_ref().unwrap();
                        assert_eq!(update_msg.contents.short_channel_id, scid);
                        assert_eq!(update_msg.contents.short_channel_id, announcement.contents.short_channel_id);
                        assert_eq!(update_msg.contents.short_channel_id, bs_update.contents.short_channel_id);
@@ -851,7 +848,7 @@ fn test_zero_conf_accept_reject() {
 
        open_channel_msg.channel_type = Some(channel_type_features.clone());
 
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel_msg);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
 
        let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
        match msg_events[0] {
@@ -879,8 +876,7 @@ fn test_zero_conf_accept_reject() {
 
        open_channel_msg.channel_type = Some(channel_type_features.clone());
 
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(),
-               &open_channel_msg);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
 
        // Assert that `nodes[1]` has no `MessageSendEvent::SendAcceptChannel` in the `msg_events`.
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
@@ -912,8 +908,7 @@ fn test_zero_conf_accept_reject() {
 
        open_channel_msg.channel_type = Some(channel_type_features);
 
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(),
-               &open_channel_msg);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
 
        let events = nodes[1].node.get_and_clear_pending_events();
 
@@ -951,7 +946,7 @@ fn test_connect_before_funding() {
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 10_001, 42, None).unwrap();
        let open_channel = 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(), channelmanager::provided_init_features(), &open_channel);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
        let events = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 1);
        match events[0] {
@@ -963,7 +958,7 @@ fn test_connect_before_funding() {
 
        let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
        assert_eq!(accept_channel.minimum_depth, 0);
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
 
        let events = nodes[0].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 1);
index 1f0c781d003af8b74fd876eab4c51b299971ab3d..14deefd3f93828181f6cfad952d48913c8e25586 100644 (file)
@@ -12,9 +12,9 @@
 use crate::chain::{ChannelMonitorUpdateStatus, Watch};
 use crate::chain::chaininterface::LowerBoundedFeeEstimator;
 use crate::chain::channelmonitor::ChannelMonitor;
-use crate::chain::keysinterface::{EntropySource, KeysInterface};
+use crate::chain::keysinterface::EntropySource;
 use crate::chain::transaction::OutPoint;
-use crate::ln::channelmanager::{self, ChannelManager, ChannelManagerReadArgs, PaymentId};
+use crate::ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, PaymentId};
 use crate::ln::msgs;
 use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction};
 use crate::util::enforcing_trait_impls::EnforcingSigner;
@@ -40,12 +40,12 @@ fn test_funding_peer_disconnect() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-       let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        confirm_transaction(&nodes[0], &tx);
        let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
@@ -53,16 +53,16 @@ fn test_funding_peer_disconnect() {
 
        reconnect_nodes(&nodes[0], &nodes[1], (false, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        confirm_transaction(&nodes[1], &tx);
        let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
        assert!(events_2.is_empty());
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        let as_reestablish = get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap();
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
 
        // nodes[0] hasn't yet received a channel_ready, so it only sends that on reconnect.
@@ -140,7 +140,7 @@ fn test_funding_peer_disconnect() {
        assert_eq!(events_7.len(), 1);
        let (chan_announcement, as_update) = match events_7[0] {
                MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
-                       (msg.clone(), update_msg.clone())
+                       (msg.clone(), update_msg.clone().unwrap())
                },
                _ => panic!("Unexpected event {:?}", events_7[0]),
        };
@@ -153,7 +153,7 @@ fn test_funding_peer_disconnect() {
        let bs_update = match events_8[0] {
                MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
                        assert_eq!(*msg, chan_announcement);
-                       update_msg.clone()
+                       update_msg.clone().unwrap()
                },
                _ => panic!("Unexpected event {:?}", events_8[0]),
        };
@@ -169,7 +169,7 @@ fn test_funding_peer_disconnect() {
 
        // Check that after deserialization and reconnection we can still generate an identical
        // channel_announcement from the cached signatures.
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
 
@@ -185,20 +185,20 @@ fn test_no_txn_manager_serialize_deserialize() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001);
 
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        let chan_0_monitor_serialized =
                get_monitor!(nodes[0], OutPoint { txid: tx.txid(), index: 0 }.to_channel_id()).encode();
        reload_node!(nodes[0], nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister, new_chain_monitor, nodes_0_deserialized);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
 
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]);
@@ -225,19 +225,17 @@ fn test_manager_serialize_deserialize_events() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Start creating a channel, but stop right before broadcasting the funding transaction
        let channel_value = 100000;
        let push_msat = 10001;
-       let a_flags = channelmanager::provided_init_features();
-       let b_flags = channelmanager::provided_init_features();
        let node_a = nodes.remove(0);
        let node_b = nodes.remove(0);
        node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None).unwrap();
-       node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), a_flags, &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id()));
-       node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), b_flags, &get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id()));
+       node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id()));
+       node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), &get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id()));
 
        let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&node_a, &node_b.node.get_our_node_id(), channel_value, 42);
 
@@ -269,7 +267,7 @@ fn test_manager_serialize_deserialize_events() {
        let chan_0_monitor_serialized = get_monitor!(nodes[0], bs_funding_signed.channel_id).encode();
        reload_node!(nodes[0], nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister, new_chain_monitor, nodes_0_deserialized);
 
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        // After deserializing, make sure the funding_transaction is still held by the channel manager
        let events_4 = nodes[0].node.get_and_clear_pending_events();
@@ -280,9 +278,9 @@ fn test_manager_serialize_deserialize_events() {
        // Make sure the channel is functioning as though the de/serialization never happened
        assert_eq!(nodes[0].node.list_channels().len(), 1);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
 
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]);
@@ -308,14 +306,14 @@ fn test_simple_manager_serialize_deserialize() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        let (our_payment_preimage, _, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
        let (_, our_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
 
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
        reload_node!(nodes[0], nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister, new_chain_monitor, nodes_0_deserialized);
@@ -336,11 +334,11 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
        let fee_estimator: test_utils::TestFeeEstimator;
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
-       let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
-       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 2, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
-       let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
+       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 2, 0).2;
+       let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3);
 
        let mut node_0_stale_monitors_serialized = Vec::new();
        for chan_id_iter in &[chan_id_1, chan_id_2, channel_id] {
@@ -355,9 +353,9 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
        let nodes_0_serialized = nodes[0].node.encode();
 
        route_payment(&nodes[0], &[&nodes[3]], 1000000);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-       nodes[2].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-       nodes[3].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
+       nodes[2].node.peer_disconnected(&nodes[0].node.get_our_node_id());
+       nodes[3].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        // Now the ChannelMonitor (which is now out-of-sync with ChannelManager for channel w/
        // nodes[3])
@@ -377,7 +375,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
        let mut node_0_stale_monitors = Vec::new();
        for serialized in node_0_stale_monitors_serialized.iter() {
                let mut read = &serialized[..];
-               let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut read, keys_manager).unwrap();
+               let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut read, (keys_manager, keys_manager)).unwrap();
                assert!(read.is_empty());
                node_0_stale_monitors.push(monitor);
        }
@@ -385,16 +383,18 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
        let mut node_0_monitors = Vec::new();
        for serialized in node_0_monitors_serialized.iter() {
                let mut read = &serialized[..];
-               let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut read, keys_manager).unwrap();
+               let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut read, (keys_manager, keys_manager)).unwrap();
                assert!(read.is_empty());
                node_0_monitors.push(monitor);
        }
 
        let mut nodes_0_read = &nodes_0_serialized[..];
        if let Err(msgs::DecodeError::InvalidValue) =
-               <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+               <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
                default_config: UserConfig::default(),
-               keys_manager,
+               entropy_source: keys_manager,
+               node_signer: keys_manager,
+               signer_provider: keys_manager,
                fee_estimator: &fee_estimator,
                router: &nodes[0].router,
                chain_monitor: nodes[0].chain_monitor,
@@ -407,9 +407,11 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
 
        let mut nodes_0_read = &nodes_0_serialized[..];
        let (_, nodes_0_deserialized_tmp) =
-               <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+               <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
                default_config: UserConfig::default(),
-               keys_manager,
+               entropy_source: keys_manager,
+               node_signer: keys_manager,
+               signer_provider: keys_manager,
                fee_estimator: &fee_estimator,
                router: nodes[0].router,
                chain_monitor: nodes[0].chain_monitor,
@@ -441,9 +443,9 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
        //... and we can even still claim the payment!
        claim_payment(&nodes[2], &[&nodes[0], &nodes[1]], our_payment_preimage);
 
-       nodes[3].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[3].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, true).unwrap();
        let reestablish = get_chan_reestablish_msgs!(nodes[3], nodes[0]).pop().unwrap();
-       nodes[0].node.peer_connected(&nodes[3].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[3].node.get_our_node_id(), &msgs::Init { features: nodes[3].node.init_features(), remote_network_address: None }, false).unwrap();
        nodes[0].node.handle_channel_reestablish(&nodes[3].node.get_our_node_id(), &reestablish);
        let mut found_err = false;
        for msg_event in nodes[0].node.get_and_clear_pending_msg_events() {
@@ -477,7 +479,7 @@ fn do_test_data_loss_protect(reconnect_panicing: bool) {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
 
        // Cache node A state before any channel update
        let previous_node_state = nodes[0].node.encode();
@@ -486,14 +488,14 @@ fn do_test_data_loss_protect(reconnect_panicing: bool) {
        send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
        send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
        reload_node!(nodes[0], previous_node_state, &[&previous_chain_monitor_state], persister, new_chain_monitor, nodes_0_deserialized);
 
        if reconnect_panicing {
-               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), 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(), remote_network_address: None }, false).unwrap();
 
                let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
 
@@ -541,8 +543,8 @@ fn do_test_data_loss_protect(reconnect_panicing: bool) {
        // after the warning message sent by B, we should not able to
        // use the channel, or reconnect with success to the channel.
        assert!(nodes[0].node.list_usable_channels().is_empty());
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), 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(), remote_network_address: None }, false).unwrap();
        let retry_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
 
        nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &retry_reestablish[0]);
@@ -551,7 +553,7 @@ fn do_test_data_loss_protect(reconnect_panicing: bool) {
                if let MessageSendEvent::HandleError { ref action, .. } = msg {
                        match action {
                                &ErrorAction::SendErrorMessage { ref msg } => {
-                                       assert_eq!(msg.data, "Failed to find corresponding channel");
+                                       assert_eq!(msg.data, format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", &nodes[1].node.get_our_node_id()));
                                        err_msgs_0.push(msg.clone());
                                },
                                _ => panic!("Unexpected event!"),
@@ -564,7 +566,7 @@ fn do_test_data_loss_protect(reconnect_panicing: bool) {
        nodes[1].node.handle_error(&nodes[0].node.get_our_node_id(), &err_msgs_0[0]);
        assert!(nodes[1].node.list_usable_channels().is_empty());
        check_added_monitors!(nodes[1], 1);
-       check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: "Failed to find corresponding channel".to_owned() });
+       check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", &nodes[1].node.get_our_node_id()) });
        check_closed_broadcast!(nodes[1], false);
 }
 
@@ -591,10 +593,10 @@ fn test_forwardable_regen() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_1_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_1_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
-       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
+       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
 
        // First send a payment to nodes[1]
        let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000);
@@ -625,8 +627,8 @@ fn test_forwardable_regen() {
        assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
 
        // Now restart nodes[1] and make sure it regenerates a single PendingHTLCsForwardable
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id());
 
        let chan_0_monitor_serialized = get_monitor!(nodes[1], chan_id_1).encode();
        let chan_1_monitor_serialized = get_monitor!(nodes[1], chan_id_2).encode();
@@ -675,14 +677,14 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
 
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_3_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_3_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
 
        let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_id_persisted = create_announced_chan_between_nodes_with_value(&nodes, 1, 3, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
-       let chan_id_not_persisted = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 100_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0);
+       create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100_000, 0);
+       let chan_id_persisted = create_announced_chan_between_nodes_with_value(&nodes, 1, 3, 100_000, 0).2;
+       let chan_id_not_persisted = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 100_000, 0).2;
 
        // Create an MPP route for 15k sats, more than the default htlc-max of 10%
        let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[3], 15_000_000);
@@ -699,8 +701,10 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
        // Send the payment through to nodes[3] *without* clearing the PaymentClaimable event
        let mut send_events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(send_events.len(), 2);
-       do_pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 15_000_000, payment_hash, Some(payment_secret), send_events[0].clone(), true, false, None);
-       do_pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 15_000_000, payment_hash, Some(payment_secret), send_events[1].clone(), true, false, None);
+       let node_1_msgs = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut send_events);
+       let node_2_msgs = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut send_events);
+       do_pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 15_000_000, payment_hash, Some(payment_secret), node_1_msgs, true, false, None);
+       do_pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 15_000_000, payment_hash, Some(payment_secret), node_2_msgs, true, false, None);
 
        // Now that we have an MPP payment pending, get the latest encoded copies of nodes[3]'s
        // monitors and ChannelManager, for use later, if we don't want to persist both monitors.
@@ -749,8 +753,8 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
        assert!(get_monitor!(nodes[3], chan_id_persisted).get_stored_preimages().contains_key(&payment_hash));
        assert!(get_monitor!(nodes[3], chan_id_not_persisted).get_stored_preimages().contains_key(&payment_hash));
 
-       nodes[1].node.peer_disconnected(&nodes[3].node.get_our_node_id(), false);
-       nodes[2].node.peer_disconnected(&nodes[3].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[3].node.get_our_node_id());
+       nodes[2].node.peer_disconnected(&nodes[3].node.get_our_node_id());
 
        // During deserialization, we should have closed one channel and broadcast its latest
        // commitment transaction. We should also still have the original PaymentClaimable event we
@@ -775,9 +779,9 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
        if !persist_both_monitors {
                // If one of the two channels is still live, reveal the payment preimage over it.
 
-               nodes[3].node.peer_connected(&nodes[2].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+               nodes[3].node.peer_connected(&nodes[2].node.get_our_node_id(), &msgs::Init { features: nodes[2].node.init_features(), remote_network_address: None }, true).unwrap();
                let reestablish_1 = get_chan_reestablish_msgs!(nodes[3], nodes[2]);
-               nodes[2].node.peer_connected(&nodes[3].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+               nodes[2].node.peer_connected(&nodes[3].node.get_our_node_id(), &msgs::Init { features: nodes[3].node.init_features(), remote_network_address: None }, false).unwrap();
                let reestablish_2 = get_chan_reestablish_msgs!(nodes[2], nodes[3]);
 
                nodes[2].node.handle_channel_reestablish(&nodes[3].node.get_our_node_id(), &reestablish_1[0]);
@@ -835,8 +839,8 @@ fn do_forwarded_payment_no_manager_persistence(use_cs_commitment: bool, claim_ht
 
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
-       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
+       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
 
        let intercept_scid = nodes[1].node.get_intercept_scid();
 
@@ -919,7 +923,7 @@ fn do_forwarded_payment_no_manager_persistence(use_cs_commitment: bool, claim_ht
        let bs_commitment_tx = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
        assert_eq!(bs_commitment_tx.len(), 1);
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), true);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
        reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
        if use_cs_commitment {
@@ -1000,8 +1004,8 @@ fn removed_payment_no_manager_persistence() {
 
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
-       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
+       let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
 
        let (_, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000);
 
@@ -1034,7 +1038,7 @@ fn removed_payment_no_manager_persistence() {
        // Now that the ChannelManager has force-closed the channel which had the HTLC removed, it is
        // now forgotten everywhere. The ChannelManager should have, as a side-effect of reload,
        // learned that the HTLC is gone from the ChannelMonitor and added it to the to-fail-back set.
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), true);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
        reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
        expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[1], [HTLCDestination::NextHopChannel { node_id: Some(nodes[2].node.get_our_node_id()), channel_id: chan_id_2 }]);
index c261c3d6eadfd3516f8c045d876f1cb098e0b6cc..69e0c9afa9e49c056c7d081ef8e42913d7492d55 100644 (file)
@@ -12,9 +12,9 @@
 use crate::chain::channelmonitor::ANTI_REORG_DELAY;
 use crate::chain::transaction::OutPoint;
 use crate::chain::Confirm;
-use crate::ln::channelmanager::{self, ChannelManager};
-use crate::ln::msgs::ChannelMessageHandler;
-use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
+use crate::ln::channelmanager::ChannelManager;
+use crate::ln::msgs::{ChannelMessageHandler, Init};
+use crate::util::events::{Event, MessageSendEventsProvider, ClosureReason, HTLCDestination};
 use crate::util::test_utils;
 use crate::util::ser::Writeable;
 
@@ -24,7 +24,6 @@ use bitcoin::blockdata::opcodes;
 use bitcoin::secp256k1::Secp256k1;
 
 use crate::prelude::*;
-use core::mem;
 use bitcoin::hashes::Hash;
 use bitcoin::TxMerkleNode;
 
@@ -51,8 +50,8 @@ fn do_test_onchain_htlc_reorg(local_commitment: bool, claim: bool) {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        // Make sure all nodes are at the same starting height
        connect_blocks(&nodes[0], 2*CHAN_CONFIRM_DEPTH + 1 - nodes[0].best_block_info().1);
@@ -191,7 +190,7 @@ fn test_counterparty_revoked_reorg() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000);
 
        // Get the initial commitment transaction for broadcast, before any HTLCs are added at all.
        let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan.2);
@@ -260,17 +259,19 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let persister: test_utils::TestPersister;
        let new_chain_monitor: test_utils::TestChainMonitor;
-       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
+       let nodes_0_deserialized: ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>;
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
        *nodes[0].connect_style.borrow_mut() = connect_style;
 
        let chan_conf_height = core::cmp::max(nodes[0].best_block_info().1 + 1, nodes[1].best_block_info().1 + 1);
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
-       let channel_state = nodes[0].node.channel_state.lock().unwrap();
-       assert_eq!(channel_state.by_id.len(), 1);
-       assert_eq!(nodes[0].node.short_to_chan_info.read().unwrap().len(), 2);
-       mem::drop(channel_state);
+       {
+               let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+               let peer_state = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
+               assert_eq!(peer_state.channel_by_id.len(), 1);
+               assert_eq!(nodes[0].node.short_to_chan_info.read().unwrap().len(), 2);
+       }
 
        assert_eq!(nodes[0].node.list_channels()[0].confirmations, Some(10));
        assert_eq!(nodes[1].node.list_channels()[0].confirmations, Some(10));
@@ -303,8 +304,9 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
                handle_announce_close_broadcast_events(&nodes, 0, 1, true, "Channel closed because of an exception: Funding transaction was un-confirmed. Locked at 6 confs, now have 0 confs.");
                check_added_monitors!(nodes[1], 1);
                {
-                       let channel_state = nodes[0].node.channel_state.lock().unwrap();
-                       assert_eq!(channel_state.by_id.len(), 0);
+                       let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+                       let peer_state = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
+                       assert_eq!(peer_state.channel_by_id.len(), 0);
                        assert_eq!(nodes[0].node.short_to_chan_info.read().unwrap().len(), 0);
                }
        }
@@ -354,8 +356,9 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
                handle_announce_close_broadcast_events(&nodes, 0, 1, true, "Channel closed because of an exception: Funding transaction was un-confirmed. Locked at 6 confs, now have 0 confs.");
                check_added_monitors!(nodes[1], 1);
                {
-                       let channel_state = nodes[0].node.channel_state.lock().unwrap();
-                       assert_eq!(channel_state.by_id.len(), 0);
+                       let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
+                       let peer_state = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
+                       assert_eq!(peer_state.channel_by_id.len(), 0);
                        assert_eq!(nodes[0].node.short_to_chan_info.read().unwrap().len(), 0);
                }
        }
@@ -371,7 +374,13 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
        nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clear();
 
        // Now check that we can create a new channel
-       create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       if reload_node && nodes[0].node.per_peer_state.read().unwrap().len() == 0 {
+               // If we dropped the channel before reloading the node, nodes[1] was also dropped from
+               // nodes[0] storage, and hence not connected again on startup. We therefore need to
+               // reconnect to the node before attempting to create a new channel.
+               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
+       }
+       create_announced_chan_between_nodes(&nodes, 0, 1);
        send_payment(&nodes[0], &[&nodes[1]], 8000000);
 }
 
@@ -424,7 +433,7 @@ fn test_set_outpoints_partial_claiming() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000);
        let (payment_preimage_1, payment_hash_1, _) = route_payment(&nodes[1], &[&nodes[0]], 3_000_000);
        let (payment_preimage_2, payment_hash_2, _) = route_payment(&nodes[1], &[&nodes[0]], 3_000_000);
 
@@ -526,7 +535,7 @@ fn do_test_to_remote_after_local_detection(style: ConnectStyle) {
        *nodes[1].connect_style.borrow_mut() = style;
 
        let (_, _, chan_id, funding_tx) =
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 100_000_000, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 100_000_000);
        let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
        assert_eq!(funding_outpoint.to_channel_id(), chan_id);
 
index d5094f69ce1aac5390415d25183601e65a875161..6c1d2102400786d41a124eafd26db70903bb82d2 100644 (file)
@@ -135,7 +135,7 @@ impl TryFrom<Script> for ShutdownScript {
        type Error = InvalidShutdownScript;
 
        fn try_from(script: Script) -> Result<Self, Self::Error> {
-               Self::try_from((script, &channelmanager::provided_init_features()))
+               Self::try_from((script, &channelmanager::provided_init_features(&crate::util::config::UserConfig::default())))
        }
 }
 
index 6a0d7c61fb905d32fa53937b7d4908cb1b502f79..75eacb74bc2fe7352a99288e28fcef82eac4c81d 100644 (file)
@@ -9,7 +9,7 @@
 
 //! Tests of our shutdown and closing_signed negotiation logic.
 
-use crate::chain::keysinterface::{EntropySource, KeysInterface, SignerProvider};
+use crate::chain::keysinterface::{EntropySource, SignerProvider};
 use crate::chain::transaction::OutPoint;
 use crate::ln::channelmanager::{self, PaymentSendFailure, PaymentId};
 use crate::routing::router::{PaymentParameters, get_route};
@@ -41,15 +41,15 @@ fn pre_funding_lock_shutdown_test() {
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-       let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 8000000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 8000000, 0);
        mine_transaction(&nodes[0], &tx);
        mine_transaction(&nodes[1], &tx);
 
        nodes[0].node.close_channel(&OutPoint { txid: tx.txid(), index: 0 }.to_channel_id(), &nodes[1].node.get_our_node_id()).unwrap();
        let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
        let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_shutdown);
 
        let node_0_closing_signed = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
        nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_closing_signed);
@@ -73,10 +73,10 @@ fn updates_shutdown_wait() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
        let logger = test_utils::TestLogger::new();
-       let scorer = test_utils::TestScorer::with_penalty(0);
+       let scorer = test_utils::TestScorer::new();
        let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
        let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -84,18 +84,18 @@ fn updates_shutdown_wait() {
 
        nodes[0].node.close_channel(&chan_1.2, &nodes[1].node.get_our_node_id()).unwrap();
        let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
        let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_shutdown);
 
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
 
        let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[0]);
 
-       let payment_params_1 = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id()).with_features(channelmanager::provided_invoice_features());
+       let payment_params_1 = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV).with_features(nodes[1].node.invoice_features());
        let route_1 = get_route(&nodes[0].node.get_our_node_id(), &payment_params_1, &nodes[0].network_graph.read_only(), None, 100000, TEST_FINAL_CLTV, &logger, &scorer, &random_seed_bytes).unwrap();
-       let payment_params_2 = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id()).with_features(channelmanager::provided_invoice_features());
+       let payment_params_2 = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id(), TEST_FINAL_CLTV).with_features(nodes[0].node.invoice_features());
        let route_2 = get_route(&nodes[1].node.get_our_node_id(), &payment_params_2, &nodes[1].network_graph.read_only(), None, 100000, TEST_FINAL_CLTV, &logger, &scorer, &random_seed_bytes).unwrap();
        unwrap_send_err!(nodes[0].node.send_payment(&route_1, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)), true, APIError::ChannelUnavailable {..}, {});
        unwrap_send_err!(nodes[1].node.send_payment(&route_2, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)), true, APIError::ChannelUnavailable {..}, {});
@@ -154,8 +154,8 @@ fn htlc_fail_async_shutdown() {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 100000);
        nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
@@ -169,13 +169,13 @@ fn htlc_fail_async_shutdown() {
 
        nodes[1].node.close_channel(&chan_1.2, &nodes[0].node.get_our_node_id()).unwrap();
        let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_shutdown);
        let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
 
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
        nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &updates.commitment_signed);
        check_added_monitors!(nodes[1], 1);
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
        commitment_signed_dance!(nodes[1], nodes[0], (), false, true, false);
 
        let updates_2 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
@@ -228,27 +228,27 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) {
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+       let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
 
        let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 100_000);
 
        nodes[1].node.close_channel(&chan_1.2, &nodes[0].node.get_our_node_id()).unwrap();
        let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
        if recv_count > 0 {
-               nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_shutdown);
+               nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_shutdown);
                let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
                if recv_count > 1 {
-                       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+                       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
                }
        }
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
        let node_0_reestablish = get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap();
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
        let node_1_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
 
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &node_0_reestablish);
@@ -258,15 +258,15 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) {
        nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &node_1_reestablish);
        let node_0_2nd_shutdown = if recv_count > 0 {
                let node_0_2nd_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
-               nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_2nd_shutdown);
+               nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_2nd_shutdown);
                node_0_2nd_shutdown
        } else {
                let node_0_chan_update = get_event_msg!(nodes[0], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id());
                assert_eq!(node_0_chan_update.contents.flags & 2, 0); // "disabled" flag must not be set as we just reconnected.
-               nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_2nd_shutdown);
+               nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_2nd_shutdown);
                get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id())
        };
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_2nd_shutdown);
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_2nd_shutdown);
 
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
@@ -305,12 +305,12 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) {
                assert!(node_0_2nd_closing_signed.is_some());
        }
 
-       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
-       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, true).unwrap();
        let node_1_2nd_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: channelmanager::provided_init_features(), remote_network_address: None }).unwrap();
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, false).unwrap();
        if recv_count == 0 {
                // If all closing_signeds weren't delivered we can just resume where we left off...
                let node_0_2nd_reestablish = get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap();
@@ -339,10 +339,10 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) {
                let node_1_3rd_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
                assert!(node_1_3rd_shutdown == node_1_2nd_shutdown);
 
-               nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_3rd_shutdown);
+               nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_3rd_shutdown);
                assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
 
-               nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_3rd_shutdown);
+               nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_3rd_shutdown);
 
                nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_2nd_closing_signed);
                let node_1_closing_signed = get_event_msg!(nodes[1], MessageSendEvent::SendClosingSigned, nodes[0].node.get_our_node_id());
@@ -380,7 +380,7 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) {
                // closing_signed so we do it ourselves
                check_closed_broadcast!(nodes[1], false);
                check_added_monitors!(nodes[1], 1);
-               check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: "Failed to find corresponding channel".to_string() });
+               check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", &nodes[1].node.get_our_node_id()) });
        }
 
        assert!(nodes[0].node.list_channels().is_empty());
@@ -415,30 +415,29 @@ fn test_upfront_shutdown_script() {
        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, &user_cfgs);
-       let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+       let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
        // We test that in case of peer committing upfront to a script, if it changes at closing, we refuse to sign
-       let flags = channelmanager::provided_init_features();
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000);
        nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[2].node.get_our_node_id()).unwrap();
        let node_0_orig_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id());
        let mut node_0_shutdown = node_0_orig_shutdown.clone();
        node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
        // Test we enforce upfront_scriptpbukey if by providing a different one at closing that we warn
        // the peer and ignore the message.
-       nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
        assert!(regex::Regex::new(r"Got shutdown request with a scriptpubkey \([A-Fa-f0-9]+\) which did not match their previous scriptpubkey.")
                        .unwrap().is_match(&check_warn_msg!(nodes[2], nodes[0].node.get_our_node_id(), chan.2)));
        // This allows nodes[2] to retry the shutdown message, which should get a response:
-       nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_orig_shutdown);
+       nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_orig_shutdown);
        get_event_msg!(nodes[2], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
 
        // We test that in case of peer committing upfront to a script, if it doesn't change at closing, we sign
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000);
        nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[2].node.get_our_node_id()).unwrap();
        let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id());
        // We test that in case of peer committing upfront to a script, if it oesn't change at closing, we sign
-       nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
        let events = nodes[2].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 1);
        match events[0] {
@@ -447,11 +446,11 @@ fn test_upfront_shutdown_script() {
        }
 
        // We test that if case of peer non-signaling we don't enforce committed script at channel opening
-       let flags_no = channelmanager::provided_init_features().clear_upfront_shutdown_script();
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, flags_no, flags.clone());
+       *nodes[0].override_init_features.borrow_mut() = Some(nodes[0].node.init_features().clear_upfront_shutdown_script());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
        nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[1].node.get_our_node_id()).unwrap();
        let node_1_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_shutdown);
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_1_shutdown);
        check_added_monitors!(nodes[1], 1);
        let events = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 1);
@@ -462,11 +461,12 @@ fn test_upfront_shutdown_script() {
 
        // We test that if user opt-out, we provide a zero-length script at channel opening and we are able to close
        // channel smoothly, opt-out is from channel initiator here
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 1, 0, 1000000, 1000000, flags.clone(), flags.clone());
+       *nodes[0].override_init_features.borrow_mut() = None;
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 1, 0, 1000000, 1000000);
        nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap();
        check_added_monitors!(nodes[1], 1);
        let node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
        let events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 1);
        match events[0] {
@@ -476,11 +476,11 @@ fn test_upfront_shutdown_script() {
 
        //// We test that if user opt-out, we provide a zero-length script at channel opening and we are able to close
        //// channel smoothly
-       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, flags.clone(), flags.clone());
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
        nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap();
        check_added_monitors!(nodes[1], 1);
        let node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
        let events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 2);
        match events[0] {
@@ -496,12 +496,13 @@ fn test_upfront_shutdown_script() {
 #[test]
 fn test_unsupported_anysegwit_upfront_shutdown_script() {
        let chanmon_cfgs = create_chanmon_cfgs(2);
-       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let mut node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       // Clear shutdown_anysegwit on initiator
+       *node_cfgs[0].override_init_features.borrow_mut() = Some(channelmanager::provided_init_features(&test_default_channel_config()).clear_shutdown_anysegwit());
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
        // Use a non-v0 segwit script supported by option_shutdown_anysegwit
-       let node_features = channelmanager::provided_init_features().clear_shutdown_anysegwit();
        let anysegwit_shutdown_script = Builder::new()
                .push_int(16)
                .push_slice(&[0, 40])
@@ -511,7 +512,7 @@ fn test_unsupported_anysegwit_upfront_shutdown_script() {
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
        let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
        open_channel.shutdown_scriptpubkey = Present(anysegwit_shutdown_script.clone());
-       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), node_features.clone(), &open_channel);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
 
        let events = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 1);
@@ -523,13 +524,20 @@ fn test_unsupported_anysegwit_upfront_shutdown_script() {
                _ => panic!("Unexpected event"),
        }
 
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let mut node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       // Clear shutdown_anysegwit on responder
+       *node_cfgs[1].override_init_features.borrow_mut() = Some(channelmanager::provided_init_features(&test_default_channel_config()).clear_shutdown_anysegwit());
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+       let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
        // Check script when handling an accept_channel message
        nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
        let open_channel = 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(), channelmanager::provided_init_features(), &open_channel);
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
        let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
        accept_channel.shutdown_scriptpubkey = Present(anysegwit_shutdown_script.clone());
-       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), node_features, &accept_channel);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
 
        let events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 1);
@@ -557,13 +565,13 @@ fn test_invalid_upfront_shutdown_script() {
        open_channel.shutdown_scriptpubkey = Present(Builder::new().push_int(0)
                .push_slice(&[0, 0])
                .into_script());
-       nodes[0].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel);
+       nodes[0].node.handle_open_channel(&nodes[1].node.get_our_node_id(), &open_channel);
 
        let events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 1);
        match events[0] {
                MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
-                       assert_eq!(node_id, nodes[0].node.get_our_node_id());
+                       assert_eq!(node_id, nodes[1].node.get_our_node_id());
                        assert_eq!(msg.data, "Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format: Script(OP_0 OP_PUSHBYTES_2 0000)");
                },
                _ => panic!("Unexpected event"),
@@ -582,7 +590,7 @@ fn test_segwit_v0_shutdown_script() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &user_cfgs);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
        nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap();
        check_added_monitors!(nodes[1], 1);
 
@@ -591,7 +599,7 @@ fn test_segwit_v0_shutdown_script() {
        node_0_shutdown.scriptpubkey = Builder::new().push_int(0)
                .push_slice(&[0; 20])
                .into_script();
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
 
        let events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 2);
@@ -617,7 +625,7 @@ fn test_anysegwit_shutdown_script() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &user_cfgs);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
        nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap();
        check_added_monitors!(nodes[1], 1);
 
@@ -626,7 +634,7 @@ fn test_anysegwit_shutdown_script() {
        node_0_shutdown.scriptpubkey = Builder::new().push_int(16)
                .push_slice(&[0, 0])
                .into_script();
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
 
        let events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 2);
@@ -649,8 +657,8 @@ fn test_unsupported_anysegwit_shutdown_script() {
        let user_cfgs = [None, Some(config), None];
        let chanmon_cfgs = create_chanmon_cfgs(3);
        let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
-       node_cfgs[0].features = channelmanager::provided_init_features().clear_shutdown_anysegwit();
-       node_cfgs[1].features = channelmanager::provided_init_features().clear_shutdown_anysegwit();
+       *node_cfgs[0].override_init_features.borrow_mut() = Some(channelmanager::provided_init_features(&config).clear_shutdown_anysegwit());
+       *node_cfgs[1].override_init_features.borrow_mut() = Some(channelmanager::provided_init_features(&config).clear_shutdown_anysegwit());
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &user_cfgs);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
@@ -662,7 +670,7 @@ fn test_unsupported_anysegwit_shutdown_script() {
                .expect(OnGetShutdownScriptpubkey { returns: unsupported_shutdown_script.clone() })
                .expect(OnGetShutdownScriptpubkey { returns: supported_shutdown_script });
 
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, node_cfgs[0].features.clone(), node_cfgs[1].features.clone());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
        match nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()) {
                Err(APIError::IncompatibleShutdownScript { script }) => {
                        assert_eq!(script.into_inner(), unsupported_shutdown_script.clone().into_inner());
@@ -676,7 +684,7 @@ fn test_unsupported_anysegwit_shutdown_script() {
        // Use a non-v0 segwit script unsupported without option_shutdown_anysegwit
        let mut node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
        node_0_shutdown.scriptpubkey = unsupported_shutdown_script.into_inner();
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_cfgs[1].features, &node_0_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
 
        assert_eq!(&check_warn_msg!(nodes[0], nodes[1].node.get_our_node_id(), chan.2),
                        "Got a nonstandard scriptpubkey (60020028) from remote peer");
@@ -694,7 +702,7 @@ fn test_invalid_shutdown_script() {
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &user_cfgs);
        let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
        nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap();
        check_added_monitors!(nodes[1], 1);
 
@@ -703,7 +711,7 @@ fn test_invalid_shutdown_script() {
        node_0_shutdown.scriptpubkey = Builder::new().push_int(0)
                .push_slice(&[0, 0])
                .into_script();
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
 
        assert_eq!(&check_warn_msg!(nodes[0], nodes[1].node.get_our_node_id(), chan.2),
                        "Got a nonstandard scriptpubkey (00020000) from remote peer");
@@ -729,15 +737,15 @@ fn do_test_closing_signed_reinit_timeout(timeout_step: TimeoutStep) {
        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);
-       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
+       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
 
        send_payment(&nodes[0], &[&nodes[1]], 8_000_000);
 
        nodes[0].node.close_channel(&chan_id, &nodes[1].node.get_our_node_id()).unwrap();
        let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
        let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_shutdown);
 
        {
                // Now we set nodes[1] to require a relatively high feerate for closing. This should result
@@ -761,8 +769,9 @@ fn do_test_closing_signed_reinit_timeout(timeout_step: TimeoutStep) {
                // nodes[1] should happily accept and respond to.
                node_0_closing_signed.fee_range.as_mut().unwrap().max_fee_satoshis *= 10;
                {
-                       let mut lock;
-                       get_channel_ref!(nodes[0], lock, chan_id).closing_fee_limits.as_mut().unwrap().1 *= 10;
+                       let mut node_0_per_peer_lock;
+                       let mut node_0_peer_state_lock;
+                       get_channel_ref!(nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, chan_id).closing_fee_limits.as_mut().unwrap().1 *= 10;
                }
                nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_closing_signed);
                let node_1_closing_signed = get_event_msg!(nodes[1], MessageSendEvent::SendClosingSigned, nodes[0].node.get_our_node_id());
@@ -825,7 +834,7 @@ fn do_simple_legacy_shutdown_test(high_initiator_fee: bool) {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
 
        if high_initiator_fee {
                // If high_initiator_fee is set, set nodes[0]'s feerate significantly higher. This
@@ -836,9 +845,9 @@ fn do_simple_legacy_shutdown_test(high_initiator_fee: bool) {
 
        nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[1].node.get_our_node_id()).unwrap();
        let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
        let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_shutdown);
 
        let mut node_0_closing_signed = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
        node_0_closing_signed.fee_range = None;
@@ -873,7 +882,7 @@ fn simple_target_feerate_shutdown() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       let chan = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+       let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
        let chan_id = OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id();
 
        nodes[0].node.close_channel_with_target_feerate(&chan_id, &nodes[1].node.get_our_node_id(), 253 * 10).unwrap();
@@ -881,8 +890,8 @@ fn simple_target_feerate_shutdown() {
        nodes[1].node.close_channel_with_target_feerate(&chan_id, &nodes[0].node.get_our_node_id(), 253 * 5).unwrap();
        let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
 
-       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_0_shutdown);
-       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &node_1_shutdown);
+       nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
+       nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_shutdown);
 
        let node_0_closing_signed = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
        nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_closing_signed);
diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs
new file mode 100644 (file)
index 0000000..49c03a4
--- /dev/null
@@ -0,0 +1,1675 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+//! Data structures and encoding for `invoice` messages.
+//!
+//! An [`Invoice`] can be built from a parsed [`InvoiceRequest`] for the "offer to be paid" flow or
+//! from a [`Refund`] as an "offer for money" flow. The expected recipient of the payment then sends
+//! the invoice to the intended payer, who will then pay it.
+//!
+//! The payment recipient must include a [`PaymentHash`], so as to reveal the preimage upon payment
+//! receipt, and one or more [`BlindedPath`]s for the payer to use when sending the payment.
+//!
+//! ```
+//! extern crate bitcoin;
+//! extern crate lightning;
+//!
+//! use bitcoin::hashes::Hash;
+//! use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey};
+//! use core::convert::{Infallible, TryFrom};
+//! use lightning::offers::invoice_request::InvoiceRequest;
+//! use lightning::offers::refund::Refund;
+//! use lightning::util::ser::Writeable;
+//!
+//! # use lightning::ln::PaymentHash;
+//! # use lightning::offers::invoice::BlindedPayInfo;
+//! # use lightning::onion_message::BlindedPath;
+//! #
+//! # fn create_payment_paths() -> Vec<(BlindedPath, BlindedPayInfo)> { unimplemented!() }
+//! # fn create_payment_hash() -> PaymentHash { unimplemented!() }
+//! #
+//! # fn parse_invoice_request(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::ParseError> {
+//! let payment_paths = create_payment_paths();
+//! let payment_hash = create_payment_hash();
+//! let secp_ctx = Secp256k1::new();
+//! let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32])?);
+//! let pubkey = PublicKey::from(keys);
+//! let wpubkey_hash = bitcoin::util::key::PublicKey::new(pubkey).wpubkey_hash().unwrap();
+//! let mut buffer = Vec::new();
+//!
+//! // Invoice for the "offer to be paid" flow.
+//! InvoiceRequest::try_from(bytes)?
+#![cfg_attr(feature = "std", doc = "
+    .respond_with(payment_paths, payment_hash)?
+")]
+#![cfg_attr(not(feature = "std"), doc = "
+    .respond_with_no_std(payment_paths, payment_hash, core::time::Duration::from_secs(0))?
+")]
+//!     .relative_expiry(3600)
+//!     .allow_mpp()
+//!     .fallback_v0_p2wpkh(&wpubkey_hash)
+//!     .build()?
+//!     .sign::<_, Infallible>(|digest| Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys)))
+//!     .expect("failed verifying signature")
+//!     .write(&mut buffer)
+//!     .unwrap();
+//! # Ok(())
+//! # }
+//!
+//! # fn parse_refund(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::ParseError> {
+//! # let payment_paths = create_payment_paths();
+//! # let payment_hash = create_payment_hash();
+//! # let secp_ctx = Secp256k1::new();
+//! # let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32])?);
+//! # let pubkey = PublicKey::from(keys);
+//! # let wpubkey_hash = bitcoin::util::key::PublicKey::new(pubkey).wpubkey_hash().unwrap();
+//! # let mut buffer = Vec::new();
+//!
+//! // Invoice for the "offer for money" flow.
+//! "lnr1qcp4256ypq"
+//!     .parse::<Refund>()?
+#![cfg_attr(feature = "std", doc = "
+    .respond_with(payment_paths, payment_hash, pubkey)?
+")]
+#![cfg_attr(not(feature = "std"), doc = "
+    .respond_with_no_std(payment_paths, payment_hash, pubkey, core::time::Duration::from_secs(0))?
+")]
+//!     .relative_expiry(3600)
+//!     .allow_mpp()
+//!     .fallback_v0_p2wpkh(&wpubkey_hash)
+//!     .build()?
+//!     .sign::<_, Infallible>(|digest| Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys)))
+//!     .expect("failed verifying signature")
+//!     .write(&mut buffer)
+//!     .unwrap();
+//! # Ok(())
+//! # }
+//!
+//! ```
+
+use bitcoin::blockdata::constants::ChainHash;
+use bitcoin::hash_types::{WPubkeyHash, WScriptHash};
+use bitcoin::hashes::Hash;
+use bitcoin::network::constants::Network;
+use bitcoin::secp256k1::{Message, PublicKey};
+use bitcoin::secp256k1::schnorr::Signature;
+use bitcoin::util::address::{Address, Payload, WitnessVersion};
+use bitcoin::util::schnorr::TweakedPublicKey;
+use core::convert::TryFrom;
+use core::time::Duration;
+use crate::io;
+use crate::ln::PaymentHash;
+use crate::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures};
+use crate::ln::msgs::DecodeError;
+use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
+use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, WithoutSignatures, self};
+use crate::offers::offer::{Amount, OfferTlvStream, OfferTlvStreamRef};
+use crate::offers::parse::{ParseError, ParsedMessage, SemanticError};
+use crate::offers::payer::{PayerTlvStream, PayerTlvStreamRef};
+use crate::offers::refund::{Refund, RefundContents};
+use crate::onion_message::BlindedPath;
+use crate::util::ser::{HighZeroBytesDroppedBigSize, Iterable, SeekReadable, WithoutLength, Writeable, Writer};
+
+use crate::prelude::*;
+
+#[cfg(feature = "std")]
+use std::time::SystemTime;
+
+const DEFAULT_RELATIVE_EXPIRY: Duration = Duration::from_secs(7200);
+
+const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice", "signature");
+
+/// Builds an [`Invoice`] from either:
+/// - an [`InvoiceRequest`] for the "offer to be paid" flow or
+/// - a [`Refund`] for the "offer for money" flow.
+///
+/// See [module-level documentation] for usage.
+///
+/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
+/// [`Refund`]: crate::offers::refund::Refund
+/// [module-level documentation]: self
+pub struct InvoiceBuilder<'a> {
+       invreq_bytes: &'a Vec<u8>,
+       invoice: InvoiceContents,
+}
+
+impl<'a> InvoiceBuilder<'a> {
+       pub(super) fn for_offer(
+               invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>,
+               created_at: Duration, payment_hash: PaymentHash
+       ) -> Result<Self, SemanticError> {
+               let amount_msats = match invoice_request.amount_msats() {
+                       Some(amount_msats) => amount_msats,
+                       None => match invoice_request.contents.offer.amount() {
+                               Some(Amount::Bitcoin { amount_msats }) => {
+                                       amount_msats.checked_mul(invoice_request.quantity().unwrap_or(1))
+                                               .ok_or(SemanticError::InvalidAmount)?
+                               },
+                               Some(Amount::Currency { .. }) => return Err(SemanticError::UnsupportedCurrency),
+                               None => return Err(SemanticError::MissingAmount),
+                       },
+               };
+
+               let contents = InvoiceContents::ForOffer {
+                       invoice_request: invoice_request.contents.clone(),
+                       fields: InvoiceFields {
+                               payment_paths, created_at, relative_expiry: None, payment_hash, amount_msats,
+                               fallbacks: None, features: Bolt12InvoiceFeatures::empty(),
+                               signing_pubkey: invoice_request.contents.offer.signing_pubkey(),
+                       },
+               };
+
+               Self::new(&invoice_request.bytes, contents)
+       }
+
+       pub(super) fn for_refund(
+               refund: &'a Refund, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, created_at: Duration,
+               payment_hash: PaymentHash, signing_pubkey: PublicKey
+       ) -> Result<Self, SemanticError> {
+               let contents = InvoiceContents::ForRefund {
+                       refund: refund.contents.clone(),
+                       fields: InvoiceFields {
+                               payment_paths, created_at, relative_expiry: None, payment_hash,
+                               amount_msats: refund.amount_msats(), fallbacks: None,
+                               features: Bolt12InvoiceFeatures::empty(), signing_pubkey,
+                       },
+               };
+
+               Self::new(&refund.bytes, contents)
+       }
+
+       fn new(invreq_bytes: &'a Vec<u8>, contents: InvoiceContents) -> Result<Self, SemanticError> {
+               if contents.fields().payment_paths.is_empty() {
+                       return Err(SemanticError::MissingPaths);
+               }
+
+               Ok(Self { invreq_bytes, invoice: contents })
+       }
+
+       /// Sets the [`Invoice::relative_expiry`] as seconds since [`Invoice::created_at`]. Any expiry
+       /// that has already passed is valid and can be checked for using [`Invoice::is_expired`].
+       ///
+       /// Successive calls to this method will override the previous setting.
+       pub fn relative_expiry(mut self, relative_expiry_secs: u32) -> Self {
+               let relative_expiry = Duration::from_secs(relative_expiry_secs as u64);
+               self.invoice.fields_mut().relative_expiry = Some(relative_expiry);
+               self
+       }
+
+       /// Adds a P2WSH address to [`Invoice::fallbacks`].
+       ///
+       /// Successive calls to this method will add another address. Caller is responsible for not
+       /// adding duplicate addresses and only calling if capable of receiving to P2WSH addresses.
+       pub fn fallback_v0_p2wsh(mut self, script_hash: &WScriptHash) -> Self {
+               let address = FallbackAddress {
+                       version: WitnessVersion::V0.to_num(),
+                       program: Vec::from(&script_hash.into_inner()[..]),
+               };
+               self.invoice.fields_mut().fallbacks.get_or_insert_with(Vec::new).push(address);
+               self
+       }
+
+       /// Adds a P2WPKH address to [`Invoice::fallbacks`].
+       ///
+       /// Successive calls to this method will add another address. Caller is responsible for not
+       /// adding duplicate addresses and only calling if capable of receiving to P2WPKH addresses.
+       pub fn fallback_v0_p2wpkh(mut self, pubkey_hash: &WPubkeyHash) -> Self {
+               let address = FallbackAddress {
+                       version: WitnessVersion::V0.to_num(),
+                       program: Vec::from(&pubkey_hash.into_inner()[..]),
+               };
+               self.invoice.fields_mut().fallbacks.get_or_insert_with(Vec::new).push(address);
+               self
+       }
+
+       /// Adds a P2TR address to [`Invoice::fallbacks`].
+       ///
+       /// Successive calls to this method will add another address. Caller is responsible for not
+       /// adding duplicate addresses and only calling if capable of receiving to P2TR addresses.
+       pub fn fallback_v1_p2tr_tweaked(mut self, output_key: &TweakedPublicKey) -> Self {
+               let address = FallbackAddress {
+                       version: WitnessVersion::V1.to_num(),
+                       program: Vec::from(&output_key.serialize()[..]),
+               };
+               self.invoice.fields_mut().fallbacks.get_or_insert_with(Vec::new).push(address);
+               self
+       }
+
+       /// Sets [`Invoice::features`] to indicate MPP may be used. Otherwise, MPP is disallowed.
+       pub fn allow_mpp(mut self) -> Self {
+               self.invoice.fields_mut().features.set_basic_mpp_optional();
+               self
+       }
+
+       /// Builds an unsigned [`Invoice`] after checking for valid semantics. It can be signed by
+       /// [`UnsignedInvoice::sign`].
+       pub fn build(self) -> Result<UnsignedInvoice<'a>, SemanticError> {
+               #[cfg(feature = "std")] {
+                       if self.invoice.is_offer_or_refund_expired() {
+                               return Err(SemanticError::AlreadyExpired);
+                       }
+               }
+
+               let InvoiceBuilder { invreq_bytes, invoice } = self;
+               Ok(UnsignedInvoice { invreq_bytes, invoice })
+       }
+}
+
+/// A semantically valid [`Invoice`] that hasn't been signed.
+pub struct UnsignedInvoice<'a> {
+       invreq_bytes: &'a Vec<u8>,
+       invoice: InvoiceContents,
+}
+
+impl<'a> UnsignedInvoice<'a> {
+       /// The public key corresponding to the key needed to sign the invoice.
+       pub fn signing_pubkey(&self) -> PublicKey {
+               self.invoice.fields().signing_pubkey
+       }
+
+       /// Signs the invoice using the given function.
+       pub fn sign<F, E>(self, sign: F) -> Result<Invoice, SignError<E>>
+       where
+               F: FnOnce(&Message) -> Result<Signature, E>
+       {
+               // Use the invoice_request bytes instead of the invoice_request TLV stream as the latter may
+               // have contained unknown TLV records, which are not stored in `InvoiceRequestContents` or
+               // `RefundContents`.
+               let (_, _, _, invoice_tlv_stream) = self.invoice.as_tlv_stream();
+               let invoice_request_bytes = WithoutSignatures(self.invreq_bytes);
+               let unsigned_tlv_stream = (invoice_request_bytes, invoice_tlv_stream);
+
+               let mut bytes = Vec::new();
+               unsigned_tlv_stream.write(&mut bytes).unwrap();
+
+               let pubkey = self.invoice.fields().signing_pubkey;
+               let signature = merkle::sign_message(sign, SIGNATURE_TAG, &bytes, pubkey)?;
+
+               // Append the signature TLV record to the bytes.
+               let signature_tlv_stream = SignatureTlvStreamRef {
+                       signature: Some(&signature),
+               };
+               signature_tlv_stream.write(&mut bytes).unwrap();
+
+               Ok(Invoice {
+                       bytes,
+                       contents: self.invoice,
+                       signature,
+               })
+       }
+}
+
+/// An `Invoice` is a payment request, typically corresponding to an [`Offer`] or a [`Refund`].
+///
+/// An invoice may be sent in response to an [`InvoiceRequest`] in the case of an offer or sent
+/// directly after scanning a refund. It includes all the information needed to pay a recipient.
+///
+/// [`Offer`]: crate::offers::offer::Offer
+/// [`Refund`]: crate::offers::refund::Refund
+/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
+#[derive(Clone, Debug, PartialEq)]
+pub struct Invoice {
+       bytes: Vec<u8>,
+       contents: InvoiceContents,
+       signature: Signature,
+}
+
+/// The contents of an [`Invoice`] for responding to either an [`Offer`] or a [`Refund`].
+///
+/// [`Offer`]: crate::offers::offer::Offer
+/// [`Refund`]: crate::offers::refund::Refund
+#[derive(Clone, Debug, PartialEq)]
+enum InvoiceContents {
+       /// Contents for an [`Invoice`] corresponding to an [`Offer`].
+       ///
+       /// [`Offer`]: crate::offers::offer::Offer
+       ForOffer {
+               invoice_request: InvoiceRequestContents,
+               fields: InvoiceFields,
+       },
+       /// Contents for an [`Invoice`] corresponding to a [`Refund`].
+       ///
+       /// [`Refund`]: crate::offers::refund::Refund
+       ForRefund {
+               refund: RefundContents,
+               fields: InvoiceFields,
+       },
+}
+
+/// Invoice-specific fields for an `invoice` message.
+#[derive(Clone, Debug, PartialEq)]
+struct InvoiceFields {
+       payment_paths: Vec<(BlindedPath, BlindedPayInfo)>,
+       created_at: Duration,
+       relative_expiry: Option<Duration>,
+       payment_hash: PaymentHash,
+       amount_msats: u64,
+       fallbacks: Option<Vec<FallbackAddress>>,
+       features: Bolt12InvoiceFeatures,
+       signing_pubkey: PublicKey,
+}
+
+impl Invoice {
+       /// Paths to the recipient originating from publicly reachable nodes, including information
+       /// needed for routing payments across them.
+       ///
+       /// Blinded paths provide recipient privacy by obfuscating its node id. Note, however, that this
+       /// privacy is lost if a public node id is used for [`Invoice::signing_pubkey`].
+       pub fn payment_paths(&self) -> &[(BlindedPath, BlindedPayInfo)] {
+               &self.contents.fields().payment_paths[..]
+       }
+
+       /// Duration since the Unix epoch when the invoice was created.
+       pub fn created_at(&self) -> Duration {
+               self.contents.fields().created_at
+       }
+
+       /// Duration since [`Invoice::created_at`] when the invoice has expired and therefore should no
+       /// longer be paid.
+       pub fn relative_expiry(&self) -> Duration {
+               self.contents.fields().relative_expiry.unwrap_or(DEFAULT_RELATIVE_EXPIRY)
+       }
+
+       /// Whether the invoice has expired.
+       #[cfg(feature = "std")]
+       pub fn is_expired(&self) -> bool {
+               let absolute_expiry = self.created_at().checked_add(self.relative_expiry());
+               match absolute_expiry {
+                       Some(seconds_from_epoch) => match SystemTime::UNIX_EPOCH.elapsed() {
+                               Ok(elapsed) => elapsed > seconds_from_epoch,
+                               Err(_) => false,
+                       },
+                       None => false,
+               }
+       }
+
+       /// SHA256 hash of the payment preimage that will be given in return for paying the invoice.
+       pub fn payment_hash(&self) -> PaymentHash {
+               self.contents.fields().payment_hash
+       }
+
+       /// The minimum amount required for a successful payment of the invoice.
+       pub fn amount_msats(&self) -> u64 {
+               self.contents.fields().amount_msats
+       }
+
+       /// Fallback addresses for paying the invoice on-chain, in order of most-preferred to
+       /// least-preferred.
+       pub fn fallbacks(&self) -> Vec<Address> {
+               let network = match self.network() {
+                       None => return Vec::new(),
+                       Some(network) => network,
+               };
+
+               let to_valid_address = |address: &FallbackAddress| {
+                       let version = match WitnessVersion::try_from(address.version) {
+                               Ok(version) => version,
+                               Err(_) => return None,
+                       };
+
+                       let program = &address.program;
+                       if program.len() < 2 || program.len() > 40 {
+                               return None;
+                       }
+
+                       let address = Address {
+                               payload: Payload::WitnessProgram {
+                                       version,
+                                       program: address.program.clone(),
+                               },
+                               network,
+                       };
+
+                       if !address.is_standard() && version == WitnessVersion::V0 {
+                               return None;
+                       }
+
+                       Some(address)
+               };
+
+               self.contents.fields().fallbacks
+                       .as_ref()
+                       .map(|fallbacks| fallbacks.iter().filter_map(to_valid_address).collect())
+                       .unwrap_or_else(Vec::new)
+       }
+
+       fn network(&self) -> Option<Network> {
+               let chain = self.contents.chain();
+               if chain == ChainHash::using_genesis_block(Network::Bitcoin) {
+                       Some(Network::Bitcoin)
+               } else if chain == ChainHash::using_genesis_block(Network::Testnet) {
+                       Some(Network::Testnet)
+               } else if chain == ChainHash::using_genesis_block(Network::Signet) {
+                       Some(Network::Signet)
+               } else if chain == ChainHash::using_genesis_block(Network::Regtest) {
+                       Some(Network::Regtest)
+               } else {
+                       None
+               }
+       }
+
+       /// Features pertaining to paying an invoice.
+       pub fn features(&self) -> &Bolt12InvoiceFeatures {
+               &self.contents.fields().features
+       }
+
+       /// The public key corresponding to the key used to sign the invoice.
+       pub fn signing_pubkey(&self) -> PublicKey {
+               self.contents.fields().signing_pubkey
+       }
+
+       /// Signature of the invoice verified using [`Invoice::signing_pubkey`].
+       pub fn signature(&self) -> Signature {
+               self.signature
+       }
+
+       #[cfg(test)]
+       fn as_tlv_stream(&self) -> FullInvoiceTlvStreamRef {
+               let (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream) =
+                       self.contents.as_tlv_stream();
+               let signature_tlv_stream = SignatureTlvStreamRef {
+                       signature: Some(&self.signature),
+               };
+               (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream,
+                signature_tlv_stream)
+       }
+}
+
+impl InvoiceContents {
+       /// Whether the original offer or refund has expired.
+       #[cfg(feature = "std")]
+       fn is_offer_or_refund_expired(&self) -> bool {
+               match self {
+                       InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.offer.is_expired(),
+                       InvoiceContents::ForRefund { refund, .. } => refund.is_expired(),
+               }
+       }
+
+       fn chain(&self) -> ChainHash {
+               match self {
+                       InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.chain(),
+                       InvoiceContents::ForRefund { refund, .. } => refund.chain(),
+               }
+       }
+
+       fn fields(&self) -> &InvoiceFields {
+               match self {
+                       InvoiceContents::ForOffer { fields, .. } => fields,
+                       InvoiceContents::ForRefund { fields, .. } => fields,
+               }
+       }
+
+       fn fields_mut(&mut self) -> &mut InvoiceFields {
+               match self {
+                       InvoiceContents::ForOffer { fields, .. } => fields,
+                       InvoiceContents::ForRefund { fields, .. } => fields,
+               }
+       }
+
+       fn as_tlv_stream(&self) -> PartialInvoiceTlvStreamRef {
+               let (payer, offer, invoice_request) = match self {
+                       InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.as_tlv_stream(),
+                       InvoiceContents::ForRefund { refund, .. } => refund.as_tlv_stream(),
+               };
+               let invoice = self.fields().as_tlv_stream();
+
+               (payer, offer, invoice_request, invoice)
+       }
+}
+
+impl InvoiceFields {
+       fn as_tlv_stream(&self) -> InvoiceTlvStreamRef {
+               let features = {
+                       if self.features == Bolt12InvoiceFeatures::empty() { None }
+                       else { Some(&self.features) }
+               };
+
+               InvoiceTlvStreamRef {
+                       paths: Some(Iterable(self.payment_paths.iter().map(|(path, _)| path))),
+                       blindedpay: Some(Iterable(self.payment_paths.iter().map(|(_, payinfo)| payinfo))),
+                       created_at: Some(self.created_at.as_secs()),
+                       relative_expiry: self.relative_expiry.map(|duration| duration.as_secs() as u32),
+                       payment_hash: Some(&self.payment_hash),
+                       amount: Some(self.amount_msats),
+                       fallbacks: self.fallbacks.as_ref(),
+                       features,
+                       node_id: Some(&self.signing_pubkey),
+               }
+       }
+}
+
+impl Writeable for Invoice {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               WithoutLength(&self.bytes).write(writer)
+       }
+}
+
+impl Writeable for InvoiceContents {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               self.as_tlv_stream().write(writer)
+       }
+}
+
+impl TryFrom<Vec<u8>> for Invoice {
+       type Error = ParseError;
+
+       fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
+               let parsed_invoice = ParsedMessage::<FullInvoiceTlvStream>::try_from(bytes)?;
+               Invoice::try_from(parsed_invoice)
+       }
+}
+
+tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef, 160..240, {
+       (160, paths: (Vec<BlindedPath>, WithoutLength, Iterable<'a, BlindedPathIter<'a>, BlindedPath>)),
+       (162, blindedpay: (Vec<BlindedPayInfo>, WithoutLength, Iterable<'a, BlindedPayInfoIter<'a>, BlindedPayInfo>)),
+       (164, created_at: (u64, HighZeroBytesDroppedBigSize)),
+       (166, relative_expiry: (u32, HighZeroBytesDroppedBigSize)),
+       (168, payment_hash: PaymentHash),
+       (170, amount: (u64, HighZeroBytesDroppedBigSize)),
+       (172, fallbacks: (Vec<FallbackAddress>, WithoutLength)),
+       (174, features: (Bolt12InvoiceFeatures, WithoutLength)),
+       (176, node_id: PublicKey),
+});
+
+type BlindedPathIter<'a> = core::iter::Map<
+       core::slice::Iter<'a, (BlindedPath, BlindedPayInfo)>,
+       for<'r> fn(&'r (BlindedPath, BlindedPayInfo)) -> &'r BlindedPath,
+>;
+
+type BlindedPayInfoIter<'a> = core::iter::Map<
+       core::slice::Iter<'a, (BlindedPath, BlindedPayInfo)>,
+       for<'r> fn(&'r (BlindedPath, BlindedPayInfo)) -> &'r BlindedPayInfo,
+>;
+
+/// Information needed to route a payment across a [`BlindedPath`].
+#[derive(Clone, Debug, PartialEq)]
+pub struct BlindedPayInfo {
+       /// Base fee charged (in millisatoshi) for the entire blinded path.
+       pub fee_base_msat: u32,
+
+       /// Liquidity fee charged (in millionths of the amount transferred) for the entire blinded path
+       /// (i.e., 10,000 is 1%).
+       pub fee_proportional_millionths: u32,
+
+       /// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for the entire blinded
+       /// path.
+       pub cltv_expiry_delta: u16,
+
+       /// The minimum HTLC value (in millisatoshi) that is acceptable to all channel peers on the
+       /// blinded path from the introduction node to the recipient, accounting for any fees, i.e., as
+       /// seen by the recipient.
+       pub htlc_minimum_msat: u64,
+
+       /// The maximum HTLC value (in millisatoshi) that is acceptable to all channel peers on the
+       /// blinded path from the introduction node to the recipient, accounting for any fees, i.e., as
+       /// seen by the recipient.
+       pub htlc_maximum_msat: u64,
+
+       /// Features set in `encrypted_data_tlv` for the `encrypted_recipient_data` TLV record in an
+       /// onion payload.
+       pub features: BlindedHopFeatures,
+}
+
+impl_writeable!(BlindedPayInfo, {
+       fee_base_msat,
+       fee_proportional_millionths,
+       cltv_expiry_delta,
+       htlc_minimum_msat,
+       htlc_maximum_msat,
+       features
+});
+
+/// Wire representation for an on-chain fallback address.
+#[derive(Clone, Debug, PartialEq)]
+pub(super) struct FallbackAddress {
+       version: u8,
+       program: Vec<u8>,
+}
+
+impl_writeable!(FallbackAddress, { version, program });
+
+type FullInvoiceTlvStream =
+       (PayerTlvStream, OfferTlvStream, InvoiceRequestTlvStream, InvoiceTlvStream, SignatureTlvStream);
+
+#[cfg(test)]
+type FullInvoiceTlvStreamRef<'a> = (
+       PayerTlvStreamRef<'a>,
+       OfferTlvStreamRef<'a>,
+       InvoiceRequestTlvStreamRef<'a>,
+       InvoiceTlvStreamRef<'a>,
+       SignatureTlvStreamRef<'a>,
+);
+
+impl SeekReadable for FullInvoiceTlvStream {
+       fn read<R: io::Read + io::Seek>(r: &mut R) -> Result<Self, DecodeError> {
+               let payer = SeekReadable::read(r)?;
+               let offer = SeekReadable::read(r)?;
+               let invoice_request = SeekReadable::read(r)?;
+               let invoice = SeekReadable::read(r)?;
+               let signature = SeekReadable::read(r)?;
+
+               Ok((payer, offer, invoice_request, invoice, signature))
+       }
+}
+
+type PartialInvoiceTlvStream =
+       (PayerTlvStream, OfferTlvStream, InvoiceRequestTlvStream, InvoiceTlvStream);
+
+type PartialInvoiceTlvStreamRef<'a> = (
+       PayerTlvStreamRef<'a>,
+       OfferTlvStreamRef<'a>,
+       InvoiceRequestTlvStreamRef<'a>,
+       InvoiceTlvStreamRef<'a>,
+);
+
+impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for Invoice {
+       type Error = ParseError;
+
+       fn try_from(invoice: ParsedMessage<FullInvoiceTlvStream>) -> Result<Self, Self::Error> {
+               let ParsedMessage { bytes, tlv_stream } = invoice;
+               let (
+                       payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream,
+                       SignatureTlvStream { signature },
+               ) = tlv_stream;
+               let contents = InvoiceContents::try_from(
+                       (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream)
+               )?;
+
+               let signature = match signature {
+                       None => return Err(ParseError::InvalidSemantics(SemanticError::MissingSignature)),
+                       Some(signature) => signature,
+               };
+               let pubkey = contents.fields().signing_pubkey;
+               merkle::verify_signature(&signature, SIGNATURE_TAG, &bytes, pubkey)?;
+
+               Ok(Invoice { bytes, contents, signature })
+       }
+}
+
+impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
+       type Error = SemanticError;
+
+       fn try_from(tlv_stream: PartialInvoiceTlvStream) -> Result<Self, Self::Error> {
+               let (
+                       payer_tlv_stream,
+                       offer_tlv_stream,
+                       invoice_request_tlv_stream,
+                       InvoiceTlvStream {
+                               paths, blindedpay, created_at, relative_expiry, payment_hash, amount, fallbacks,
+                               features, node_id,
+                       },
+               ) = tlv_stream;
+
+               let payment_paths = match (paths, blindedpay) {
+                       (None, _) => return Err(SemanticError::MissingPaths),
+                       (_, None) => return Err(SemanticError::InvalidPayInfo),
+                       (Some(paths), _) if paths.is_empty() => return Err(SemanticError::MissingPaths),
+                       (Some(paths), Some(blindedpay)) if paths.len() != blindedpay.len() => {
+                               return Err(SemanticError::InvalidPayInfo);
+                       },
+                       (Some(paths), Some(blindedpay)) => {
+                               paths.into_iter().zip(blindedpay.into_iter()).collect::<Vec<_>>()
+                       },
+               };
+
+               let created_at = match created_at {
+                       None => return Err(SemanticError::MissingCreationTime),
+                       Some(timestamp) => Duration::from_secs(timestamp),
+               };
+
+               let relative_expiry = relative_expiry
+                       .map(Into::<u64>::into)
+                       .map(Duration::from_secs);
+
+               let payment_hash = match payment_hash {
+                       None => return Err(SemanticError::MissingPaymentHash),
+                       Some(payment_hash) => payment_hash,
+               };
+
+               let amount_msats = match amount {
+                       None => return Err(SemanticError::MissingAmount),
+                       Some(amount) => amount,
+               };
+
+               let features = features.unwrap_or_else(Bolt12InvoiceFeatures::empty);
+
+               let signing_pubkey = match node_id {
+                       None => return Err(SemanticError::MissingSigningPubkey),
+                       Some(node_id) => node_id,
+               };
+
+               let fields = InvoiceFields {
+                       payment_paths, created_at, relative_expiry, payment_hash, amount_msats, fallbacks,
+                       features, signing_pubkey,
+               };
+
+               match offer_tlv_stream.node_id {
+                       Some(expected_signing_pubkey) => {
+                               if fields.signing_pubkey != expected_signing_pubkey {
+                                       return Err(SemanticError::InvalidSigningPubkey);
+                               }
+
+                               let invoice_request = InvoiceRequestContents::try_from(
+                                       (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
+                               )?;
+                               Ok(InvoiceContents::ForOffer { invoice_request, fields })
+                       },
+                       None => {
+                               let refund = RefundContents::try_from(
+                                       (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
+                               )?;
+                               Ok(InvoiceContents::ForRefund { refund, fields })
+                       },
+               }
+       }
+}
+
+#[cfg(test)]
+mod tests {
+       use super::{DEFAULT_RELATIVE_EXPIRY, BlindedPayInfo, FallbackAddress, FullInvoiceTlvStreamRef, Invoice, InvoiceTlvStreamRef, SIGNATURE_TAG};
+
+       use bitcoin::blockdata::script::Script;
+       use bitcoin::hashes::Hash;
+       use bitcoin::network::constants::Network;
+       use bitcoin::secp256k1::{KeyPair, Message, PublicKey, Secp256k1, SecretKey, XOnlyPublicKey, self};
+       use bitcoin::secp256k1::schnorr::Signature;
+       use bitcoin::util::address::{Address, Payload, WitnessVersion};
+       use bitcoin::util::schnorr::TweakedPublicKey;
+       use core::convert::{Infallible, TryFrom};
+       use core::time::Duration;
+       use crate::ln::PaymentHash;
+       use crate::ln::msgs::DecodeError;
+       use crate::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures};
+       use crate::offers::invoice_request::InvoiceRequestTlvStreamRef;
+       use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self};
+       use crate::offers::offer::{OfferBuilder, OfferTlvStreamRef, Quantity};
+       use crate::offers::parse::{ParseError, SemanticError};
+       use crate::offers::payer::PayerTlvStreamRef;
+       use crate::offers::refund::RefundBuilder;
+       use crate::onion_message::{BlindedHop, BlindedPath};
+       use crate::util::ser::{BigSize, Iterable, Writeable};
+
+       fn payer_keys() -> KeyPair {
+               let secp_ctx = Secp256k1::new();
+               KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap())
+       }
+
+       fn payer_sign(digest: &Message) -> Result<Signature, Infallible> {
+               let secp_ctx = Secp256k1::new();
+               let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
+               Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys))
+       }
+
+       fn payer_pubkey() -> PublicKey {
+               payer_keys().public_key()
+       }
+
+       fn recipient_keys() -> KeyPair {
+               let secp_ctx = Secp256k1::new();
+               KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap())
+       }
+
+       fn recipient_sign(digest: &Message) -> Result<Signature, Infallible> {
+               let secp_ctx = Secp256k1::new();
+               let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap());
+               Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys))
+       }
+
+       fn recipient_pubkey() -> PublicKey {
+               recipient_keys().public_key()
+       }
+
+       fn pubkey(byte: u8) -> PublicKey {
+               let secp_ctx = Secp256k1::new();
+               PublicKey::from_secret_key(&secp_ctx, &privkey(byte))
+       }
+
+       fn privkey(byte: u8) -> SecretKey {
+               SecretKey::from_slice(&[byte; 32]).unwrap()
+       }
+
+       trait ToBytes {
+               fn to_bytes(&self) -> Vec<u8>;
+       }
+
+       impl<'a> ToBytes for FullInvoiceTlvStreamRef<'a> {
+               fn to_bytes(&self) -> Vec<u8> {
+                       let mut buffer = Vec::new();
+                       self.0.write(&mut buffer).unwrap();
+                       self.1.write(&mut buffer).unwrap();
+                       self.2.write(&mut buffer).unwrap();
+                       self.3.write(&mut buffer).unwrap();
+                       self.4.write(&mut buffer).unwrap();
+                       buffer
+               }
+       }
+
+       fn payment_paths() -> Vec<(BlindedPath, BlindedPayInfo)> {
+               let paths = vec![
+                       BlindedPath {
+                               introduction_node_id: pubkey(40),
+                               blinding_point: pubkey(41),
+                               blinded_hops: vec![
+                                       BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
+                                       BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
+                               ],
+                       },
+                       BlindedPath {
+                               introduction_node_id: pubkey(40),
+                               blinding_point: pubkey(41),
+                               blinded_hops: vec![
+                                       BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
+                                       BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
+                               ],
+                       },
+               ];
+
+               let payinfo = vec![
+                       BlindedPayInfo {
+                               fee_base_msat: 1,
+                               fee_proportional_millionths: 1_000,
+                               cltv_expiry_delta: 42,
+                               htlc_minimum_msat: 100,
+                               htlc_maximum_msat: 1_000_000_000_000,
+                               features: BlindedHopFeatures::empty(),
+                       },
+                       BlindedPayInfo {
+                               fee_base_msat: 1,
+                               fee_proportional_millionths: 1_000,
+                               cltv_expiry_delta: 42,
+                               htlc_minimum_msat: 100,
+                               htlc_maximum_msat: 1_000_000_000_000,
+                               features: BlindedHopFeatures::empty(),
+                       },
+               ];
+
+               paths.into_iter().zip(payinfo.into_iter()).collect()
+       }
+
+       fn payment_hash() -> PaymentHash {
+               PaymentHash([42; 32])
+       }
+
+       fn now() -> Duration {
+               std::time::SystemTime::now()
+                       .duration_since(std::time::SystemTime::UNIX_EPOCH)
+                       .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH")
+       }
+
+       #[test]
+       fn builds_invoice_for_offer_with_defaults() {
+               let payment_paths = payment_paths();
+               let payment_hash = payment_hash();
+               let now = now();
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths.clone(), payment_hash, now).unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               assert_eq!(invoice.bytes, buffer.as_slice());
+               assert_eq!(invoice.payment_paths(), payment_paths.as_slice());
+               assert_eq!(invoice.created_at(), now);
+               assert_eq!(invoice.relative_expiry(), DEFAULT_RELATIVE_EXPIRY);
+               #[cfg(feature = "std")]
+               assert!(!invoice.is_expired());
+               assert_eq!(invoice.payment_hash(), payment_hash);
+               assert_eq!(invoice.amount_msats(), 1000);
+               assert_eq!(invoice.fallbacks(), vec![]);
+               assert_eq!(invoice.features(), &Bolt12InvoiceFeatures::empty());
+               assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
+               assert!(
+                       merkle::verify_signature(
+                               &invoice.signature, SIGNATURE_TAG, &invoice.bytes, recipient_pubkey()
+                       ).is_ok()
+               );
+
+               assert_eq!(
+                       invoice.as_tlv_stream(),
+                       (
+                               PayerTlvStreamRef { metadata: Some(&vec![1; 32]) },
+                               OfferTlvStreamRef {
+                                       chains: None,
+                                       metadata: None,
+                                       currency: None,
+                                       amount: Some(1000),
+                                       description: Some(&String::from("foo")),
+                                       features: None,
+                                       absolute_expiry: None,
+                                       paths: None,
+                                       issuer: None,
+                                       quantity_max: None,
+                                       node_id: Some(&recipient_pubkey()),
+                               },
+                               InvoiceRequestTlvStreamRef {
+                                       chain: None,
+                                       amount: None,
+                                       features: None,
+                                       quantity: None,
+                                       payer_id: Some(&payer_pubkey()),
+                                       payer_note: None,
+                               },
+                               InvoiceTlvStreamRef {
+                                       paths: Some(Iterable(payment_paths.iter().map(|(path, _)| path))),
+                                       blindedpay: Some(Iterable(payment_paths.iter().map(|(_, payinfo)| payinfo))),
+                                       created_at: Some(now.as_secs()),
+                                       relative_expiry: None,
+                                       payment_hash: Some(&payment_hash),
+                                       amount: Some(1000),
+                                       fallbacks: None,
+                                       features: None,
+                                       node_id: Some(&recipient_pubkey()),
+                               },
+                               SignatureTlvStreamRef { signature: Some(&invoice.signature()) },
+                       ),
+               );
+
+               if let Err(e) = Invoice::try_from(buffer) {
+                       panic!("error parsing invoice: {:?}", e);
+               }
+       }
+
+       #[test]
+       fn builds_invoice_for_refund_with_defaults() {
+               let payment_paths = payment_paths();
+               let payment_hash = payment_hash();
+               let now = now();
+               let invoice = RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()
+                       .build().unwrap()
+                       .respond_with_no_std(payment_paths.clone(), payment_hash, recipient_pubkey(), now)
+                       .unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               assert_eq!(invoice.bytes, buffer.as_slice());
+               assert_eq!(invoice.payment_paths(), payment_paths.as_slice());
+               assert_eq!(invoice.created_at(), now);
+               assert_eq!(invoice.relative_expiry(), DEFAULT_RELATIVE_EXPIRY);
+               #[cfg(feature = "std")]
+               assert!(!invoice.is_expired());
+               assert_eq!(invoice.payment_hash(), payment_hash);
+               assert_eq!(invoice.amount_msats(), 1000);
+               assert_eq!(invoice.fallbacks(), vec![]);
+               assert_eq!(invoice.features(), &Bolt12InvoiceFeatures::empty());
+               assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
+               assert!(
+                       merkle::verify_signature(
+                               &invoice.signature, SIGNATURE_TAG, &invoice.bytes, recipient_pubkey()
+                       ).is_ok()
+               );
+
+               assert_eq!(
+                       invoice.as_tlv_stream(),
+                       (
+                               PayerTlvStreamRef { metadata: Some(&vec![1; 32]) },
+                               OfferTlvStreamRef {
+                                       chains: None,
+                                       metadata: None,
+                                       currency: None,
+                                       amount: None,
+                                       description: Some(&String::from("foo")),
+                                       features: None,
+                                       absolute_expiry: None,
+                                       paths: None,
+                                       issuer: None,
+                                       quantity_max: None,
+                                       node_id: None,
+                               },
+                               InvoiceRequestTlvStreamRef {
+                                       chain: None,
+                                       amount: Some(1000),
+                                       features: None,
+                                       quantity: None,
+                                       payer_id: Some(&payer_pubkey()),
+                                       payer_note: None,
+                               },
+                               InvoiceTlvStreamRef {
+                                       paths: Some(Iterable(payment_paths.iter().map(|(path, _)| path))),
+                                       blindedpay: Some(Iterable(payment_paths.iter().map(|(_, payinfo)| payinfo))),
+                                       created_at: Some(now.as_secs()),
+                                       relative_expiry: None,
+                                       payment_hash: Some(&payment_hash),
+                                       amount: Some(1000),
+                                       fallbacks: None,
+                                       features: None,
+                                       node_id: Some(&recipient_pubkey()),
+                               },
+                               SignatureTlvStreamRef { signature: Some(&invoice.signature()) },
+                       ),
+               );
+
+               if let Err(e) = Invoice::try_from(buffer) {
+                       panic!("error parsing invoice: {:?}", e);
+               }
+       }
+
+       #[cfg(feature = "std")]
+       #[test]
+       fn builds_invoice_from_offer_with_expiration() {
+               let future_expiry = Duration::from_secs(u64::max_value());
+               let past_expiry = Duration::from_secs(0);
+
+               if let Err(e) = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .absolute_expiry(future_expiry)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with(payment_paths(), payment_hash())
+                       .unwrap()
+                       .build()
+               {
+                       panic!("error building invoice: {:?}", e);
+               }
+
+               match OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .absolute_expiry(past_expiry)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build_unchecked()
+                       .sign(payer_sign).unwrap()
+                       .respond_with(payment_paths(), payment_hash())
+                       .unwrap()
+                       .build()
+               {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, SemanticError::AlreadyExpired),
+               }
+       }
+
+       #[cfg(feature = "std")]
+       #[test]
+       fn builds_invoice_from_refund_with_expiration() {
+               let future_expiry = Duration::from_secs(u64::max_value());
+               let past_expiry = Duration::from_secs(0);
+
+               if let Err(e) = RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()
+                       .absolute_expiry(future_expiry)
+                       .build().unwrap()
+                       .respond_with(payment_paths(), payment_hash(), recipient_pubkey())
+                       .unwrap()
+                       .build()
+               {
+                       panic!("error building invoice: {:?}", e);
+               }
+
+               match RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()
+                       .absolute_expiry(past_expiry)
+                       .build().unwrap()
+                       .respond_with(payment_paths(), payment_hash(), recipient_pubkey())
+                       .unwrap()
+                       .build()
+               {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, SemanticError::AlreadyExpired),
+               }
+       }
+
+       #[test]
+       fn builds_invoice_with_relative_expiry() {
+               let now = now();
+               let one_hour = Duration::from_secs(3600);
+
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now).unwrap()
+                       .relative_expiry(one_hour.as_secs() as u32)
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+               let (_, _, _, tlv_stream, _) = invoice.as_tlv_stream();
+               #[cfg(feature = "std")]
+               assert!(!invoice.is_expired());
+               assert_eq!(invoice.relative_expiry(), one_hour);
+               assert_eq!(tlv_stream.relative_expiry, Some(one_hour.as_secs() as u32));
+
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now - one_hour).unwrap()
+                       .relative_expiry(one_hour.as_secs() as u32 - 1)
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+               let (_, _, _, tlv_stream, _) = invoice.as_tlv_stream();
+               #[cfg(feature = "std")]
+               assert!(invoice.is_expired());
+               assert_eq!(invoice.relative_expiry(), one_hour - Duration::from_secs(1));
+               assert_eq!(tlv_stream.relative_expiry, Some(one_hour.as_secs() as u32 - 1));
+       }
+
+       #[test]
+       fn builds_invoice_with_amount_from_request() {
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .amount_msats(1001).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+               let (_, _, _, tlv_stream, _) = invoice.as_tlv_stream();
+               assert_eq!(invoice.amount_msats(), 1001);
+               assert_eq!(tlv_stream.amount, Some(1001));
+       }
+
+       #[test]
+       fn builds_invoice_with_quantity_from_request() {
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .supported_quantity(Quantity::Unbounded)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .quantity(2).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+               let (_, _, _, tlv_stream, _) = invoice.as_tlv_stream();
+               assert_eq!(invoice.amount_msats(), 2000);
+               assert_eq!(tlv_stream.amount, Some(2000));
+
+               match OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .supported_quantity(Quantity::Unbounded)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .quantity(u64::max_value()).unwrap()
+                       .build_unchecked()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now())
+               {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, SemanticError::InvalidAmount),
+               }
+       }
+
+       #[test]
+       fn builds_invoice_with_fallback_address() {
+               let script = Script::new();
+               let pubkey = bitcoin::util::key::PublicKey::new(recipient_pubkey());
+               let x_only_pubkey = XOnlyPublicKey::from_keypair(&recipient_keys()).0;
+               let tweaked_pubkey = TweakedPublicKey::dangerous_assume_tweaked(x_only_pubkey);
+
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .fallback_v0_p2wsh(&script.wscript_hash())
+                       .fallback_v0_p2wpkh(&pubkey.wpubkey_hash().unwrap())
+                       .fallback_v1_p2tr_tweaked(&tweaked_pubkey)
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+               let (_, _, _, tlv_stream, _) = invoice.as_tlv_stream();
+               assert_eq!(
+                       invoice.fallbacks(),
+                       vec![
+                               Address::p2wsh(&script, Network::Bitcoin),
+                               Address::p2wpkh(&pubkey, Network::Bitcoin).unwrap(),
+                               Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin),
+                       ],
+               );
+               assert_eq!(
+                       tlv_stream.fallbacks,
+                       Some(&vec![
+                               FallbackAddress {
+                                       version: WitnessVersion::V0.to_num(),
+                                       program: Vec::from(&script.wscript_hash().into_inner()[..]),
+                               },
+                               FallbackAddress {
+                                       version: WitnessVersion::V0.to_num(),
+                                       program: Vec::from(&pubkey.wpubkey_hash().unwrap().into_inner()[..]),
+                               },
+                               FallbackAddress {
+                                       version: WitnessVersion::V1.to_num(),
+                                       program: Vec::from(&tweaked_pubkey.serialize()[..]),
+                               },
+                       ])
+               );
+       }
+
+       #[test]
+       fn builds_invoice_with_allow_mpp() {
+               let mut features = Bolt12InvoiceFeatures::empty();
+               features.set_basic_mpp_optional();
+
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .allow_mpp()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+               let (_, _, _, tlv_stream, _) = invoice.as_tlv_stream();
+               assert_eq!(invoice.features(), &features);
+               assert_eq!(tlv_stream.features, Some(&features));
+       }
+
+       #[test]
+       fn fails_signing_invoice() {
+               match OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(|_| Err(()))
+               {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, SignError::Signing(())),
+               }
+
+               match OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign)
+               {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, SignError::Verification(secp256k1::Error::InvalidSignature)),
+               }
+       }
+
+       #[test]
+       fn parses_invoice_with_payment_paths() {
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               if let Err(e) = Invoice::try_from(buffer) {
+                       panic!("error parsing invoice: {:?}", e);
+               }
+
+               let mut tlv_stream = invoice.as_tlv_stream();
+               tlv_stream.3.paths = None;
+
+               match Invoice::try_from(tlv_stream.to_bytes()) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)),
+               }
+
+               let mut tlv_stream = invoice.as_tlv_stream();
+               tlv_stream.3.blindedpay = None;
+
+               match Invoice::try_from(tlv_stream.to_bytes()) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)),
+               }
+
+               let empty_payment_paths = vec![];
+               let mut tlv_stream = invoice.as_tlv_stream();
+               tlv_stream.3.paths = Some(Iterable(empty_payment_paths.iter().map(|(path, _)| path)));
+
+               match Invoice::try_from(tlv_stream.to_bytes()) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)),
+               }
+
+               let mut payment_paths = payment_paths();
+               payment_paths.pop();
+               let mut tlv_stream = invoice.as_tlv_stream();
+               tlv_stream.3.blindedpay = Some(Iterable(payment_paths.iter().map(|(_, payinfo)| payinfo)));
+
+               match Invoice::try_from(tlv_stream.to_bytes()) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)),
+               }
+       }
+
+       #[test]
+       fn parses_invoice_with_created_at() {
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               if let Err(e) = Invoice::try_from(buffer) {
+                       panic!("error parsing invoice: {:?}", e);
+               }
+
+               let mut tlv_stream = invoice.as_tlv_stream();
+               tlv_stream.3.created_at = None;
+
+               match Invoice::try_from(tlv_stream.to_bytes()) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => {
+                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingCreationTime));
+                       },
+               }
+       }
+
+       #[test]
+       fn parses_invoice_with_relative_expiry() {
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .relative_expiry(3600)
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               match Invoice::try_from(buffer) {
+                       Ok(invoice) => assert_eq!(invoice.relative_expiry(), Duration::from_secs(3600)),
+                       Err(e) => panic!("error parsing invoice: {:?}", e),
+               }
+       }
+
+       #[test]
+       fn parses_invoice_with_payment_hash() {
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               if let Err(e) = Invoice::try_from(buffer) {
+                       panic!("error parsing invoice: {:?}", e);
+               }
+
+               let mut tlv_stream = invoice.as_tlv_stream();
+               tlv_stream.3.payment_hash = None;
+
+               match Invoice::try_from(tlv_stream.to_bytes()) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => {
+                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaymentHash));
+                       },
+               }
+       }
+
+       #[test]
+       fn parses_invoice_with_amount() {
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               if let Err(e) = Invoice::try_from(buffer) {
+                       panic!("error parsing invoice: {:?}", e);
+               }
+
+               let mut tlv_stream = invoice.as_tlv_stream();
+               tlv_stream.3.amount = None;
+
+               match Invoice::try_from(tlv_stream.to_bytes()) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingAmount)),
+               }
+       }
+
+       #[test]
+       fn parses_invoice_with_allow_mpp() {
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .allow_mpp()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               match Invoice::try_from(buffer) {
+                       Ok(invoice) => {
+                               let mut features = Bolt12InvoiceFeatures::empty();
+                               features.set_basic_mpp_optional();
+                               assert_eq!(invoice.features(), &features);
+                       },
+                       Err(e) => panic!("error parsing invoice: {:?}", e),
+               }
+       }
+
+       #[test]
+       fn parses_invoice_with_fallback_address() {
+               let script = Script::new();
+               let pubkey = bitcoin::util::key::PublicKey::new(recipient_pubkey());
+               let x_only_pubkey = XOnlyPublicKey::from_keypair(&recipient_keys()).0;
+               let tweaked_pubkey = TweakedPublicKey::dangerous_assume_tweaked(x_only_pubkey);
+
+               let offer = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap();
+               let invoice_request = offer
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap();
+               let mut unsigned_invoice = invoice_request
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .fallback_v0_p2wsh(&script.wscript_hash())
+                       .fallback_v0_p2wpkh(&pubkey.wpubkey_hash().unwrap())
+                       .fallback_v1_p2tr_tweaked(&tweaked_pubkey)
+                       .build().unwrap();
+
+               // Only standard addresses will be included.
+               let fallbacks = unsigned_invoice.invoice.fields_mut().fallbacks.as_mut().unwrap();
+               // Non-standard addresses
+               fallbacks.push(FallbackAddress { version: 1, program: vec![0u8; 41] });
+               fallbacks.push(FallbackAddress { version: 2, program: vec![0u8; 1] });
+               fallbacks.push(FallbackAddress { version: 17, program: vec![0u8; 40] });
+               // Standard address
+               fallbacks.push(FallbackAddress { version: 1, program: vec![0u8; 33] });
+               fallbacks.push(FallbackAddress { version: 2, program: vec![0u8; 40] });
+
+               let invoice = unsigned_invoice.sign(recipient_sign).unwrap();
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               match Invoice::try_from(buffer) {
+                       Ok(invoice) => {
+                               assert_eq!(
+                                       invoice.fallbacks(),
+                                       vec![
+                                               Address::p2wsh(&script, Network::Bitcoin),
+                                               Address::p2wpkh(&pubkey, Network::Bitcoin).unwrap(),
+                                               Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin),
+                                               Address {
+                                                       payload: Payload::WitnessProgram {
+                                                               version: WitnessVersion::V1,
+                                                               program: vec![0u8; 33],
+                                                       },
+                                                       network: Network::Bitcoin,
+                                               },
+                                               Address {
+                                                       payload: Payload::WitnessProgram {
+                                                               version: WitnessVersion::V2,
+                                                               program: vec![0u8; 40],
+                                                       },
+                                                       network: Network::Bitcoin,
+                                               },
+                                       ],
+                               );
+                       },
+                       Err(e) => panic!("error parsing invoice: {:?}", e),
+               }
+       }
+
+       #[test]
+       fn parses_invoice_with_node_id() {
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               if let Err(e) = Invoice::try_from(buffer) {
+                       panic!("error parsing invoice: {:?}", e);
+               }
+
+               let mut tlv_stream = invoice.as_tlv_stream();
+               tlv_stream.3.node_id = None;
+
+               match Invoice::try_from(tlv_stream.to_bytes()) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => {
+                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey));
+                       },
+               }
+
+               let invalid_pubkey = payer_pubkey();
+               let mut tlv_stream = invoice.as_tlv_stream();
+               tlv_stream.3.node_id = Some(&invalid_pubkey);
+
+               match Invoice::try_from(tlv_stream.to_bytes()) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => {
+                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidSigningPubkey));
+                       },
+               }
+       }
+
+       #[test]
+       fn fails_parsing_invoice_without_signature() {
+               let mut buffer = Vec::new();
+               OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .invoice
+                       .write(&mut buffer).unwrap();
+
+               match Invoice::try_from(buffer) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSignature)),
+               }
+       }
+
+       #[test]
+       fn fails_parsing_invoice_with_invalid_signature() {
+               let mut invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+               let last_signature_byte = invoice.bytes.last_mut().unwrap();
+               *last_signature_byte = last_signature_byte.wrapping_add(1);
+
+               let mut buffer = Vec::new();
+               invoice.write(&mut buffer).unwrap();
+
+               match Invoice::try_from(buffer) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => {
+                               assert_eq!(e, ParseError::InvalidSignature(secp256k1::Error::InvalidSignature));
+                       },
+               }
+       }
+
+       #[test]
+       fn fails_parsing_invoice_with_extra_tlv_records() {
+               let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build().unwrap()
+                       .sign(payer_sign).unwrap()
+                       .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
+                       .build().unwrap()
+                       .sign(recipient_sign).unwrap();
+
+               let mut encoded_invoice = Vec::new();
+               invoice.write(&mut encoded_invoice).unwrap();
+               BigSize(1002).write(&mut encoded_invoice).unwrap();
+               BigSize(32).write(&mut encoded_invoice).unwrap();
+               [42u8; 32].write(&mut encoded_invoice).unwrap();
+
+               match Invoice::try_from(encoded_invoice) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, ParseError::Decode(DecodeError::InvalidValue)),
+               }
+       }
+}
index fd5ecda558af523f1664452f98968edef311da9c..a1a0520c62259409b4cd516ed9607eb17bad3296 100644 (file)
 //!
 //! An [`InvoiceRequest`] can be built from a parsed [`Offer`] as an "offer to be paid". It is
 //! typically constructed by a customer and sent to the merchant who had published the corresponding
-//! offer. The recipient of the request responds with an `Invoice`.
+//! offer. The recipient of the request responds with an [`Invoice`].
 //!
 //! For an "offer for money" (e.g., refund, ATM withdrawal), where an offer doesn't exist as a
 //! precursor, see [`Refund`].
 //!
+//! [`Invoice`]: crate::offers::invoice::Invoice
 //! [`Refund`]: crate::offers::refund::Refund
 //!
-//! ```ignore
+//! ```
 //! extern crate bitcoin;
 //! extern crate lightning;
 //!
@@ -57,12 +58,15 @@ use bitcoin::secp256k1::{Message, PublicKey};
 use bitcoin::secp256k1::schnorr::Signature;
 use core::convert::TryFrom;
 use crate::io;
+use crate::ln::PaymentHash;
 use crate::ln::features::InvoiceRequestFeatures;
 use crate::ln::msgs::DecodeError;
+use crate::offers::invoice::{BlindedPayInfo, InvoiceBuilder};
 use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, self};
 use crate::offers::offer::{Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef};
 use crate::offers::parse::{ParseError, ParsedMessage, SemanticError};
 use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef};
+use crate::onion_message::BlindedPath;
 use crate::util::ser::{HighZeroBytesDroppedBigSize, SeekReadable, WithoutLength, Writeable, Writer};
 use crate::util::string::PrintableString;
 
@@ -239,24 +243,27 @@ impl<'a> UnsignedInvoiceRequest<'a> {
        }
 }
 
-/// An `InvoiceRequest` is a request for an `Invoice` formulated from an [`Offer`].
+/// An `InvoiceRequest` is a request for an [`Invoice`] formulated from an [`Offer`].
 ///
 /// An offer may provide choices such as quantity, amount, chain, features, etc. An invoice request
 /// specifies these such that its recipient can send an invoice for payment.
 ///
+/// [`Invoice`]: crate::offers::invoice::Invoice
 /// [`Offer`]: crate::offers::offer::Offer
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq)]
 pub struct InvoiceRequest {
        pub(super) bytes: Vec<u8>,
-       contents: InvoiceRequestContents,
+       pub(super) contents: InvoiceRequestContents,
        signature: Signature,
 }
 
-/// The contents of an [`InvoiceRequest`], which may be shared with an `Invoice`.
-#[derive(Clone, Debug)]
+/// The contents of an [`InvoiceRequest`], which may be shared with an [`Invoice`].
+///
+/// [`Invoice`]: crate::offers::invoice::Invoice
+#[derive(Clone, Debug, PartialEq)]
 pub(super) struct InvoiceRequestContents {
        payer: PayerContents,
-       offer: OfferContents,
+       pub(super) offer: OfferContents,
        chain: Option<ChainHash>,
        amount_msats: Option<u64>,
        features: InvoiceRequestFeatures,
@@ -315,6 +322,54 @@ impl InvoiceRequest {
                self.signature
        }
 
+       /// Creates an [`Invoice`] for the request with the given required fields and using the
+       /// [`Duration`] since [`std::time::SystemTime::UNIX_EPOCH`] as the creation time.
+       ///
+       /// See [`InvoiceRequest::respond_with_no_std`] for further details where the aforementioned
+       /// creation time is used for the `created_at` parameter.
+       ///
+       /// [`Invoice`]: crate::offers::invoice::Invoice
+       /// [`Duration`]: core::time::Duration
+       #[cfg(feature = "std")]
+       pub fn respond_with(
+               &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash
+       ) -> Result<InvoiceBuilder, SemanticError> {
+               let created_at = std::time::SystemTime::now()
+                       .duration_since(std::time::SystemTime::UNIX_EPOCH)
+                       .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
+
+               self.respond_with_no_std(payment_paths, payment_hash, created_at)
+       }
+
+       /// Creates an [`Invoice`] for the request with the given required fields.
+       ///
+       /// Unless [`InvoiceBuilder::relative_expiry`] is set, the invoice will expire two hours after
+       /// `created_at`, which is used to set [`Invoice::created_at`]. Useful for `no-std` builds where
+       /// [`std::time::SystemTime`] is not available.
+       ///
+       /// The caller is expected to remember the preimage of `payment_hash` in order to claim a payment
+       /// for the invoice.
+       ///
+       /// The `payment_paths` parameter is useful for maintaining the payment recipient's privacy. It
+       /// must contain one or more elements ordered from most-preferred to least-preferred, if there's
+       /// a preference. Note, however, that any privacy is lost if a public node id was used for
+       /// [`Offer::signing_pubkey`].
+       ///
+       /// Errors if the request contains unknown required features.
+       ///
+       /// [`Invoice`]: crate::offers::invoice::Invoice
+       /// [`Invoice::created_at`]: crate::offers::invoice::Invoice::created_at
+       pub fn respond_with_no_std(
+               &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
+               created_at: core::time::Duration
+       ) -> Result<InvoiceBuilder, SemanticError> {
+               if self.features().requires_unknown_bits() {
+                       return Err(SemanticError::UnknownRequiredFeatures);
+               }
+
+               InvoiceBuilder::for_offer(self, payment_paths, created_at, payment_hash)
+       }
+
        #[cfg(test)]
        fn as_tlv_stream(&self) -> FullInvoiceRequestTlvStreamRef {
                let (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream) =
@@ -327,7 +382,7 @@ impl InvoiceRequest {
 }
 
 impl InvoiceRequestContents {
-       fn chain(&self) -> ChainHash {
+       pub(super) fn chain(&self) -> ChainHash {
                self.chain.unwrap_or_else(|| self.offer.implied_chain())
        }
 
@@ -773,6 +828,18 @@ mod tests {
                        Ok(_) => panic!("expected error"),
                        Err(e) => assert_eq!(e, SemanticError::MissingAmount),
                }
+
+               match OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .supported_quantity(Quantity::Unbounded)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .quantity(u64::max_value()).unwrap()
+                       .build()
+               {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, SemanticError::InvalidAmount),
+               }
        }
 
        #[test]
@@ -803,11 +870,12 @@ mod tests {
 
        #[test]
        fn builds_invoice_request_with_quantity() {
+               let one = NonZeroU64::new(1).unwrap();
                let ten = NonZeroU64::new(10).unwrap();
 
                let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
                        .amount_msats(1000)
-                       .supported_quantity(Quantity::one())
+                       .supported_quantity(Quantity::One)
                        .build().unwrap()
                        .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
                        .build().unwrap()
@@ -818,7 +886,7 @@ mod tests {
 
                match OfferBuilder::new("foo".into(), recipient_pubkey())
                        .amount_msats(1000)
-                       .supported_quantity(Quantity::one())
+                       .supported_quantity(Quantity::One)
                        .build().unwrap()
                        .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
                        .amount_msats(2_000).unwrap()
@@ -876,6 +944,17 @@ mod tests {
                        Ok(_) => panic!("expected error"),
                        Err(e) => assert_eq!(e, SemanticError::MissingQuantity),
                }
+
+               match OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .supported_quantity(Quantity::Bounded(one))
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build()
+               {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, SemanticError::MissingQuantity),
+               }
        }
 
        #[test]
@@ -1056,15 +1135,33 @@ mod tests {
                                assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnsupportedCurrency));
                        },
                }
+
+               let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .supported_quantity(Quantity::Unbounded)
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .quantity(u64::max_value()).unwrap()
+                       .build_unchecked()
+                       .sign(payer_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice_request.write(&mut buffer).unwrap();
+
+               match InvoiceRequest::try_from(buffer) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidAmount)),
+               }
        }
 
        #[test]
        fn parses_invoice_request_with_quantity() {
+               let one = NonZeroU64::new(1).unwrap();
                let ten = NonZeroU64::new(10).unwrap();
 
                let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
                        .amount_msats(1000)
-                       .supported_quantity(Quantity::one())
+                       .supported_quantity(Quantity::One)
                        .build().unwrap()
                        .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
                        .build().unwrap()
@@ -1079,7 +1176,7 @@ mod tests {
 
                let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
                        .amount_msats(1000)
-                       .supported_quantity(Quantity::one())
+                       .supported_quantity(Quantity::One)
                        .build().unwrap()
                        .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
                        .amount_msats(2_000).unwrap()
@@ -1164,6 +1261,22 @@ mod tests {
                        Ok(_) => panic!("expected error"),
                        Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingQuantity)),
                }
+
+               let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
+                       .amount_msats(1000)
+                       .supported_quantity(Quantity::Bounded(one))
+                       .build().unwrap()
+                       .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
+                       .build_unchecked()
+                       .sign(payer_sign).unwrap();
+
+               let mut buffer = Vec::new();
+               invoice_request.write(&mut buffer).unwrap();
+
+               match InvoiceRequest::try_from(buffer) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingQuantity)),
+               }
        }
 
        #[test]
index 57e7fe6833c2fd7eac8f4ec6125a0e0b2bc58039..9782dc7d1e84131f1d6e659dce2d28ac7e9de6f0 100644 (file)
@@ -13,7 +13,7 @@ use bitcoin::hashes::{Hash, HashEngine, sha256};
 use bitcoin::secp256k1::{Message, PublicKey, Secp256k1, self};
 use bitcoin::secp256k1::schnorr::Signature;
 use crate::io;
-use crate::util::ser::{BigSize, Readable};
+use crate::util::ser::{BigSize, Readable, Writeable, Writer};
 
 use crate::prelude::*;
 
@@ -75,22 +75,21 @@ fn message_digest(tag: &str, bytes: &[u8]) -> Message {
 /// Computes a merkle root hash for the given data, which must be a well-formed TLV stream
 /// containing at least one TLV record.
 fn root_hash(data: &[u8]) -> sha256::Hash {
-       let mut tlv_stream = TlvStream::new(&data[..]).peekable();
        let nonce_tag = tagged_hash_engine(sha256::Hash::from_engine({
+               let first_tlv_record = TlvStream::new(&data[..]).next().unwrap();
                let mut engine = sha256::Hash::engine();
                engine.input("LnNonce".as_bytes());
-               engine.input(tlv_stream.peek().unwrap().record_bytes);
+               engine.input(first_tlv_record.record_bytes);
                engine
        }));
        let leaf_tag = tagged_hash_engine(sha256::Hash::hash("LnLeaf".as_bytes()));
        let branch_tag = tagged_hash_engine(sha256::Hash::hash("LnBranch".as_bytes()));
 
        let mut leaves = Vec::new();
-       for record in tlv_stream {
-               if !SIGNATURE_TYPES.contains(&record.r#type) {
-                       leaves.push(tagged_hash_from_engine(leaf_tag.clone(), &record));
-                       leaves.push(tagged_hash_from_engine(nonce_tag.clone(), &record.type_bytes));
-               }
+       let tlv_stream = TlvStream::new(&data[..]);
+       for record in tlv_stream.skip_signatures() {
+               leaves.push(tagged_hash_from_engine(leaf_tag.clone(), &record.record_bytes));
+               leaves.push(tagged_hash_from_engine(nonce_tag.clone(), &record.type_bytes));
        }
 
        // Calculate the merkle root hash in place.
@@ -154,6 +153,10 @@ impl<'a> TlvStream<'a> {
                        data: io::Cursor::new(data),
                }
        }
+
+       fn skip_signatures(self) -> core::iter::Filter<TlvStream<'a>, fn(&TlvRecord) -> bool> {
+               self.filter(|record| !SIGNATURE_TYPES.contains(&record.r#type))
+       }
 }
 
 /// A slice into a [`TlvStream`] for a record.
@@ -164,10 +167,6 @@ struct TlvRecord<'a> {
        record_bytes: &'a [u8],
 }
 
-impl AsRef<[u8]> for TlvRecord<'_> {
-       fn as_ref(&self) -> &[u8] { &self.record_bytes }
-}
-
 impl<'a> Iterator for TlvStream<'a> {
        type Item = TlvRecord<'a>;
 
@@ -195,14 +194,33 @@ impl<'a> Iterator for TlvStream<'a> {
        }
 }
 
+/// Encoding for a pre-serialized TLV stream that excludes any signature TLV records.
+///
+/// Panics if the wrapped bytes are not a well-formed TLV stream.
+pub(super) struct WithoutSignatures<'a>(pub &'a Vec<u8>);
+
+impl<'a> Writeable for WithoutSignatures<'a> {
+       #[inline]
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               let tlv_stream = TlvStream::new(&self.0[..]);
+               for record in tlv_stream.skip_signatures() {
+                       writer.write_all(record.record_bytes)?;
+               }
+               Ok(())
+       }
+}
+
 #[cfg(test)]
 mod tests {
+       use super::{TlvStream, WithoutSignatures};
+
        use bitcoin::hashes::{Hash, sha256};
        use bitcoin::secp256k1::{KeyPair, Secp256k1, SecretKey};
        use core::convert::Infallible;
        use crate::offers::offer::{Amount, OfferBuilder};
        use crate::offers::invoice_request::InvoiceRequest;
        use crate::offers::parse::Bech32Encode;
+       use crate::util::ser::Writeable;
 
        #[test]
        fn calculates_merkle_root_hash() {
@@ -254,6 +272,36 @@ mod tests {
                );
        }
 
+       #[test]
+       fn skips_encoding_signature_tlv_records() {
+               let secp_ctx = Secp256k1::new();
+               let recipient_pubkey = {
+                       let secret_key = SecretKey::from_slice(&[41; 32]).unwrap();
+                       KeyPair::from_secret_key(&secp_ctx, &secret_key).public_key()
+               };
+               let payer_keys = {
+                       let secret_key = SecretKey::from_slice(&[42; 32]).unwrap();
+                       KeyPair::from_secret_key(&secp_ctx, &secret_key)
+               };
+
+               let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey)
+                       .amount_msats(100)
+                       .build_unchecked()
+                       .request_invoice(vec![0; 8], payer_keys.public_key()).unwrap()
+                       .build_unchecked()
+                       .sign::<_, Infallible>(|digest| Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &payer_keys)))
+                       .unwrap();
+
+               let mut bytes_without_signature = Vec::new();
+               WithoutSignatures(&invoice_request.bytes).write(&mut bytes_without_signature).unwrap();
+
+               assert_ne!(bytes_without_signature, invoice_request.bytes);
+               assert_eq!(
+                       TlvStream::new(&bytes_without_signature).count(),
+                       TlvStream::new(&invoice_request.bytes).count() - 1,
+               );
+       }
+
        impl AsRef<[u8]> for InvoiceRequest {
                fn as_ref(&self) -> &[u8] {
                        &self.bytes
index 11df5ca1f8a108457fe1df9864ec8c0a916fdbe8..2da6fac08ff929e788af18ad1b8970ad71388730 100644 (file)
@@ -12,6 +12,7 @@
 //!
 //! Offers are a flexible protocol for Lightning payments.
 
+pub mod invoice;
 pub mod invoice_request;
 mod merkle;
 pub mod offer;
index e655004460024acd7afe2971bc9556392c405a0b..405e2e278d8073eac345a801f88906422989f173 100644 (file)
@@ -13,7 +13,7 @@
 //! published as a QR code to be scanned by a customer. The customer uses the offer to request an
 //! invoice from the merchant to be paid.
 //!
-//! ```ignore
+//! ```
 //! extern crate bitcoin;
 //! extern crate core;
 //! extern crate lightning;
@@ -106,7 +106,7 @@ impl OfferBuilder {
                let offer = OfferContents {
                        chains: None, metadata: None, amount: None, description,
                        features: OfferFeatures::empty(), absolute_expiry: None, issuer: None, paths: None,
-                       supported_quantity: Quantity::one(), signing_pubkey,
+                       supported_quantity: Quantity::One, signing_pubkey,
                };
                OfferBuilder { offer }
        }
@@ -178,7 +178,7 @@ impl OfferBuilder {
        }
 
        /// Sets the quantity of items for [`Offer::supported_quantity`]. If not called, defaults to
-       /// [`Quantity::one`].
+       /// [`Quantity::One`].
        ///
        /// Successive calls to this method will override the previous setting.
        pub fn supported_quantity(mut self, quantity: Quantity) -> Self {
@@ -232,7 +232,7 @@ impl OfferBuilder {
 /// An `Offer` is a potentially long-lived proposal for payment of a good or service.
 ///
 /// An offer is a precursor to an [`InvoiceRequest`]. A merchant publishes an offer from which a
-/// customer may request an `Invoice` for a specific quantity and using an amount sufficient to
+/// customer may request an [`Invoice`] for a specific quantity and using an amount sufficient to
 /// cover that quantity (i.e., at least `quantity * amount`). See [`Offer::amount`].
 ///
 /// Offers may be denominated in currency other than bitcoin but are ultimately paid using the
@@ -241,7 +241,8 @@ impl OfferBuilder {
 /// Through the use of [`BlindedPath`]s, offers provide recipient privacy.
 ///
 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
-#[derive(Clone, Debug)]
+/// [`Invoice`]: crate::offers::invoice::Invoice
+#[derive(Clone, Debug, PartialEq)]
 pub struct Offer {
        // The serialized offer. Needed when creating an `InvoiceRequest` if the offer contains unknown
        // fields.
@@ -249,10 +250,11 @@ pub struct Offer {
        pub(super) contents: OfferContents,
 }
 
-/// The contents of an [`Offer`], which may be shared with an [`InvoiceRequest`] or an `Invoice`.
+/// The contents of an [`Offer`], which may be shared with an [`InvoiceRequest`] or an [`Invoice`].
 ///
 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
-#[derive(Clone, Debug)]
+/// [`Invoice`]: crate::offers::invoice::Invoice
+#[derive(Clone, Debug, PartialEq)]
 pub(super) struct OfferContents {
        chains: Option<Vec<ChainHash>>,
        metadata: Option<Vec<u8>>,
@@ -319,13 +321,7 @@ impl Offer {
        /// Whether the offer has expired.
        #[cfg(feature = "std")]
        pub fn is_expired(&self) -> bool {
-               match self.absolute_expiry() {
-                       Some(seconds_from_epoch) => match SystemTime::UNIX_EPOCH.elapsed() {
-                               Ok(elapsed) => elapsed > seconds_from_epoch,
-                               Err(_) => false,
-                       },
-                       None => false,
-               }
+               self.contents.is_expired()
        }
 
        /// The issuer of the offer, possibly beginning with `user@domain` or `domain`. Intended to be
@@ -359,7 +355,7 @@ impl Offer {
 
        /// The public key used by the recipient to sign invoices.
        pub fn signing_pubkey(&self) -> PublicKey {
-               self.contents.signing_pubkey
+               self.contents.signing_pubkey()
        }
 
        /// Creates an [`InvoiceRequest`] for the offer with the given `metadata` and `payer_id`, which
@@ -410,6 +406,17 @@ impl OfferContents {
                self.chains().contains(&chain)
        }
 
+       #[cfg(feature = "std")]
+       pub(super) fn is_expired(&self) -> bool {
+               match self.absolute_expiry {
+                       Some(seconds_from_epoch) => match SystemTime::UNIX_EPOCH.elapsed() {
+                               Ok(elapsed) => elapsed > seconds_from_epoch,
+                               Err(_) => false,
+                       },
+                       None => false,
+               }
+       }
+
        pub fn amount(&self) -> Option<&Amount> {
                self.amount.as_ref()
        }
@@ -424,7 +431,8 @@ impl OfferContents {
                };
 
                if !self.expects_quantity() || quantity.is_some() {
-                       let expected_amount_msats = offer_amount_msats * quantity.unwrap_or(1);
+                       let expected_amount_msats = offer_amount_msats.checked_mul(quantity.unwrap_or(1))
+                               .ok_or(SemanticError::InvalidAmount)?;
                        let amount_msats = amount_msats.unwrap_or(expected_amount_msats);
 
                        if amount_msats < expected_amount_msats {
@@ -457,22 +465,24 @@ impl OfferContents {
 
        fn is_valid_quantity(&self, quantity: u64) -> bool {
                match self.supported_quantity {
-                       Quantity::Bounded(n) => {
-                               let n = n.get();
-                               if n == 1 { false }
-                               else { quantity > 0 && quantity <= n }
-                       },
+                       Quantity::Bounded(n) => quantity <= n.get(),
                        Quantity::Unbounded => quantity > 0,
+                       Quantity::One => quantity == 1,
                }
        }
 
        fn expects_quantity(&self) -> bool {
                match self.supported_quantity {
-                       Quantity::Bounded(n) => n.get() != 1,
+                       Quantity::Bounded(_) => true,
                        Quantity::Unbounded => true,
+                       Quantity::One => false,
                }
        }
 
+       pub(super) fn signing_pubkey(&self) -> PublicKey {
+               self.signing_pubkey
+       }
+
        pub(super) fn as_tlv_stream(&self) -> OfferTlvStreamRef {
                let (currency, amount) = match &self.amount {
                        None => (None, None),
@@ -538,25 +548,24 @@ pub type CurrencyCode = [u8; 3];
 /// Quantity of items supported by an [`Offer`].
 #[derive(Clone, Copy, Debug, PartialEq)]
 pub enum Quantity {
-       /// Up to a specific number of items (inclusive).
+       /// Up to a specific number of items (inclusive). Use when more than one item can be requested
+       /// but is limited (e.g., because of per customer or inventory limits).
+       ///
+       /// May be used with `NonZeroU64::new(1)` but prefer to use [`Quantity::One`] if only one item
+       /// is supported.
        Bounded(NonZeroU64),
-       /// One or more items.
+       /// One or more items. Use when more than one item can be requested without any limit.
        Unbounded,
+       /// Only one item. Use when only a single item can be requested.
+       One,
 }
 
 impl Quantity {
-       /// The default quantity of one.
-       pub fn one() -> Self {
-               Quantity::Bounded(NonZeroU64::new(1).unwrap())
-       }
-
        fn to_tlv_record(&self) -> Option<u64> {
                match self {
-                       Quantity::Bounded(n) => {
-                               let n = n.get();
-                               if n == 1 { None } else { Some(n) }
-                       },
+                       Quantity::Bounded(n) => Some(n.get()),
                        Quantity::Unbounded => Some(0),
+                       Quantity::One => None,
                }
        }
 }
@@ -628,9 +637,8 @@ impl TryFrom<OfferTlvStream> for OfferContents {
                        .map(|seconds_from_epoch| Duration::from_secs(seconds_from_epoch));
 
                let supported_quantity = match quantity_max {
-                       None => Quantity::one(),
+                       None => Quantity::One,
                        Some(0) => Quantity::Unbounded,
-                       Some(1) => return Err(SemanticError::InvalidQuantity),
                        Some(n) => Quantity::Bounded(NonZeroU64::new(n).unwrap()),
                };
 
@@ -697,7 +705,7 @@ mod tests {
                assert!(!offer.is_expired());
                assert_eq!(offer.paths(), &[]);
                assert_eq!(offer.issuer(), None);
-               assert_eq!(offer.supported_quantity(), Quantity::one());
+               assert_eq!(offer.supported_quantity(), Quantity::One);
                assert_eq!(offer.signing_pubkey(), pubkey(42));
 
                assert_eq!(
@@ -919,14 +927,15 @@ mod tests {
 
        #[test]
        fn builds_offer_with_supported_quantity() {
+               let one = NonZeroU64::new(1).unwrap();
                let ten = NonZeroU64::new(10).unwrap();
 
                let offer = OfferBuilder::new("foo".into(), pubkey(42))
-                       .supported_quantity(Quantity::one())
+                       .supported_quantity(Quantity::One)
                        .build()
                        .unwrap();
                let tlv_stream = offer.as_tlv_stream();
-               assert_eq!(offer.supported_quantity(), Quantity::one());
+               assert_eq!(offer.supported_quantity(), Quantity::One);
                assert_eq!(tlv_stream.quantity_max, None);
 
                let offer = OfferBuilder::new("foo".into(), pubkey(42))
@@ -945,13 +954,21 @@ mod tests {
                assert_eq!(offer.supported_quantity(), Quantity::Bounded(ten));
                assert_eq!(tlv_stream.quantity_max, Some(10));
 
+               let offer = OfferBuilder::new("foo".into(), pubkey(42))
+                       .supported_quantity(Quantity::Bounded(one))
+                       .build()
+                       .unwrap();
+               let tlv_stream = offer.as_tlv_stream();
+               assert_eq!(offer.supported_quantity(), Quantity::Bounded(one));
+               assert_eq!(tlv_stream.quantity_max, Some(1));
+
                let offer = OfferBuilder::new("foo".into(), pubkey(42))
                        .supported_quantity(Quantity::Bounded(ten))
-                       .supported_quantity(Quantity::one())
+                       .supported_quantity(Quantity::One)
                        .build()
                        .unwrap();
                let tlv_stream = offer.as_tlv_stream();
-               assert_eq!(offer.supported_quantity(), Quantity::one());
+               assert_eq!(offer.supported_quantity(), Quantity::One);
                assert_eq!(tlv_stream.quantity_max, None);
        }
 
@@ -1083,7 +1100,7 @@ mod tests {
        #[test]
        fn parses_offer_with_quantity() {
                let offer = OfferBuilder::new("foo".into(), pubkey(42))
-                       .supported_quantity(Quantity::one())
+                       .supported_quantity(Quantity::One)
                        .build()
                        .unwrap();
                if let Err(e) = offer.to_string().parse::<Offer>() {
@@ -1106,17 +1123,12 @@ mod tests {
                        panic!("error parsing offer: {:?}", e);
                }
 
-               let mut tlv_stream = offer.as_tlv_stream();
-               tlv_stream.quantity_max = Some(1);
-
-               let mut encoded_offer = Vec::new();
-               tlv_stream.write(&mut encoded_offer).unwrap();
-
-               match Offer::try_from(encoded_offer) {
-                       Ok(_) => panic!("expected error"),
-                       Err(e) => {
-                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidQuantity));
-                       },
+               let offer = OfferBuilder::new("foo".into(), pubkey(42))
+                       .supported_quantity(Quantity::Bounded(NonZeroU64::new(1).unwrap()))
+                       .build()
+                       .unwrap();
+               if let Err(e) = offer.to_string().parse::<Offer>() {
+                       panic!("error parsing offer: {:?}", e);
                }
        }
 
index deada66b05c2549ad29ca2b77459e6c6779b0346..6afd4d68fef385bb5b6b77b8375891e53878f6e7 100644 (file)
 //! Parsing and formatting for bech32 message encoding.
 
 use bitcoin::bech32;
-use bitcoin::bech32::{FromBase32, ToBase32};
 use bitcoin::secp256k1;
 use core::convert::TryFrom;
-use core::fmt;
 use crate::io;
 use crate::ln::msgs::DecodeError;
 use crate::util::ser::SeekReadable;
 
 use crate::prelude::*;
 
-/// Indicates a message can be encoded using bech32.
-pub(super) trait Bech32Encode: AsRef<[u8]> + TryFrom<Vec<u8>, Error=ParseError> {
-       /// Human readable part of the message's bech32 encoding.
-       const BECH32_HRP: &'static str;
-
-       /// Parses a bech32-encoded message into a TLV stream.
-       fn from_bech32_str(s: &str) -> Result<Self, ParseError> {
-               // Offer encoding may be split by '+' followed by optional whitespace.
-               let encoded = match s.split('+').skip(1).next() {
-                       Some(_) => {
-                               for chunk in s.split('+') {
-                                       let chunk = chunk.trim_start();
-                                       if chunk.is_empty() || chunk.contains(char::is_whitespace) {
-                                               return Err(ParseError::InvalidContinuation);
+#[cfg(not(fuzzing))]
+pub(super) use sealed::Bech32Encode;
+
+#[cfg(fuzzing)]
+pub use sealed::Bech32Encode;
+
+mod sealed {
+       use bitcoin::bech32;
+       use bitcoin::bech32::{FromBase32, ToBase32};
+       use core::convert::TryFrom;
+       use core::fmt;
+       use super::ParseError;
+
+       use crate::prelude::*;
+
+       /// Indicates a message can be encoded using bech32.
+       pub trait Bech32Encode: AsRef<[u8]> + TryFrom<Vec<u8>, Error=ParseError> {
+               /// Human readable part of the message's bech32 encoding.
+               const BECH32_HRP: &'static str;
+
+               /// Parses a bech32-encoded message into a TLV stream.
+               fn from_bech32_str(s: &str) -> Result<Self, ParseError> {
+                       // Offer encoding may be split by '+' followed by optional whitespace.
+                       let encoded = match s.split('+').skip(1).next() {
+                               Some(_) => {
+                                       for chunk in s.split('+') {
+                                               let chunk = chunk.trim_start();
+                                               if chunk.is_empty() || chunk.contains(char::is_whitespace) {
+                                                       return Err(ParseError::InvalidContinuation);
+                                               }
                                        }
-                               }
 
-                               let s = s.chars().filter(|c| *c != '+' && !c.is_whitespace()).collect::<String>();
-                               Bech32String::Owned(s)
-                       },
-                       None => Bech32String::Borrowed(s),
-               };
+                                       let s: String = s.chars().filter(|c| *c != '+' && !c.is_whitespace()).collect();
+                                       Bech32String::Owned(s)
+                               },
+                               None => Bech32String::Borrowed(s),
+                       };
 
-               let (hrp, data) = bech32::decode_without_checksum(encoded.as_ref())?;
+                       let (hrp, data) = bech32::decode_without_checksum(encoded.as_ref())?;
 
-               if hrp != Self::BECH32_HRP {
-                       return Err(ParseError::InvalidBech32Hrp);
-               }
+                       if hrp != Self::BECH32_HRP {
+                               return Err(ParseError::InvalidBech32Hrp);
+                       }
 
-               let data = Vec::<u8>::from_base32(&data)?;
-               Self::try_from(data)
-       }
+                       let data = Vec::<u8>::from_base32(&data)?;
+                       Self::try_from(data)
+               }
 
-       /// Formats the message using bech32-encoding.
-       fn fmt_bech32_str(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-               bech32::encode_without_checksum_to_fmt(f, Self::BECH32_HRP, self.as_ref().to_base32())
-                       .expect("HRP is invalid").unwrap();
+               /// Formats the message using bech32-encoding.
+               fn fmt_bech32_str(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+                       bech32::encode_without_checksum_to_fmt(f, Self::BECH32_HRP, self.as_ref().to_base32())
+                               .expect("HRP is invalid").unwrap();
 
-               Ok(())
+                       Ok(())
+               }
        }
-}
 
-// Used to avoid copying a bech32 string not containing the continuation character (+).
-enum Bech32String<'a> {
-       Borrowed(&'a str),
-       Owned(String),
-}
+       // Used to avoid copying a bech32 string not containing the continuation character (+).
+       enum Bech32String<'a> {
+               Borrowed(&'a str),
+               Owned(String),
+       }
 
-impl<'a> AsRef<str> for Bech32String<'a> {
-       fn as_ref(&self) -> &str {
-               match self {
-                       Bech32String::Borrowed(s) => s,
-                       Bech32String::Owned(s) => s,
+       impl<'a> AsRef<str> for Bech32String<'a> {
+               fn as_ref(&self) -> &str {
+                       match self {
+                               Bech32String::Borrowed(s) => s,
+                               Bech32String::Owned(s) => s,
+                       }
                }
        }
 }
@@ -147,6 +161,8 @@ pub enum SemanticError {
        MissingDescription,
        /// A signing pubkey was not provided.
        MissingSigningPubkey,
+       /// A signing pubkey was provided but a different one was expected.
+       InvalidSigningPubkey,
        /// A signing pubkey was provided but was not expected.
        UnexpectedSigningPubkey,
        /// A quantity was expected but was missing.
@@ -155,10 +171,20 @@ pub enum SemanticError {
        InvalidQuantity,
        /// A quantity or quantity bounds was provided but was not expected.
        UnexpectedQuantity,
+       /// Metadata was provided but was not expected.
+       UnexpectedMetadata,
        /// Payer metadata was expected but was missing.
        MissingPayerMetadata,
        /// A payer id was expected but was missing.
        MissingPayerId,
+       /// Blinded paths were expected but were missing.
+       MissingPaths,
+       /// The blinded payinfo given does not match the number of blinded path hops.
+       InvalidPayInfo,
+       /// An invoice creation time was expected but was missing.
+       MissingCreationTime,
+       /// An invoice payment hash was expected but was missing.
+       MissingPaymentHash,
        /// A signature was expected but was missing.
        MissingSignature,
 }
index e389a8f6d5d5daf36dd8e8c3b259c59438472b95..7e1da769edab6cec527c4de425bb7711fc50fa1f 100644 (file)
@@ -17,7 +17,7 @@ use crate::prelude::*;
 /// [`InvoiceRequest::payer_id`].
 ///
 /// [`InvoiceRequest::payer_id`]: crate::offers::invoice_request::InvoiceRequest::payer_id
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq)]
 pub(super) struct PayerContents(pub Vec<u8>);
 
 tlv_stream!(PayerTlvStream, PayerTlvStreamRef, 0..1, {
index d3798463b440ed6c0bead3034392671aa57b5555..cc0388c0241b5f77a125ab0dabe4da8427504e8f 100644 (file)
 //! Data structures and encoding for refunds.
 //!
 //! A [`Refund`] is an "offer for money" and is typically constructed by a merchant and presented
-//! directly to the customer. The recipient responds with an `Invoice` to be paid.
+//! directly to the customer. The recipient responds with an [`Invoice`] to be paid.
 //!
 //! This is an [`InvoiceRequest`] produced *not* in response to an [`Offer`].
 //!
+//! [`Invoice`]: crate::offers::invoice::Invoice
 //! [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
 //! [`Offer`]: crate::offers::offer::Offer
 //!
-//! ```ignore
+//! ```
 //! extern crate bitcoin;
 //! extern crate core;
 //! extern crate lightning;
@@ -77,8 +78,10 @@ use core::convert::TryFrom;
 use core::str::FromStr;
 use core::time::Duration;
 use crate::io;
+use crate::ln::PaymentHash;
 use crate::ln::features::InvoiceRequestFeatures;
 use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
+use crate::offers::invoice::{BlindedPayInfo, InvoiceBuilder};
 use crate::offers::invoice_request::{InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
 use crate::offers::offer::{OfferTlvStream, OfferTlvStreamRef};
 use crate::offers::parse::{Bech32Encode, ParseError, ParsedMessage, SemanticError};
@@ -115,9 +118,9 @@ impl RefundBuilder {
                }
 
                let refund = RefundContents {
-                       payer: PayerContents(metadata), metadata: None, description, absolute_expiry: None,
-                       issuer: None, paths: None, chain: None, amount_msats,
-                       features: InvoiceRequestFeatures::empty(), payer_id, payer_note: None,
+                       payer: PayerContents(metadata), description, absolute_expiry: None, issuer: None,
+                       paths: None, chain: None, amount_msats, features: InvoiceRequestFeatures::empty(),
+                       quantity: None, payer_id, payer_note: None,
                };
 
                Ok(RefundBuilder { refund })
@@ -159,6 +162,20 @@ impl RefundBuilder {
                self
        }
 
+       /// Sets [`Refund::quantity`] of items. This is purely for informational purposes. It is useful
+       /// when the refund pertains to an [`Invoice`] that paid for more than one item from an
+       /// [`Offer`] as specified by [`InvoiceRequest::quantity`].
+       ///
+       /// Successive calls to this method will override the previous setting.
+       ///
+       /// [`Invoice`]: crate::offers::invoice::Invoice
+       /// [`InvoiceRequest::quantity`]: crate::offers::invoice_request::InvoiceRequest::quantity
+       /// [`Offer`]: crate::offers::offer::Offer
+       pub fn quantity(mut self, quantity: u64) -> Self {
+               self.refund.quantity = Some(quantity);
+               self
+       }
+
        /// Sets the [`Refund::payer_note`].
        ///
        /// Successive calls to this method will override the previous setting.
@@ -191,25 +208,27 @@ impl RefundBuilder {
        }
 }
 
-/// A `Refund` is a request to send an `Invoice` without a preceding [`Offer`].
+/// A `Refund` is a request to send an [`Invoice`] without a preceding [`Offer`].
 ///
 /// Typically, after an invoice is paid, the recipient may publish a refund allowing the sender to
 /// recoup their funds. A refund may be used more generally as an "offer for money", such as with a
 /// bitcoin ATM.
 ///
+/// [`Invoice`]: crate::offers::invoice::Invoice
 /// [`Offer`]: crate::offers::offer::Offer
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq)]
 pub struct Refund {
-       bytes: Vec<u8>,
-       contents: RefundContents,
+       pub(super) bytes: Vec<u8>,
+       pub(super) contents: RefundContents,
 }
 
-/// The contents of a [`Refund`], which may be shared with an `Invoice`.
-#[derive(Clone, Debug)]
-struct RefundContents {
+/// The contents of a [`Refund`], which may be shared with an [`Invoice`].
+///
+/// [`Invoice`]: crate::offers::invoice::Invoice
+#[derive(Clone, Debug, PartialEq)]
+pub(super) struct RefundContents {
        payer: PayerContents,
        // offer fields
-       metadata: Option<Vec<u8>>,
        description: String,
        absolute_expiry: Option<Duration>,
        issuer: Option<String>,
@@ -218,6 +237,7 @@ struct RefundContents {
        chain: Option<ChainHash>,
        amount_msats: u64,
        features: InvoiceRequestFeatures,
+       quantity: Option<u64>,
        payer_id: PublicKey,
        payer_note: Option<String>,
 }
@@ -239,13 +259,7 @@ impl Refund {
        /// Whether the refund has expired.
        #[cfg(feature = "std")]
        pub fn is_expired(&self) -> bool {
-               match self.absolute_expiry() {
-                       Some(seconds_from_epoch) => match SystemTime::UNIX_EPOCH.elapsed() {
-                               Ok(elapsed) => elapsed > seconds_from_epoch,
-                               Err(_) => false,
-                       },
-                       None => false,
-               }
+               self.contents.is_expired()
        }
 
        /// The issuer of the refund, possibly beginning with `user@domain` or `domain`. Intended to be
@@ -285,6 +299,11 @@ impl Refund {
                &self.contents.features
        }
 
+       /// The quantity of an item that refund is for.
+       pub fn quantity(&self) -> Option<u64> {
+               self.contents.quantity
+       }
+
        /// A public node id to send to in the case where there are no [`paths`]. Otherwise, a possibly
        /// transient pubkey.
        ///
@@ -298,6 +317,58 @@ impl Refund {
                self.contents.payer_note.as_ref().map(|payer_note| PrintableString(payer_note.as_str()))
        }
 
+       /// Creates an [`Invoice`] for the refund with the given required fields and using the
+       /// [`Duration`] since [`std::time::SystemTime::UNIX_EPOCH`] as the creation time.
+       ///
+       /// See [`Refund::respond_with_no_std`] for further details where the aforementioned creation
+       /// time is used for the `created_at` parameter.
+       ///
+       /// [`Invoice`]: crate::offers::invoice::Invoice
+       /// [`Duration`]: core::time::Duration
+       #[cfg(feature = "std")]
+       pub fn respond_with(
+               &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
+               signing_pubkey: PublicKey,
+       ) -> Result<InvoiceBuilder, SemanticError> {
+               let created_at = std::time::SystemTime::now()
+                       .duration_since(std::time::SystemTime::UNIX_EPOCH)
+                       .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
+
+               self.respond_with_no_std(payment_paths, payment_hash, signing_pubkey, created_at)
+       }
+
+       /// Creates an [`Invoice`] for the refund with the given required fields.
+       ///
+       /// Unless [`InvoiceBuilder::relative_expiry`] is set, the invoice will expire two hours after
+       /// `created_at`, which is used to set [`Invoice::created_at`]. Useful for `no-std` builds where
+       /// [`std::time::SystemTime`] is not available.
+       ///
+       /// The caller is expected to remember the preimage of `payment_hash` in order to
+       /// claim a payment for the invoice.
+       ///
+       /// The `signing_pubkey` is required to sign the invoice since refunds are not in response to an
+       /// offer, which does have a `signing_pubkey`.
+       ///
+       /// The `payment_paths` parameter is useful for maintaining the payment recipient's privacy. It
+       /// must contain one or more elements ordered from most-preferred to least-preferred, if there's
+       /// a preference. Note, however, that any privacy is lost if a public node id is used for
+       /// `signing_pubkey`.
+       ///
+       /// Errors if the request contains unknown required features.
+       ///
+       /// [`Invoice`]: crate::offers::invoice::Invoice
+       /// [`Invoice::created_at`]: crate::offers::invoice::Invoice::created_at
+       pub fn respond_with_no_std(
+               &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
+               signing_pubkey: PublicKey, created_at: Duration
+       ) -> Result<InvoiceBuilder, SemanticError> {
+               if self.features().requires_unknown_bits() {
+                       return Err(SemanticError::UnknownRequiredFeatures);
+               }
+
+               InvoiceBuilder::for_refund(self, payment_paths, created_at, payment_hash, signing_pubkey)
+       }
+
        #[cfg(test)]
        fn as_tlv_stream(&self) -> RefundTlvStreamRef {
                self.contents.as_tlv_stream()
@@ -311,7 +382,18 @@ impl AsRef<[u8]> for Refund {
 }
 
 impl RefundContents {
-       fn chain(&self) -> ChainHash {
+       #[cfg(feature = "std")]
+       pub(super) fn is_expired(&self) -> bool {
+               match self.absolute_expiry {
+                       Some(seconds_from_epoch) => match SystemTime::UNIX_EPOCH.elapsed() {
+                               Ok(elapsed) => elapsed > seconds_from_epoch,
+                               Err(_) => false,
+                       },
+                       None => false,
+               }
+       }
+
+       pub(super) fn chain(&self) -> ChainHash {
                self.chain.unwrap_or_else(|| self.implied_chain())
        }
 
@@ -326,7 +408,7 @@ impl RefundContents {
 
                let offer = OfferTlvStreamRef {
                        chains: None,
-                       metadata: self.metadata.as_ref(),
+                       metadata: None,
                        currency: None,
                        amount: None,
                        description: Some(&self.description),
@@ -347,7 +429,7 @@ impl RefundContents {
                        chain: self.chain.as_ref(),
                        amount: Some(self.amount_msats),
                        features,
-                       quantity: None,
+                       quantity: self.quantity,
                        payer_id: Some(&self.payer_id),
                        payer_note: self.payer_note.as_ref(),
                };
@@ -428,6 +510,10 @@ impl TryFrom<RefundTlvStream> for RefundContents {
                        Some(metadata) => PayerContents(metadata),
                };
 
+               if metadata.is_some() {
+                       return Err(SemanticError::UnexpectedMetadata);
+               }
+
                if chains.is_some() {
                        return Err(SemanticError::UnexpectedChain);
                }
@@ -465,20 +551,14 @@ impl TryFrom<RefundTlvStream> for RefundContents {
 
                let features = features.unwrap_or_else(InvoiceRequestFeatures::empty);
 
-               // TODO: Check why this isn't in the spec.
-               if quantity.is_some() {
-                       return Err(SemanticError::UnexpectedQuantity);
-               }
-
                let payer_id = match payer_id {
                        None => return Err(SemanticError::MissingPayerId),
                        Some(payer_id) => payer_id,
                };
 
-               // TODO: Should metadata be included?
                Ok(RefundContents {
-                       payer, metadata, description, absolute_expiry, issuer, paths, chain, amount_msats,
-                       features, payer_id, payer_note,
+                       payer, description, absolute_expiry, issuer, paths, chain, amount_msats, features,
+                       quantity, payer_id, payer_note,
                })
        }
 }
@@ -706,6 +786,24 @@ mod tests {
                assert_eq!(tlv_stream.chain, Some(&testnet));
        }
 
+       #[test]
+       fn builds_refund_with_quantity() {
+               let refund = RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()
+                       .quantity(10)
+                       .build().unwrap();
+               let (_, _, tlv_stream) = refund.as_tlv_stream();
+               assert_eq!(refund.quantity(), Some(10));
+               assert_eq!(tlv_stream.quantity, Some(10));
+
+               let refund = RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()
+                       .quantity(10)
+                       .quantity(1)
+                       .build().unwrap();
+               let (_, _, tlv_stream) = refund.as_tlv_stream();
+               assert_eq!(refund.quantity(), Some(1));
+               assert_eq!(tlv_stream.quantity, Some(1));
+       }
+
        #[test]
        fn builds_refund_with_payer_note() {
                let refund = RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()
@@ -839,6 +937,7 @@ mod tests {
                        .path(paths[1].clone())
                        .chain(Network::Testnet)
                        .features_unchecked(InvoiceRequestFeatures::unknown())
+                       .quantity(10)
                        .payer_note("baz".into())
                        .build()
                        .unwrap();
@@ -851,6 +950,7 @@ mod tests {
                                assert_eq!(refund.issuer(), Some(PrintableString("bar")));
                                assert_eq!(refund.chain(), ChainHash::using_genesis_block(Network::Testnet));
                                assert_eq!(refund.features(), &InvoiceRequestFeatures::unknown());
+                               assert_eq!(refund.quantity(), Some(10));
                                assert_eq!(refund.payer_note(), Some(PrintableString("baz")));
                        },
                        Err(e) => panic!("error parsing refund: {:?}", e),
@@ -865,6 +965,17 @@ mod tests {
                        panic!("error parsing refund: {:?}", e);
                }
 
+               let metadata = vec![42; 32];
+               let mut tlv_stream = refund.as_tlv_stream();
+               tlv_stream.1.metadata = Some(&metadata);
+
+               match Refund::try_from(tlv_stream.to_bytes()) {
+                       Ok(_) => panic!("expected error"),
+                       Err(e) => {
+                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnexpectedMetadata));
+                       },
+               }
+
                let chains = vec![ChainHash::using_genesis_block(Network::Testnet)];
                let mut tlv_stream = refund.as_tlv_stream();
                tlv_stream.1.chains = Some(&chains);
@@ -918,16 +1029,6 @@ mod tests {
                                assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnexpectedSigningPubkey));
                        },
                }
-
-               let mut tlv_stream = refund.as_tlv_stream();
-               tlv_stream.2.quantity = Some(10);
-
-               match Refund::try_from(tlv_stream.to_bytes()) {
-                       Ok(_) => panic!("expected error"),
-                       Err(e) => {
-                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnexpectedQuantity));
-                       },
-               }
        }
 
        #[test]
index 49949bc0d5895fdf2b123f59e9f44e7c647c24b4..946e5e7cf8d74472e9fa56a719f2a8dd5e426ba5 100644 (file)
@@ -13,7 +13,7 @@ use bitcoin::hashes::{Hash, HashEngine};
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
 
-use crate::chain::keysinterface::{KeysInterface, NodeSigner, Recipient};
+use crate::chain::keysinterface::{EntropySource, NodeSigner, Recipient};
 use super::packet::ControlTlvs;
 use super::utils;
 use crate::ln::msgs::DecodeError;
@@ -63,11 +63,11 @@ impl BlindedPath {
        ///
        /// Errors if less than two hops are provided or if `node_pk`(s) are invalid.
        //  TODO: make all payloads the same size with padding + add dummy hops
-       pub fn new<K: KeysInterface, T: secp256k1::Signing + secp256k1::Verification>
-               (node_pks: &[PublicKey], keys_manager: &K, secp_ctx: &Secp256k1<T>) -> Result<Self, ()>
+       pub fn new<ES: EntropySource, T: secp256k1::Signing + secp256k1::Verification>
+               (node_pks: &[PublicKey], entropy_source: &ES, secp_ctx: &Secp256k1<T>) -> Result<Self, ()>
        {
                if node_pks.len() < 2 { return Err(()) }
-               let blinding_secret_bytes = keys_manager.get_secure_random_bytes();
+               let blinding_secret_bytes = entropy_source.get_secure_random_bytes();
                let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
                let introduction_node_id = node_pks[0];
 
@@ -79,11 +79,11 @@ impl BlindedPath {
        }
 
        // Advance the blinded path by one hop, so make the second hop into the new introduction node.
-       pub(super) fn advance_by_one<K: Deref, T: secp256k1::Signing + secp256k1::Verification>
-               (&mut self, keys_manager: &K, secp_ctx: &Secp256k1<T>) -> Result<(), ()>
-               where K::Target: KeysInterface
+       pub(super) fn advance_by_one<NS: Deref, T: secp256k1::Signing + secp256k1::Verification>
+               (&mut self, node_signer: &NS, secp_ctx: &Secp256k1<T>) -> Result<(), ()>
+               where NS::Target: NodeSigner
        {
-               let control_tlvs_ss = keys_manager.ecdh(Recipient::Node, &self.blinding_point, None)?;
+               let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &self.blinding_point, None)?;
                let rho = onion_utils::gen_rho_from_shared_secret(&control_tlvs_ss.secret_bytes());
                let encrypted_control_tlvs = self.blinded_hops.remove(0).encrypted_payload;
                let mut s = Cursor::new(&encrypted_control_tlvs);
index 7fc225cbc9c6fc30e25453ae3c0993af57ef4137..aee7f562defc5915517d696cf032353deee4e3d6 100644 (file)
@@ -9,7 +9,7 @@
 
 //! Onion message testing and test utilities live here.
 
-use crate::chain::keysinterface::{KeysInterface, NodeSigner, Recipient};
+use crate::chain::keysinterface::{NodeSigner, Recipient};
 use crate::ln::features::InitFeatures;
 use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
 use super::{BlindedPath, CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError};
@@ -24,14 +24,13 @@ use crate::sync::Arc;
 
 struct MessengerNode {
        keys_manager: Arc<test_utils::TestKeysInterface>,
-       messenger: OnionMessenger<Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestLogger>, Arc<TestCustomMessageHandler>>,
+       messenger: OnionMessenger<Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestLogger>, Arc<TestCustomMessageHandler>>,
        logger: Arc<test_utils::TestLogger>,
 }
 
 impl MessengerNode {
        fn get_node_pk(&self) -> PublicKey {
-               let secp_ctx = Secp256k1::new();
-               PublicKey::from_secret_key(&secp_ctx, &self.keys_manager.get_node_secret(Recipient::Node).unwrap())
+               self.keys_manager.get_node_id(Recipient::Node).unwrap()
        }
 }
 
@@ -77,7 +76,7 @@ fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
                let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet));
                nodes.push(MessengerNode {
                        keys_manager: keys_manager.clone(),
-                       messenger: OnionMessenger::new(keys_manager, logger.clone(), Arc::new(TestCustomMessageHandler {})),
+                       messenger: OnionMessenger::new(keys_manager.clone(), keys_manager.clone(), logger.clone(), Arc::new(TestCustomMessageHandler {})),
                        logger,
                });
        }
@@ -86,8 +85,8 @@ fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
                let mut features = InitFeatures::empty();
                features.set_onion_messages_optional();
                let init_msg = msgs::Init { features, remote_network_address: None };
-               nodes[i].messenger.peer_connected(&nodes[i + 1].get_node_pk(), &init_msg.clone()).unwrap();
-               nodes[i + 1].messenger.peer_connected(&nodes[i].get_node_pk(), &init_msg.clone()).unwrap();
+               nodes[i].messenger.peer_connected(&nodes[i + 1].get_node_pk(), &init_msg.clone(), true).unwrap();
+               nodes[i + 1].messenger.peer_connected(&nodes[i].get_node_pk(), &init_msg.clone(), false).unwrap();
        }
        nodes
 }
index d9d6070ae058c7f0041901b6e0e0eae4f89e3a6b..7814ccb6508c77a10abfa32ee189914493a62278 100644 (file)
@@ -15,7 +15,7 @@ use bitcoin::hashes::hmac::{Hmac, HmacEngine};
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
 
-use crate::chain::keysinterface::{EntropySource, KeysInterface, KeysManager, NodeSigner, Recipient};
+use crate::chain::keysinterface::{EntropySource, KeysManager, NodeSigner, Recipient};
 use crate::ln::features::{InitFeatures, NodeFeatures};
 use crate::ln::msgs::{self, OnionMessageHandler};
 use crate::ln::onion_utils;
@@ -43,15 +43,14 @@ use crate::prelude::*;
 /// # extern crate bitcoin;
 /// # use bitcoin::hashes::_export::_core::time::Duration;
 /// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
-/// # use lightning::chain::keysinterface::{InMemorySigner, KeysManager, KeysInterface};
-/// # use lightning::ln::msgs::DecodeError;
+/// # use lightning::chain::keysinterface::KeysManager;
 /// # use lightning::ln::peer_handler::IgnoringMessageHandler;
 /// # use lightning::onion_message::{BlindedPath, CustomOnionMessageContents, Destination, OnionMessageContents, OnionMessenger};
 /// # use lightning::util::logger::{Logger, Record};
 /// # use lightning::util::ser::{Writeable, Writer};
 /// # use lightning::io;
 /// # use std::sync::Arc;
-/// # struct FakeLogger {};
+/// # struct FakeLogger;
 /// # impl Logger for FakeLogger {
 /// #     fn log(&self, record: &Record) { unimplemented!() }
 /// # }
@@ -67,7 +66,7 @@ use crate::prelude::*;
 /// # let your_custom_message_handler = IgnoringMessageHandler {};
 /// // Create the onion messenger. This must use the same `keys_manager` as is passed to your
 /// // ChannelManager.
-/// let onion_messenger = OnionMessenger::new(&keys_manager, logger, your_custom_message_handler);
+/// let onion_messenger = OnionMessenger::new(&keys_manager, &keys_manager, logger, &your_custom_message_handler);
 ///
 /// # struct YourCustomMessage {}
 /// impl Writeable for YourCustomMessage {
@@ -104,12 +103,14 @@ use crate::prelude::*;
 ///
 /// [offers]: <https://github.com/lightning/bolts/pull/798>
 /// [`OnionMessenger`]: crate::onion_message::OnionMessenger
-pub struct OnionMessenger<K: Deref, L: Deref, CMH: Deref>
-       where K::Target: KeysInterface,
-             L::Target: Logger,
-             CMH:: Target: CustomOnionMessageHandler,
+pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, CMH: Deref>
+       where ES::Target: EntropySource,
+                 NS::Target: NodeSigner,
+                 L::Target: Logger,
+                 CMH:: Target: CustomOnionMessageHandler,
 {
-       keys_manager: K,
+       entropy_source: ES,
+       node_signer: NS,
        logger: L,
        pending_messages: Mutex<HashMap<PublicKey, VecDeque<msgs::OnionMessage>>>,
        secp_ctx: Secp256k1<secp256k1::All>,
@@ -154,9 +155,9 @@ pub enum SendError {
        InvalidMessage,
        /// Our next-hop peer's buffer was full or our total outbound buffer was full.
        BufferFull,
-       /// Failed to retrieve our node id from the provided [`KeysInterface`].
+       /// Failed to retrieve our node id from the provided [`NodeSigner`].
        ///
-       /// [`KeysInterface`]: crate::chain::keysinterface::KeysInterface
+       /// [`NodeSigner`]: crate::chain::keysinterface::NodeSigner
        GetNodeIdFailed,
        /// We attempted to send to a blinded path where we are the introduction node, and failed to
        /// advance the blinded path to make the second hop the new introduction node. Either
@@ -186,18 +187,20 @@ pub trait CustomOnionMessageHandler {
        fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError>;
 }
 
-impl<K: Deref, L: Deref, CMH: Deref> OnionMessenger<K, L, CMH>
-       where K::Target: KeysInterface,
-             L::Target: Logger,
-             CMH::Target: CustomOnionMessageHandler,
+impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessenger<ES, NS, L, CMH>
+       where ES::Target: EntropySource,
+                 NS::Target: NodeSigner,
+                 L::Target: Logger,
+                 CMH::Target: CustomOnionMessageHandler,
 {
        /// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
        /// their respective handlers.
-       pub fn new(keys_manager: K, logger: L, custom_handler: CMH) -> Self {
+       pub fn new(entropy_source: ES, node_signer: NS, logger: L, custom_handler: CMH) -> Self {
                let mut secp_ctx = Secp256k1::new();
-               secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
+               secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
                OnionMessenger {
-                       keys_manager,
+                       entropy_source,
+                       node_signer,
                        pending_messages: Mutex::new(HashMap::new()),
                        secp_ctx,
                        logger,
@@ -220,16 +223,16 @@ impl<K: Deref, L: Deref, CMH: Deref> OnionMessenger<K, L, CMH>
                // advance the blinded path by 1 hop so the second hop is the new introduction node.
                if intermediate_nodes.len() == 0 {
                        if let Destination::BlindedPath(ref mut blinded_path) = destination {
-                               let our_node_id = self.keys_manager.get_node_id(Recipient::Node)
+                               let our_node_id = self.node_signer.get_node_id(Recipient::Node)
                                        .map_err(|()| SendError::GetNodeIdFailed)?;
                                if blinded_path.introduction_node_id == our_node_id {
-                                       blinded_path.advance_by_one(&self.keys_manager, &self.secp_ctx)
+                                       blinded_path.advance_by_one(&self.node_signer, &self.secp_ctx)
                                                .map_err(|()| SendError::BlindedPathAdvanceFailed)?;
                                }
                        }
                }
 
-               let blinding_secret_bytes = self.keys_manager.get_secure_random_bytes();
+               let blinding_secret_bytes = self.entropy_source.get_secure_random_bytes();
                let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
                let (introduction_node_id, blinding_point) = if intermediate_nodes.len() != 0 {
                        (intermediate_nodes[0], PublicKey::from_secret_key(&self.secp_ctx, &blinding_secret))
@@ -244,7 +247,7 @@ impl<K: Deref, L: Deref, CMH: Deref> OnionMessenger<K, L, CMH>
                        &self.secp_ctx, intermediate_nodes, destination, message, reply_path, &blinding_secret)
                        .map_err(|e| SendError::Secp256k1(e))?;
 
-               let prng_seed = self.keys_manager.get_secure_random_bytes();
+               let prng_seed = self.entropy_source.get_secure_random_bytes();
                let onion_routing_packet = construct_onion_message_packet(
                        packet_payloads, packet_keys, prng_seed).map_err(|()| SendError::TooBigPacket)?;
 
@@ -295,16 +298,17 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap<PublicKey, Ve
        false
 }
 
-impl<K: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMessenger<K, L, CMH>
-       where K::Target: KeysInterface,
-             L::Target: Logger,
-             CMH::Target: CustomOnionMessageHandler + Sized,
+impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMessenger<ES, NS, L, CMH>
+       where ES::Target: EntropySource,
+                 NS::Target: NodeSigner,
+                 L::Target: Logger,
+                 CMH::Target: CustomOnionMessageHandler + Sized,
 {
        /// Handle an incoming onion message. Currently, if a message was destined for us we will log, but
        /// soon we'll delegate the onion message to a handler that can generate invoices or send
        /// payments.
        fn handle_onion_message(&self, _peer_node_id: &PublicKey, msg: &msgs::OnionMessage) {
-               let control_tlvs_ss = match self.keys_manager.ecdh(Recipient::Node, &msg.blinding_point, None) {
+               let control_tlvs_ss = match self.node_signer.ecdh(Recipient::Node, &msg.blinding_point, None) {
                        Ok(ss) => ss,
                        Err(e) =>  {
                                log_error!(self.logger, "Failed to retrieve node secret: {:?}", e);
@@ -317,7 +321,7 @@ impl<K: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMessenger<K, L
                                hmac.input(control_tlvs_ss.as_ref());
                                Hmac::from_engine(hmac).into_inner()
                        };
-                       match self.keys_manager.ecdh(Recipient::Node, &msg.onion_routing_packet.public_key,
+                       match self.node_signer.ecdh(Recipient::Node, &msg.onion_routing_packet.public_key,
                                Some(&Scalar::from_be_bytes(blinding_factor).unwrap()))
                        {
                                Ok(ss) => ss.secret_bytes(),
@@ -413,7 +417,7 @@ impl<K: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMessenger<K, L
                };
        }
 
-       fn peer_connected(&self, their_node_id: &PublicKey, init: &msgs::Init) -> Result<(), ()> {
+       fn peer_connected(&self, their_node_id: &PublicKey, init: &msgs::Init, _inbound: bool) -> Result<(), ()> {
                if init.features.supports_onion_messages() {
                        let mut peers = self.pending_messages.lock().unwrap();
                        peers.insert(their_node_id.clone(), VecDeque::new());
@@ -421,7 +425,7 @@ impl<K: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMessenger<K, L
                Ok(())
        }
 
-       fn peer_disconnected(&self, their_node_id: &PublicKey, _no_connection_possible: bool) {
+       fn peer_disconnected(&self, their_node_id: &PublicKey) {
                let mut pending_msgs = self.pending_messages.lock().unwrap();
                pending_msgs.remove(their_node_id);
        }
@@ -439,10 +443,11 @@ impl<K: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMessenger<K, L
        }
 }
 
-impl<K: Deref, L: Deref, CMH: Deref> OnionMessageProvider for OnionMessenger<K, L, CMH>
-       where K::Target: KeysInterface,
-             L::Target: Logger,
-             CMH::Target: CustomOnionMessageHandler,
+impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageProvider for OnionMessenger<ES, NS, L, CMH>
+       where ES::Target: EntropySource,
+                 NS::Target: NodeSigner,
+                 L::Target: Logger,
+                 CMH::Target: CustomOnionMessageHandler,
 {
        fn next_onion_message_for_peer(&self, peer_node_id: PublicKey) -> Option<msgs::OnionMessage> {
                let mut pending_msgs = self.pending_messages.lock().unwrap();
@@ -462,7 +467,7 @@ impl<K: Deref, L: Deref, CMH: Deref> OnionMessageProvider for OnionMessenger<K,
 ///
 /// [`SimpleArcChannelManager`]: crate::ln::channelmanager::SimpleArcChannelManager
 /// [`SimpleArcPeerManager`]: crate::ln::peer_handler::SimpleArcPeerManager
-pub type SimpleArcOnionMessenger<L> = OnionMessenger<Arc<KeysManager>, Arc<L>, IgnoringMessageHandler>;
+pub type SimpleArcOnionMessenger<L> = OnionMessenger<Arc<KeysManager>, Arc<KeysManager>, Arc<L>, IgnoringMessageHandler>;
 /// Useful for simplifying the parameters of [`SimpleRefChannelManager`] and
 /// [`SimpleRefPeerManager`]. See their docs for more details.
 ///
@@ -470,7 +475,7 @@ pub type SimpleArcOnionMessenger<L> = OnionMessenger<Arc<KeysManager>, Arc<L>, I
 ///
 /// [`SimpleRefChannelManager`]: crate::ln::channelmanager::SimpleRefChannelManager
 /// [`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager
-pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<&'a KeysManager, &'b L, IgnoringMessageHandler>;
+pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<&'a KeysManager, &'a KeysManager, &'b L, IgnoringMessageHandler>;
 
 /// Construct onion packet payloads and keys for sending an onion message along the given
 /// `unblinded_path` to the given `destination`.
index 5ff226387107ae23f839dc376d1db15d73c8a345..27c329335c358c0956e4ed09e03447ec96a1ed57 100644 (file)
@@ -166,14 +166,14 @@ impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                match &self.0 {
                        Payload::Forward(ForwardControlTlvs::Blinded(encrypted_bytes)) => {
-                               encode_varint_length_prefixed_tlv!(w, {
+                               _encode_varint_length_prefixed_tlv!(w, {
                                        (4, *encrypted_bytes, vec_type)
                                })
                        },
                        Payload::Receive {
                                control_tlvs: ReceiveControlTlvs::Blinded(encrypted_bytes), reply_path, message,
                        } => {
-                               encode_varint_length_prefixed_tlv!(w, {
+                               _encode_varint_length_prefixed_tlv!(w, {
                                        (2, reply_path, option),
                                        (4, *encrypted_bytes, vec_type),
                                        (message.tlv_type(), message, required)
@@ -181,7 +181,7 @@ impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
                        },
                        Payload::Forward(ForwardControlTlvs::Unblinded(control_tlvs)) => {
                                let write_adapter = ChaChaPolyWriteAdapter::new(self.1, &control_tlvs);
-                               encode_varint_length_prefixed_tlv!(w, {
+                               _encode_varint_length_prefixed_tlv!(w, {
                                        (4, write_adapter, required)
                                })
                        },
@@ -189,7 +189,7 @@ impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
                                control_tlvs: ReceiveControlTlvs::Unblinded(control_tlvs), reply_path, message,
                        } => {
                                let write_adapter = ChaChaPolyWriteAdapter::new(self.1, &control_tlvs);
-                               encode_varint_length_prefixed_tlv!(w, {
+                               _encode_varint_length_prefixed_tlv!(w, {
                                        (2, reply_path, option),
                                        (4, write_adapter, required),
                                        (message.tlv_type(), message, required)
@@ -212,7 +212,7 @@ impl<H: CustomOnionMessageHandler> ReadableArgs<(SharedSecret, &H)> for Payload<
                let rho = onion_utils::gen_rho_from_shared_secret(&encrypted_tlvs_ss.secret_bytes());
                let mut message_type: Option<u64> = None;
                let mut message = None;
-               decode_tlv_stream!(&mut rd, {
+               decode_tlv_stream_with_custom_tlv_decode!(&mut rd, {
                        (2, reply_path, option),
                        (4, read_adapter, (option: LengthReadableArgs, rho)),
                }, |msg_type, msg_reader| {
index 947df9edae0f2b3a166e96ff704c9c5775e7da8e..3f9313c686aab4bd1454f8b8bda84f762afee36a 100644 (file)
@@ -7,7 +7,7 @@
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
-//! The top-level network map tracking logic lives here.
+//! The [`NetworkGraph`] stores the network gossip and [`P2PGossipSync`] fetches it from peers
 
 use bitcoin::secp256k1::constants::PUBLIC_KEY_SIZE;
 use bitcoin::secp256k1::PublicKey;
@@ -16,34 +16,33 @@ use bitcoin::secp256k1;
 
 use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hashes::Hash;
-use bitcoin::blockdata::transaction::TxOut;
 use bitcoin::hash_types::BlockHash;
 
-use crate::chain;
-use crate::chain::Access;
-use crate::ln::chan_utils::make_funding_redeemscript;
+use bitcoin::network::constants::Network;
+use bitcoin::blockdata::constants::genesis_block;
+
 use crate::ln::features::{ChannelFeatures, NodeFeatures, InitFeatures};
 use crate::ln::msgs::{DecodeError, ErrorAction, Init, LightningError, RoutingMessageHandler, NetAddress, MAX_VALUE_MSAT};
 use crate::ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, GossipTimestampFilter};
 use crate::ln::msgs::{QueryChannelRange, ReplyChannelRange, QueryShortChannelIds, ReplyShortChannelIdsEnd};
 use crate::ln::msgs;
+use crate::routing::utxo::{self, UtxoLookup};
 use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, MaybeReadable};
 use crate::util::logger::{Logger, Level};
 use crate::util::events::{MessageSendEvent, MessageSendEventsProvider};
 use crate::util::scid_utils::{block_from_scid, scid_from_parts, MAX_SCID_BLOCK};
 use crate::util::string::PrintableString;
+use crate::util::indexed_map::{IndexedMap, Entry as IndexedMapEntry};
 
 use crate::io;
 use crate::io_extras::{copy, sink};
 use crate::prelude::*;
-use alloc::collections::{BTreeMap, btree_map::Entry as BtreeEntry};
 use core::{cmp, fmt};
 use crate::sync::{RwLock, RwLockReadGuard};
 #[cfg(feature = "std")]
 use core::sync::atomic::{AtomicUsize, Ordering};
 use crate::sync::Mutex;
 use core::ops::{Bound, Deref};
-use bitcoin::hashes::hex::ToHex;
 
 #[cfg(feature = "std")]
 use std::time::{SystemTime, UNIX_EPOCH};
@@ -84,6 +83,11 @@ impl fmt::Debug for NodeId {
                write!(f, "NodeId({})", log_bytes!(self.0))
        }
 }
+impl fmt::Display for NodeId {
+       fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+               write!(f, "{}", log_bytes!(self.0))
+       }
+}
 
 impl core::hash::Hash for NodeId {
        fn hash<H: core::hash::Hasher>(&self, hasher: &mut H) {
@@ -133,8 +137,8 @@ pub struct NetworkGraph<L: Deref> where L::Target: Logger {
        genesis_hash: BlockHash,
        logger: L,
        // Lock order: channels -> nodes
-       channels: RwLock<BTreeMap<u64, ChannelInfo>>,
-       nodes: RwLock<BTreeMap<NodeId, NodeInfo>>,
+       channels: RwLock<IndexedMap<u64, ChannelInfo>>,
+       nodes: RwLock<IndexedMap<NodeId, NodeInfo>>,
        // Lock order: removed_channels -> removed_nodes
        //
        // NOTE: In the following `removed_*` maps, we use seconds since UNIX epoch to track time instead
@@ -154,12 +158,14 @@ pub struct NetworkGraph<L: Deref> where L::Target: Logger {
        /// resync them from gossip. Each `NodeId` is mapped to the time (in seconds) it was removed so
        /// that once some time passes, we can potentially resync it from gossip again.
        removed_nodes: Mutex<HashMap<NodeId, Option<u64>>>,
+       /// Announcement messages which are awaiting an on-chain lookup to be processed.
+       pub(super) pending_checks: utxo::PendingChecks,
 }
 
 /// A read-only view of [`NetworkGraph`].
 pub struct ReadOnlyNetworkGraph<'a> {
-       channels: RwLockReadGuard<'a, BTreeMap<u64, ChannelInfo>>,
-       nodes: RwLockReadGuard<'a, BTreeMap<NodeId, NodeInfo>>,
+       channels: RwLockReadGuard<'a, IndexedMap<u64, ChannelInfo>>,
+       nodes: RwLockReadGuard<'a, IndexedMap<NodeId, NodeInfo>>,
 }
 
 /// Update to the [`NetworkGraph`] based on payment failure information conveyed via the Onion
@@ -213,31 +219,30 @@ impl_writeable_tlv_based_enum_upgradable!(NetworkUpdate,
 /// This network graph is then used for routing payments.
 /// Provides interface to help with initial routing sync by
 /// serving historical announcements.
-pub struct P2PGossipSync<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref>
-where C::Target: chain::Access, L::Target: Logger
+pub struct P2PGossipSync<G: Deref<Target=NetworkGraph<L>>, U: Deref, L: Deref>
+where U::Target: UtxoLookup, L::Target: Logger
 {
        network_graph: G,
-       chain_access: Option<C>,
+       utxo_lookup: Option<U>,
        #[cfg(feature = "std")]
        full_syncs_requested: AtomicUsize,
        pending_events: Mutex<Vec<MessageSendEvent>>,
        logger: L,
 }
 
-impl<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref> P2PGossipSync<G, C, L>
-where C::Target: chain::Access, L::Target: Logger
+impl<G: Deref<Target=NetworkGraph<L>>, U: Deref, L: Deref> P2PGossipSync<G, U, L>
+where U::Target: UtxoLookup, L::Target: Logger
 {
        /// Creates a new tracker of the actual state of the network of channels and nodes,
        /// assuming an existing Network Graph.
-       /// Chain monitor is used to make sure announced channels exist on-chain,
-       /// channel data is correct, and that the announcement is signed with
-       /// channel owners' keys.
-       pub fn new(network_graph: G, chain_access: Option<C>, logger: L) -> Self {
+       /// UTXO lookup is used to make sure announced channels exist on-chain, channel data is
+       /// correct, and the announcement is signed with channel owners' keys.
+       pub fn new(network_graph: G, utxo_lookup: Option<U>, logger: L) -> Self {
                P2PGossipSync {
                        network_graph,
                        #[cfg(feature = "std")]
                        full_syncs_requested: AtomicUsize::new(0),
-                       chain_access,
+                       utxo_lookup,
                        pending_events: Mutex::new(vec![]),
                        logger,
                }
@@ -246,8 +251,8 @@ where C::Target: chain::Access, L::Target: Logger
        /// Adds a provider used to check new announcements. Does not affect
        /// existing announcements unless they are updated.
        /// Add, update or remove the provider would replace the current one.
-       pub fn add_chain_access(&mut self, chain_access: Option<C>) {
-               self.chain_access = chain_access;
+       pub fn add_utxo_lookup(&mut self, utxo_lookup: Option<U>) {
+               self.utxo_lookup = utxo_lookup;
        }
 
        /// Gets a reference to the underlying [`NetworkGraph`] which was provided in
@@ -270,6 +275,36 @@ where C::Target: chain::Access, L::Target: Logger
                        false
                }
        }
+
+       /// Used to broadcast forward gossip messages which were validated async.
+       ///
+       /// Note that this will ignore events other than `Broadcast*` or messages with too much excess
+       /// data.
+       pub(super) fn forward_gossip_msg(&self, mut ev: MessageSendEvent) {
+               match &mut ev {
+                       MessageSendEvent::BroadcastChannelAnnouncement { msg, ref mut update_msg } => {
+                               if msg.contents.excess_data.len() > MAX_EXCESS_BYTES_FOR_RELAY { return; }
+                               if update_msg.as_ref()
+                                       .map(|msg| msg.contents.excess_data.len()).unwrap_or(0) > MAX_EXCESS_BYTES_FOR_RELAY
+                               {
+                                       *update_msg = None;
+                               }
+                       },
+                       MessageSendEvent::BroadcastChannelUpdate { msg } => {
+                               if msg.contents.excess_data.len() > MAX_EXCESS_BYTES_FOR_RELAY { return; }
+                       },
+                       MessageSendEvent::BroadcastNodeAnnouncement { msg } => {
+                               if msg.contents.excess_data.len() >  MAX_EXCESS_BYTES_FOR_RELAY ||
+                                  msg.contents.excess_address_data.len() > MAX_EXCESS_BYTES_FOR_RELAY ||
+                                  msg.contents.excess_data.len() + msg.contents.excess_address_data.len() > MAX_EXCESS_BYTES_FOR_RELAY
+                               {
+                                       return;
+                               }
+                       },
+                       _ => return,
+               }
+               self.pending_events.lock().unwrap().push(ev);
+       }
 }
 
 impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
@@ -321,8 +356,24 @@ macro_rules! secp_verify_sig {
        };
 }
 
-impl<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref> RoutingMessageHandler for P2PGossipSync<G, C, L>
-where C::Target: chain::Access, L::Target: Logger
+macro_rules! get_pubkey_from_node_id {
+       ( $node_id: expr, $msg_type: expr ) => {
+               PublicKey::from_slice($node_id.as_slice())
+                       .map_err(|_| LightningError {
+                               err: format!("Invalid public key on {} message", $msg_type),
+                               action: ErrorAction::SendWarningMessage {
+                                       msg: msgs::WarningMessage {
+                                               channel_id: [0; 32],
+                                               data: format!("Invalid public key on {} message", $msg_type),
+                                       },
+                                       log_level: Level::Trace
+                               }
+                       })?
+       }
+}
+
+impl<G: Deref<Target=NetworkGraph<L>>, U: Deref, L: Deref> RoutingMessageHandler for P2PGossipSync<G, U, L>
+where U::Target: UtxoLookup, L::Target: Logger
 {
        fn handle_node_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result<bool, LightningError> {
                self.network_graph.update_node_from_announcement(msg)?;
@@ -332,8 +383,7 @@ where C::Target: chain::Access, L::Target: Logger
        }
 
        fn handle_channel_announcement(&self, msg: &msgs::ChannelAnnouncement) -> Result<bool, LightningError> {
-               self.network_graph.update_channel_from_announcement(msg, &self.chain_access)?;
-               log_gossip!(self.logger, "Added channel_announcement for {}{}", msg.contents.short_channel_id, if !msg.contents.excess_data.is_empty() { " with excess uninterpreted data!" } else { "" });
+               self.network_graph.update_channel_from_announcement(msg, &self.utxo_lookup)?;
                Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY)
        }
 
@@ -343,7 +393,7 @@ where C::Target: chain::Access, L::Target: Logger
        }
 
        fn get_next_channel_announcement(&self, starting_point: u64) -> Option<(ChannelAnnouncement, Option<ChannelUpdate>, Option<ChannelUpdate>)> {
-               let channels = self.network_graph.channels.read().unwrap();
+               let mut channels = self.network_graph.channels.write().unwrap();
                for (_, ref chan) in channels.range(starting_point..) {
                        if chan.announcement_message.is_some() {
                                let chan_announcement = chan.announcement_message.clone().unwrap();
@@ -364,10 +414,10 @@ where C::Target: chain::Access, L::Target: Logger
                None
        }
 
-       fn get_next_node_announcement(&self, starting_point: Option<&PublicKey>) -> Option<NodeAnnouncement> {
-               let nodes = self.network_graph.nodes.read().unwrap();
-               let iter = if let Some(pubkey) = starting_point {
-                               nodes.range((Bound::Excluded(NodeId::from_pubkey(pubkey)), Bound::Unbounded))
+       fn get_next_node_announcement(&self, starting_point: Option<&NodeId>) -> Option<NodeAnnouncement> {
+               let mut nodes = self.network_graph.nodes.write().unwrap();
+               let iter = if let Some(node_id) = starting_point {
+                               nodes.range((Bound::Excluded(node_id), Bound::Unbounded))
                        } else {
                                nodes.range(..)
                        };
@@ -390,7 +440,7 @@ where C::Target: chain::Access, L::Target: Logger
        /// to request gossip messages for each channel. The sync is considered complete
        /// when the final reply_scids_end message is received, though we are not
        /// tracking this directly.
-       fn peer_connected(&self, their_node_id: &PublicKey, init_msg: &Init) -> Result<(), ()> {
+       fn peer_connected(&self, their_node_id: &PublicKey, init_msg: &Init, _inbound: bool) -> Result<(), ()> {
                // We will only perform a sync with peers that support gossip_queries.
                if !init_msg.features.supports_gossip_queries() {
                        // Don't disconnect peers for not supporting gossip queries. We may wish to have
@@ -525,7 +575,7 @@ where C::Target: chain::Access, L::Target: Logger
                // (has at least one update). A peer may still want to know the channel
                // exists even if its not yet routable.
                let mut batches: Vec<Vec<u64>> = vec![Vec::with_capacity(MAX_SCIDS_PER_REPLY)];
-               let channels = self.network_graph.channels.read().unwrap();
+               let mut channels = self.network_graph.channels.write().unwrap();
                for (_, ref chan) in channels.range(inclusive_start_scid.unwrap()..exclusive_end_scid.unwrap()) {
                        if let Some(chan_announcement) = &chan.announcement_message {
                                // Construct a new batch if last one is full
@@ -609,11 +659,15 @@ where C::Target: chain::Access, L::Target: Logger
                features.set_gossip_queries_optional();
                features
        }
+
+       fn processing_queue_high(&self) -> bool {
+               self.network_graph.pending_checks.too_many_checks_pending()
+       }
 }
 
-impl<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref> MessageSendEventsProvider for P2PGossipSync<G, C, L>
+impl<G: Deref<Target=NetworkGraph<L>>, U: Deref, L: Deref> MessageSendEventsProvider for P2PGossipSync<G, U, L>
 where
-       C::Target: chain::Access,
+       U::Target: UtxoLookup,
        L::Target: Logger,
 {
        fn get_and_clear_pending_msg_events(&self) -> Vec<MessageSendEvent> {
@@ -673,13 +727,13 @@ impl Writeable for ChannelUpdateInfo {
 
 impl Readable for ChannelUpdateInfo {
        fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
-               init_tlv_field_var!(last_update, required);
-               init_tlv_field_var!(enabled, required);
-               init_tlv_field_var!(cltv_expiry_delta, required);
-               init_tlv_field_var!(htlc_minimum_msat, required);
-               init_tlv_field_var!(htlc_maximum_msat, option);
-               init_tlv_field_var!(fees, required);
-               init_tlv_field_var!(last_update_message, required);
+               _init_tlv_field_var!(last_update, required);
+               _init_tlv_field_var!(enabled, required);
+               _init_tlv_field_var!(cltv_expiry_delta, required);
+               _init_tlv_field_var!(htlc_minimum_msat, required);
+               _init_tlv_field_var!(htlc_maximum_msat, option);
+               _init_tlv_field_var!(fees, required);
+               _init_tlv_field_var!(last_update_message, required);
 
                read_tlv_fields!(reader, {
                        (0, last_update, required),
@@ -693,13 +747,13 @@ impl Readable for ChannelUpdateInfo {
 
                if let Some(htlc_maximum_msat) = htlc_maximum_msat {
                        Ok(ChannelUpdateInfo {
-                               last_update: init_tlv_based_struct_field!(last_update, required),
-                               enabled: init_tlv_based_struct_field!(enabled, required),
-                               cltv_expiry_delta: init_tlv_based_struct_field!(cltv_expiry_delta, required),
-                               htlc_minimum_msat: init_tlv_based_struct_field!(htlc_minimum_msat, required),
+                               last_update: _init_tlv_based_struct_field!(last_update, required),
+                               enabled: _init_tlv_based_struct_field!(enabled, required),
+                               cltv_expiry_delta: _init_tlv_based_struct_field!(cltv_expiry_delta, required),
+                               htlc_minimum_msat: _init_tlv_based_struct_field!(htlc_minimum_msat, required),
                                htlc_maximum_msat,
-                               fees: init_tlv_based_struct_field!(fees, required),
-                               last_update_message: init_tlv_based_struct_field!(last_update_message, required),
+                               fees: _init_tlv_based_struct_field!(fees, required),
+                               last_update_message: _init_tlv_based_struct_field!(last_update_message, required),
                        })
                } else {
                        Err(DecodeError::InvalidValue)
@@ -820,34 +874,34 @@ impl MaybeReadable for ChannelUpdateInfoDeserWrapper {
 
 impl Readable for ChannelInfo {
        fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
-               init_tlv_field_var!(features, required);
-               init_tlv_field_var!(announcement_received_time, (default_value, 0));
-               init_tlv_field_var!(node_one, required);
+               _init_tlv_field_var!(features, required);
+               _init_tlv_field_var!(announcement_received_time, (default_value, 0));
+               _init_tlv_field_var!(node_one, required);
                let mut one_to_two_wrap: Option<ChannelUpdateInfoDeserWrapper> = None;
-               init_tlv_field_var!(node_two, required);
+               _init_tlv_field_var!(node_two, required);
                let mut two_to_one_wrap: Option<ChannelUpdateInfoDeserWrapper> = None;
-               init_tlv_field_var!(capacity_sats, required);
-               init_tlv_field_var!(announcement_message, required);
+               _init_tlv_field_var!(capacity_sats, required);
+               _init_tlv_field_var!(announcement_message, required);
                read_tlv_fields!(reader, {
                        (0, features, required),
                        (1, announcement_received_time, (default_value, 0)),
                        (2, node_one, required),
-                       (4, one_to_two_wrap, ignorable),
+                       (4, one_to_two_wrap, upgradable_option),
                        (6, node_two, required),
-                       (8, two_to_one_wrap, ignorable),
+                       (8, two_to_one_wrap, upgradable_option),
                        (10, capacity_sats, required),
                        (12, announcement_message, required),
                });
 
                Ok(ChannelInfo {
-                       features: init_tlv_based_struct_field!(features, required),
-                       node_one: init_tlv_based_struct_field!(node_one, required),
+                       features: _init_tlv_based_struct_field!(features, required),
+                       node_one: _init_tlv_based_struct_field!(node_one, required),
                        one_to_two: one_to_two_wrap.map(|w| w.0).unwrap_or(None),
-                       node_two: init_tlv_based_struct_field!(node_two, required),
+                       node_two: _init_tlv_based_struct_field!(node_two, required),
                        two_to_one: two_to_one_wrap.map(|w| w.0).unwrap_or(None),
-                       capacity_sats: init_tlv_based_struct_field!(capacity_sats, required),
-                       announcement_message: init_tlv_based_struct_field!(announcement_message, required),
-                       announcement_received_time: init_tlv_based_struct_field!(announcement_received_time, (default_value, 0)),
+                       capacity_sats: _init_tlv_based_struct_field!(capacity_sats, required),
+                       announcement_message: _init_tlv_based_struct_field!(announcement_message, required),
+                       announcement_received_time: _init_tlv_based_struct_field!(announcement_received_time, (default_value, 0)),
                })
        }
 }
@@ -917,7 +971,7 @@ impl<'a> fmt::Debug for DirectedChannelInfo<'a> {
 ///
 /// While this may be smaller than the actual channel capacity, amounts greater than
 /// [`Self::as_msat`] should not be routed through the channel.
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Copy, Debug, PartialEq)]
 pub enum EffectiveCapacity {
        /// The available liquidity in the channel known from being a channel counterparty, and thus a
        /// direct hop.
@@ -966,7 +1020,7 @@ impl EffectiveCapacity {
 /// Fees for routing via a given channel or a node
 #[derive(Eq, PartialEq, Copy, Clone, Debug, Hash)]
 pub struct RoutingFees {
-       /// Flat routing fee in satoshis
+       /// Flat routing fee in millisatoshis.
        pub base_msat: u32,
        /// Liquidity-based routing fee in millionths of a routed amount.
        /// In other words, 10000 is 1%.
@@ -1054,10 +1108,6 @@ impl Readable for NodeAlias {
 pub struct NodeInfo {
        /// All valid channels a node has announced
        pub channels: Vec<u64>,
-       /// Lowest fees enabling routing via any of the enabled, known channels to a node.
-       /// The two fields (flat and proportional fee) are independent,
-       /// meaning they don't have to refer to the same channel.
-       pub lowest_inbound_channel_fees: Option<RoutingFees>,
        /// More information about a node from node_announcement.
        /// Optional because we store a Node entry after learning about it from
        /// a channel announcement, but before receiving a node announcement.
@@ -1066,8 +1116,8 @@ pub struct NodeInfo {
 
 impl fmt::Display for NodeInfo {
        fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-               write!(f, "lowest_inbound_channel_fees: {:?}, channels: {:?}, announcement_info: {:?}",
-                  self.lowest_inbound_channel_fees, &self.channels[..], self.announcement_info)?;
+               write!(f, " channels: {:?}, announcement_info: {:?}",
+                       &self.channels[..], self.announcement_info)?;
                Ok(())
        }
 }
@@ -1075,7 +1125,7 @@ impl fmt::Display for NodeInfo {
 impl Writeable for NodeInfo {
        fn write<W: crate::util::ser::Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                write_tlv_fields!(writer, {
-                       (0, self.lowest_inbound_channel_fees, option),
+                       // Note that older versions of LDK wrote the lowest inbound fees here at type 0
                        (2, self.announcement_info, option),
                        (4, self.channels, vec_type),
                });
@@ -1103,20 +1153,24 @@ impl MaybeReadable for NodeAnnouncementInfoDeserWrapper {
 
 impl Readable for NodeInfo {
        fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
-               init_tlv_field_var!(lowest_inbound_channel_fees, option);
+               // Historically, we tracked the lowest inbound fees for any node in order to use it as an
+               // A* heuristic when routing. Sadly, these days many, many nodes have at least one channel
+               // with zero inbound fees, causing that heuristic to provide little gain. Worse, because it
+               // requires additional complexity and lookups during routing, it ends up being a
+               // performance loss. Thus, we simply ignore the old field here and no longer track it.
+               let mut _lowest_inbound_channel_fees: Option<RoutingFees> = None;
                let mut announcement_info_wrap: Option<NodeAnnouncementInfoDeserWrapper> = None;
-               init_tlv_field_var!(channels, vec_type);
+               _init_tlv_field_var!(channels, vec_type);
 
                read_tlv_fields!(reader, {
-                       (0, lowest_inbound_channel_fees, option),
-                       (2, announcement_info_wrap, ignorable),
+                       (0, _lowest_inbound_channel_fees, option),
+                       (2, announcement_info_wrap, upgradable_option),
                        (4, channels, vec_type),
                });
 
                Ok(NodeInfo {
-                       lowest_inbound_channel_fees: init_tlv_based_struct_field!(lowest_inbound_channel_fees, option),
                        announcement_info: announcement_info_wrap.map(|w| w.0),
-                       channels: init_tlv_based_struct_field!(channels, vec_type),
+                       channels: _init_tlv_based_struct_field!(channels, vec_type),
                })
        }
 }
@@ -1131,13 +1185,13 @@ impl<L: Deref> Writeable for NetworkGraph<L> where L::Target: Logger {
                self.genesis_hash.write(writer)?;
                let channels = self.channels.read().unwrap();
                (channels.len() as u64).write(writer)?;
-               for (ref chan_id, ref chan_info) in channels.iter() {
+               for (ref chan_id, ref chan_info) in channels.unordered_iter() {
                        (*chan_id).write(writer)?;
                        chan_info.write(writer)?;
                }
                let nodes = self.nodes.read().unwrap();
                (nodes.len() as u64).write(writer)?;
-               for (ref node_id, ref node_info) in nodes.iter() {
+               for (ref node_id, ref node_info) in nodes.unordered_iter() {
                        node_id.write(writer)?;
                        node_info.write(writer)?;
                }
@@ -1156,14 +1210,14 @@ impl<L: Deref> ReadableArgs<L> for NetworkGraph<L> where L::Target: Logger {
 
                let genesis_hash: BlockHash = Readable::read(reader)?;
                let channels_count: u64 = Readable::read(reader)?;
-               let mut channels = BTreeMap::new();
+               let mut channels = IndexedMap::new();
                for _ in 0..channels_count {
                        let chan_id: u64 = Readable::read(reader)?;
                        let chan_info = Readable::read(reader)?;
                        channels.insert(chan_id, chan_info);
                }
                let nodes_count: u64 = Readable::read(reader)?;
-               let mut nodes = BTreeMap::new();
+               let mut nodes = IndexedMap::new();
                for _ in 0..nodes_count {
                        let node_id = Readable::read(reader)?;
                        let node_info = Readable::read(reader)?;
@@ -1184,6 +1238,7 @@ impl<L: Deref> ReadableArgs<L> for NetworkGraph<L> where L::Target: Logger {
                        last_rapid_gossip_sync_timestamp: Mutex::new(last_rapid_gossip_sync_timestamp),
                        removed_nodes: Mutex::new(HashMap::new()),
                        removed_channels: Mutex::new(HashMap::new()),
+                       pending_checks: utxo::PendingChecks::new(),
                })
        }
 }
@@ -1191,11 +1246,11 @@ impl<L: Deref> ReadableArgs<L> for NetworkGraph<L> where L::Target: Logger {
 impl<L: Deref> fmt::Display for NetworkGraph<L> where L::Target: Logger {
        fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
                writeln!(f, "Network map\n[Channels]")?;
-               for (key, val) in self.channels.read().unwrap().iter() {
+               for (key, val) in self.channels.read().unwrap().unordered_iter() {
                        writeln!(f, " {}: {}", key, val)?;
                }
                writeln!(f, "[Nodes]")?;
-               for (&node_id, val) in self.nodes.read().unwrap().iter() {
+               for (&node_id, val) in self.nodes.read().unwrap().unordered_iter() {
                        writeln!(f, " {}: {}", log_bytes!(node_id.as_slice()), val)?;
                }
                Ok(())
@@ -1213,16 +1268,17 @@ impl<L: Deref> PartialEq for NetworkGraph<L> where L::Target: Logger {
 
 impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
        /// Creates a new, empty, network graph.
-       pub fn new(genesis_hash: BlockHash, logger: L) -> NetworkGraph<L> {
+       pub fn new(network: Network, logger: L) -> NetworkGraph<L> {
                Self {
                        secp_ctx: Secp256k1::verification_only(),
-                       genesis_hash,
+                       genesis_hash: genesis_block(network).header.block_hash(),
                        logger,
-                       channels: RwLock::new(BTreeMap::new()),
-                       nodes: RwLock::new(BTreeMap::new()),
+                       channels: RwLock::new(IndexedMap::new()),
+                       nodes: RwLock::new(IndexedMap::new()),
                        last_rapid_gossip_sync_timestamp: Mutex::new(None),
                        removed_channels: Mutex::new(HashMap::new()),
                        removed_nodes: Mutex::new(HashMap::new()),
+                       pending_checks: utxo::PendingChecks::new(),
                }
        }
 
@@ -1252,7 +1308,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
        /// purposes.
        #[cfg(test)]
        pub fn clear_nodes_announcement_info(&self) {
-               for node in self.nodes.write().unwrap().iter_mut() {
+               for node in self.nodes.write().unwrap().unordered_iter_mut() {
                        node.1.announcement_info = None;
                }
        }
@@ -1265,7 +1321,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
        /// routing messages from a source using a protocol other than the lightning P2P protocol.
        pub fn update_node_from_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result<(), LightningError> {
                let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
-               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.signature, &msg.contents.node_id, "node_announcement");
+               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.signature, &get_pubkey_from_node_id!(msg.contents.node_id, "node_announcement"), "node_announcement");
                self.update_node_from_announcement_intern(&msg.contents, Some(&msg))
        }
 
@@ -1278,8 +1334,13 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
        }
 
        fn update_node_from_announcement_intern(&self, msg: &msgs::UnsignedNodeAnnouncement, full_msg: Option<&msgs::NodeAnnouncement>) -> Result<(), LightningError> {
-               match self.nodes.write().unwrap().get_mut(&NodeId::from_pubkey(&msg.node_id)) {
-                       None => Err(LightningError{err: "No existing channels for node_announcement".to_owned(), action: ErrorAction::IgnoreError}),
+               let mut nodes = self.nodes.write().unwrap();
+               match nodes.get_mut(&msg.node_id) {
+                       None => {
+                               core::mem::drop(nodes);
+                               self.pending_checks.check_hold_pending_node_announcement(msg, full_msg)?;
+                               Err(LightningError{err: "No existing channels for node_announcement".to_owned(), action: ErrorAction::IgnoreError})
+                       },
                        Some(node) => {
                                if let Some(node_info) = node.announcement_info.as_ref() {
                                        // The timestamp field is somewhat of a misnomer - the BOLTs use it to order
@@ -1316,35 +1377,35 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
        /// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept
        /// routing messages from a source using a protocol other than the lightning P2P protocol.
        ///
-       /// If a `chain::Access` object is provided via `chain_access`, it will be called to verify
+       /// If a [`UtxoLookup`] object is provided via `utxo_lookup`, it will be called to verify
        /// the corresponding UTXO exists on chain and is correctly-formatted.
-       pub fn update_channel_from_announcement<C: Deref>(
-               &self, msg: &msgs::ChannelAnnouncement, chain_access: &Option<C>,
+       pub fn update_channel_from_announcement<U: Deref>(
+               &self, msg: &msgs::ChannelAnnouncement, utxo_lookup: &Option<U>,
        ) -> Result<(), LightningError>
        where
-               C::Target: chain::Access,
+               U::Target: UtxoLookup,
        {
                let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
-               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_1, &msg.contents.node_id_1, "channel_announcement");
-               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_2, &msg.contents.node_id_2, "channel_announcement");
-               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.bitcoin_signature_1, &msg.contents.bitcoin_key_1, "channel_announcement");
-               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.bitcoin_signature_2, &msg.contents.bitcoin_key_2, "channel_announcement");
-               self.update_channel_from_unsigned_announcement_intern(&msg.contents, Some(msg), chain_access)
+               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_1, &get_pubkey_from_node_id!(msg.contents.node_id_1, "channel_announcement"), "channel_announcement");
+               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_2, &get_pubkey_from_node_id!(msg.contents.node_id_2, "channel_announcement"), "channel_announcement");
+               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.bitcoin_signature_1, &get_pubkey_from_node_id!(msg.contents.bitcoin_key_1, "channel_announcement"), "channel_announcement");
+               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.bitcoin_signature_2, &get_pubkey_from_node_id!(msg.contents.bitcoin_key_2, "channel_announcement"), "channel_announcement");
+               self.update_channel_from_unsigned_announcement_intern(&msg.contents, Some(msg), utxo_lookup)
        }
 
        /// Store or update channel info from a channel announcement without verifying the associated
        /// signatures. Because we aren't given the associated signatures here we cannot relay the
        /// channel announcement to any of our peers.
        ///
-       /// If a `chain::Access` object is provided via `chain_access`, it will be called to verify
+       /// If a [`UtxoLookup`] object is provided via `utxo_lookup`, it will be called to verify
        /// the corresponding UTXO exists on chain and is correctly-formatted.
-       pub fn update_channel_from_unsigned_announcement<C: Deref>(
-               &self, msg: &msgs::UnsignedChannelAnnouncement, chain_access: &Option<C>
+       pub fn update_channel_from_unsigned_announcement<U: Deref>(
+               &self, msg: &msgs::UnsignedChannelAnnouncement, utxo_lookup: &Option<U>
        ) -> Result<(), LightningError>
        where
-               C::Target: chain::Access,
+               U::Target: UtxoLookup,
        {
-               self.update_channel_from_unsigned_announcement_intern(msg, None, chain_access)
+               self.update_channel_from_unsigned_announcement_intern(msg, None, utxo_lookup)
        }
 
        /// Update channel from partial announcement data received via rapid gossip sync
@@ -1382,7 +1443,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                let node_id_b = channel_info.node_two.clone();
 
                match channels.entry(short_channel_id) {
-                       BtreeEntry::Occupied(mut entry) => {
+                       IndexedMapEntry::Occupied(mut entry) => {
                                //TODO: because asking the blockchain if short_channel_id is valid is only optional
                                //in the blockchain API, we need to handle it smartly here, though it's unclear
                                //exactly how...
@@ -1401,20 +1462,19 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                                        return Err(LightningError{err: "Already have knowledge of channel".to_owned(), action: ErrorAction::IgnoreDuplicateGossip});
                                }
                        },
-                       BtreeEntry::Vacant(entry) => {
+                       IndexedMapEntry::Vacant(entry) => {
                                entry.insert(channel_info);
                        }
                };
 
                for current_node_id in [node_id_a, node_id_b].iter() {
                        match nodes.entry(current_node_id.clone()) {
-                               BtreeEntry::Occupied(node_entry) => {
+                               IndexedMapEntry::Occupied(node_entry) => {
                                        node_entry.into_mut().channels.push(short_channel_id);
                                },
-                               BtreeEntry::Vacant(node_entry) => {
+                               IndexedMapEntry::Vacant(node_entry) => {
                                        node_entry.insert(NodeInfo {
                                                channels: vec!(short_channel_id),
-                                               lowest_inbound_channel_fees: None,
                                                announcement_info: None,
                                        });
                                }
@@ -1424,19 +1484,16 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                Ok(())
        }
 
-       fn update_channel_from_unsigned_announcement_intern<C: Deref>(
-               &self, msg: &msgs::UnsignedChannelAnnouncement, full_msg: Option<&msgs::ChannelAnnouncement>, chain_access: &Option<C>
+       fn update_channel_from_unsigned_announcement_intern<U: Deref>(
+               &self, msg: &msgs::UnsignedChannelAnnouncement, full_msg: Option<&msgs::ChannelAnnouncement>, utxo_lookup: &Option<U>
        ) -> Result<(), LightningError>
        where
-               C::Target: chain::Access,
+               U::Target: UtxoLookup,
        {
                if msg.node_id_1 == msg.node_id_2 || msg.bitcoin_key_1 == msg.bitcoin_key_2 {
                        return Err(LightningError{err: "Channel announcement node had a channel with itself".to_owned(), action: ErrorAction::IgnoreError});
                }
 
-               let node_one = NodeId::from_pubkey(&msg.node_id_1);
-               let node_two = NodeId::from_pubkey(&msg.node_id_2);
-
                {
                        let channels = self.channels.read().unwrap();
 
@@ -1453,13 +1510,13 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                                        // We use the Node IDs rather than the bitcoin_keys to check for "equivalence"
                                        // as we didn't (necessarily) store the bitcoin keys, and we only really care
                                        // if the peers on the channel changed anyway.
-                                       if node_one == chan.node_one && node_two == chan.node_two {
+                                       if msg.node_id_1 == chan.node_one && msg.node_id_2 == chan.node_two {
                                                return Err(LightningError {
                                                        err: "Already have chain-validated channel".to_owned(),
                                                        action: ErrorAction::IgnoreDuplicateGossip
                                                });
                                        }
-                               } else if chain_access.is_none() {
+                               } else if utxo_lookup.is_none() {
                                        // Similarly, if we can't check the chain right now anyway, ignore the
                                        // duplicate announcement without bothering to take the channels write lock.
                                        return Err(LightningError {
@@ -1474,40 +1531,16 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                        let removed_channels = self.removed_channels.lock().unwrap();
                        let removed_nodes = self.removed_nodes.lock().unwrap();
                        if removed_channels.contains_key(&msg.short_channel_id) ||
-                               removed_nodes.contains_key(&node_one) ||
-                               removed_nodes.contains_key(&node_two) {
+                               removed_nodes.contains_key(&msg.node_id_1) ||
+                               removed_nodes.contains_key(&msg.node_id_2) {
                                return Err(LightningError{
                                        err: format!("Channel with SCID {} or one of its nodes was removed from our network graph recently", &msg.short_channel_id),
                                        action: ErrorAction::IgnoreAndLog(Level::Gossip)});
                        }
                }
 
-               let utxo_value = match &chain_access {
-                       &None => {
-                               // Tentatively accept, potentially exposing us to DoS attacks
-                               None
-                       },
-                       &Some(ref chain_access) => {
-                               match chain_access.get_utxo(&msg.chain_hash, msg.short_channel_id) {
-                                       Ok(TxOut { value, script_pubkey }) => {
-                                               let expected_script =
-                                                       make_funding_redeemscript(&msg.bitcoin_key_1, &msg.bitcoin_key_2).to_v0_p2wsh();
-                                               if script_pubkey != expected_script {
-                                                       return Err(LightningError{err: format!("Channel announcement key ({}) didn't match on-chain script ({})", expected_script.to_hex(), script_pubkey.to_hex()), action: ErrorAction::IgnoreError});
-                                               }
-                                               //TODO: Check if value is worth storing, use it to inform routing, and compare it
-                                               //to the new HTLC max field in channel_update
-                                               Some(value)
-                                       },
-                                       Err(chain::AccessError::UnknownChain) => {
-                                               return Err(LightningError{err: format!("Channel announced on an unknown chain ({})", msg.chain_hash.encode().to_hex()), action: ErrorAction::IgnoreError});
-                                       },
-                                       Err(chain::AccessError::UnknownTx) => {
-                                               return Err(LightningError{err: "Channel announced without corresponding UTXO entry".to_owned(), action: ErrorAction::IgnoreError});
-                                       },
-                               }
-                       },
-               };
+               let utxo_value = self.pending_checks.check_channel_announcement(
+                       utxo_lookup, msg, full_msg)?;
 
                #[allow(unused_mut, unused_assignments)]
                let mut announcement_received_time = 0;
@@ -1518,9 +1551,9 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
 
                let chan_info = ChannelInfo {
                        features: msg.features.clone(),
-                       node_one,
+                       node_one: msg.node_id_1,
                        one_to_two: None,
-                       node_two,
+                       node_two: msg.node_id_2,
                        two_to_one: None,
                        capacity_sats: utxo_value,
                        announcement_message: if msg.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY
@@ -1528,7 +1561,10 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                        announcement_received_time,
                };
 
-               self.add_channel_between_nodes(msg.short_channel_id, chan_info, utxo_value)
+               self.add_channel_between_nodes(msg.short_channel_id, chan_info, utxo_value)?;
+
+               log_gossip!(self.logger, "Added channel_announcement for {}{}", msg.short_channel_id, if !msg.excess_data.is_empty() { " with excess uninterpreted data!" } else { "" });
+               Ok(())
        }
 
        /// Marks a channel in the graph as failed if a corresponding HTLC fail was sent.
@@ -1541,6 +1577,14 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                #[cfg(not(feature = "std"))]
                let current_time_unix = None;
 
+               self.channel_failed_with_time(short_channel_id, is_permanent, current_time_unix)
+       }
+
+       /// Marks a channel in the graph as failed if a corresponding HTLC fail was sent.
+       /// If permanent, removes a channel from the local storage.
+       /// May cause the removal of nodes too, if this was their last channel.
+       /// If not permanent, makes channels unavailable for routing.
+       fn channel_failed_with_time(&self, short_channel_id: u64, is_permanent: bool, current_time_unix: Option<u64>) {
                let mut channels = self.channels.write().unwrap();
                if is_permanent {
                        if let Some(chan) = channels.remove(&short_channel_id) {
@@ -1578,7 +1622,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                        for scid in node.channels.iter() {
                                if let Some(chan_info) = channels.remove(scid) {
                                        let other_node_id = if node_id == chan_info.node_one { chan_info.node_two } else { chan_info.node_one };
-                                       if let BtreeEntry::Occupied(mut other_node_entry) = nodes.entry(other_node_id) {
+                                       if let IndexedMapEntry::Occupied(mut other_node_entry) = nodes.entry(other_node_id) {
                                                other_node_entry.get_mut().channels.retain(|chan_id| {
                                                        *scid != *chan_id
                                                });
@@ -1637,7 +1681,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                // Sadly BTreeMap::retain was only stabilized in 1.53 so we can't switch to it for some
                // time.
                let mut scids_to_remove = Vec::new();
-               for (scid, info) in channels.iter_mut() {
+               for (scid, info) in channels.unordered_iter_mut() {
                        if info.one_to_two.is_some() && info.one_to_two.as_ref().unwrap().last_update < min_time_unix {
                                info.one_to_two = None;
                        }
@@ -1707,9 +1751,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
        }
 
        fn update_channel_intern(&self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig: Option<&secp256k1::ecdsa::Signature>) -> Result<(), LightningError> {
-               let dest_node_id;
                let chan_enabled = msg.flags & (1 << 1) != (1 << 1);
-               let chan_was_enabled;
 
                #[cfg(all(feature = "std", not(test), not(feature = "_test_utils")))]
                {
@@ -1726,7 +1768,11 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
 
                let mut channels = self.channels.write().unwrap();
                match channels.get_mut(&msg.short_channel_id) {
-                       None => return Err(LightningError{err: "Couldn't find channel for update".to_owned(), action: ErrorAction::IgnoreError}),
+                       None => {
+                               core::mem::drop(channels);
+                               self.pending_checks.check_hold_pending_channel_update(msg, full_msg)?;
+                               return Err(LightningError{err: "Couldn't find channel for update".to_owned(), action: ErrorAction::IgnoreError});
+                       },
                        Some(channel) => {
                                if msg.htlc_maximum_msat > MAX_VALUE_MSAT {
                                        return Err(LightningError{err:
@@ -1757,9 +1803,6 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                                                        } else if existing_chan_info.last_update == msg.timestamp {
                                                                return Err(LightningError{err: "Update had same timestamp as last processed update".to_owned(), action: ErrorAction::IgnoreDuplicateGossip});
                                                        }
-                                                       chan_was_enabled = existing_chan_info.enabled;
-                                               } else {
-                                                       chan_was_enabled = false;
                                                }
                                        }
                                }
@@ -1787,7 +1830,6 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
 
                                let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
                                if msg.flags & 1 == 1 {
-                                       dest_node_id = channel.node_one.clone();
                                        check_update_latest!(channel.two_to_one);
                                        if let Some(sig) = sig {
                                                secp_verify_sig!(self.secp_ctx, &msg_hash, &sig, &PublicKey::from_slice(channel.node_two.as_slice()).map_err(|_| LightningError{
@@ -1797,7 +1839,6 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                                        }
                                        channel.two_to_one = get_new_channel_info!();
                                } else {
-                                       dest_node_id = channel.node_two.clone();
                                        check_update_latest!(channel.one_to_two);
                                        if let Some(sig) = sig {
                                                secp_verify_sig!(self.secp_ctx, &msg_hash, &sig, &PublicKey::from_slice(channel.node_one.as_slice()).map_err(|_| LightningError{
@@ -1810,51 +1851,13 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                        }
                }
 
-               let mut nodes = self.nodes.write().unwrap();
-               if chan_enabled {
-                       let node = nodes.get_mut(&dest_node_id).unwrap();
-                       let mut base_msat = msg.fee_base_msat;
-                       let mut proportional_millionths = msg.fee_proportional_millionths;
-                       if let Some(fees) = node.lowest_inbound_channel_fees {
-                               base_msat = cmp::min(base_msat, fees.base_msat);
-                               proportional_millionths = cmp::min(proportional_millionths, fees.proportional_millionths);
-                       }
-                       node.lowest_inbound_channel_fees = Some(RoutingFees {
-                               base_msat,
-                               proportional_millionths
-                       });
-               } else if chan_was_enabled {
-                       let node = nodes.get_mut(&dest_node_id).unwrap();
-                       let mut lowest_inbound_channel_fees = None;
-
-                       for chan_id in node.channels.iter() {
-                               let chan = channels.get(chan_id).unwrap();
-                               let chan_info_opt;
-                               if chan.node_one == dest_node_id {
-                                       chan_info_opt = chan.two_to_one.as_ref();
-                               } else {
-                                       chan_info_opt = chan.one_to_two.as_ref();
-                               }
-                               if let Some(chan_info) = chan_info_opt {
-                                       if chan_info.enabled {
-                                               let fees = lowest_inbound_channel_fees.get_or_insert(RoutingFees {
-                                                       base_msat: u32::max_value(), proportional_millionths: u32::max_value() });
-                                               fees.base_msat = cmp::min(fees.base_msat, chan_info.fees.base_msat);
-                                               fees.proportional_millionths = cmp::min(fees.proportional_millionths, chan_info.fees.proportional_millionths);
-                                       }
-                               }
-                       }
-
-                       node.lowest_inbound_channel_fees = lowest_inbound_channel_fees;
-               }
-
                Ok(())
        }
 
-       fn remove_channel_in_nodes(nodes: &mut BTreeMap<NodeId, NodeInfo>, chan: &ChannelInfo, short_channel_id: u64) {
+       fn remove_channel_in_nodes(nodes: &mut IndexedMap<NodeId, NodeInfo>, chan: &ChannelInfo, short_channel_id: u64) {
                macro_rules! remove_from_node {
                        ($node_id: expr) => {
-                               if let BtreeEntry::Occupied(mut entry) = nodes.entry($node_id) {
+                               if let IndexedMapEntry::Occupied(mut entry) = nodes.entry($node_id) {
                                        entry.get_mut().channels.retain(|chan_id| {
                                                short_channel_id != *chan_id
                                        });
@@ -1875,8 +1878,8 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
 impl ReadOnlyNetworkGraph<'_> {
        /// Returns all known valid channels' short ids along with announced channel info.
        ///
-       /// (C-not exported) because we have no mapping for `BTreeMap`s
-       pub fn channels(&self) -> &BTreeMap<u64, ChannelInfo> {
+       /// (C-not exported) because we don't want to return lifetime'd references
+       pub fn channels(&self) -> &IndexedMap<u64, ChannelInfo> {
                &*self.channels
        }
 
@@ -1888,13 +1891,13 @@ impl ReadOnlyNetworkGraph<'_> {
        #[cfg(c_bindings)] // Non-bindings users should use `channels`
        /// Returns the list of channels in the graph
        pub fn list_channels(&self) -> Vec<u64> {
-               self.channels.keys().map(|c| *c).collect()
+               self.channels.unordered_keys().map(|c| *c).collect()
        }
 
        /// Returns all known nodes' public keys along with announced node info.
        ///
-       /// (C-not exported) because we have no mapping for `BTreeMap`s
-       pub fn nodes(&self) -> &BTreeMap<NodeId, NodeInfo> {
+       /// (C-not exported) because we don't want to return lifetime'd references
+       pub fn nodes(&self) -> &IndexedMap<NodeId, NodeInfo> {
                &*self.nodes
        }
 
@@ -1906,7 +1909,7 @@ impl ReadOnlyNetworkGraph<'_> {
        #[cfg(c_bindings)] // Non-bindings users should use `nodes`
        /// Returns the list of nodes in the graph
        pub fn list_nodes(&self) -> Vec<NodeId> {
-               self.nodes.keys().map(|n| *n).collect()
+               self.nodes.unordered_keys().map(|n| *n).collect()
        }
 
        /// Get network addresses by node id.
@@ -1923,15 +1926,17 @@ impl ReadOnlyNetworkGraph<'_> {
 }
 
 #[cfg(test)]
-mod tests {
-       use crate::chain;
+pub(crate) mod tests {
        use crate::ln::channelmanager;
        use crate::ln::chan_utils::make_funding_redeemscript;
+       #[cfg(feature = "std")]
        use crate::ln::features::InitFeatures;
        use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate, NodeAlias, MAX_EXCESS_BYTES_FOR_RELAY, NodeId, RoutingFees, ChannelUpdateInfo, ChannelInfo, NodeAnnouncementInfo, NodeInfo};
+       use crate::routing::utxo::{UtxoLookupError, UtxoResult};
        use crate::ln::msgs::{RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement,
                UnsignedChannelAnnouncement, ChannelAnnouncement, UnsignedChannelUpdate, ChannelUpdate,
                ReplyChannelRange, QueryChannelRange, QueryShortChannelIds, MAX_VALUE_MSAT};
+       use crate::util::config::UserConfig;
        use crate::util::test_utils;
        use crate::util::ser::{ReadableArgs, Writeable};
        use crate::util::events::{MessageSendEvent, MessageSendEventsProvider};
@@ -1958,9 +1963,8 @@ mod tests {
        use crate::sync::Arc;
 
        fn create_network_graph() -> NetworkGraph<Arc<test_utils::TestLogger>> {
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
                let logger = Arc::new(test_utils::TestLogger::new());
-               NetworkGraph::new(genesis_hash, logger)
+               NetworkGraph::new(Network::Testnet, logger)
        }
 
        fn create_gossip_sync(network_graph: &NetworkGraph<Arc<test_utils::TestLogger>>) -> (
@@ -1988,12 +1992,12 @@ mod tests {
                assert!(!gossip_sync.should_request_full_sync(&node_id));
        }
 
-       fn get_signed_node_announcement<F: Fn(&mut UnsignedNodeAnnouncement)>(f: F, node_key: &SecretKey, secp_ctx: &Secp256k1<secp256k1::All>) -> NodeAnnouncement {
-               let node_id = PublicKey::from_secret_key(&secp_ctx, node_key);
+       pub(crate) fn get_signed_node_announcement<F: Fn(&mut UnsignedNodeAnnouncement)>(f: F, node_key: &SecretKey, secp_ctx: &Secp256k1<secp256k1::All>) -> NodeAnnouncement {
+               let node_id = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_key));
                let mut unsigned_announcement = UnsignedNodeAnnouncement {
-                       features: channelmanager::provided_node_features(),
+                       features: channelmanager::provided_node_features(&UserConfig::default()),
                        timestamp: 100,
-                       node_id: node_id,
+                       node_id,
                        rgb: [0; 3],
                        alias: [0; 32],
                        addresses: Vec::new(),
@@ -2008,20 +2012,20 @@ mod tests {
                }
        }
 
-       fn get_signed_channel_announcement<F: Fn(&mut UnsignedChannelAnnouncement)>(f: F, node_1_key: &SecretKey, node_2_key: &SecretKey, secp_ctx: &Secp256k1<secp256k1::All>) -> ChannelAnnouncement {
+       pub(crate) fn get_signed_channel_announcement<F: Fn(&mut UnsignedChannelAnnouncement)>(f: F, node_1_key: &SecretKey, node_2_key: &SecretKey, secp_ctx: &Secp256k1<secp256k1::All>) -> ChannelAnnouncement {
                let node_id_1 = PublicKey::from_secret_key(&secp_ctx, node_1_key);
                let node_id_2 = PublicKey::from_secret_key(&secp_ctx, node_2_key);
                let node_1_btckey = &SecretKey::from_slice(&[40; 32]).unwrap();
                let node_2_btckey = &SecretKey::from_slice(&[39; 32]).unwrap();
 
                let mut unsigned_announcement = UnsignedChannelAnnouncement {
-                       features: channelmanager::provided_channel_features(),
+                       features: channelmanager::provided_channel_features(&UserConfig::default()),
                        chain_hash: genesis_block(Network::Testnet).header.block_hash(),
                        short_channel_id: 0,
-                       node_id_1,
-                       node_id_2,
-                       bitcoin_key_1: PublicKey::from_secret_key(&secp_ctx, node_1_btckey),
-                       bitcoin_key_2: PublicKey::from_secret_key(&secp_ctx, node_2_btckey),
+                       node_id_1: NodeId::from_pubkey(&node_id_1),
+                       node_id_2: NodeId::from_pubkey(&node_id_2),
+                       bitcoin_key_1: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_1_btckey)),
+                       bitcoin_key_2: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_2_btckey)),
                        excess_data: Vec::new(),
                };
                f(&mut unsigned_announcement);
@@ -2035,14 +2039,14 @@ mod tests {
                }
        }
 
-       fn get_channel_script(secp_ctx: &Secp256k1<secp256k1::All>) -> Script {
+       pub(crate) fn get_channel_script(secp_ctx: &Secp256k1<secp256k1::All>) -> Script {
                let node_1_btckey = SecretKey::from_slice(&[40; 32]).unwrap();
                let node_2_btckey = SecretKey::from_slice(&[39; 32]).unwrap();
                make_funding_redeemscript(&PublicKey::from_secret_key(secp_ctx, &node_1_btckey),
                        &PublicKey::from_secret_key(secp_ctx, &node_2_btckey)).to_v0_p2wsh()
        }
 
-       fn get_signed_channel_update<F: Fn(&mut UnsignedChannelUpdate)>(f: F, node_key: &SecretKey, secp_ctx: &Secp256k1<secp256k1::All>) -> ChannelUpdate {
+       pub(crate) fn get_signed_channel_update<F: Fn(&mut UnsignedChannelUpdate)>(f: F, node_key: &SecretKey, secp_ctx: &Secp256k1<secp256k1::All>) -> ChannelUpdate {
                let mut unsigned_channel_update = UnsignedChannelUpdate {
                        chain_hash: genesis_block(Network::Testnet).header.block_hash(),
                        short_channel_id: 0,
@@ -2135,8 +2139,7 @@ mod tests {
                let valid_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx);
 
                // Test if the UTXO lookups were not supported
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
-               let network_graph = NetworkGraph::new(genesis_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Testnet, &logger);
                let mut gossip_sync = P2PGossipSync::new(&network_graph, None, &logger);
                match gossip_sync.handle_channel_announcement(&valid_announcement) {
                        Ok(res) => assert!(res),
@@ -2159,8 +2162,8 @@ mod tests {
 
                // Test if an associated transaction were not on-chain (or not confirmed).
                let chain_source = test_utils::TestChainSource::new(Network::Testnet);
-               *chain_source.utxo_ret.lock().unwrap() = Err(chain::AccessError::UnknownTx);
-               let network_graph = NetworkGraph::new(genesis_hash, &logger);
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Sync(Err(UtxoLookupError::UnknownTx));
+               let network_graph = NetworkGraph::new(Network::Testnet, &logger);
                gossip_sync = P2PGossipSync::new(&network_graph, Some(&chain_source), &logger);
 
                let valid_announcement = get_signed_channel_announcement(|unsigned_announcement| {
@@ -2172,7 +2175,8 @@ mod tests {
                };
 
                // Now test if the transaction is found in the UTXO set and the script is correct.
-               *chain_source.utxo_ret.lock().unwrap() = Ok(TxOut { value: 0, script_pubkey: good_script.clone() });
+               *chain_source.utxo_ret.lock().unwrap() =
+                       UtxoResult::Sync(Ok(TxOut { value: 0, script_pubkey: good_script.clone() }));
                let valid_announcement = get_signed_channel_announcement(|unsigned_announcement| {
                        unsigned_announcement.short_channel_id += 2;
                }, node_1_privkey, node_2_privkey, &secp_ctx);
@@ -2190,7 +2194,8 @@ mod tests {
 
                // If we receive announcement for the same channel, once we've validated it against the
                // chain, we simply ignore all new (duplicate) announcements.
-               *chain_source.utxo_ret.lock().unwrap() = Ok(TxOut { value: 0, script_pubkey: good_script });
+               *chain_source.utxo_ret.lock().unwrap() =
+                       UtxoResult::Sync(Ok(TxOut { value: 0, script_pubkey: good_script }));
                match gossip_sync.handle_channel_announcement(&valid_announcement) {
                        Ok(_) => panic!(),
                        Err(e) => assert_eq!(e.err, "Already have chain-validated channel")
@@ -2251,8 +2256,7 @@ mod tests {
                let secp_ctx = Secp256k1::new();
                let logger = test_utils::TestLogger::new();
                let chain_source = test_utils::TestChainSource::new(Network::Testnet);
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
-               let network_graph = NetworkGraph::new(genesis_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Testnet, &logger);
                let gossip_sync = P2PGossipSync::new(&network_graph, Some(&chain_source), &logger);
 
                let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap();
@@ -2264,7 +2268,8 @@ mod tests {
                {
                        // Announce a channel we will update
                        let good_script = get_channel_script(&secp_ctx);
-                       *chain_source.utxo_ret.lock().unwrap() = Ok(TxOut { value: amount_sats, script_pubkey: good_script.clone() });
+                       *chain_source.utxo_ret.lock().unwrap() =
+                               UtxoResult::Sync(Ok(TxOut { value: amount_sats, script_pubkey: good_script.clone() }));
 
                        let valid_channel_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx);
                        short_channel_id = valid_channel_announcement.contents.short_channel_id;
@@ -2353,8 +2358,7 @@ mod tests {
        #[test]
        fn handling_network_update() {
                let logger = test_utils::TestLogger::new();
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
-               let network_graph = NetworkGraph::new(genesis_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Testnet, &logger);
                let secp_ctx = Secp256k1::new();
 
                let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap();
@@ -2419,7 +2423,7 @@ mod tests {
 
                {
                        // Get a new network graph since we don't want to track removed nodes in this test with "std"
-                       let network_graph = NetworkGraph::new(genesis_hash, &logger);
+                       let network_graph = NetworkGraph::new(Network::Testnet, &logger);
 
                        // Announce a channel to test permanent node failure
                        let valid_channel_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx);
@@ -2454,8 +2458,7 @@ mod tests {
                // Test the removal of channels with `remove_stale_channels_and_tracking`.
                let logger = test_utils::TestLogger::new();
                let chain_source = test_utils::TestChainSource::new(Network::Testnet);
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
-               let network_graph = NetworkGraph::new(genesis_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Testnet, &logger);
                let gossip_sync = P2PGossipSync::new(&network_graph, Some(&chain_source), &logger);
                let secp_ctx = Secp256k1::new();
 
@@ -2537,18 +2540,18 @@ mod tests {
 
                        // Mark the channel as permanently failed. This will also remove the two nodes
                        // and all of the entries will be tracked as removed.
-                       network_graph.channel_failed(short_channel_id, true);
+                       network_graph.channel_failed_with_time(short_channel_id, true, Some(tracking_time));
 
                        // Should not remove from tracking if insufficient time has passed
                        network_graph.remove_stale_channels_and_tracking_with_time(
                                tracking_time + REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS - 1);
-                       assert_eq!(network_graph.removed_channels.lock().unwrap().len(), 1);
+                       assert_eq!(network_graph.removed_channels.lock().unwrap().len(), 1, "Removed channel count â‰  1 with tracking_time {}", tracking_time);
 
                        // Provide a later time so that sufficient time has passed
                        network_graph.remove_stale_channels_and_tracking_with_time(
                                tracking_time + REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS);
-                       assert!(network_graph.removed_channels.lock().unwrap().is_empty());
-                       assert!(network_graph.removed_nodes.lock().unwrap().is_empty());
+                       assert!(network_graph.removed_channels.lock().unwrap().is_empty(), "Unexpectedly removed channels with tracking_time {}", tracking_time);
+                       assert!(network_graph.removed_nodes.lock().unwrap().is_empty(), "Unexpectedly removed nodes with tracking_time {}", tracking_time);
                }
 
                #[cfg(not(feature = "std"))]
@@ -2670,7 +2673,7 @@ mod tests {
                let (secp_ctx, gossip_sync) = create_gossip_sync(&network_graph);
                let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap();
                let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap();
-               let node_id_1 = PublicKey::from_secret_key(&secp_ctx, node_1_privkey);
+               let node_id_1 = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_1_privkey));
 
                // No nodes yet.
                let next_announcements = gossip_sync.get_next_node_announcement(None);
@@ -2786,7 +2789,7 @@ mod tests {
                // It should ignore if gossip_queries feature is not enabled
                {
                        let init_msg = Init { features: InitFeatures::empty(), remote_network_address: None };
-                       gossip_sync.peer_connected(&node_id_1, &init_msg).unwrap();
+                       gossip_sync.peer_connected(&node_id_1, &init_msg, true).unwrap();
                        let events = gossip_sync.get_and_clear_pending_msg_events();
                        assert_eq!(events.len(), 0);
                }
@@ -2796,7 +2799,7 @@ mod tests {
                        let mut features = InitFeatures::empty();
                        features.set_gossip_queries_optional();
                        let init_msg = Init { features, remote_network_address: None };
-                       gossip_sync.peer_connected(&node_id_1, &init_msg).unwrap();
+                       gossip_sync.peer_connected(&node_id_1, &init_msg, true).unwrap();
                        let events = gossip_sync.get_and_clear_pending_msg_events();
                        assert_eq!(events.len(), 1);
                        match &events[0] {
@@ -3149,6 +3152,7 @@ mod tests {
                let node_cfgs = crate::ln::functional_test_utils::create_node_cfgs(2, &chanmon_cfgs);
                let node_chanmgrs = crate::ln::functional_test_utils::create_node_chanmgrs(2, &node_cfgs, &[None, None, None, None]);
                let nodes = crate::ln::functional_test_utils::create_network(2, &node_cfgs, &node_chanmgrs);
+               let config = crate::ln::functional_test_utils::test_default_channel_config();
 
                // 1. Test encoding/decoding of ChannelUpdateInfo
                let chan_update_info = ChannelUpdateInfo {
@@ -3185,7 +3189,7 @@ mod tests {
                // 2. Test encoding/decoding of ChannelInfo
                // Check we can encode/decode ChannelInfo without ChannelUpdateInfo fields present.
                let chan_info_none_updates = ChannelInfo {
-                       features: channelmanager::provided_channel_features(),
+                       features: channelmanager::provided_channel_features(&config),
                        node_one: NodeId::from_pubkey(&nodes[0].node.get_our_node_id()),
                        one_to_two: None,
                        node_two: NodeId::from_pubkey(&nodes[1].node.get_our_node_id()),
@@ -3203,7 +3207,7 @@ mod tests {
 
                // Check we can encode/decode ChannelInfo with ChannelUpdateInfo fields present.
                let chan_info_some_updates = ChannelInfo {
-                       features: channelmanager::provided_channel_features(),
+                       features: channelmanager::provided_channel_features(&config),
                        node_one: NodeId::from_pubkey(&nodes[0].node.get_our_node_id()),
                        one_to_two: Some(chan_update_info.clone()),
                        node_two: NodeId::from_pubkey(&nodes[1].node.get_our_node_id()),
@@ -3245,7 +3249,7 @@ mod tests {
                // 1. Check we can read a valid NodeAnnouncementInfo and fail on an invalid one
                let valid_netaddr = crate::ln::msgs::NetAddress::Hostname { hostname: crate::util::ser::Hostname::try_from("A".to_string()).unwrap(), port: 1234 };
                let valid_node_ann_info = NodeAnnouncementInfo {
-                       features: channelmanager::provided_node_features(),
+                       features: channelmanager::provided_node_features(&UserConfig::default()),
                        last_update: 0,
                        rgb: [0u8; 3],
                        alias: NodeAlias([0u8; 32]),
@@ -3265,7 +3269,6 @@ mod tests {
                // 2. Check we can read a NodeInfo anyways, but set the NodeAnnouncementInfo to None if invalid
                let valid_node_info = NodeInfo {
                        channels: Vec::new(),
-                       lowest_inbound_channel_fees: None,
                        announcement_info: Some(valid_node_ann_info),
                };
 
index 9bf0910663d92210ce649bfec959538214cd12cd..7fff856345c84c8f8fadadfe262992a4a4e8f6bc 100644 (file)
@@ -9,6 +9,7 @@
 
 //! Structs and impls for receiving messages about the network and storing the topology live here.
 
+pub mod utxo;
 pub mod gossip;
 pub mod router;
 pub mod scoring;
index 3f14b0c6a1128a366d8b80c9b59c216febe0b816..9682503ee45c22d5062a099f5c1af015bbe3ffc0 100644 (file)
@@ -7,10 +7,7 @@
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
-//! The top-level routing/network map tracking logic lives here.
-//!
-//! You probably want to create a P2PGossipSync and use that as your RoutingMessageHandler and then
-//! interrogate it to get routes for your own payments.
+//! The router finds paths within a [`NetworkGraph`] for a payment.
 
 use bitcoin::secp256k1::PublicKey;
 use bitcoin::hashes::Hash;
@@ -22,7 +19,7 @@ use crate::ln::features::{ChannelFeatures, InvoiceFeatures, NodeFeatures};
 use crate::ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT};
 use crate::routing::gossip::{DirectedChannelInfo, EffectiveCapacity, ReadOnlyNetworkGraph, NetworkGraph, NodeId, RoutingFees};
 use crate::routing::scoring::{ChannelUsage, LockableScore, Score};
-use crate::util::ser::{Writeable, Readable, Writer};
+use crate::util::ser::{Writeable, Readable, ReadableArgs, Writer};
 use crate::util::logger::{Level, Logger};
 use crate::util::chacha20::ChaCha20;
 
@@ -75,22 +72,6 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref> Router for DefaultR
                        &random_seed_bytes
                )
        }
-
-       fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) {
-               self.scorer.lock().payment_path_failed(path, short_channel_id);
-       }
-
-       fn notify_payment_path_successful(&self, path: &[&RouteHop]) {
-               self.scorer.lock().payment_path_successful(path);
-       }
-
-       fn notify_payment_probe_successful(&self, path: &[&RouteHop]) {
-               self.scorer.lock().probe_successful(path);
-       }
-
-       fn notify_payment_probe_failed(&self, path: &[&RouteHop], short_channel_id: u64) {
-               self.scorer.lock().probe_failed(path, short_channel_id);
-       }
 }
 
 /// A trait defining behavior for routing a payment.
@@ -109,14 +90,6 @@ pub trait Router {
        ) -> Result<Route, LightningError> {
                self.find_route(payer, route_params, first_hops, inflight_htlcs)
        }
-       /// Lets the router know that payment through a specific path has failed.
-       fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64);
-       /// Lets the router know that payment through a specific path was successful.
-       fn notify_payment_path_successful(&self, path: &[&RouteHop]);
-       /// Lets the router know that a payment probe was successful.
-       fn notify_payment_probe_successful(&self, path: &[&RouteHop]);
-       /// Lets the router know that a payment probe failed.
-       fn notify_payment_probe_failed(&self, path: &[&RouteHop], short_channel_id: u64);
 }
 
 /// [`Score`] implementation that factors in in-flight HTLC liquidity.
@@ -340,18 +313,23 @@ impl Readable for Route {
        fn read<R: io::Read>(reader: &mut R) -> Result<Route, DecodeError> {
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
                let path_count: u64 = Readable::read(reader)?;
+               if path_count == 0 { return Err(DecodeError::InvalidValue); }
                let mut paths = Vec::with_capacity(cmp::min(path_count, 128) as usize);
+               let mut min_final_cltv_expiry_delta = u32::max_value();
                for _ in 0..path_count {
                        let hop_count: u8 = Readable::read(reader)?;
-                       let mut hops = Vec::with_capacity(hop_count as usize);
+                       let mut hops: Vec<RouteHop> = Vec::with_capacity(hop_count as usize);
                        for _ in 0..hop_count {
                                hops.push(Readable::read(reader)?);
                        }
+                       if hops.is_empty() { return Err(DecodeError::InvalidValue); }
+                       min_final_cltv_expiry_delta =
+                               cmp::min(min_final_cltv_expiry_delta, hops.last().unwrap().cltv_expiry_delta);
                        paths.push(hops);
                }
                let mut payment_params = None;
                read_tlv_fields!(reader, {
-                       (1, payment_params, option),
+                       (1, payment_params, (option: ReadableArgs, min_final_cltv_expiry_delta)),
                });
                Ok(Route { paths, payment_params })
        }
@@ -360,26 +338,48 @@ impl Readable for Route {
 /// Parameters needed to find a [`Route`].
 ///
 /// Passed to [`find_route`] and [`build_route_from_hops`], but also provided in
-/// [`Event::PaymentPathFailed`] for retrying a failed payment path.
+/// [`Event::PaymentPathFailed`].
 ///
 /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct RouteParameters {
        /// The parameters of the failed payment path.
        pub payment_params: PaymentParameters,
 
        /// The amount in msats sent on the failed payment path.
        pub final_value_msat: u64,
+}
 
-       /// The CLTV on the final hop of the failed payment path.
-       pub final_cltv_expiry_delta: u32,
+impl Writeable for RouteParameters {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               write_tlv_fields!(writer, {
+                       (0, self.payment_params, required),
+                       (2, self.final_value_msat, required),
+                       // LDK versions prior to 0.0.114 had the `final_cltv_expiry_delta` parameter in
+                       // `RouteParameters` directly. For compatibility, we write it here.
+                       (4, self.payment_params.final_cltv_expiry_delta, required),
+               });
+               Ok(())
+       }
 }
 
-impl_writeable_tlv_based!(RouteParameters, {
-       (0, payment_params, required),
-       (2, final_value_msat, required),
-       (4, final_cltv_expiry_delta, required),
-});
+impl Readable for RouteParameters {
+       fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+               _init_and_read_tlv_fields!(reader, {
+                       (0, payment_params, (required: ReadableArgs, 0)),
+                       (2, final_value_msat, required),
+                       (4, final_cltv_expiry_delta, required),
+               });
+               let mut payment_params: PaymentParameters = payment_params.0.unwrap();
+               if payment_params.final_cltv_expiry_delta == 0 {
+                       payment_params.final_cltv_expiry_delta = final_cltv_expiry_delta.0.unwrap();
+               }
+               Ok(Self {
+                       payment_params,
+                       final_value_msat: final_value_msat.0.unwrap(),
+               })
+       }
+}
 
 /// Maximum total CTLV difference we allow for a full payment path.
 pub const DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA: u32 = 1008;
@@ -452,22 +452,62 @@ pub struct PaymentParameters {
        /// payment to fail. Future attempts for the same payment shouldn't be relayed through any of
        /// these SCIDs.
        pub previously_failed_channels: Vec<u64>,
+
+       /// The minimum CLTV delta at the end of the route. This value must not be zero.
+       pub final_cltv_expiry_delta: u32,
+}
+
+impl Writeable for PaymentParameters {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               write_tlv_fields!(writer, {
+                       (0, self.payee_pubkey, required),
+                       (1, self.max_total_cltv_expiry_delta, required),
+                       (2, self.features, option),
+                       (3, self.max_path_count, required),
+                       (4, self.route_hints, vec_type),
+                       (5, self.max_channel_saturation_power_of_half, required),
+                       (6, self.expiry_time, option),
+                       (7, self.previously_failed_channels, vec_type),
+                       (9, self.final_cltv_expiry_delta, required),
+               });
+               Ok(())
+       }
+}
+
+impl ReadableArgs<u32> for PaymentParameters {
+       fn read<R: io::Read>(reader: &mut R, default_final_cltv_expiry_delta: u32) -> Result<Self, DecodeError> {
+               _init_and_read_tlv_fields!(reader, {
+                       (0, payee_pubkey, required),
+                       (1, max_total_cltv_expiry_delta, (default_value, DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA)),
+                       (2, features, option),
+                       (3, max_path_count, (default_value, DEFAULT_MAX_PATH_COUNT)),
+                       (4, route_hints, vec_type),
+                       (5, max_channel_saturation_power_of_half, (default_value, 2)),
+                       (6, expiry_time, option),
+                       (7, previously_failed_channels, vec_type),
+                       (9, final_cltv_expiry_delta, (default_value, default_final_cltv_expiry_delta)),
+               });
+               Ok(Self {
+                       payee_pubkey: _init_tlv_based_struct_field!(payee_pubkey, required),
+                       max_total_cltv_expiry_delta: _init_tlv_based_struct_field!(max_total_cltv_expiry_delta, (default_value, unused)),
+                       features,
+                       max_path_count: _init_tlv_based_struct_field!(max_path_count, (default_value, unused)),
+                       route_hints: route_hints.unwrap_or(Vec::new()),
+                       max_channel_saturation_power_of_half: _init_tlv_based_struct_field!(max_channel_saturation_power_of_half, (default_value, unused)),
+                       expiry_time,
+                       previously_failed_channels: previously_failed_channels.unwrap_or(Vec::new()),
+                       final_cltv_expiry_delta: _init_tlv_based_struct_field!(final_cltv_expiry_delta, (default_value, unused)),
+               })
+       }
 }
 
-impl_writeable_tlv_based!(PaymentParameters, {
-       (0, payee_pubkey, required),
-       (1, max_total_cltv_expiry_delta, (default_value, DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA)),
-       (2, features, option),
-       (3, max_path_count, (default_value, DEFAULT_MAX_PATH_COUNT)),
-       (4, route_hints, vec_type),
-       (5, max_channel_saturation_power_of_half, (default_value, 2)),
-       (6, expiry_time, option),
-       (7, previously_failed_channels, vec_type),
-});
 
 impl PaymentParameters {
        /// Creates a payee with the node id of the given `pubkey`.
-       pub fn from_node_id(payee_pubkey: PublicKey) -> Self {
+       ///
+       /// The `final_cltv_expiry_delta` should match the expected final CLTV delta the recipient has
+       /// provided.
+       pub fn from_node_id(payee_pubkey: PublicKey, final_cltv_expiry_delta: u32) -> Self {
                Self {
                        payee_pubkey,
                        features: None,
@@ -477,12 +517,16 @@ impl PaymentParameters {
                        max_path_count: DEFAULT_MAX_PATH_COUNT,
                        max_channel_saturation_power_of_half: 2,
                        previously_failed_channels: Vec::new(),
+                       final_cltv_expiry_delta,
                }
        }
 
        /// Creates a payee with the node id of the given `pubkey` to use for keysend payments.
-       pub fn for_keysend(payee_pubkey: PublicKey) -> Self {
-               Self::from_node_id(payee_pubkey).with_features(InvoiceFeatures::for_keysend())
+       ///
+       /// The `final_cltv_expiry_delta` should match the expected final CLTV delta the recipient has
+       /// provided.
+       pub fn for_keysend(payee_pubkey: PublicKey, final_cltv_expiry_delta: u32) -> Self {
+               Self::from_node_id(payee_pubkey, final_cltv_expiry_delta).with_features(InvoiceFeatures::for_keysend())
        }
 
        /// Includes the payee's features.
@@ -582,7 +626,6 @@ impl_writeable_tlv_based!(RouteHintHop, {
 #[derive(Eq, PartialEq)]
 struct RouteGraphNode {
        node_id: NodeId,
-       lowest_fee_to_peer_through_node: u64,
        lowest_fee_to_node: u64,
        total_cltv_delta: u32,
        // The maximum value a yet-to-be-constructed payment path might flow through this node.
@@ -603,9 +646,9 @@ struct RouteGraphNode {
 
 impl cmp::Ord for RouteGraphNode {
        fn cmp(&self, other: &RouteGraphNode) -> cmp::Ordering {
-               let other_score = cmp::max(other.lowest_fee_to_peer_through_node, other.path_htlc_minimum_msat)
+               let other_score = cmp::max(other.lowest_fee_to_node, other.path_htlc_minimum_msat)
                        .saturating_add(other.path_penalty_msat);
-               let self_score = cmp::max(self.lowest_fee_to_peer_through_node, self.path_htlc_minimum_msat)
+               let self_score = cmp::max(self.lowest_fee_to_node, self.path_htlc_minimum_msat)
                        .saturating_add(self.path_penalty_msat);
                other_score.cmp(&self_score).then_with(|| other.node_id.cmp(&self.node_id))
        }
@@ -729,8 +772,6 @@ struct PathBuildingHop<'a> {
        candidate: CandidateRouteHop<'a>,
        fee_msat: u64,
 
-       /// Minimal fees required to route to the source node of the current hop via any of its inbound channels.
-       src_lowest_inbound_fees: RoutingFees,
        /// All the fees paid *after* this channel on the way to the destination
        next_hops_fee_msat: u64,
        /// Fee paid for the use of the current channel (see candidate.fees()).
@@ -888,18 +929,20 @@ impl<'a> PaymentPath<'a> {
        }
 }
 
+#[inline(always)]
+/// Calculate the fees required to route the given amount over a channel with the given fees.
 fn compute_fees(amount_msat: u64, channel_fees: RoutingFees) -> Option<u64> {
-       let proportional_fee_millions =
-               amount_msat.checked_mul(channel_fees.proportional_millionths as u64);
-       if let Some(new_fee) = proportional_fee_millions.and_then(|part| {
-                       (channel_fees.base_msat as u64).checked_add(part / 1_000_000) }) {
+       amount_msat.checked_mul(channel_fees.proportional_millionths as u64)
+               .and_then(|part| (channel_fees.base_msat as u64).checked_add(part / 1_000_000))
+}
 
-               Some(new_fee)
-       } else {
-               // This function may be (indirectly) called without any verification,
-               // with channel_fees provided by a caller. We should handle it gracefully.
-               None
-       }
+#[inline(always)]
+/// Calculate the fees required to route the given amount over a channel with the given fees,
+/// saturating to [`u64::max_value`].
+fn compute_fees_saturating(amount_msat: u64, channel_fees: RoutingFees) -> u64 {
+       amount_msat.checked_mul(channel_fees.proportional_millionths as u64)
+               .map(|prop| prop / 1_000_000).unwrap_or(u64::max_value())
+               .saturating_add(channel_fees.base_msat as u64)
 }
 
 /// The default `features` we assume for a node in a route, when no `features` are known about that
@@ -949,8 +992,9 @@ pub fn find_route<L: Deref, GL: Deref, S: Score>(
 ) -> Result<Route, LightningError>
 where L::Target: Logger, GL::Target: Logger {
        let graph_lock = network_graph.read_only();
+       let final_cltv_expiry_delta = route_params.payment_params.final_cltv_expiry_delta;
        let mut route = get_route(our_node_pubkey, &route_params.payment_params, &graph_lock, first_hops,
-               route_params.final_value_msat, route_params.final_cltv_expiry_delta, logger, scorer,
+               route_params.final_value_msat, final_cltv_expiry_delta, logger, scorer,
                random_seed_bytes)?;
        add_random_cltv_offset(&mut route, &route_params.payment_params, &graph_lock, random_seed_bytes);
        Ok(route)
@@ -988,6 +1032,9 @@ where L::Target: Logger {
                return Err(LightningError{err: "Can't find a route where the maximum total CLTV expiry delta is below the final CLTV expiry.".to_owned(), action: ErrorAction::IgnoreError});
        }
 
+       // TODO: Remove the explicit final_cltv_expiry_delta parameter
+       debug_assert_eq!(final_cltv_expiry_delta, payment_params.final_cltv_expiry_delta);
+
        // The general routing idea is the following:
        // 1. Fill first/last hops communicated by the caller.
        // 2. Attempt to construct a path from payer to payee for transferring
@@ -1007,9 +1054,8 @@ where L::Target: Logger {
        // 8. If our maximum channel saturation limit caused us to pick two identical paths, combine
        //    them so that we're not sending two HTLCs along the same path.
 
-       // As for the actual search algorithm,
-       // we do a payee-to-payer pseudo-Dijkstra's sorting by each node's distance from the payee
-       // plus the minimum per-HTLC fee to get from it to another node (aka "shitty pseudo-A*").
+       // As for the actual search algorithm, we do a payee-to-payer Dijkstra's sorting by each node's
+       // distance from the payee
        //
        // We are not a faithful Dijkstra's implementation because we can change values which impact
        // earlier nodes while processing later nodes. Specifically, if we reach a channel with a lower
@@ -1044,10 +1090,6 @@ where L::Target: Logger {
        // runtime for little gain. Specifically, the current algorithm rather efficiently explores the
        // graph for candidate paths, calculating the maximum value which can realistically be sent at
        // the same time, remaining generic across different payment values.
-       //
-       // TODO: There are a few tweaks we could do, including possibly pre-calculating more stuff
-       // to use as the A* heuristic beyond just the cost to get one node further than the current
-       // one.
 
        let network_channels = network_graph.channels();
        let network_nodes = network_graph.nodes();
@@ -1097,7 +1139,7 @@ where L::Target: Logger {
                }
        }
 
-       // The main heap containing all candidate next-hops sorted by their score (max(A* fee,
+       // The main heap containing all candidate next-hops sorted by their score (max(fee,
        // htlc_minimum)). Ideally this would be a heap which allowed cheap score reduction instead of
        // adding duplicate entries when we find a better path to a given node.
        let mut targets: BinaryHeap<RouteGraphNode> = BinaryHeap::new();
@@ -1262,10 +1304,10 @@ where L::Target: Logger {
                                                // might violate htlc_minimum_msat on the hops which are next along the
                                                // payment path (upstream to the payee). To avoid that, we recompute
                                                // path fees knowing the final path contribution after constructing it.
-                                               let path_htlc_minimum_msat = compute_fees($next_hops_path_htlc_minimum_msat, $candidate.fees())
-                                                       .and_then(|fee_msat| fee_msat.checked_add($next_hops_path_htlc_minimum_msat))
-                                                       .map(|fee_msat| cmp::max(fee_msat, $candidate.htlc_minimum_msat()))
-                                                       .unwrap_or_else(|| u64::max_value());
+                                               let path_htlc_minimum_msat = cmp::max(
+                                                       compute_fees_saturating($next_hops_path_htlc_minimum_msat, $candidate.fees())
+                                                               .saturating_add($next_hops_path_htlc_minimum_msat),
+                                                       $candidate.htlc_minimum_msat());
                                                let hm_entry = dist.entry($src_node_id);
                                                let old_entry = hm_entry.or_insert_with(|| {
                                                        // If there was previously no known way to access the source node
@@ -1273,20 +1315,10 @@ where L::Target: Logger {
                                                        // semi-dummy record just to compute the fees to reach the source node.
                                                        // This will affect our decision on selecting short_channel_id
                                                        // as a way to reach the $dest_node_id.
-                                                       let mut fee_base_msat = 0;
-                                                       let mut fee_proportional_millionths = 0;
-                                                       if let Some(Some(fees)) = network_nodes.get(&$src_node_id).map(|node| node.lowest_inbound_channel_fees) {
-                                                               fee_base_msat = fees.base_msat;
-                                                               fee_proportional_millionths = fees.proportional_millionths;
-                                                       }
                                                        PathBuildingHop {
                                                                node_id: $dest_node_id.clone(),
                                                                candidate: $candidate.clone(),
                                                                fee_msat: 0,
-                                                               src_lowest_inbound_fees: RoutingFees {
-                                                                       base_msat: fee_base_msat,
-                                                                       proportional_millionths: fee_proportional_millionths,
-                                                               },
                                                                next_hops_fee_msat: u64::max_value(),
                                                                hop_use_fee_msat: u64::max_value(),
                                                                total_fee_msat: u64::max_value(),
@@ -1309,38 +1341,15 @@ where L::Target: Logger {
 
                                                if should_process {
                                                        let mut hop_use_fee_msat = 0;
-                                                       let mut total_fee_msat = $next_hops_fee_msat;
+                                                       let mut total_fee_msat: u64 = $next_hops_fee_msat;
 
                                                        // Ignore hop_use_fee_msat for channel-from-us as we assume all channels-from-us
                                                        // will have the same effective-fee
                                                        if $src_node_id != our_node_id {
-                                                               match compute_fees(amount_to_transfer_over_msat, $candidate.fees()) {
-                                                                       // max_value means we'll always fail
-                                                                       // the old_entry.total_fee_msat > total_fee_msat check
-                                                                       None => total_fee_msat = u64::max_value(),
-                                                                       Some(fee_msat) => {
-                                                                               hop_use_fee_msat = fee_msat;
-                                                                               total_fee_msat += hop_use_fee_msat;
-                                                                               // When calculating the lowest inbound fees to a node, we
-                                                                               // calculate fees here not based on the actual value we think
-                                                                               // will flow over this channel, but on the minimum value that
-                                                                               // we'll accept flowing over it. The minimum accepted value
-                                                                               // is a constant through each path collection run, ensuring
-                                                                               // consistent basis. Otherwise we may later find a
-                                                                               // different path to the source node that is more expensive,
-                                                                               // but which we consider to be cheaper because we are capacity
-                                                                               // constrained and the relative fee becomes lower.
-                                                                               match compute_fees(minimal_value_contribution_msat, old_entry.src_lowest_inbound_fees)
-                                                                                               .map(|a| a.checked_add(total_fee_msat)) {
-                                                                                       Some(Some(v)) => {
-                                                                                               total_fee_msat = v;
-                                                                                       },
-                                                                                       _ => {
-                                                                                               total_fee_msat = u64::max_value();
-                                                                                       }
-                                                                               };
-                                                                       }
-                                                               }
+                                                               // Note that `u64::max_value` means we'll always fail the
+                                                               // `old_entry.total_fee_msat > total_fee_msat` check below
+                                                               hop_use_fee_msat = compute_fees_saturating(amount_to_transfer_over_msat, $candidate.fees());
+                                                               total_fee_msat = total_fee_msat.saturating_add(hop_use_fee_msat);
                                                        }
 
                                                        let channel_usage = ChannelUsage {
@@ -1355,8 +1364,7 @@ where L::Target: Logger {
                                                                .saturating_add(channel_penalty_msat);
                                                        let new_graph_node = RouteGraphNode {
                                                                node_id: $src_node_id,
-                                                               lowest_fee_to_peer_through_node: total_fee_msat,
-                                                               lowest_fee_to_node: $next_hops_fee_msat as u64 + hop_use_fee_msat,
+                                                               lowest_fee_to_node: total_fee_msat,
                                                                total_cltv_delta: hop_total_cltv_delta,
                                                                value_contribution_msat,
                                                                path_htlc_minimum_msat,
@@ -2064,7 +2072,8 @@ where L::Target: Logger, GL::Target: Logger {
        let graph_lock = network_graph.read_only();
        let mut route = build_route_from_hops_internal(
                our_node_pubkey, hops, &route_params.payment_params, &graph_lock,
-               route_params.final_value_msat, route_params.final_cltv_expiry_delta, logger, random_seed_bytes)?;
+               route_params.final_value_msat, route_params.payment_params.final_cltv_expiry_delta,
+               logger, random_seed_bytes)?;
        add_random_cltv_offset(&mut route, &route_params.payment_params, &graph_lock, random_seed_bytes);
        Ok(route)
 }
@@ -2133,16 +2142,18 @@ fn build_route_from_hops_internal<L: Deref>(
 #[cfg(test)]
 mod tests {
        use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, EffectiveCapacity};
+       use crate::routing::utxo::UtxoResult;
        use crate::routing::router::{get_route, build_route_from_hops_internal, add_random_cltv_offset, default_node_features,
                PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RoutingFees,
                DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, MAX_PATH_LENGTH_ESTIMATE};
-       use crate::routing::scoring::{ChannelUsage, Score, ProbabilisticScorer, ProbabilisticScoringParameters};
+       use crate::routing::scoring::{ChannelUsage, FixedPenaltyScorer, Score, ProbabilisticScorer, ProbabilisticScoringParameters};
        use crate::routing::test_utils::{add_channel, add_or_update_node, build_graph, build_line_graph, id_to_feature_flags, get_nodes, update_channel};
        use crate::chain::transaction::OutPoint;
-       use crate::chain::keysinterface::{EntropySource, KeysInterface};
+       use crate::chain::keysinterface::EntropySource;
        use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
        use crate::ln::msgs::{ErrorAction, LightningError, UnsignedChannelUpdate, MAX_VALUE_MSAT};
        use crate::ln::channelmanager;
+       use crate::util::config::UserConfig;
        use crate::util::test_utils as ln_test_utils;
        use crate::util::chacha20::ChaCha20;
        #[cfg(c_bindings)]
@@ -2204,8 +2215,8 @@ mod tests {
        fn simple_route_test() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let payment_params = PaymentParameters::from_node_id(nodes[2]);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2237,8 +2248,8 @@ mod tests {
        fn invalid_first_hop_test() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let payment_params = PaymentParameters::from_node_id(nodes[2]);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2259,8 +2270,8 @@ mod tests {
        fn htlc_minimum_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let payment_params = PaymentParameters::from_node_id(nodes[2]);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2386,8 +2397,9 @@ mod tests {
        fn htlc_minimum_overpay_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(channelmanager::provided_invoice_features());
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config));
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2524,8 +2536,8 @@ mod tests {
        fn disable_channels_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let payment_params = PaymentParameters::from_node_id(nodes[2]);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2584,8 +2596,8 @@ mod tests {
        fn disable_node_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (_, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let payment_params = PaymentParameters::from_node_id(nodes[2]);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2629,12 +2641,12 @@ mod tests {
        fn our_chans_test() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
                // Route to 1 via 2 and 3 because our channel to 1 is disabled
-               let payment_params = PaymentParameters::from_node_id(nodes[0]);
+               let payment_params = PaymentParameters::from_node_id(nodes[0], 42);
                let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
                assert_eq!(route.paths[0].len(), 3);
 
@@ -2660,7 +2672,7 @@ mod tests {
                assert_eq!(route.paths[0][2].channel_features.le_flags(), &id_to_feature_flags(3));
 
                // If we specify a channel to node7, that overrides our local channel view and that gets used
-               let payment_params = PaymentParameters::from_node_id(nodes[2]);
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
                let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)];
                let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::<Vec<_>>()), 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
                assert_eq!(route.paths[0].len(), 2);
@@ -2760,7 +2772,7 @@ mod tests {
        fn partial_route_hint_test() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2784,13 +2796,13 @@ mod tests {
                let mut invalid_last_hops = last_hops_multi_private_channels(&nodes);
                invalid_last_hops.push(invalid_last_hop);
                {
-                       let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(invalid_last_hops);
+                       let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(invalid_last_hops);
                        if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes) {
                                assert_eq!(err, "Route hint cannot have the payee as the source.");
                        } else { panic!(); }
                }
 
-               let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops_multi_private_channels(&nodes));
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops_multi_private_channels(&nodes));
                let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
                assert_eq!(route.paths[0].len(), 5);
 
@@ -2860,8 +2872,8 @@ mod tests {
        fn ignores_empty_last_hops_test() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(empty_last_hop(&nodes));
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(empty_last_hop(&nodes));
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2940,8 +2952,8 @@ mod tests {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (_, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
                let last_hops = multi_hop_last_hops_hint([nodes[2], nodes[3]]);
-               let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops.clone());
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone());
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                // Test through channels 2, 3, 0xff00, 0xff01.
@@ -3014,8 +3026,8 @@ mod tests {
                let non_announced_pubkey = PublicKey::from_secret_key(&secp_ctx, &non_announced_privkey);
 
                let last_hops = multi_hop_last_hops_hint([nodes[2], non_announced_pubkey]);
-               let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops.clone());
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone());
+               let scorer = ln_test_utils::TestScorer::new();
                // Test through channels 2, 3, 0xff00, 0xff01.
                // Test shows that multiple hop hints are considered.
 
@@ -3120,8 +3132,8 @@ mod tests {
        fn last_hops_with_public_channel_test() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops_with_public_channel(&nodes));
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops_with_public_channel(&nodes));
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                // This test shows that public routes can be present in the invoice
@@ -3172,14 +3184,14 @@ mod tests {
        fn our_chans_last_hop_connect_test() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
                // Simple test with outbound channel to 4 to test that last_hops and first_hops connect
                let our_chans = vec![get_channel_details(Some(42), nodes[3].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)];
                let mut last_hops = last_hops(&nodes);
-               let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops.clone());
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone());
                let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::<Vec<_>>()), 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
                assert_eq!(route.paths[0].len(), 2);
 
@@ -3200,7 +3212,7 @@ mod tests {
                last_hops[0].0[0].fees.base_msat = 1000;
 
                // Revert to via 6 as the fee on 8 goes up
-               let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops);
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops);
                let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
                assert_eq!(route.paths[0].len(), 4);
 
@@ -3293,14 +3305,13 @@ mod tests {
                        htlc_minimum_msat: None,
                        htlc_maximum_msat: last_hop_htlc_max,
                }]);
-               let payment_params = PaymentParameters::from_node_id(target_node_id).with_route_hints(vec![last_hops]);
+               let payment_params = PaymentParameters::from_node_id(target_node_id, 42).with_route_hints(vec![last_hops]);
                let our_chans = vec![get_channel_details(Some(42), middle_node_id, InitFeatures::from_le_bytes(vec![0b11]), outbound_capacity_msat)];
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
                let logger = ln_test_utils::TestLogger::new();
-               let network_graph = NetworkGraph::new(genesis_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Testnet, &logger);
                let route = get_route(&source_node_id, &payment_params, &network_graph.read_only(),
                                Some(&our_chans.iter().collect::<Vec<_>>()), route_val, 42, &logger, &scorer, &random_seed_bytes);
                route
@@ -3356,10 +3367,11 @@ mod tests {
 
                let (secp_ctx, network_graph, mut gossip_sync, chain_monitor, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(channelmanager::provided_invoice_features());
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config));
 
                // We will use a simple single-path route from
                // our node to node2 via node0: channels {1, 3}.
@@ -3544,8 +3556,9 @@ mod tests {
                .push_opcode(opcodes::all::OP_PUSHNUM_2)
                .push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script().to_v0_p2wsh();
 
-               *chain_monitor.utxo_ret.lock().unwrap() = Ok(TxOut { value: 15, script_pubkey: good_script.clone() });
-               gossip_sync.add_chain_access(Some(chain_monitor));
+               *chain_monitor.utxo_ret.lock().unwrap() =
+                       UtxoResult::Sync(Ok(TxOut { value: 15, script_pubkey: good_script.clone() }));
+               gossip_sync.add_utxo_lookup(Some(chain_monitor));
 
                add_channel(&gossip_sync, &secp_ctx, &privkeys[0], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 333);
                update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
@@ -3630,10 +3643,11 @@ mod tests {
                // one of the latter hops is limited.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[3]).with_features(channelmanager::provided_invoice_features());
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[3], 42).with_features(channelmanager::provided_invoice_features(&config));
 
                // Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
                // {12, 13, 11} have the capacities of 100, {6} has a capacity of 50.
@@ -3755,10 +3769,10 @@ mod tests {
        fn ignore_fee_first_hop_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[2]);
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
 
                // Path via node0 is channels {1, 3}. Limit them to 100 and 50 sats (total limit 50).
                update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
@@ -3803,11 +3817,12 @@ mod tests {
        fn simple_mpp_route_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[2])
-                       .with_features(channelmanager::provided_invoice_features());
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42)
+                       .with_features(channelmanager::provided_invoice_features(&config));
 
                // We need a route consisting of 3 paths:
                // From our node to node2 via node0, node7, node1 (three paths one hop each).
@@ -3962,10 +3977,11 @@ mod tests {
        fn long_mpp_route_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[3]).with_features(channelmanager::provided_invoice_features());
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[3], 42).with_features(channelmanager::provided_invoice_features(&config));
 
                // We need a route consisting of 3 paths:
                // From our node to node3 via {node0, node2}, {node7, node2, node4} and {node7, node2}.
@@ -4126,10 +4142,11 @@ mod tests {
        fn mpp_cheaper_route_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[3]).with_features(channelmanager::provided_invoice_features());
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[3], 42).with_features(channelmanager::provided_invoice_features(&config));
 
                // This test checks that if we have two cheaper paths and one more expensive path,
                // so that liquidity-wise any 2 of 3 combination is sufficient,
@@ -4295,10 +4312,11 @@ mod tests {
                // if the fee is not properly accounted for, the behavior is different.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[3]).with_features(channelmanager::provided_invoice_features());
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[3], 42).with_features(channelmanager::provided_invoice_features(&config));
 
                // We need a route consisting of 2 paths:
                // From our node to node3 via {node0, node2} and {node7, node2, node4}.
@@ -4476,10 +4494,11 @@ mod tests {
                // This bug appeared in production in some specific channel configurations.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(PublicKey::from_slice(&[02; 33]).unwrap()).with_features(channelmanager::provided_invoice_features())
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(PublicKey::from_slice(&[02; 33]).unwrap(), 42).with_features(channelmanager::provided_invoice_features(&config))
                        .with_route_hints(vec![RouteHint(vec![RouteHintHop {
                                src_node_id: nodes[2],
                                short_channel_id: 42,
@@ -4567,10 +4586,11 @@ mod tests {
                // path finding we realize that we found more capacity than we need.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(channelmanager::provided_invoice_features())
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config))
                        .with_max_channel_saturation_power_of_half(0);
 
                // We need a route consisting of 3 paths:
@@ -4723,15 +4743,14 @@ mod tests {
                // payment) htlc_minimum_msat. In the original algorithm, this resulted in node4's
                // "previous hop" being set to node 3, creating a loop in the path.
                let secp_ctx = Secp256k1::new();
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
                let logger = Arc::new(ln_test_utils::TestLogger::new());
-               let network = Arc::new(NetworkGraph::new(genesis_hash, Arc::clone(&logger)));
+               let network = Arc::new(NetworkGraph::new(Network::Testnet, Arc::clone(&logger)));
                let gossip_sync = P2PGossipSync::new(Arc::clone(&network), None, Arc::clone(&logger));
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[6]);
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42);
 
                add_channel(&gossip_sync, &secp_ctx, &our_privkey, &privkeys[1], ChannelFeatures::from_le_bytes(id_to_feature_flags(6)), 6);
                update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
@@ -4859,10 +4878,10 @@ mod tests {
                // we calculated fees on a higher value, resulting in us ignoring such paths.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[2]);
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
 
                // We modify the graph to set the htlc_maximum of channel 2 to below the value we wish to
                // send.
@@ -4923,10 +4942,11 @@ mod tests {
                // resulting in us thinking there is no possible path, even if other paths exist.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(channelmanager::provided_invoice_features());
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config));
 
                // We modify the graph to set the htlc_minimum of channel 2 and 4 as needed - channel 2
                // gets an htlc_maximum_msat of 80_000 and channel 4 an htlc_minimum_msat of 90_000. We
@@ -4975,7 +4995,7 @@ mod tests {
                        assert_eq!(route.paths[0][1].short_channel_id, 13);
                        assert_eq!(route.paths[0][1].fee_msat, 90_000);
                        assert_eq!(route.paths[0][1].cltv_expiry_delta, 42);
-                       assert_eq!(route.paths[0][1].node_features.le_flags(), channelmanager::provided_invoice_features().le_flags());
+                       assert_eq!(route.paths[0][1].node_features.le_flags(), channelmanager::provided_invoice_features(&config).le_flags());
                        assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags(13));
                }
        }
@@ -4990,18 +5010,18 @@ mod tests {
                // route over multiple channels with the same first hop.
                let secp_ctx = Secp256k1::new();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
                let logger = Arc::new(ln_test_utils::TestLogger::new());
-               let network_graph = NetworkGraph::new(genesis_hash, Arc::clone(&logger));
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
-               let payment_params = PaymentParameters::from_node_id(nodes[0]).with_features(channelmanager::provided_invoice_features());
+               let network_graph = NetworkGraph::new(Network::Testnet, Arc::clone(&logger));
+               let scorer = ln_test_utils::TestScorer::new();
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[0], 42).with_features(channelmanager::provided_invoice_features(&config));
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
                {
                        let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&[
-                               &get_channel_details(Some(3), nodes[0], channelmanager::provided_init_features(), 200_000),
-                               &get_channel_details(Some(2), nodes[0], channelmanager::provided_init_features(), 10_000),
+                               &get_channel_details(Some(3), nodes[0], channelmanager::provided_init_features(&config), 200_000),
+                               &get_channel_details(Some(2), nodes[0], channelmanager::provided_init_features(&config), 10_000),
                        ]), 100_000, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
                        assert_eq!(route.paths.len(), 1);
                        assert_eq!(route.paths[0].len(), 1);
@@ -5012,8 +5032,8 @@ mod tests {
                }
                {
                        let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&[
-                               &get_channel_details(Some(3), nodes[0], channelmanager::provided_init_features(), 50_000),
-                               &get_channel_details(Some(2), nodes[0], channelmanager::provided_init_features(), 50_000),
+                               &get_channel_details(Some(3), nodes[0], channelmanager::provided_init_features(&config), 50_000),
+                               &get_channel_details(Some(2), nodes[0], channelmanager::provided_init_features(&config), 50_000),
                        ]), 100_000, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
                        assert_eq!(route.paths.len(), 2);
                        assert_eq!(route.paths[0].len(), 1);
@@ -5038,14 +5058,14 @@ mod tests {
                        // smallest of them, avoiding further fragmenting our available outbound balance to
                        // this node.
                        let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&[
-                               &get_channel_details(Some(2), nodes[0], channelmanager::provided_init_features(), 50_000),
-                               &get_channel_details(Some(3), nodes[0], channelmanager::provided_init_features(), 50_000),
-                               &get_channel_details(Some(5), nodes[0], channelmanager::provided_init_features(), 50_000),
-                               &get_channel_details(Some(6), nodes[0], channelmanager::provided_init_features(), 300_000),
-                               &get_channel_details(Some(7), nodes[0], channelmanager::provided_init_features(), 50_000),
-                               &get_channel_details(Some(8), nodes[0], channelmanager::provided_init_features(), 50_000),
-                               &get_channel_details(Some(9), nodes[0], channelmanager::provided_init_features(), 50_000),
-                               &get_channel_details(Some(4), nodes[0], channelmanager::provided_init_features(), 1_000_000),
+                               &get_channel_details(Some(2), nodes[0], channelmanager::provided_init_features(&config), 50_000),
+                               &get_channel_details(Some(3), nodes[0], channelmanager::provided_init_features(&config), 50_000),
+                               &get_channel_details(Some(5), nodes[0], channelmanager::provided_init_features(&config), 50_000),
+                               &get_channel_details(Some(6), nodes[0], channelmanager::provided_init_features(&config), 300_000),
+                               &get_channel_details(Some(7), nodes[0], channelmanager::provided_init_features(&config), 50_000),
+                               &get_channel_details(Some(8), nodes[0], channelmanager::provided_init_features(&config), 50_000),
+                               &get_channel_details(Some(9), nodes[0], channelmanager::provided_init_features(&config), 50_000),
+                               &get_channel_details(Some(4), nodes[0], channelmanager::provided_init_features(&config), 1_000_000),
                        ]), 100_000, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
                        assert_eq!(route.paths.len(), 1);
                        assert_eq!(route.paths[0].len(), 1);
@@ -5060,10 +5080,10 @@ mod tests {
        fn prefers_shorter_route_with_higher_fees() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes));
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes));
 
                // Without penalizing each hop 100 msats, a longer path with lower fees is chosen.
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let route = get_route(
@@ -5078,7 +5098,7 @@ mod tests {
 
                // Applying a 100 msat penalty to each hop results in taking channels 7 and 10 to nodes[6]
                // from nodes[2] rather than channel 6, 11, and 8, even though the longer path is cheaper.
-               let scorer = ln_test_utils::TestScorer::with_penalty(100);
+               let scorer = FixedPenaltyScorer::with_penalty(100);
                let route = get_route(
                        &our_id, &payment_params, &network_graph.read_only(), None, 100, 42,
                        Arc::clone(&logger), &scorer, &random_seed_bytes
@@ -5133,11 +5153,11 @@ mod tests {
        fn avoids_routing_through_bad_channels_and_nodes() {
                let (secp_ctx, network, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes));
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes));
                let network_graph = network.read_only();
 
                // A path to nodes[6] exists when no penalties are applied to any channel.
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let route = get_route(
@@ -5252,11 +5272,11 @@ mod tests {
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
                let network_graph = network.read_only();
 
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
 
                // Make sure that generally there is at least one route available
                let feasible_max_total_cltv_delta = 1008;
-               let feasible_payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes))
+               let feasible_payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes))
                        .with_max_total_cltv_expiry_delta(feasible_max_total_cltv_delta);
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
@@ -5266,7 +5286,7 @@ mod tests {
 
                // But not if we exclude all paths on the basis of their accumulated CLTV delta
                let fail_max_total_cltv_delta = 23;
-               let fail_payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes))
+               let fail_payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes))
                        .with_max_total_cltv_expiry_delta(fail_max_total_cltv_delta);
                match get_route(&our_id, &fail_payment_params, &network_graph, None, 100, 0, Arc::clone(&logger), &scorer, &random_seed_bytes)
                {
@@ -5285,8 +5305,8 @@ mod tests {
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
                let network_graph = network.read_only();
 
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
-               let mut payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes))
+               let scorer = ln_test_utils::TestScorer::new();
+               let mut payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes))
                        .with_max_path_count(1);
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
@@ -5312,19 +5332,19 @@ mod tests {
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
                let network_graph = network.read_only();
 
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
                // First check we can actually create a long route on this graph.
-               let feasible_payment_params = PaymentParameters::from_node_id(nodes[18]);
+               let feasible_payment_params = PaymentParameters::from_node_id(nodes[18], 0);
                let route = get_route(&our_id, &feasible_payment_params, &network_graph, None, 100, 0,
                        Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
                let path = route.paths[0].iter().map(|hop| hop.short_channel_id).collect::<Vec<_>>();
                assert!(path.len() == MAX_PATH_LENGTH_ESTIMATE.into());
 
                // But we can't create a path surpassing the MAX_PATH_LENGTH_ESTIMATE limit.
-               let fail_payment_params = PaymentParameters::from_node_id(nodes[19]);
+               let fail_payment_params = PaymentParameters::from_node_id(nodes[19], 0);
                match get_route(&our_id, &fail_payment_params, &network_graph, None, 100, 0,
                        Arc::clone(&logger), &scorer, &random_seed_bytes)
                {
@@ -5340,9 +5360,9 @@ mod tests {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
 
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
 
-               let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes));
+               let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes));
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
@@ -5374,8 +5394,8 @@ mod tests {
                let network_graph = network.read_only();
                let network_nodes = network_graph.nodes();
                let network_channels = network_graph.channels();
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
-               let payment_params = PaymentParameters::from_node_id(nodes[3]);
+               let scorer = ln_test_utils::TestScorer::new();
+               let payment_params = PaymentParameters::from_node_id(nodes[3], 0);
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[4u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -5442,7 +5462,7 @@ mod tests {
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
-               let payment_params = PaymentParameters::from_node_id(nodes[3]);
+               let payment_params = PaymentParameters::from_node_id(nodes[3], 0);
                let hops = [nodes[1], nodes[2], nodes[4], nodes[3]];
                let route = build_route_from_hops_internal(&our_id, &hops, &payment_params,
                         &network_graph, 100, 0, Arc::clone(&logger), &random_seed_bytes).unwrap();
@@ -5487,7 +5507,8 @@ mod tests {
                        excess_data: Vec::new()
                });
 
-               let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(channelmanager::provided_invoice_features());
+               let config = UserConfig::default();
+               let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config));
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                // 100,000 sats is less than the available liquidity on each channel, set above.
@@ -5531,10 +5552,10 @@ mod tests {
                'load_endpoints: for _ in 0..10 {
                        loop {
                                seed = seed.overflowing_mul(0xdeadbeef).0;
-                               let src = &PublicKey::from_slice(nodes.keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
+                               let src = &PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
                                seed = seed.overflowing_mul(0xdeadbeef).0;
-                               let dst = PublicKey::from_slice(nodes.keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
-                               let payment_params = PaymentParameters::from_node_id(dst);
+                               let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
+                               let payment_params = PaymentParameters::from_node_id(dst, 42);
                                let amt = seed as u64 % 200_000_000;
                                let params = ProbabilisticScoringParameters::default();
                                let scorer = ProbabilisticScorer::new(params, &graph, &logger);
@@ -5561,6 +5582,7 @@ mod tests {
                let graph = NetworkGraph::read(&mut d, &logger).unwrap();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
+               let config = UserConfig::default();
 
                // First, get 100 (source, destination) pairs for which route-getting actually succeeds...
                let mut seed = random_init_seed() as usize;
@@ -5568,10 +5590,10 @@ mod tests {
                'load_endpoints: for _ in 0..10 {
                        loop {
                                seed = seed.overflowing_mul(0xdeadbeef).0;
-                               let src = &PublicKey::from_slice(nodes.keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
+                               let src = &PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
                                seed = seed.overflowing_mul(0xdeadbeef).0;
-                               let dst = PublicKey::from_slice(nodes.keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
-                               let payment_params = PaymentParameters::from_node_id(dst).with_features(channelmanager::provided_invoice_features());
+                               let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
+                               let payment_params = PaymentParameters::from_node_id(dst, 42).with_features(channelmanager::provided_invoice_features(&config));
                                let amt = seed as u64 % 200_000_000;
                                let params = ProbabilisticScoringParameters::default();
                                let scorer = ProbabilisticScorer::new(params, &graph, &logger);
@@ -5604,7 +5626,7 @@ mod tests {
                assert_eq!(scorer.channel_penalty_msat(42, &NodeId::from_pubkey(&nodes[3]), &NodeId::from_pubkey(&nodes[4]), usage), 456);
 
                // Then check we can get a normal route
-               let payment_params = PaymentParameters::from_node_id(nodes[10]);
+               let payment_params = PaymentParameters::from_node_id(nodes[10], 42);
                let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes);
                assert!(route.is_ok());
 
@@ -5625,8 +5647,8 @@ pub(crate) mod bench_utils {
        use std::fs::File;
        /// Tries to open a network graph file, or panics with a URL to fetch it.
        pub(crate) fn get_route_file() -> Result<std::fs::File, &'static str> {
-               let res = File::open("net_graph-2021-05-31.bin") // By default we're run in RL/lightning
-                       .or_else(|_| File::open("lightning/net_graph-2021-05-31.bin")) // We may be run manually in RL/
+               let res = File::open("net_graph-2023-01-18.bin") // By default we're run in RL/lightning
+                       .or_else(|_| File::open("lightning/net_graph-2023-01-18.bin")) // We may be run manually in RL/
                        .or_else(|_| { // Fall back to guessing based on the binary location
                                // path is likely something like .../rust-lightning/target/debug/deps/lightning-...
                                let mut path = std::env::current_exe().unwrap();
@@ -5635,11 +5657,11 @@ pub(crate) mod bench_utils {
                                path.pop(); // debug
                                path.pop(); // target
                                path.push("lightning");
-                               path.push("net_graph-2021-05-31.bin");
+                               path.push("net_graph-2023-01-18.bin");
                                eprintln!("{}", path.to_str().unwrap());
                                File::open(path)
                        })
-               .map_err(|_| "Please fetch https://bitcoin.ninja/ldk-net_graph-v0.0.15-2021-05-31.bin and place it at lightning/net_graph-2021-05-31.bin");
+               .map_err(|_| "Please fetch https://bitcoin.ninja/ldk-net_graph-v0.0.113-2023-01-18.bin and place it at lightning/net_graph-2023-01-18.bin");
                #[cfg(require_route_graph_test)]
                return Ok(res.unwrap());
                #[cfg(not(require_route_graph_test))]
@@ -5653,11 +5675,12 @@ mod benches {
        use bitcoin::hashes::Hash;
        use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
        use crate::chain::transaction::OutPoint;
-       use crate::chain::keysinterface::{EntropySource, KeysManager,KeysInterface};
+       use crate::chain::keysinterface::{EntropySource, KeysManager};
        use crate::ln::channelmanager::{self, ChannelCounterparty, ChannelDetails};
        use crate::ln::features::InvoiceFeatures;
        use crate::routing::gossip::NetworkGraph;
        use crate::routing::scoring::{FixedPenaltyScorer, ProbabilisticScorer, ProbabilisticScoringParameters};
+       use crate::util::config::UserConfig;
        use crate::util::logger::{Logger, Record};
        use crate::util::ser::ReadableArgs;
 
@@ -5683,7 +5706,7 @@ mod benches {
                ChannelDetails {
                        channel_id: [0; 32],
                        counterparty: ChannelCounterparty {
-                               features: channelmanager::provided_init_features(),
+                               features: channelmanager::provided_init_features(&UserConfig::default()),
                                node_id,
                                unspendable_punishment_reserve: 0,
                                forwarding_info: None,
@@ -5730,7 +5753,7 @@ mod benches {
                let logger = DummyLogger {};
                let network_graph = read_network_graph(&logger);
                let scorer = FixedPenaltyScorer::with_penalty(0);
-               generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features());
+               generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
        }
 
        #[bench]
@@ -5748,7 +5771,7 @@ mod benches {
                let network_graph = read_network_graph(&logger);
                let params = ProbabilisticScoringParameters::default();
                let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
-               generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features());
+               generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
        }
 
        fn generate_routes<S: Score>(
@@ -5767,10 +5790,10 @@ mod benches {
                'load_endpoints: for _ in 0..150 {
                        loop {
                                seed *= 0xdeadbeef;
-                               let src = PublicKey::from_slice(nodes.keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
+                               let src = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
                                seed *= 0xdeadbeef;
-                               let dst = PublicKey::from_slice(nodes.keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
-                               let params = PaymentParameters::from_node_id(dst).with_features(features.clone());
+                               let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
+                               let params = PaymentParameters::from_node_id(dst, 42).with_features(features.clone());
                                let first_hop = first_hop(src);
                                let amt = seed as u64 % 1_000_000;
                                if let Ok(route) = get_route(&payer, &params, &graph.read_only(), Some(&[&first_hop]), amt, 42, &DummyLogger{}, &scorer, &random_seed_bytes) {
index 860f3cb195418054322cd551f5e7487b84af8cad..31158d41bc37570b7f95a98b5fb48bb9b68ea52d 100644 (file)
@@ -20,7 +20,7 @@
 //! # use lightning::routing::gossip::NetworkGraph;
 //! # use lightning::routing::router::{RouteParameters, find_route};
 //! # use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringParameters};
-//! # use lightning::chain::keysinterface::{KeysManager, KeysInterface};
+//! # use lightning::chain::keysinterface::KeysManager;
 //! # use lightning::util::logger::{Logger, Record};
 //! # use bitcoin::secp256k1::PublicKey;
 //! #
@@ -260,7 +260,7 @@ impl<'a, S: Writeable> Writeable for MutexGuard<'a, S> {
 }
 
 /// Proposed use of a channel passed as a parameter to [`Score::channel_penalty_msat`].
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Copy, Debug, PartialEq)]
 pub struct ChannelUsage {
        /// The amount to send through the channel, denominated in millisatoshis.
        pub amount_msat: u64,
@@ -597,7 +597,22 @@ struct HistoricalMinMaxBuckets<'a> {
 
 impl HistoricalMinMaxBuckets<'_> {
        #[inline]
-       fn calculate_success_probability_times_billion(&self, required_decays: u32, payment_amt_64th_bucket: u8) -> Option<u64> {
+       fn get_decayed_buckets<T: Time>(&self, now: T, last_updated: T, half_life: Duration)
+       -> ([u16; 8], [u16; 8], u32) {
+               let required_decays = now.duration_since(last_updated).as_secs()
+                       .checked_div(half_life.as_secs())
+                       .map_or(u32::max_value(), |decays| cmp::min(decays, u32::max_value() as u64) as u32);
+               let mut min_buckets = *self.min_liquidity_offset_history;
+               min_buckets.time_decay_data(required_decays);
+               let mut max_buckets = *self.max_liquidity_offset_history;
+               max_buckets.time_decay_data(required_decays);
+               (min_buckets.buckets, max_buckets.buckets, required_decays)
+       }
+
+       #[inline]
+       fn calculate_success_probability_times_billion<T: Time>(
+               &self, now: T, last_updated: T, half_life: Duration, payment_amt_64th_bucket: u8)
+       -> Option<u64> {
                // If historical penalties are enabled, calculate the penalty by walking the set of
                // historical liquidity bucket (min, max) combinations (where min_idx < max_idx) and, for
                // each, calculate the probability of success given our payment amount, then total the
@@ -619,23 +634,22 @@ impl HistoricalMinMaxBuckets<'_> {
                // less than 1/16th of a channel's capacity, or 1/8th if we used the top of the bucket.
                let mut total_valid_points_tracked = 0;
 
-               // Rather than actually decaying the individual buckets, which would lose precision, we
-               // simply track whether all buckets would be decayed to zero, in which case we treat it as
-               // if we had no data.
-               let mut is_fully_decayed = true;
-               let mut check_track_bucket_contains_undecayed_points =
-                       |bucket_val: u16| if bucket_val.checked_shr(required_decays).unwrap_or(0) > 0 { is_fully_decayed = false; };
+               // Check if all our buckets are zero, once decayed and treat it as if we had no data. We
+               // don't actually use the decayed buckets, though, as that would lose precision.
+               let (decayed_min_buckets, decayed_max_buckets, required_decays) =
+                       self.get_decayed_buckets(now, last_updated, half_life);
+               if decayed_min_buckets.iter().all(|v| *v == 0) || decayed_max_buckets.iter().all(|v| *v == 0) {
+                       return None;
+               }
 
                for (min_idx, min_bucket) in self.min_liquidity_offset_history.buckets.iter().enumerate() {
-                       check_track_bucket_contains_undecayed_points(*min_bucket);
                        for max_bucket in self.max_liquidity_offset_history.buckets.iter().take(8 - min_idx) {
                                total_valid_points_tracked += (*min_bucket as u64) * (*max_bucket as u64);
-                               check_track_bucket_contains_undecayed_points(*max_bucket);
                        }
                }
                // If the total valid points is smaller than 1.0 (i.e. 32 in our fixed-point scheme), treat
                // it as if we were fully decayed.
-               if total_valid_points_tracked.checked_shr(required_decays).unwrap_or(0) < 32*32 || is_fully_decayed {
+               if total_valid_points_tracked.checked_shr(required_decays).unwrap_or(0) < 32*32 {
                        return None;
                }
 
@@ -717,6 +731,8 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> ProbabilisticScorerU
        /// Note that this writes roughly one line per channel for which we have a liquidity estimate,
        /// which may be a substantial amount of log output.
        pub fn debug_log_liquidity_stats(&self) {
+               let now = T::now();
+
                let graph = self.network_graph.read_only();
                for (scid, liq) in self.channel_liquidities.iter() {
                        if let Some(chan_debug) = graph.channels().get(scid) {
@@ -724,8 +740,25 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> ProbabilisticScorerU
                                        if let Some((directed_info, _)) = chan_debug.as_directed_to(target) {
                                                let amt = directed_info.effective_capacity().as_msat();
                                                let dir_liq = liq.as_directed(source, target, amt, &self.params);
-                                               log_debug!(self.logger, "Liquidity from {:?} to {:?} via {} is in the range ({}, {})",
-                                                       source, target, scid, dir_liq.min_liquidity_msat(), dir_liq.max_liquidity_msat());
+
+                                               let buckets = HistoricalMinMaxBuckets {
+                                                       min_liquidity_offset_history: &dir_liq.min_liquidity_offset_history,
+                                                       max_liquidity_offset_history: &dir_liq.max_liquidity_offset_history,
+                                               };
+                                               let (min_buckets, max_buckets, _) = buckets.get_decayed_buckets(now,
+                                                       *dir_liq.last_updated, self.params.historical_no_updates_half_life);
+
+                                               log_debug!(self.logger, core::concat!(
+                                                       "Liquidity from {} to {} via {} is in the range ({}, {}).\n",
+                                                       "\tHistorical min liquidity octile relative probabilities: {} {} {} {} {} {} {} {}\n",
+                                                       "\tHistorical max liquidity octile relative probabilities: {} {} {} {} {} {} {} {}"),
+                                                       source, target, scid, dir_liq.min_liquidity_msat(), dir_liq.max_liquidity_msat(),
+                                                       min_buckets[0], min_buckets[1], min_buckets[2], min_buckets[3],
+                                                       min_buckets[4], min_buckets[5], min_buckets[6], min_buckets[7],
+                                                       // Note that the liquidity buckets are an offset from the edge, so we
+                                                       // inverse the max order to get the probabilities from zero.
+                                                       max_buckets[7], max_buckets[6], max_buckets[5], max_buckets[4],
+                                                       max_buckets[3], max_buckets[2], max_buckets[1], max_buckets[0]);
                                        } else {
                                                log_debug!(self.logger, "No amount known for SCID {} from {:?} to {:?}", scid, source, target);
                                        }
@@ -756,6 +789,53 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> ProbabilisticScorerU
                None
        }
 
+       /// Query the historical estimated minimum and maximum liquidity available for sending a
+       /// payment over the channel with `scid` towards the given `target` node.
+       ///
+       /// Returns two sets of 8 buckets. The first set describes the octiles for lower-bound
+       /// liquidity estimates, the second set describes the octiles for upper-bound liquidity
+       /// estimates. Each bucket describes the relative frequency at which we've seen a liquidity
+       /// bound in the octile relative to the channel's total capacity, on an arbitrary scale.
+       /// Because the values are slowly decayed, more recent data points are weighted more heavily
+       /// than older datapoints.
+       ///
+       /// When scoring, the estimated probability that an upper-/lower-bound lies in a given octile
+       /// relative to the channel's total capacity is calculated by dividing that bucket's value with
+       /// the total of all buckets for the given bound.
+       ///
+       /// For example, a value of `[0, 0, 0, 0, 0, 0, 32]` indicates that we believe the probability
+       /// of a bound being in the top octile to be 100%, and have never (recently) seen it in any
+       /// other octiles. A value of `[31, 0, 0, 0, 0, 0, 0, 32]` indicates we've seen the bound being
+       /// both in the top and bottom octile, and roughly with similar (recent) frequency.
+       ///
+       /// Because the datapoints are decayed slowly over time, values will eventually return to
+       /// `Some(([0; 8], [0; 8]))`.
+       pub fn historical_estimated_channel_liquidity_probabilities(&self, scid: u64, target: &NodeId)
+       -> Option<([u16; 8], [u16; 8])> {
+               let graph = self.network_graph.read_only();
+
+               if let Some(chan) = graph.channels().get(&scid) {
+                       if let Some(liq) = self.channel_liquidities.get(&scid) {
+                               if let Some((directed_info, source)) = chan.as_directed_to(target) {
+                                       let amt = directed_info.effective_capacity().as_msat();
+                                       let dir_liq = liq.as_directed(source, target, amt, &self.params);
+
+                                       let buckets = HistoricalMinMaxBuckets {
+                                               min_liquidity_offset_history: &dir_liq.min_liquidity_offset_history,
+                                               max_liquidity_offset_history: &dir_liq.max_liquidity_offset_history,
+                                       };
+                                       let (min_buckets, mut max_buckets, _) = buckets.get_decayed_buckets(T::now(),
+                                               *dir_liq.last_updated, self.params.historical_no_updates_half_life);
+                                       // Note that the liquidity buckets are an offset from the edge, so we inverse
+                                       // the max order to get the probabilities from zero.
+                                       max_buckets.reverse();
+                                       return Some((min_buckets, max_buckets));
+                               }
+                       }
+               }
+               None
+       }
+
        /// Marks the node with the given `node_id` as banned, i.e.,
        /// it will be avoided during path finding.
        pub fn add_banned(&mut self, node_id: &NodeId) {
@@ -942,9 +1022,6 @@ impl<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>,
 
                if params.historical_liquidity_penalty_multiplier_msat != 0 ||
                   params.historical_liquidity_penalty_amount_multiplier_msat != 0 {
-                       let required_decays = self.now.duration_since(*self.last_updated).as_secs()
-                               .checked_div(params.historical_no_updates_half_life.as_secs())
-                               .map_or(u32::max_value(), |decays| cmp::min(decays, u32::max_value() as u64) as u32);
                        let payment_amt_64th_bucket = amount_msat * 64 / self.capacity_msat;
                        debug_assert!(payment_amt_64th_bucket <= 64);
                        if payment_amt_64th_bucket > 64 { return res; }
@@ -954,7 +1031,9 @@ impl<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>,
                                max_liquidity_offset_history: &self.max_liquidity_offset_history,
                        };
                        if let Some(cumulative_success_prob_times_billion) = buckets
-                                       .calculate_success_probability_times_billion(required_decays, payment_amt_64th_bucket as u8) {
+                               .calculate_success_probability_times_billion(self.now, *self.last_updated,
+                                       params.historical_no_updates_half_life, payment_amt_64th_bucket as u8)
+                       {
                                let historical_negative_log10_times_2048 = approx::negative_log10_times_2048(cumulative_success_prob_times_billion + 1, 1024 * 1024 * 1024);
                                res = res.saturating_add(Self::combined_penalty_msat(amount_msat,
                                        historical_negative_log10_times_2048, params.historical_liquidity_penalty_multiplier_msat,
@@ -1602,6 +1681,7 @@ impl<T: Time> Readable for ChannelLiquidity<T> {
 #[cfg(test)]
 mod tests {
        use super::{ChannelLiquidity, HistoricalBucketRangeTracker, ProbabilisticScoringParameters, ProbabilisticScorerUsingTime};
+       use crate::util::config::UserConfig;
        use crate::util::time::Time;
        use crate::util::time::tests::SinceEpoch;
 
@@ -1679,8 +1759,7 @@ mod tests {
        }
 
        fn network_graph(logger: &TestLogger) -> NetworkGraph<&TestLogger> {
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
-               let mut network_graph = NetworkGraph::new(genesis_hash, logger);
+               let mut network_graph = NetworkGraph::new(Network::Testnet, logger);
                add_channel(&mut network_graph, 42, source_privkey(), target_privkey());
                add_channel(&mut network_graph, 43, target_privkey(), recipient_privkey());
 
@@ -1696,13 +1775,13 @@ mod tests {
                let node_2_secret = &SecretKey::from_slice(&[40; 32]).unwrap();
                let secp_ctx = Secp256k1::new();
                let unsigned_announcement = UnsignedChannelAnnouncement {
-                       features: channelmanager::provided_channel_features(),
+                       features: channelmanager::provided_channel_features(&UserConfig::default()),
                        chain_hash: genesis_hash,
                        short_channel_id,
-                       node_id_1: PublicKey::from_secret_key(&secp_ctx, &node_1_key),
-                       node_id_2: PublicKey::from_secret_key(&secp_ctx, &node_2_key),
-                       bitcoin_key_1: PublicKey::from_secret_key(&secp_ctx, &node_1_secret),
-                       bitcoin_key_2: PublicKey::from_secret_key(&secp_ctx, &node_2_secret),
+                       node_id_1: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_1_key)),
+                       node_id_2: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_2_key)),
+                       bitcoin_key_1: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_1_secret)),
+                       bitcoin_key_2: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_2_secret)),
                        excess_data: Vec::new(),
                };
                let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_announcement.encode()[..])[..]);
@@ -1747,11 +1826,12 @@ mod tests {
        }
 
        fn path_hop(pubkey: PublicKey, short_channel_id: u64, fee_msat: u64) -> RouteHop {
+               let config = UserConfig::default();
                RouteHop {
                        pubkey,
-                       node_features: channelmanager::provided_node_features(),
+                       node_features: channelmanager::provided_node_features(&config),
                        short_channel_id,
-                       channel_features: channelmanager::provided_channel_features(),
+                       channel_features: channelmanager::provided_channel_features(&config),
                        fee_msat,
                        cltv_expiry_delta: 18,
                }
@@ -2145,8 +2225,7 @@ mod tests {
                // we do not score such channels.
                let secp_ctx = Secp256k1::new();
                let logger = TestLogger::new();
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
-               let mut network_graph = NetworkGraph::new(genesis_hash, &logger);
+               let mut network_graph = NetworkGraph::new(Network::Testnet, &logger);
                let secret_a = SecretKey::from_slice(&[42; 32]).unwrap();
                let secret_b = SecretKey::from_slice(&[43; 32]).unwrap();
                let secret_c = SecretKey::from_slice(&[44; 32]).unwrap();
@@ -2669,19 +2748,32 @@ mod tests {
                };
                // With no historical data the normal liquidity penalty calculation is used.
                assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 47);
+               assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
+                       None);
 
                scorer.payment_path_failed(&payment_path_for_amount(1).iter().collect::<Vec<_>>(), 42);
                assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2048);
+               // The "it failed" increment is 32, where the probability should lie fully in the first
+               // octile.
+               assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
+                       Some(([32, 0, 0, 0, 0, 0, 0, 0], [32, 0, 0, 0, 0, 0, 0, 0])));
 
                // Even after we tell the scorer we definitely have enough available liquidity, it will
                // still remember that there was some failure in the past, and assign a non-0 penalty.
                scorer.payment_path_failed(&payment_path_for_amount(1000).iter().collect::<Vec<_>>(), 43);
                assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 198);
+               // The first octile should be decayed just slightly and the last octile has a new point.
+               assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
+                       Some(([31, 0, 0, 0, 0, 0, 0, 32], [31, 0, 0, 0, 0, 0, 0, 32])));
 
                // Advance the time forward 16 half-lives (which the docs claim will ensure all data is
                // gone), and check that we're back to where we started.
                SinceEpoch::advance(Duration::from_secs(10 * 16));
                assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 47);
+               // Once fully decayed we still have data, but its all-0s. In the future we may remove the
+               // data entirely instead.
+               assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
+                       Some(([0; 8], [0; 8])));
        }
 
        #[test]
index a5d2af43c6ccbf90d04a6274d997c34689d03247..68264207f589e249fd90bde0a6d00298c2621b74 100644 (file)
@@ -27,13 +27,15 @@ use bitcoin::secp256k1::{Secp256k1, All};
 use crate::prelude::*;
 use crate::sync::{self, Arc};
 
+use crate::routing::gossip::NodeId;
+
 // Using the same keys for LN and BTC ids
 pub(super) fn add_channel(
        gossip_sync: &P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
        secp_ctx: &Secp256k1<All>, node_1_privkey: &SecretKey, node_2_privkey: &SecretKey, features: ChannelFeatures, short_channel_id: u64
 ) {
-       let node_id_1 = PublicKey::from_secret_key(&secp_ctx, node_1_privkey);
-       let node_id_2 = PublicKey::from_secret_key(&secp_ctx, node_2_privkey);
+       let node_id_1 = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_1_privkey));
+       let node_id_2 = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_2_privkey));
 
        let unsigned_announcement = UnsignedChannelAnnouncement {
                features,
@@ -64,7 +66,7 @@ pub(super) fn add_or_update_node(
        gossip_sync: &P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
        secp_ctx: &Secp256k1<All>, node_privkey: &SecretKey, features: NodeFeatures, timestamp: u32
 ) {
-       let node_id = PublicKey::from_secret_key(&secp_ctx, node_privkey);
+       let node_id = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_privkey));
        let unsigned_announcement = UnsignedNodeAnnouncement {
                features,
                timestamp,
@@ -139,8 +141,7 @@ pub(super) fn build_line_graph() -> (
        let secp_ctx = Secp256k1::new();
        let logger = Arc::new(test_utils::TestLogger::new());
        let chain_monitor = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
-       let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
-       let network_graph = Arc::new(NetworkGraph::new(genesis_hash, Arc::clone(&logger)));
+       let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, Arc::clone(&logger)));
        let gossip_sync = P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger));
 
        // Build network from our_id to node 19:
@@ -193,8 +194,7 @@ pub(super) fn build_graph() -> (
        let secp_ctx = Secp256k1::new();
        let logger = Arc::new(test_utils::TestLogger::new());
        let chain_monitor = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
-       let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
-       let network_graph = Arc::new(NetworkGraph::new(genesis_hash, Arc::clone(&logger)));
+       let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, Arc::clone(&logger)));
        let gossip_sync = P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger));
        // Build network from our_id to node6:
        //
diff --git a/lightning/src/routing/utxo.rs b/lightning/src/routing/utxo.rs
new file mode 100644 (file)
index 0000000..74abd42
--- /dev/null
@@ -0,0 +1,863 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+//! This module contains traits for LDK to access UTXOs to check gossip data is correct.
+//!
+//! When lightning nodes gossip channel information, they resist DoS attacks by checking that each
+//! channel matches a UTXO on-chain, requiring at least some marginal on-chain transacting in
+//! order to announce a channel. This module handles that checking.
+
+use bitcoin::{BlockHash, TxOut};
+use bitcoin::hashes::hex::ToHex;
+
+use crate::ln::chan_utils::make_funding_redeemscript_from_slices;
+use crate::ln::msgs::{self, LightningError, ErrorAction};
+use crate::routing::gossip::{NetworkGraph, NodeId, P2PGossipSync};
+use crate::util::events::MessageSendEvent;
+use crate::util::logger::{Level, Logger};
+use crate::util::ser::Writeable;
+
+use crate::prelude::*;
+
+use alloc::sync::{Arc, Weak};
+use crate::sync::{Mutex, LockTestExt};
+use core::ops::Deref;
+
+/// An error when accessing the chain via [`UtxoLookup`].
+#[derive(Clone, Debug)]
+pub enum UtxoLookupError {
+       /// The requested chain is unknown.
+       UnknownChain,
+
+       /// The requested transaction doesn't exist or hasn't confirmed.
+       UnknownTx,
+}
+
+/// The result of a [`UtxoLookup::get_utxo`] call. A call may resolve either synchronously,
+/// returning the `Sync` variant, or asynchronously, returning an [`UtxoFuture`] in the `Async`
+/// variant.
+#[derive(Clone)]
+pub enum UtxoResult {
+       /// A result which was resolved synchronously. It either includes a [`TxOut`] for the output
+       /// requested or a [`UtxoLookupError`].
+       Sync(Result<TxOut, UtxoLookupError>),
+       /// A result which will be resolved asynchronously. It includes a [`UtxoFuture`], a `clone` of
+       /// which you must keep locally and call [`UtxoFuture::resolve`] on once the lookup completes.
+       ///
+       /// Note that in order to avoid runaway memory usage, the number of parallel checks is limited,
+       /// but only fairly loosely. Because a pending checks block all message processing, leaving
+       /// checks pending for an extended time may cause DoS of other functions. It is recommended you
+       /// keep a tight timeout on lookups, on the order of a few seconds.
+       Async(UtxoFuture),
+}
+
+/// The `UtxoLookup` trait defines behavior for accessing on-chain UTXOs.
+pub trait UtxoLookup {
+       /// Returns the transaction output of a funding transaction encoded by [`short_channel_id`].
+       /// Returns an error if `genesis_hash` is for a different chain or if such a transaction output
+       /// is unknown.
+       ///
+       /// [`short_channel_id`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#definition-of-short_channel_id
+       fn get_utxo(&self, genesis_hash: &BlockHash, short_channel_id: u64) -> UtxoResult;
+}
+
+enum ChannelAnnouncement {
+       Full(msgs::ChannelAnnouncement),
+       Unsigned(msgs::UnsignedChannelAnnouncement),
+}
+impl ChannelAnnouncement {
+       fn node_id_1(&self) -> &NodeId {
+               match self {
+                       ChannelAnnouncement::Full(msg) => &msg.contents.node_id_1,
+                       ChannelAnnouncement::Unsigned(msg) => &msg.node_id_1,
+               }
+       }
+}
+
+enum NodeAnnouncement {
+       Full(msgs::NodeAnnouncement),
+       Unsigned(msgs::UnsignedNodeAnnouncement),
+}
+impl NodeAnnouncement {
+       fn timestamp(&self) -> u32 {
+               match self {
+                       NodeAnnouncement::Full(msg) => msg.contents.timestamp,
+                       NodeAnnouncement::Unsigned(msg) => msg.timestamp,
+               }
+       }
+}
+
+enum ChannelUpdate {
+       Full(msgs::ChannelUpdate),
+       Unsigned(msgs::UnsignedChannelUpdate),
+}
+impl ChannelUpdate {
+       fn timestamp(&self) -> u32 {
+               match self {
+                       ChannelUpdate::Full(msg) => msg.contents.timestamp,
+                       ChannelUpdate::Unsigned(msg) => msg.timestamp,
+               }
+       }
+}
+
+struct UtxoMessages {
+       complete: Option<Result<TxOut, UtxoLookupError>>,
+       channel_announce: Option<ChannelAnnouncement>,
+       latest_node_announce_a: Option<NodeAnnouncement>,
+       latest_node_announce_b: Option<NodeAnnouncement>,
+       latest_channel_update_a: Option<ChannelUpdate>,
+       latest_channel_update_b: Option<ChannelUpdate>,
+}
+
+/// Represents a future resolution of a [`UtxoLookup::get_utxo`] query resolving async.
+///
+/// See [`UtxoResult::Async`] and [`UtxoFuture::resolve`] for more info.
+#[derive(Clone)]
+pub struct UtxoFuture {
+       state: Arc<Mutex<UtxoMessages>>,
+}
+
+/// A trivial implementation of [`UtxoLookup`] which is used to call back into the network graph
+/// once we have a concrete resolution of a request.
+struct UtxoResolver(Result<TxOut, UtxoLookupError>);
+impl UtxoLookup for UtxoResolver {
+       fn get_utxo(&self, _genesis_hash: &BlockHash, _short_channel_id: u64) -> UtxoResult {
+               UtxoResult::Sync(self.0.clone())
+       }
+}
+
+impl UtxoFuture {
+       /// Builds a new future for later resolution.
+       pub fn new() -> Self {
+               Self { state: Arc::new(Mutex::new(UtxoMessages {
+                       complete: None,
+                       channel_announce: None,
+                       latest_node_announce_a: None,
+                       latest_node_announce_b: None,
+                       latest_channel_update_a: None,
+                       latest_channel_update_b: None,
+               }))}
+       }
+
+       /// Resolves this future against the given `graph` and with the given `result`.
+       ///
+       /// This is identical to calling [`UtxoFuture::resolve`] with a dummy `gossip`, disabling
+       /// forwarding the validated gossip message onwards to peers.
+       ///
+       /// Because this may cause the [`NetworkGraph`]'s [`processing_queue_high`] to flip, in order
+       /// to allow us to interact with peers again, you should call [`PeerManager::process_events`]
+       /// after this.
+       ///
+       /// [`processing_queue_high`]: crate::ln::msgs::RoutingMessageHandler::processing_queue_high
+       /// [`PeerManager::process_events`]: crate::ln::peer_handler::PeerManager::process_events
+       pub fn resolve_without_forwarding<L: Deref>(&self,
+               graph: &NetworkGraph<L>, result: Result<TxOut, UtxoLookupError>)
+       where L::Target: Logger {
+               self.do_resolve(graph, result);
+       }
+
+       /// Resolves this future against the given `graph` and with the given `result`.
+       ///
+       /// The given `gossip` is used to broadcast any validated messages onwards to all peers which
+       /// have available buffer space.
+       ///
+       /// Because this may cause the [`NetworkGraph`]'s [`processing_queue_high`] to flip, in order
+       /// to allow us to interact with peers again, you should call [`PeerManager::process_events`]
+       /// after this.
+       ///
+       /// [`processing_queue_high`]: crate::ln::msgs::RoutingMessageHandler::processing_queue_high
+       /// [`PeerManager::process_events`]: crate::ln::peer_handler::PeerManager::process_events
+       pub fn resolve<L: Deref, G: Deref<Target=NetworkGraph<L>>, U: Deref, GS: Deref<Target = P2PGossipSync<G, U, L>>>(&self,
+               graph: &NetworkGraph<L>, gossip: GS, result: Result<TxOut, UtxoLookupError>
+       ) where L::Target: Logger, U::Target: UtxoLookup {
+               let mut res = self.do_resolve(graph, result);
+               for msg_opt in res.iter_mut() {
+                       if let Some(msg) = msg_opt.take() {
+                               gossip.forward_gossip_msg(msg);
+                       }
+               }
+       }
+
+       fn do_resolve<L: Deref>(&self, graph: &NetworkGraph<L>, result: Result<TxOut, UtxoLookupError>)
+       -> [Option<MessageSendEvent>; 5] where L::Target: Logger {
+               let (announcement, node_a, node_b, update_a, update_b) = {
+                       let mut pending_checks = graph.pending_checks.internal.lock().unwrap();
+                       let mut async_messages = self.state.lock().unwrap();
+
+                       if async_messages.channel_announce.is_none() {
+                               // We raced returning to `check_channel_announcement` which hasn't updated
+                               // `channel_announce` yet. That's okay, we can set the `complete` field which it will
+                               // check once it gets control again.
+                               async_messages.complete = Some(result);
+                               return [None, None, None, None, None];
+                       }
+
+                       let announcement_msg = match async_messages.channel_announce.as_ref().unwrap() {
+                               ChannelAnnouncement::Full(signed_msg) => &signed_msg.contents,
+                               ChannelAnnouncement::Unsigned(msg) => &msg,
+                       };
+
+                       pending_checks.lookup_completed(announcement_msg, &Arc::downgrade(&self.state));
+
+                       (async_messages.channel_announce.take().unwrap(),
+                               async_messages.latest_node_announce_a.take(),
+                               async_messages.latest_node_announce_b.take(),
+                               async_messages.latest_channel_update_a.take(),
+                               async_messages.latest_channel_update_b.take())
+               };
+
+               let mut res = [None, None, None, None, None];
+               let mut res_idx = 0;
+
+               // Now that we've updated our internal state, pass the pending messages back through the
+               // network graph with a different `UtxoLookup` which will resolve immediately.
+               // Note that we ignore errors as we don't disconnect peers anyway, so there's nothing to do
+               // with them.
+               let resolver = UtxoResolver(result);
+               match announcement {
+                       ChannelAnnouncement::Full(signed_msg) => {
+                               if graph.update_channel_from_announcement(&signed_msg, &Some(&resolver)).is_ok() {
+                                       res[res_idx] = Some(MessageSendEvent::BroadcastChannelAnnouncement {
+                                               msg: signed_msg, update_msg: None,
+                                       });
+                                       res_idx += 1;
+                               }
+                       },
+                       ChannelAnnouncement::Unsigned(msg) => {
+                               let _ = graph.update_channel_from_unsigned_announcement(&msg, &Some(&resolver));
+                       },
+               }
+
+               for announce in core::iter::once(node_a).chain(core::iter::once(node_b)) {
+                       match announce {
+                               Some(NodeAnnouncement::Full(signed_msg)) => {
+                                       if graph.update_node_from_announcement(&signed_msg).is_ok() {
+                                               res[res_idx] = Some(MessageSendEvent::BroadcastNodeAnnouncement {
+                                                       msg: signed_msg,
+                                               });
+                                               res_idx += 1;
+                                       }
+                               },
+                               Some(NodeAnnouncement::Unsigned(msg)) => {
+                                       let _ = graph.update_node_from_unsigned_announcement(&msg);
+                               },
+                               None => {},
+                       }
+               }
+
+               for update in core::iter::once(update_a).chain(core::iter::once(update_b)) {
+                       match update {
+                               Some(ChannelUpdate::Full(signed_msg)) => {
+                                       if graph.update_channel(&signed_msg).is_ok() {
+                                               res[res_idx] = Some(MessageSendEvent::BroadcastChannelUpdate {
+                                                       msg: signed_msg,
+                                               });
+                                               res_idx += 1;
+                                       }
+                               },
+                               Some(ChannelUpdate::Unsigned(msg)) => {
+                                       let _ = graph.update_channel_unsigned(&msg);
+                               },
+                               None => {},
+                       }
+               }
+
+               res
+       }
+}
+
+struct PendingChecksContext {
+       channels: HashMap<u64, Weak<Mutex<UtxoMessages>>>,
+       nodes: HashMap<NodeId, Vec<Weak<Mutex<UtxoMessages>>>>,
+}
+
+impl PendingChecksContext {
+       fn lookup_completed(&mut self,
+               msg: &msgs::UnsignedChannelAnnouncement, completed_state: &Weak<Mutex<UtxoMessages>>
+       ) {
+               if let hash_map::Entry::Occupied(e) = self.channels.entry(msg.short_channel_id) {
+                       if Weak::ptr_eq(e.get(), &completed_state) {
+                               e.remove();
+                       }
+               }
+
+               if let hash_map::Entry::Occupied(mut e) = self.nodes.entry(msg.node_id_1) {
+                       e.get_mut().retain(|elem| !Weak::ptr_eq(&elem, &completed_state));
+                       if e.get().is_empty() { e.remove(); }
+               }
+               if let hash_map::Entry::Occupied(mut e) = self.nodes.entry(msg.node_id_2) {
+                       e.get_mut().retain(|elem| !Weak::ptr_eq(&elem, &completed_state));
+                       if e.get().is_empty() { e.remove(); }
+               }
+       }
+}
+
+/// A set of messages which are pending UTXO lookups for processing.
+pub(super) struct PendingChecks {
+       internal: Mutex<PendingChecksContext>,
+}
+
+impl PendingChecks {
+       pub(super) fn new() -> Self {
+               PendingChecks { internal: Mutex::new(PendingChecksContext {
+                       channels: HashMap::new(), nodes: HashMap::new(),
+               }) }
+       }
+
+       /// Checks if there is a pending `channel_update` UTXO validation for the given channel,
+       /// and, if so, stores the channel message for handling later and returns an `Err`.
+       pub(super) fn check_hold_pending_channel_update(
+               &self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>
+       ) -> Result<(), LightningError> {
+               let mut pending_checks = self.internal.lock().unwrap();
+               if let hash_map::Entry::Occupied(e) = pending_checks.channels.entry(msg.short_channel_id) {
+                       let is_from_a = (msg.flags & 1) == 1;
+                       match Weak::upgrade(e.get()) {
+                               Some(msgs_ref) => {
+                                       let mut messages = msgs_ref.lock().unwrap();
+                                       let latest_update = if is_from_a {
+                                                       &mut messages.latest_channel_update_a
+                                               } else {
+                                                       &mut messages.latest_channel_update_b
+                                               };
+                                       if latest_update.is_none() || latest_update.as_ref().unwrap().timestamp() < msg.timestamp {
+                                               // If the messages we got has a higher timestamp, just blindly assume the
+                                               // signatures on the new message are correct and drop the old message. This
+                                               // may cause us to end up dropping valid `channel_update`s if a peer is
+                                               // malicious, but we should get the correct ones when the node updates them.
+                                               *latest_update = Some(
+                                                       if let Some(msg) = full_msg { ChannelUpdate::Full(msg.clone()) }
+                                                       else { ChannelUpdate::Unsigned(msg.clone()) });
+                                       }
+                                       return Err(LightningError {
+                                               err: "Awaiting channel_announcement validation to accept channel_update".to_owned(),
+                                               action: ErrorAction::IgnoreAndLog(Level::Gossip),
+                                       });
+                               },
+                               None => { e.remove(); },
+                       }
+               }
+               Ok(())
+       }
+
+       /// Checks if there is a pending `node_announcement` UTXO validation for a channel with the
+       /// given node and, if so, stores the channel message for handling later and returns an `Err`.
+       pub(super) fn check_hold_pending_node_announcement(
+               &self, msg: &msgs::UnsignedNodeAnnouncement, full_msg: Option<&msgs::NodeAnnouncement>
+       ) -> Result<(), LightningError> {
+               let mut pending_checks = self.internal.lock().unwrap();
+               if let hash_map::Entry::Occupied(mut e) = pending_checks.nodes.entry(msg.node_id) {
+                       let mut found_at_least_one_chan = false;
+                       e.get_mut().retain(|node_msgs| {
+                               match Weak::upgrade(&node_msgs) {
+                                       Some(chan_mtx) => {
+                                               let mut chan_msgs = chan_mtx.lock().unwrap();
+                                               if let Some(chan_announce) = &chan_msgs.channel_announce {
+                                                       let latest_announce =
+                                                               if *chan_announce.node_id_1() == msg.node_id {
+                                                                       &mut chan_msgs.latest_node_announce_a
+                                                               } else {
+                                                                       &mut chan_msgs.latest_node_announce_b
+                                                               };
+                                                       if latest_announce.is_none() ||
+                                                               latest_announce.as_ref().unwrap().timestamp() < msg.timestamp
+                                                       {
+                                                               *latest_announce = Some(
+                                                                       if let Some(msg) = full_msg { NodeAnnouncement::Full(msg.clone()) }
+                                                                       else { NodeAnnouncement::Unsigned(msg.clone()) });
+                                                       }
+                                                       found_at_least_one_chan = true;
+                                                       true
+                                               } else {
+                                                       debug_assert!(false, "channel_announce is set before struct is added to node map");
+                                                       false
+                                               }
+                                       },
+                                       None => false,
+                               }
+                       });
+                       if e.get().is_empty() { e.remove(); }
+                       if found_at_least_one_chan {
+                               return Err(LightningError {
+                                       err: "Awaiting channel_announcement validation to accept node_announcement".to_owned(),
+                                       action: ErrorAction::IgnoreAndLog(Level::Gossip),
+                               });
+                       }
+               }
+               Ok(())
+       }
+
+       fn check_replace_previous_entry(msg: &msgs::UnsignedChannelAnnouncement,
+               full_msg: Option<&msgs::ChannelAnnouncement>, replacement: Option<Weak<Mutex<UtxoMessages>>>,
+               pending_channels: &mut HashMap<u64, Weak<Mutex<UtxoMessages>>>
+       ) -> Result<(), msgs::LightningError> {
+               match pending_channels.entry(msg.short_channel_id) {
+                       hash_map::Entry::Occupied(mut e) => {
+                               // There's already a pending lookup for the given SCID. Check if the messages
+                               // are the same and, if so, return immediately (don't bother spawning another
+                               // lookup if we haven't gotten that far yet).
+                               match Weak::upgrade(&e.get()) {
+                                       Some(pending_msgs) => {
+                                               // This may be called with the mutex held on a different UtxoMessages
+                                               // struct, however in that case we have a global lockorder of new messages
+                                               // -> old messages, which makes this safe.
+                                               let pending_matches = match &pending_msgs.unsafe_well_ordered_double_lock_self().channel_announce {
+                                                       Some(ChannelAnnouncement::Full(pending_msg)) => Some(pending_msg) == full_msg,
+                                                       Some(ChannelAnnouncement::Unsigned(pending_msg)) => pending_msg == msg,
+                                                       None => {
+                                                               // This shouldn't actually be reachable. We set the
+                                                               // `channel_announce` field under the same lock as setting the
+                                                               // channel map entry. Still, we can just treat it as
+                                                               // non-matching and let the new request fly.
+                                                               debug_assert!(false);
+                                                               false
+                                                       },
+                                               };
+                                               if pending_matches {
+                                                       return Err(LightningError {
+                                                               err: "Channel announcement is already being checked".to_owned(),
+                                                               action: ErrorAction::IgnoreDuplicateGossip,
+                                                       });
+                                               } else {
+                                                       // The earlier lookup is a different message. If we have another
+                                                       // request in-flight now replace the original.
+                                                       // Note that in the replace case whether to replace is somewhat
+                                                       // arbitrary - both results will be handled, we're just updating the
+                                                       // value that will be compared to future lookups with the same SCID.
+                                                       if let Some(item) = replacement {
+                                                               *e.get_mut() = item;
+                                                       }
+                                               }
+                                       },
+                                       None => {
+                                               // The earlier lookup already resolved. We can't be sure its the same
+                                               // so just remove/replace it and move on.
+                                               if let Some(item) = replacement {
+                                                       *e.get_mut() = item;
+                                               } else { e.remove(); }
+                                       },
+                               }
+                       },
+                       hash_map::Entry::Vacant(v) => {
+                               if let Some(item) = replacement { v.insert(item); }
+                       },
+               }
+               Ok(())
+       }
+
+       pub(super) fn check_channel_announcement<U: Deref>(&self,
+               utxo_lookup: &Option<U>, msg: &msgs::UnsignedChannelAnnouncement,
+               full_msg: Option<&msgs::ChannelAnnouncement>
+       ) -> Result<Option<u64>, msgs::LightningError> where U::Target: UtxoLookup {
+               let handle_result = |res| {
+                       match res {
+                               Ok(TxOut { value, script_pubkey }) => {
+                                       let expected_script =
+                                               make_funding_redeemscript_from_slices(msg.bitcoin_key_1.as_slice(), msg.bitcoin_key_2.as_slice()).to_v0_p2wsh();
+                                       if script_pubkey != expected_script {
+                                               return Err(LightningError{
+                                                       err: format!("Channel announcement key ({}) didn't match on-chain script ({})",
+                                                               expected_script.to_hex(), script_pubkey.to_hex()),
+                                                       action: ErrorAction::IgnoreError
+                                               });
+                                       }
+                                       Ok(Some(value))
+                               },
+                               Err(UtxoLookupError::UnknownChain) => {
+                                       Err(LightningError {
+                                               err: format!("Channel announced on an unknown chain ({})",
+                                                       msg.chain_hash.encode().to_hex()),
+                                               action: ErrorAction::IgnoreError
+                                       })
+                               },
+                               Err(UtxoLookupError::UnknownTx) => {
+                                       Err(LightningError {
+                                               err: "Channel announced without corresponding UTXO entry".to_owned(),
+                                               action: ErrorAction::IgnoreError
+                                       })
+                               },
+                       }
+               };
+
+               Self::check_replace_previous_entry(msg, full_msg, None,
+                       &mut self.internal.lock().unwrap().channels)?;
+
+               match utxo_lookup {
+                       &None => {
+                               // Tentatively accept, potentially exposing us to DoS attacks
+                               Ok(None)
+                       },
+                       &Some(ref utxo_lookup) => {
+                               match utxo_lookup.get_utxo(&msg.chain_hash, msg.short_channel_id) {
+                                       UtxoResult::Sync(res) => handle_result(res),
+                                       UtxoResult::Async(future) => {
+                                               let mut pending_checks = self.internal.lock().unwrap();
+                                               let mut async_messages = future.state.lock().unwrap();
+                                               if let Some(res) = async_messages.complete.take() {
+                                                       // In the unlikely event the future resolved before we managed to get it,
+                                                       // handle the result in-line.
+                                                       handle_result(res)
+                                               } else {
+                                                       Self::check_replace_previous_entry(msg, full_msg,
+                                                               Some(Arc::downgrade(&future.state)), &mut pending_checks.channels)?;
+                                                       async_messages.channel_announce = Some(
+                                                               if let Some(msg) = full_msg { ChannelAnnouncement::Full(msg.clone()) }
+                                                               else { ChannelAnnouncement::Unsigned(msg.clone()) });
+                                                       pending_checks.nodes.entry(msg.node_id_1)
+                                                               .or_insert(Vec::new()).push(Arc::downgrade(&future.state));
+                                                       pending_checks.nodes.entry(msg.node_id_2)
+                                                               .or_insert(Vec::new()).push(Arc::downgrade(&future.state));
+                                                       Err(LightningError {
+                                                               err: "Channel being checked async".to_owned(),
+                                                               action: ErrorAction::IgnoreAndLog(Level::Gossip),
+                                                       })
+                                               }
+                                       },
+                               }
+                       }
+               }
+       }
+
+       /// The maximum number of pending gossip checks before [`Self::too_many_checks_pending`]
+       /// returns `true`. Note that this isn't a strict upper-bound on the number of checks pending -
+       /// each peer may, at a minimum, read one more socket buffer worth of `channel_announcement`s
+       /// which we'll have to process. With a socket buffer of 4KB and a minimum
+       /// `channel_announcement` size of, roughly, 429 bytes, this may leave us with `10*our peer
+       /// count` messages to process beyond this limit. Because we'll probably have a few peers,
+       /// there's no reason for this constant to be materially less than 30 or so, and 32 in-flight
+       /// checks should be more than enough for decent parallelism.
+       const MAX_PENDING_LOOKUPS: usize = 32;
+
+       /// Returns true if there are a large number of async checks pending and future
+       /// `channel_announcement` messages should be delayed. Note that this is only a hint and
+       /// messages already in-flight may still have to be handled for various reasons.
+       pub(super) fn too_many_checks_pending(&self) -> bool {
+               let mut pending_checks = self.internal.lock().unwrap();
+               if pending_checks.channels.len() > Self::MAX_PENDING_LOOKUPS {
+                       // If we have many channel checks pending, ensure we don't have any dangling checks
+                       // (i.e. checks where the user told us they'd call back but drop'd the `UtxoFuture`
+                       // instead) before we commit to applying backpressure.
+                       pending_checks.channels.retain(|_, chan| {
+                               Weak::upgrade(&chan).is_some()
+                       });
+                       pending_checks.nodes.retain(|_, channels| {
+                               channels.retain(|chan| Weak::upgrade(&chan).is_some());
+                               !channels.is_empty()
+                       });
+                       pending_checks.channels.len() > Self::MAX_PENDING_LOOKUPS
+               } else {
+                       false
+               }
+       }
+}
+
+#[cfg(test)]
+mod tests {
+       use super::*;
+       use crate::routing::gossip::tests::*;
+       use crate::util::test_utils::{TestChainSource, TestLogger};
+       use crate::ln::msgs;
+
+       use bitcoin::secp256k1::{Secp256k1, SecretKey};
+
+       use core::sync::atomic::Ordering;
+
+       fn get_network() -> (TestChainSource, NetworkGraph<Box<TestLogger>>) {
+               let logger = Box::new(TestLogger::new());
+               let chain_source = TestChainSource::new(bitcoin::Network::Testnet);
+               let network_graph = NetworkGraph::new(bitcoin::Network::Testnet, logger);
+
+               (chain_source, network_graph)
+       }
+
+       fn get_test_objects() -> (msgs::ChannelAnnouncement, TestChainSource,
+               NetworkGraph<Box<TestLogger>>, bitcoin::Script, msgs::NodeAnnouncement,
+               msgs::NodeAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, msgs::ChannelUpdate)
+       {
+               let secp_ctx = Secp256k1::new();
+
+               let (chain_source, network_graph) = get_network();
+
+               let good_script = get_channel_script(&secp_ctx);
+               let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap();
+               let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap();
+               let valid_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx);
+
+               let node_a_announce = get_signed_node_announcement(|_| {}, node_1_privkey, &secp_ctx);
+               let node_b_announce = get_signed_node_announcement(|_| {}, node_2_privkey, &secp_ctx);
+
+               // Note that we have to set the "direction" flag correctly on both messages
+               let chan_update_a = get_signed_channel_update(|msg| msg.flags = 0, node_1_privkey, &secp_ctx);
+               let chan_update_b = get_signed_channel_update(|msg| msg.flags = 1, node_2_privkey, &secp_ctx);
+               let chan_update_c = get_signed_channel_update(|msg| {
+                       msg.flags = 1; msg.timestamp += 1; }, node_2_privkey, &secp_ctx);
+
+               (valid_announcement, chain_source, network_graph, good_script, node_a_announce,
+                       node_b_announce, chan_update_a, chan_update_b, chan_update_c)
+       }
+
+       #[test]
+       fn test_fast_async_lookup() {
+               // Check that async lookups which resolve quicker than the future is returned to the
+               // `get_utxo` call can read it still resolve properly.
+               let (valid_announcement, chain_source, network_graph, good_script, ..) = get_test_objects();
+
+               let future = UtxoFuture::new();
+               future.resolve_without_forwarding(&network_graph,
+                       Ok(TxOut { value: 1_000_000, script_pubkey: good_script }));
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Async(future.clone());
+
+               network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap();
+               assert!(network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).is_some());
+       }
+
+       #[test]
+       fn test_async_lookup() {
+               // Test a simple async lookup
+               let (valid_announcement, chain_source, network_graph, good_script,
+                       node_a_announce, node_b_announce, ..) = get_test_objects();
+
+               let future = UtxoFuture::new();
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Async(future.clone());
+
+               assert_eq!(
+                       network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err().err,
+                       "Channel being checked async");
+               assert!(network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).is_none());
+
+               future.resolve_without_forwarding(&network_graph,
+                       Ok(TxOut { value: 0, script_pubkey: good_script }));
+               network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).unwrap();
+               network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).unwrap();
+
+               assert!(network_graph.read_only().nodes().get(&valid_announcement.contents.node_id_1)
+                       .unwrap().announcement_info.is_none());
+
+               network_graph.update_node_from_announcement(&node_a_announce).unwrap();
+               network_graph.update_node_from_announcement(&node_b_announce).unwrap();
+
+               assert!(network_graph.read_only().nodes().get(&valid_announcement.contents.node_id_1)
+                       .unwrap().announcement_info.is_some());
+       }
+
+       #[test]
+       fn test_invalid_async_lookup() {
+               // Test an async lookup which returns an incorrect script
+               let (valid_announcement, chain_source, network_graph, ..) = get_test_objects();
+
+               let future = UtxoFuture::new();
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Async(future.clone());
+
+               assert_eq!(
+                       network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err().err,
+                       "Channel being checked async");
+               assert!(network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).is_none());
+
+               future.resolve_without_forwarding(&network_graph,
+                       Ok(TxOut { value: 1_000_000, script_pubkey: bitcoin::Script::new() }));
+               assert!(network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).is_none());
+       }
+
+       #[test]
+       fn test_failing_async_lookup() {
+               // Test an async lookup which returns an error
+               let (valid_announcement, chain_source, network_graph, ..) = get_test_objects();
+
+               let future = UtxoFuture::new();
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Async(future.clone());
+
+               assert_eq!(
+                       network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err().err,
+                       "Channel being checked async");
+               assert!(network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).is_none());
+
+               future.resolve_without_forwarding(&network_graph, Err(UtxoLookupError::UnknownTx));
+               assert!(network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).is_none());
+       }
+
+       #[test]
+       fn test_updates_async_lookup() {
+               // Test async lookups will process pending channel_update/node_announcements once they
+               // complete.
+               let (valid_announcement, chain_source, network_graph, good_script, node_a_announce,
+                       node_b_announce, chan_update_a, chan_update_b, ..) = get_test_objects();
+
+               let future = UtxoFuture::new();
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Async(future.clone());
+
+               assert_eq!(
+                       network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err().err,
+                       "Channel being checked async");
+               assert!(network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).is_none());
+
+               assert_eq!(
+                       network_graph.update_node_from_announcement(&node_a_announce).unwrap_err().err,
+                       "Awaiting channel_announcement validation to accept node_announcement");
+               assert_eq!(
+                       network_graph.update_node_from_announcement(&node_b_announce).unwrap_err().err,
+                       "Awaiting channel_announcement validation to accept node_announcement");
+
+               assert_eq!(network_graph.update_channel(&chan_update_a).unwrap_err().err,
+                       "Awaiting channel_announcement validation to accept channel_update");
+               assert_eq!(network_graph.update_channel(&chan_update_b).unwrap_err().err,
+                       "Awaiting channel_announcement validation to accept channel_update");
+
+               future.resolve_without_forwarding(&network_graph,
+                       Ok(TxOut { value: 1_000_000, script_pubkey: good_script }));
+
+               assert!(network_graph.read_only().channels()
+                       .get(&valid_announcement.contents.short_channel_id).unwrap().one_to_two.is_some());
+               assert!(network_graph.read_only().channels()
+                       .get(&valid_announcement.contents.short_channel_id).unwrap().two_to_one.is_some());
+
+               assert!(network_graph.read_only().nodes().get(&valid_announcement.contents.node_id_1)
+                       .unwrap().announcement_info.is_some());
+               assert!(network_graph.read_only().nodes().get(&valid_announcement.contents.node_id_2)
+                       .unwrap().announcement_info.is_some());
+       }
+
+       #[test]
+       fn test_latest_update_async_lookup() {
+               // Test async lookups will process the latest channel_update if two are received while
+               // awaiting an async UTXO lookup.
+               let (valid_announcement, chain_source, network_graph, good_script, _,
+                       _, chan_update_a, chan_update_b, chan_update_c, ..) = get_test_objects();
+
+               let future = UtxoFuture::new();
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Async(future.clone());
+
+               assert_eq!(
+                       network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err().err,
+                       "Channel being checked async");
+               assert!(network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).is_none());
+
+               assert_eq!(network_graph.update_channel(&chan_update_a).unwrap_err().err,
+                       "Awaiting channel_announcement validation to accept channel_update");
+               assert_eq!(network_graph.update_channel(&chan_update_b).unwrap_err().err,
+                       "Awaiting channel_announcement validation to accept channel_update");
+               assert_eq!(network_graph.update_channel(&chan_update_c).unwrap_err().err,
+                       "Awaiting channel_announcement validation to accept channel_update");
+
+               future.resolve_without_forwarding(&network_graph,
+                       Ok(TxOut { value: 1_000_000, script_pubkey: good_script }));
+
+               assert_eq!(chan_update_a.contents.timestamp, chan_update_b.contents.timestamp);
+               let graph_lock = network_graph.read_only();
+               assert!(graph_lock.channels()
+                               .get(&valid_announcement.contents.short_channel_id).as_ref().unwrap()
+                               .one_to_two.as_ref().unwrap().last_update !=
+                       graph_lock.channels()
+                               .get(&valid_announcement.contents.short_channel_id).as_ref().unwrap()
+                               .two_to_one.as_ref().unwrap().last_update);
+       }
+
+       #[test]
+       fn test_no_double_lookups() {
+               // Test that a pending async lookup will prevent a second async lookup from flying, but
+               // only if the channel_announcement message is identical.
+               let (valid_announcement, chain_source, network_graph, good_script, ..) = get_test_objects();
+
+               let future = UtxoFuture::new();
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Async(future.clone());
+
+               assert_eq!(
+                       network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err().err,
+                       "Channel being checked async");
+               assert_eq!(chain_source.get_utxo_call_count.load(Ordering::Relaxed), 1);
+
+               // If we make a second request with the same message, the call count doesn't increase...
+               let future_b = UtxoFuture::new();
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Async(future_b.clone());
+               assert_eq!(
+                       network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err().err,
+                       "Channel announcement is already being checked");
+               assert_eq!(chain_source.get_utxo_call_count.load(Ordering::Relaxed), 1);
+
+               // But if we make a third request with a tweaked message, we should get a second call
+               // against our new future...
+               let secp_ctx = Secp256k1::new();
+               let replacement_pk_1 = &SecretKey::from_slice(&[99; 32]).unwrap();
+               let replacement_pk_2 = &SecretKey::from_slice(&[98; 32]).unwrap();
+               let invalid_announcement = get_signed_channel_announcement(|_| {}, replacement_pk_1, replacement_pk_2, &secp_ctx);
+               assert_eq!(
+                       network_graph.update_channel_from_announcement(&invalid_announcement, &Some(&chain_source)).unwrap_err().err,
+                       "Channel being checked async");
+               assert_eq!(chain_source.get_utxo_call_count.load(Ordering::Relaxed), 2);
+
+               // Still, if we resolve the original future, the original channel will be accepted.
+               future.resolve_without_forwarding(&network_graph,
+                       Ok(TxOut { value: 1_000_000, script_pubkey: good_script }));
+               assert!(!network_graph.read_only().channels()
+                       .get(&valid_announcement.contents.short_channel_id).unwrap()
+                       .announcement_message.as_ref().unwrap()
+                       .contents.features.supports_unknown_test_feature());
+       }
+
+       #[test]
+       fn test_checks_backpressure() {
+               // Test that too_many_checks_pending returns true when there are many checks pending, and
+               // returns false once they complete.
+               let secp_ctx = Secp256k1::new();
+               let (chain_source, network_graph) = get_network();
+
+               // We cheat and use a single future for all the lookups to complete them all at once.
+               let future = UtxoFuture::new();
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Async(future.clone());
+
+               let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap();
+               let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap();
+
+               for i in 0..PendingChecks::MAX_PENDING_LOOKUPS {
+                       let valid_announcement = get_signed_channel_announcement(
+                               |msg| msg.short_channel_id += 1 + i as u64, node_1_privkey, node_2_privkey, &secp_ctx);
+                       network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err();
+                       assert!(!network_graph.pending_checks.too_many_checks_pending());
+               }
+
+               let valid_announcement = get_signed_channel_announcement(
+                       |_| {}, node_1_privkey, node_2_privkey, &secp_ctx);
+               network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err();
+               assert!(network_graph.pending_checks.too_many_checks_pending());
+
+               // Once the future completes the "too many checks" flag should reset.
+               future.resolve_without_forwarding(&network_graph, Err(UtxoLookupError::UnknownTx));
+               assert!(!network_graph.pending_checks.too_many_checks_pending());
+       }
+
+       #[test]
+       fn test_checks_backpressure_drop() {
+               // Test that too_many_checks_pending returns true when there are many checks pending, and
+               // returns false if we drop some of the futures without completion.
+               let secp_ctx = Secp256k1::new();
+               let (chain_source, network_graph) = get_network();
+
+               // We cheat and use a single future for all the lookups to complete them all at once.
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Async(UtxoFuture::new());
+
+               let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap();
+               let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap();
+
+               for i in 0..PendingChecks::MAX_PENDING_LOOKUPS {
+                       let valid_announcement = get_signed_channel_announcement(
+                               |msg| msg.short_channel_id += 1 + i as u64, node_1_privkey, node_2_privkey, &secp_ctx);
+                       network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err();
+                       assert!(!network_graph.pending_checks.too_many_checks_pending());
+               }
+
+               let valid_announcement = get_signed_channel_announcement(
+                       |_| {}, node_1_privkey, node_2_privkey, &secp_ctx);
+               network_graph.update_channel_from_announcement(&valid_announcement, &Some(&chain_source)).unwrap_err();
+               assert!(network_graph.pending_checks.too_many_checks_pending());
+
+               // Once the future is drop'd (by resetting the `utxo_ret` value) the "too many checks" flag
+               // should reset to false.
+               *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Sync(Err(UtxoLookupError::UnknownTx));
+               assert!(!network_graph.pending_checks.too_many_checks_pending());
+       }
+}
diff --git a/lightning/src/sync.rs b/lightning/src/sync.rs
deleted file mode 100644 (file)
index 482759b..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-pub use ::alloc::sync::Arc;
-use core::ops::{Deref, DerefMut};
-use core::time::Duration;
-use core::cell::{RefCell, Ref, RefMut};
-
-pub type LockResult<Guard> = Result<Guard, ()>;
-
-pub struct Condvar {}
-
-impl Condvar {
-       pub fn new() -> Condvar {
-               Condvar { }
-       }
-
-       pub fn wait<'a, T>(&'a self, guard: MutexGuard<'a, T>) -> LockResult<MutexGuard<'a, T>> {
-               Ok(guard)
-       }
-
-       #[allow(unused)]
-       pub fn wait_timeout<'a, T>(&'a self, guard: MutexGuard<'a, T>, _dur: Duration) -> LockResult<(MutexGuard<'a, T>, ())> {
-               Ok((guard, ()))
-       }
-
-       pub fn notify_all(&self) {}
-}
-
-pub struct Mutex<T: ?Sized> {
-       inner: RefCell<T>
-}
-
-#[must_use = "if unused the Mutex will immediately unlock"]
-pub struct MutexGuard<'a, T: ?Sized + 'a> {
-       lock: RefMut<'a, T>,
-}
-
-impl<T: ?Sized> Deref for MutexGuard<'_, T> {
-       type Target = T;
-
-       fn deref(&self) -> &T {
-               &self.lock.deref()
-       }
-}
-
-impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
-       fn deref_mut(&mut self) -> &mut T {
-               self.lock.deref_mut()
-       }
-}
-
-impl<T> Mutex<T> {
-       pub fn new(inner: T) -> Mutex<T> {
-               Mutex { inner: RefCell::new(inner) }
-       }
-
-       pub fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
-               Ok(MutexGuard { lock: self.inner.borrow_mut() })
-       }
-
-       pub fn try_lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
-               Ok(MutexGuard { lock: self.inner.borrow_mut() })
-       }
-}
-
-pub struct RwLock<T: ?Sized> {
-       inner: RefCell<T>
-}
-
-pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
-       lock: Ref<'a, T>,
-}
-
-pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
-       lock: RefMut<'a, T>,
-}
-
-impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
-       type Target = T;
-
-       fn deref(&self) -> &T {
-               &self.lock.deref()
-       }
-}
-
-impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
-       type Target = T;
-
-       fn deref(&self) -> &T {
-               &self.lock.deref()
-       }
-}
-
-impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
-       fn deref_mut(&mut self) -> &mut T {
-               self.lock.deref_mut()
-       }
-}
-
-impl<T> RwLock<T> {
-       pub fn new(inner: T) -> RwLock<T> {
-               RwLock { inner: RefCell::new(inner) }
-       }
-
-       pub fn read<'a>(&'a self) -> LockResult<RwLockReadGuard<'a, T>> {
-               Ok(RwLockReadGuard { lock: self.inner.borrow() })
-       }
-
-       pub fn write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
-               Ok(RwLockWriteGuard { lock: self.inner.borrow_mut() })
-       }
-
-       pub fn try_write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
-               // There is no try, grasshopper - only used for tests and expected to fail
-               Err(())
-       }
-}
-
-pub type FairRwLock<T> = RwLock<T>;
diff --git a/lightning/src/sync/debug_sync.rs b/lightning/src/sync/debug_sync.rs
new file mode 100644 (file)
index 0000000..11824d5
--- /dev/null
@@ -0,0 +1,375 @@
+pub use ::alloc::sync::Arc;
+use core::ops::{Deref, DerefMut};
+use core::time::Duration;
+
+use std::cell::RefCell;
+
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::Mutex as StdMutex;
+use std::sync::MutexGuard as StdMutexGuard;
+use std::sync::RwLock as StdRwLock;
+use std::sync::RwLockReadGuard as StdRwLockReadGuard;
+use std::sync::RwLockWriteGuard as StdRwLockWriteGuard;
+use std::sync::Condvar as StdCondvar;
+
+use crate::prelude::HashMap;
+
+use super::{LockTestExt, LockHeldState};
+
+#[cfg(feature = "backtrace")]
+use {crate::prelude::hash_map, backtrace::Backtrace, std::sync::Once};
+
+#[cfg(not(feature = "backtrace"))]
+struct Backtrace{}
+#[cfg(not(feature = "backtrace"))]
+impl Backtrace { fn new() -> Backtrace { Backtrace {} } }
+
+pub type LockResult<Guard> = Result<Guard, ()>;
+
+pub struct Condvar {
+       inner: StdCondvar,
+}
+
+impl Condvar {
+       pub fn new() -> Condvar {
+               Condvar { inner: StdCondvar::new() }
+       }
+
+       pub fn wait<'a, T>(&'a self, guard: MutexGuard<'a, T>) -> LockResult<MutexGuard<'a, T>> {
+               let mutex: &'a Mutex<T> = guard.mutex;
+               self.inner.wait(guard.into_inner()).map(|lock| MutexGuard { mutex, lock }).map_err(|_| ())
+       }
+
+       #[allow(unused)]
+       pub fn wait_timeout<'a, T>(&'a self, guard: MutexGuard<'a, T>, dur: Duration) -> LockResult<(MutexGuard<'a, T>, ())> {
+               let mutex = guard.mutex;
+               self.inner.wait_timeout(guard.into_inner(), dur).map(|(lock, _)| (MutexGuard { mutex, lock }, ())).map_err(|_| ())
+       }
+
+       pub fn notify_all(&self) { self.inner.notify_all(); }
+}
+
+thread_local! {
+       /// We track the set of locks currently held by a reference to their `LockMetadata`
+       static LOCKS_HELD: RefCell<HashMap<u64, Arc<LockMetadata>>> = RefCell::new(HashMap::new());
+}
+static LOCK_IDX: AtomicUsize = AtomicUsize::new(0);
+
+#[cfg(feature = "backtrace")]
+static mut LOCKS: Option<StdMutex<HashMap<String, Arc<LockMetadata>>>> = None;
+#[cfg(feature = "backtrace")]
+static LOCKS_INIT: Once = Once::new();
+
+/// Metadata about a single lock, by id, the set of things locked-before it, and the backtrace of
+/// when the Mutex itself was constructed.
+struct LockMetadata {
+       lock_idx: u64,
+       locked_before: StdMutex<HashMap<u64, LockDep>>,
+       _lock_construction_bt: Backtrace,
+}
+
+struct LockDep {
+       lock: Arc<LockMetadata>,
+       /// lockdep_trace is unused unless we're building with `backtrace`, so we mark it _
+       _lockdep_trace: Backtrace,
+}
+
+#[cfg(feature = "backtrace")]
+fn get_construction_location(backtrace: &Backtrace) -> (String, Option<u32>) {
+       // Find the first frame that is after `debug_sync` (or that is in our tests) and use
+       // that as the mutex construction site. Note that the first few frames may be in
+       // the `backtrace` crate, so we have to ignore those.
+       let sync_mutex_constr_regex = regex::Regex::new(r"lightning.*debug_sync").unwrap();
+       let mut found_debug_sync = false;
+       for frame in backtrace.frames() {
+               for symbol in frame.symbols() {
+                       let symbol_name = symbol.name().unwrap().as_str().unwrap();
+                       if !sync_mutex_constr_regex.is_match(symbol_name) {
+                               if found_debug_sync {
+                                       return (format!("{}:{}", symbol.filename().unwrap().display(), symbol.lineno().unwrap()), symbol.colno());
+                               }
+                       } else { found_debug_sync = true; }
+               }
+       }
+       panic!("Couldn't find mutex construction callsite");
+}
+
+impl LockMetadata {
+       fn new() -> Arc<LockMetadata> {
+               let backtrace = Backtrace::new();
+               let lock_idx = LOCK_IDX.fetch_add(1, Ordering::Relaxed) as u64;
+
+               let res = Arc::new(LockMetadata {
+                       locked_before: StdMutex::new(HashMap::new()),
+                       lock_idx,
+                       _lock_construction_bt: backtrace,
+               });
+
+               #[cfg(feature = "backtrace")]
+               {
+                       let (lock_constr_location, lock_constr_colno) =
+                               get_construction_location(&res._lock_construction_bt);
+                       LOCKS_INIT.call_once(|| { unsafe { LOCKS = Some(StdMutex::new(HashMap::new())); } });
+                       let mut locks = unsafe { LOCKS.as_ref() }.unwrap().lock().unwrap();
+                       match locks.entry(lock_constr_location) {
+                               hash_map::Entry::Occupied(e) => {
+                                       assert_eq!(lock_constr_colno,
+                                               get_construction_location(&e.get()._lock_construction_bt).1,
+                                               "Because Windows doesn't support column number results in backtraces, we cannot construct two mutexes on the same line or we risk lockorder detection false positives.");
+                                       return Arc::clone(e.get())
+                               },
+                               hash_map::Entry::Vacant(e) => { e.insert(Arc::clone(&res)); },
+                       }
+               }
+               res
+       }
+
+       fn pre_lock(this: &Arc<LockMetadata>, _double_lock_self_allowed: bool) {
+               LOCKS_HELD.with(|held| {
+                       // For each lock which is currently locked, check that no lock's locked-before
+                       // set includes the lock we're about to lock, which would imply a lockorder
+                       // inversion.
+                       for (locked_idx, _locked) in held.borrow().iter() {
+                               if *locked_idx == this.lock_idx {
+                                       // Note that with `feature = "backtrace"` set, we may be looking at different
+                                       // instances of the same lock. Still, doing so is quite risky, a total order
+                                       // must be maintained, and doing so across a set of otherwise-identical mutexes
+                                       // is fraught with issues.
+                                       #[cfg(feature = "backtrace")]
+                                       debug_assert!(_double_lock_self_allowed,
+                                               "Tried to acquire a lock while it was held!\nLock constructed at {}",
+                                               get_construction_location(&this._lock_construction_bt).0);
+                                       #[cfg(not(feature = "backtrace"))]
+                                       panic!("Tried to acquire a lock while it was held!");
+                               }
+                       }
+                       for (_locked_idx, locked) in held.borrow().iter() {
+                               for (locked_dep_idx, _locked_dep) in locked.locked_before.lock().unwrap().iter() {
+                                       if *locked_dep_idx == this.lock_idx && *locked_dep_idx != locked.lock_idx {
+                                               #[cfg(feature = "backtrace")]
+                                               panic!("Tried to violate existing lockorder.\nMutex that should be locked after the current lock was created at the following backtrace.\nNote that to get a backtrace for the lockorder violation, you should set RUST_BACKTRACE=1\nLock being taken constructed at: {} ({}):\n{:?}\nLock constructed at: {} ({})\n{:?}\n\nLock dep created at:\n{:?}\n\n",
+                                                       get_construction_location(&this._lock_construction_bt).0,
+                                                       this.lock_idx, this._lock_construction_bt,
+                                                       get_construction_location(&locked._lock_construction_bt).0,
+                                                       locked.lock_idx, locked._lock_construction_bt,
+                                                       _locked_dep._lockdep_trace);
+                                               #[cfg(not(feature = "backtrace"))]
+                                               panic!("Tried to violate existing lockorder. Build with the backtrace feature for more info.");
+                                       }
+                               }
+                               // Insert any already-held locks in our locked-before set.
+                               let mut locked_before = this.locked_before.lock().unwrap();
+                               if !locked_before.contains_key(&locked.lock_idx) {
+                                       let lockdep = LockDep { lock: Arc::clone(locked), _lockdep_trace: Backtrace::new() };
+                                       locked_before.insert(lockdep.lock.lock_idx, lockdep);
+                               }
+                       }
+                       held.borrow_mut().insert(this.lock_idx, Arc::clone(this));
+               });
+       }
+
+       fn held_by_thread(this: &Arc<LockMetadata>) -> LockHeldState {
+               let mut res = LockHeldState::NotHeldByThread;
+               LOCKS_HELD.with(|held| {
+                       for (locked_idx, _locked) in held.borrow().iter() {
+                               if *locked_idx == this.lock_idx {
+                                       res = LockHeldState::HeldByThread;
+                               }
+                       }
+               });
+               res
+       }
+
+       fn try_locked(this: &Arc<LockMetadata>) {
+               LOCKS_HELD.with(|held| {
+                       // Since a try-lock will simply fail if the lock is held already, we do not
+                       // consider try-locks to ever generate lockorder inversions. However, if a try-lock
+                       // succeeds, we do consider it to have created lockorder dependencies.
+                       let mut locked_before = this.locked_before.lock().unwrap();
+                       for (locked_idx, locked) in held.borrow().iter() {
+                               if !locked_before.contains_key(locked_idx) {
+                                       let lockdep = LockDep { lock: Arc::clone(locked), _lockdep_trace: Backtrace::new() };
+                                       locked_before.insert(*locked_idx, lockdep);
+                               }
+                       }
+                       held.borrow_mut().insert(this.lock_idx, Arc::clone(this));
+               });
+       }
+}
+
+pub struct Mutex<T: Sized> {
+       inner: StdMutex<T>,
+       deps: Arc<LockMetadata>,
+}
+impl<T: Sized> Mutex<T> {
+       pub(crate) fn into_inner(self) -> LockResult<T> {
+               self.inner.into_inner().map_err(|_| ())
+       }
+}
+
+#[must_use = "if unused the Mutex will immediately unlock"]
+pub struct MutexGuard<'a, T: Sized + 'a> {
+       mutex: &'a Mutex<T>,
+       lock: StdMutexGuard<'a, T>,
+}
+
+impl<'a, T: Sized> MutexGuard<'a, T> {
+       fn into_inner(self) -> StdMutexGuard<'a, T> {
+               // Somewhat unclear why we cannot move out of self.lock, but doing so gets E0509.
+               unsafe {
+                       let v: StdMutexGuard<'a, T> = std::ptr::read(&self.lock);
+                       std::mem::forget(self);
+                       v
+               }
+       }
+}
+
+impl<T: Sized> Drop for MutexGuard<'_, T> {
+       fn drop(&mut self) {
+               LOCKS_HELD.with(|held| {
+                       held.borrow_mut().remove(&self.mutex.deps.lock_idx);
+               });
+       }
+}
+
+impl<T: Sized> Deref for MutexGuard<'_, T> {
+       type Target = T;
+
+       fn deref(&self) -> &T {
+               &self.lock.deref()
+       }
+}
+
+impl<T: Sized> DerefMut for MutexGuard<'_, T> {
+       fn deref_mut(&mut self) -> &mut T {
+               self.lock.deref_mut()
+       }
+}
+
+impl<T> Mutex<T> {
+       pub fn new(inner: T) -> Mutex<T> {
+               Mutex { inner: StdMutex::new(inner), deps: LockMetadata::new() }
+       }
+
+       pub fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
+               LockMetadata::pre_lock(&self.deps, false);
+               self.inner.lock().map(|lock| MutexGuard { mutex: self, lock }).map_err(|_| ())
+       }
+
+       pub fn try_lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
+               let res = self.inner.try_lock().map(|lock| MutexGuard { mutex: self, lock }).map_err(|_| ());
+               if res.is_ok() {
+                       LockMetadata::try_locked(&self.deps);
+               }
+               res
+       }
+}
+
+impl<'a, T: 'a> LockTestExt<'a> for Mutex<T> {
+       #[inline]
+       fn held_by_thread(&self) -> LockHeldState {
+               LockMetadata::held_by_thread(&self.deps)
+       }
+       type ExclLock = MutexGuard<'a, T>;
+       #[inline]
+       fn unsafe_well_ordered_double_lock_self(&'a self) -> MutexGuard<T> {
+               LockMetadata::pre_lock(&self.deps, true);
+               self.inner.lock().map(|lock| MutexGuard { mutex: self, lock }).unwrap()
+       }
+}
+
+pub struct RwLock<T: Sized> {
+       inner: StdRwLock<T>,
+       deps: Arc<LockMetadata>,
+}
+
+pub struct RwLockReadGuard<'a, T: Sized + 'a> {
+       lock: &'a RwLock<T>,
+       guard: StdRwLockReadGuard<'a, T>,
+}
+
+pub struct RwLockWriteGuard<'a, T: Sized + 'a> {
+       lock: &'a RwLock<T>,
+       guard: StdRwLockWriteGuard<'a, T>,
+}
+
+impl<T: Sized> Deref for RwLockReadGuard<'_, T> {
+       type Target = T;
+
+       fn deref(&self) -> &T {
+               &self.guard.deref()
+       }
+}
+
+impl<T: Sized> Drop for RwLockReadGuard<'_, T> {
+       fn drop(&mut self) {
+               LOCKS_HELD.with(|held| {
+                       held.borrow_mut().remove(&self.lock.deps.lock_idx);
+               });
+       }
+}
+
+impl<T: Sized> Deref for RwLockWriteGuard<'_, T> {
+       type Target = T;
+
+       fn deref(&self) -> &T {
+               &self.guard.deref()
+       }
+}
+
+impl<T: Sized> Drop for RwLockWriteGuard<'_, T> {
+       fn drop(&mut self) {
+               LOCKS_HELD.with(|held| {
+                       held.borrow_mut().remove(&self.lock.deps.lock_idx);
+               });
+       }
+}
+
+impl<T: Sized> DerefMut for RwLockWriteGuard<'_, T> {
+       fn deref_mut(&mut self) -> &mut T {
+               self.guard.deref_mut()
+       }
+}
+
+impl<T> RwLock<T> {
+       pub fn new(inner: T) -> RwLock<T> {
+               RwLock { inner: StdRwLock::new(inner), deps: LockMetadata::new() }
+       }
+
+       pub fn read<'a>(&'a self) -> LockResult<RwLockReadGuard<'a, T>> {
+               // Note that while we could be taking a recursive read lock here, Rust's `RwLock` may
+               // deadlock trying to take a second read lock if another thread is waiting on the write
+               // lock. This behavior is platform dependent, but our in-tree `FairRwLock` guarantees
+               // such a deadlock.
+               LockMetadata::pre_lock(&self.deps, false);
+               self.inner.read().map(|guard| RwLockReadGuard { lock: self, guard }).map_err(|_| ())
+       }
+
+       pub fn write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
+               LockMetadata::pre_lock(&self.deps, false);
+               self.inner.write().map(|guard| RwLockWriteGuard { lock: self, guard }).map_err(|_| ())
+       }
+
+       pub fn try_write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
+               let res = self.inner.try_write().map(|guard| RwLockWriteGuard { lock: self, guard }).map_err(|_| ());
+               if res.is_ok() {
+                       LockMetadata::try_locked(&self.deps);
+               }
+               res
+       }
+}
+
+impl<'a, T: 'a> LockTestExt<'a> for RwLock<T> {
+       #[inline]
+       fn held_by_thread(&self) -> LockHeldState {
+               LockMetadata::held_by_thread(&self.deps)
+       }
+       type ExclLock = RwLockWriteGuard<'a, T>;
+       #[inline]
+       fn unsafe_well_ordered_double_lock_self(&'a self) -> RwLockWriteGuard<'a, T> {
+               LockMetadata::pre_lock(&self.deps, true);
+               self.inner.write().map(|guard| RwLockWriteGuard { lock: self, guard }).unwrap()
+       }
+}
+
+pub type FairRwLock<T> = RwLock<T>;
diff --git a/lightning/src/sync/fairrwlock.rs b/lightning/src/sync/fairrwlock.rs
new file mode 100644 (file)
index 0000000..23b8c23
--- /dev/null
@@ -0,0 +1,65 @@
+use std::sync::{LockResult, RwLock, RwLockReadGuard, RwLockWriteGuard, TryLockResult};
+use std::sync::atomic::{AtomicUsize, Ordering};
+use super::{LockHeldState, LockTestExt};
+
+/// Rust libstd's RwLock does not provide any fairness guarantees (and, in fact, when used on
+/// Linux with pthreads under the hood, readers trivially and completely starve writers).
+/// Because we often hold read locks while doing message processing in multiple threads which
+/// can use significant CPU time, with write locks being time-sensitive but relatively small in
+/// CPU time, we can end up with starvation completely blocking incoming connections or pings,
+/// especially during initial graph sync.
+///
+/// Thus, we need to block readers when a writer is pending, which we do with a trivial RwLock
+/// wrapper here. Its not particularly optimized, but provides some reasonable fairness by
+/// blocking readers (by taking the write lock) if there are writers pending when we go to take
+/// a read lock.
+pub struct FairRwLock<T> {
+       lock: RwLock<T>,
+       waiting_writers: AtomicUsize,
+}
+
+impl<T> FairRwLock<T> {
+       pub fn new(t: T) -> Self {
+               Self { lock: RwLock::new(t), waiting_writers: AtomicUsize::new(0) }
+       }
+
+       // Note that all atomic accesses are relaxed, as we do not rely on the atomics here for any
+       // ordering at all, instead relying on the underlying RwLock to provide ordering of unrelated
+       // memory.
+       pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
+               self.waiting_writers.fetch_add(1, Ordering::Relaxed);
+               let res = self.lock.write();
+               self.waiting_writers.fetch_sub(1, Ordering::Relaxed);
+               res
+       }
+
+       pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
+               if self.waiting_writers.load(Ordering::Relaxed) != 0 {
+                       let _write_queue_lock = self.lock.write();
+               }
+               // Note that we don't consider ensuring that an underlying RwLock allowing writers to
+               // starve readers doesn't exhibit the same behavior here. I'm not aware of any
+               // libstd-backing RwLock which exhibits this behavior, and as documented in the
+               // struct-level documentation, it shouldn't pose a significant issue for our current
+               // codebase.
+               self.lock.read()
+       }
+
+       #[allow(dead_code)]
+       pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<'_, T>> {
+               self.lock.try_write()
+       }
+}
+
+impl<'a, T: 'a> LockTestExt<'a> for FairRwLock<T> {
+       #[inline]
+       fn held_by_thread(&self) -> LockHeldState {
+               // fairrwlock is only built in non-test modes, so we should never support tests.
+               LockHeldState::Unsupported
+       }
+       type ExclLock = RwLockWriteGuard<'a, T>;
+       #[inline]
+       fn unsafe_well_ordered_double_lock_self(&'a self) -> RwLockWriteGuard<'a, T> {
+               self.write().unwrap()
+       }
+}
diff --git a/lightning/src/sync/mod.rs b/lightning/src/sync/mod.rs
new file mode 100644 (file)
index 0000000..1b2b9a7
--- /dev/null
@@ -0,0 +1,58 @@
+#[allow(dead_code)] // Depending on the compilation flags some variants are never used
+#[derive(Debug, PartialEq, Eq)]
+pub(crate) enum LockHeldState {
+       HeldByThread,
+       NotHeldByThread,
+       #[cfg(any(feature = "_bench_unstable", not(test)))]
+       Unsupported,
+}
+
+pub(crate) trait LockTestExt<'a> {
+       fn held_by_thread(&self) -> LockHeldState;
+       type ExclLock;
+       /// If two instances of the same mutex are being taken at the same time, it's very easy to have
+       /// a lockorder inversion and risk deadlock. Thus, we default to disabling such locks.
+       ///
+       /// However, sometimes they cannot be avoided. In such cases, this method exists to take a
+       /// mutex while avoiding a test failure. It is deliberately verbose and includes the term
+       /// "unsafe" to indicate that special care needs to be taken to ensure no deadlocks are
+       /// possible.
+       fn unsafe_well_ordered_double_lock_self(&'a self) -> Self::ExclLock;
+}
+
+#[cfg(all(feature = "std", not(feature = "_bench_unstable"), test))]
+mod debug_sync;
+#[cfg(all(feature = "std", not(feature = "_bench_unstable"), test))]
+pub use debug_sync::*;
+#[cfg(all(feature = "std", not(feature = "_bench_unstable"), test))]
+// Note that to make debug_sync's regex work this must not contain `debug_string` in the module name
+mod test_lockorder_checks;
+
+#[cfg(all(feature = "std", any(feature = "_bench_unstable", not(test))))]
+pub(crate) mod fairrwlock;
+#[cfg(all(feature = "std", any(feature = "_bench_unstable", not(test))))]
+pub use {std::sync::{Arc, Mutex, Condvar, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard}, fairrwlock::FairRwLock};
+
+#[cfg(all(feature = "std", any(feature = "_bench_unstable", not(test))))]
+mod ext_impl {
+       use super::*;
+       impl<'a, T: 'a> LockTestExt<'a> for Mutex<T> {
+               #[inline]
+               fn held_by_thread(&self) -> LockHeldState { LockHeldState::Unsupported }
+               type ExclLock = MutexGuard<'a, T>;
+               #[inline]
+               fn unsafe_well_ordered_double_lock_self(&'a self) -> MutexGuard<T> { self.lock().unwrap() }
+       }
+       impl<'a, T: 'a> LockTestExt<'a> for RwLock<T> {
+               #[inline]
+               fn held_by_thread(&self) -> LockHeldState { LockHeldState::Unsupported }
+               type ExclLock = RwLockWriteGuard<'a, T>;
+               #[inline]
+               fn unsafe_well_ordered_double_lock_self(&'a self) -> RwLockWriteGuard<T> { self.write().unwrap() }
+       }
+}
+
+#[cfg(not(feature = "std"))]
+mod nostd_sync;
+#[cfg(not(feature = "std"))]
+pub use nostd_sync::*;
diff --git a/lightning/src/sync/nostd_sync.rs b/lightning/src/sync/nostd_sync.rs
new file mode 100644 (file)
index 0000000..1730799
--- /dev/null
@@ -0,0 +1,146 @@
+pub use ::alloc::sync::Arc;
+use core::ops::{Deref, DerefMut};
+use core::time::Duration;
+use core::cell::{RefCell, Ref, RefMut};
+use super::{LockTestExt, LockHeldState};
+
+pub type LockResult<Guard> = Result<Guard, ()>;
+
+pub struct Condvar {}
+
+impl Condvar {
+       pub fn new() -> Condvar {
+               Condvar { }
+       }
+
+       pub fn wait<'a, T>(&'a self, guard: MutexGuard<'a, T>) -> LockResult<MutexGuard<'a, T>> {
+               Ok(guard)
+       }
+
+       #[allow(unused)]
+       pub fn wait_timeout<'a, T>(&'a self, guard: MutexGuard<'a, T>, _dur: Duration) -> LockResult<(MutexGuard<'a, T>, ())> {
+               Ok((guard, ()))
+       }
+
+       pub fn notify_all(&self) {}
+}
+
+pub struct Mutex<T: ?Sized> {
+       inner: RefCell<T>
+}
+
+#[must_use = "if unused the Mutex will immediately unlock"]
+pub struct MutexGuard<'a, T: ?Sized + 'a> {
+       lock: RefMut<'a, T>,
+}
+
+impl<T: ?Sized> Deref for MutexGuard<'_, T> {
+       type Target = T;
+
+       fn deref(&self) -> &T {
+               &self.lock.deref()
+       }
+}
+
+impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
+       fn deref_mut(&mut self) -> &mut T {
+               self.lock.deref_mut()
+       }
+}
+
+impl<T> Mutex<T> {
+       pub fn new(inner: T) -> Mutex<T> {
+               Mutex { inner: RefCell::new(inner) }
+       }
+
+       pub fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
+               Ok(MutexGuard { lock: self.inner.borrow_mut() })
+       }
+
+       pub fn try_lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
+               Ok(MutexGuard { lock: self.inner.borrow_mut() })
+       }
+
+       pub fn into_inner(self) -> LockResult<T> {
+               Ok(self.inner.into_inner())
+       }
+}
+
+impl<'a, T: 'a> LockTestExt<'a> for Mutex<T> {
+       #[inline]
+       fn held_by_thread(&self) -> LockHeldState {
+               if self.lock().is_err() { return LockHeldState::HeldByThread; }
+               else { return LockHeldState::NotHeldByThread; }
+       }
+       type ExclLock = MutexGuard<'a, T>;
+       #[inline]
+       fn unsafe_well_ordered_double_lock_self(&'a self) -> MutexGuard<T> { self.lock().unwrap() }
+}
+
+pub struct RwLock<T: ?Sized> {
+       inner: RefCell<T>
+}
+
+pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
+       lock: Ref<'a, T>,
+}
+
+pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
+       lock: RefMut<'a, T>,
+}
+
+impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
+       type Target = T;
+
+       fn deref(&self) -> &T {
+               &self.lock.deref()
+       }
+}
+
+impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
+       type Target = T;
+
+       fn deref(&self) -> &T {
+               &self.lock.deref()
+       }
+}
+
+impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
+       fn deref_mut(&mut self) -> &mut T {
+               self.lock.deref_mut()
+       }
+}
+
+impl<T> RwLock<T> {
+       pub fn new(inner: T) -> RwLock<T> {
+               RwLock { inner: RefCell::new(inner) }
+       }
+
+       pub fn read<'a>(&'a self) -> LockResult<RwLockReadGuard<'a, T>> {
+               Ok(RwLockReadGuard { lock: self.inner.borrow() })
+       }
+
+       pub fn write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
+               Ok(RwLockWriteGuard { lock: self.inner.borrow_mut() })
+       }
+
+       pub fn try_write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
+               match self.inner.try_borrow_mut() {
+                       Ok(lock) => Ok(RwLockWriteGuard { lock }),
+                       Err(_) => Err(())
+               }
+       }
+}
+
+impl<'a, T: 'a> LockTestExt<'a> for RwLock<T> {
+       #[inline]
+       fn held_by_thread(&self) -> LockHeldState {
+               if self.write().is_err() { return LockHeldState::HeldByThread; }
+               else { return LockHeldState::NotHeldByThread; }
+       }
+       type ExclLock = RwLockWriteGuard<'a, T>;
+       #[inline]
+       fn unsafe_well_ordered_double_lock_self(&'a self) -> RwLockWriteGuard<T> { self.write().unwrap() }
+}
+
+pub type FairRwLock<T> = RwLock<T>;
diff --git a/lightning/src/sync/test_lockorder_checks.rs b/lightning/src/sync/test_lockorder_checks.rs
new file mode 100644 (file)
index 0000000..96e497d
--- /dev/null
@@ -0,0 +1,102 @@
+use crate::sync::debug_sync::{RwLock, Mutex};
+
+use super::{LockHeldState, LockTestExt};
+
+use std::sync::Arc;
+
+#[test]
+#[should_panic]
+#[cfg(not(feature = "backtrace"))]
+fn recursive_lock_fail() {
+       let mutex = Mutex::new(());
+       let _a = mutex.lock().unwrap();
+       let _b = mutex.lock().unwrap();
+}
+
+#[test]
+#[should_panic]
+#[cfg(not(feature = "backtrace"))]
+fn recursive_read() {
+       let lock = RwLock::new(());
+       let _a = lock.read().unwrap();
+       let _b = lock.read().unwrap();
+}
+
+#[test]
+#[should_panic]
+fn lockorder_fail() {
+       let a = Mutex::new(());
+       let b = Mutex::new(());
+       {
+               let _a = a.lock().unwrap();
+               let _b = b.lock().unwrap();
+       }
+       {
+               let _b = b.lock().unwrap();
+               let _a = a.lock().unwrap();
+       }
+}
+
+#[test]
+#[should_panic]
+fn write_lockorder_fail() {
+       let a = RwLock::new(());
+       let b = RwLock::new(());
+       {
+               let _a = a.write().unwrap();
+               let _b = b.write().unwrap();
+       }
+       {
+               let _b = b.write().unwrap();
+               let _a = a.write().unwrap();
+       }
+}
+
+#[test]
+#[should_panic]
+fn read_lockorder_fail() {
+       let a = RwLock::new(());
+       let b = RwLock::new(());
+       {
+               let _a = a.read().unwrap();
+               let _b = b.read().unwrap();
+       }
+       {
+               let _b = b.read().unwrap();
+               let _a = a.read().unwrap();
+       }
+}
+
+#[test]
+#[should_panic]
+fn read_write_lockorder_fail() {
+       let a = RwLock::new(());
+       let b = RwLock::new(());
+       {
+               let _a = a.write().unwrap();
+               let _b = b.read().unwrap();
+       }
+       {
+               let _b = b.read().unwrap();
+               let _a = a.write().unwrap();
+       }
+}
+
+#[test]
+fn test_thread_locked_state() {
+       let mtx = Arc::new(Mutex::new(()));
+       let mtx_ref = Arc::clone(&mtx);
+       assert_eq!(mtx.held_by_thread(), LockHeldState::NotHeldByThread);
+
+       let lck = mtx.lock().unwrap();
+       assert_eq!(mtx.held_by_thread(), LockHeldState::HeldByThread);
+
+       let thrd = std::thread::spawn(move || {
+               assert_eq!(mtx_ref.held_by_thread(), LockHeldState::NotHeldByThread);
+       });
+       thrd.join().unwrap();
+       assert_eq!(mtx.held_by_thread(), LockHeldState::HeldByThread);
+
+       std::mem::drop(lck);
+       assert_eq!(mtx.held_by_thread(), LockHeldState::NotHeldByThread);
+}
index 552226ca3e64121569cd2ff65589152255db9c05..052968377a5e58fe6a4236c0812718a236eaab54 100644 (file)
@@ -411,7 +411,7 @@ mod tests {
        #[test]
        fn chacha_stream_adapters_ser_macros() {
                // Test that our stream adapters work as expected with the TLV macros.
-               // This also serves to test the `option: $trait` variant of the `decode_tlv` ser macro.
+               // This also serves to test the `option: $trait` variant of the `_decode_tlv` ser macro.
                do_chacha_stream_adapters_ser_macros().unwrap()
        }
 }
index 5b1bb67292dc2b037fc03b162337d855d0392a96..b32e8660d0a8b3490c2f06f15206760a7725f6eb 100644 (file)
@@ -126,7 +126,6 @@ pub struct ChannelHandshakeConfig {
        ///
        /// [`SignerProvider::get_shutdown_scriptpubkey`]: crate::chain::keysinterface::SignerProvider::get_shutdown_scriptpubkey
        pub commit_upfront_shutdown_pubkey: bool,
-
        /// The Proportion of the channel value to configure as counterparty's channel reserve,
        /// i.e., `their_channel_reserve_satoshis` for both outbound and inbound channels.
        ///
@@ -149,7 +148,28 @@ pub struct ChannelHandshakeConfig {
        ///                as 1000 sats instead, which is a safe implementation-specific lower bound.
        /// Maximum value: 1,000,000, any values larger than 1 Million will be treated as 1 Million (or 100%)
        ///                instead, although channel negotiations will fail in that case.
-       pub their_channel_reserve_proportional_millionths: u32
+       pub their_channel_reserve_proportional_millionths: u32,
+       #[cfg(anchors)]
+       /// If set, we attempt to negotiate the `anchors_zero_fee_htlc_tx`option for outbound channels.
+       ///
+       /// If this option is set, channels may be created that will not be readable by LDK versions
+       /// prior to 0.0.114, causing [`ChannelManager`]'s read method to return a
+       /// [`DecodeError::InvalidValue`].
+       ///
+       /// Note that setting this to true does *not* prevent us from opening channels with
+       /// counterparties that do not support the `anchors_zero_fee_htlc_tx` option; we will simply
+       /// fall back to a `static_remote_key` channel.
+       ///
+       /// LDK will not support the legacy `option_anchors` commitment version due to a discovered
+       /// vulnerability after its deployment. For more context, see the [`SIGHASH_SINGLE + update_fee
+       /// Considered Harmful`] mailing list post.
+       ///
+       /// 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
+       /// [`SIGHASH_SINGLE + update_fee Considered Harmful`]: https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-September/002796.html
+       pub negotiate_anchors_zero_fee_htlc_tx: bool,
 }
 
 impl Default for ChannelHandshakeConfig {
@@ -163,6 +183,8 @@ impl Default for ChannelHandshakeConfig {
                        announced_channel: false,
                        commit_upfront_shutdown_pubkey: true,
                        their_channel_reserve_proportional_millionths: 10_000,
+                       #[cfg(anchors)]
+                       negotiate_anchors_zero_fee_htlc_tx: false,
                }
        }
 }
@@ -171,7 +193,7 @@ impl Default for ChannelHandshakeConfig {
 ///
 /// These limits are only applied to our counterparty's limits, not our own.
 ///
-/// Use 0/<type>::max_value() as appropriate to skip checking.
+/// Use 0/`<type>::max_value()` as appropriate to skip checking.
 ///
 /// Provides sane defaults for most configurations.
 ///
index 1a9038a2f5dc1c3c2122e71f8f6a5b0d4e945782..1f7b5221c8f781e337ae4a3a61b460ab21391829 100644 (file)
@@ -10,7 +10,7 @@
 use crate::ln::channel::{ANCHOR_OUTPUT_VALUE_SATOSHI, MIN_CHAN_DUST_LIMIT_SATOSHIS};
 use crate::ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, HolderCommitmentTransaction, CommitmentTransaction, ChannelTransactionParameters, TrustedCommitmentTransaction, ClosingTransaction};
 use crate::ln::{chan_utils, msgs, PaymentPreimage};
-use crate::chain::keysinterface::{Sign, InMemorySigner, BaseSign};
+use crate::chain::keysinterface::{WriteableEcdsaChannelSigner, InMemorySigner, ChannelSigner, EcdsaChannelSigner};
 
 use crate::prelude::*;
 use core::cmp;
@@ -58,6 +58,12 @@ pub struct EnforcingSigner {
        pub disable_revocation_policy_check: bool,
 }
 
+impl PartialEq for EnforcingSigner {
+       fn eq(&self, o: &Self) -> bool {
+               Arc::ptr_eq(&self.state, &o.state)
+       }
+}
+
 impl EnforcingSigner {
        /// Construct an EnforcingSigner
        pub fn new(inner: InMemorySigner) -> Self {
@@ -90,7 +96,7 @@ impl EnforcingSigner {
        }
 }
 
-impl BaseSign for EnforcingSigner {
+impl ChannelSigner for EnforcingSigner {
        fn get_per_commitment_point(&self, idx: u64, secp_ctx: &Secp256k1<secp256k1::All>) -> PublicKey {
                self.inner.get_per_commitment_point(idx, secp_ctx)
        }
@@ -114,8 +120,15 @@ impl BaseSign for EnforcingSigner {
        }
 
        fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
+
        fn channel_keys_id(&self) -> [u8; 32] { self.inner.channel_keys_id() }
 
+       fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
+               self.inner.provide_channel_parameters(channel_parameters)
+       }
+}
+
+impl EcdsaChannelSigner for EnforcingSigner {
        fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
                self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx);
 
@@ -223,23 +236,20 @@ impl BaseSign for EnforcingSigner {
                self.inner.sign_holder_anchor_input(anchor_tx, input, secp_ctx)
        }
 
-       fn sign_channel_announcement(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
-       -> Result<(Signature, Signature), ()> {
-               self.inner.sign_channel_announcement(msg, secp_ctx)
-       }
-
-       fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
-               self.inner.provide_channel_parameters(channel_parameters)
+       fn sign_channel_announcement_with_funding_key(
+               &self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
+       ) -> Result<Signature, ()> {
+               self.inner.sign_channel_announcement_with_funding_key(msg, secp_ctx)
        }
 }
 
-impl Sign for EnforcingSigner {}
+impl WriteableEcdsaChannelSigner for EnforcingSigner {}
 
 impl Writeable for EnforcingSigner {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
                // EnforcingSigner has two fields - `inner` ([`InMemorySigner`]) and `state`
                // ([`EnforcementState`]). `inner` is serialized here and deserialized by
-               // [`KeysInterface::read_chan_signer`]. `state` is managed by [`KeysInterface`]
+               // [`SignerProvider::read_chan_signer`]. `state` is managed by [`SignerProvider`]
                // and will be serialized as needed by the implementation of that trait.
                self.inner.write(writer)?;
                Ok(())
index b7d562e54ddb7d1bf3166aace8510ea10f62e2ff..aa740044676af69487ac06f928765862bbc7a417 100644 (file)
@@ -37,7 +37,7 @@ pub enum APIError {
        /// too-many-hops, etc).
        InvalidRoute {
                /// A human-readable error message
-               err: &'static str
+               err: String
        },
        /// We were unable to complete the request as the Channel required to do so is unable to
        /// complete the request (or was not found). This can take many forms, including disconnected
@@ -84,6 +84,18 @@ impl fmt::Debug for APIError {
        }
 }
 
+impl_writeable_tlv_based_enum_upgradable!(APIError,
+       (0, APIMisuseError) => { (0, err, required), },
+       (2, FeeRateTooHigh) => {
+               (0, err, required),
+               (2, feerate, required),
+       },
+       (4, InvalidRoute) => { (0, err, required), },
+       (6, ChannelUnavailable) => { (0, err, required), },
+       (8, MonitorUpdateInProgress) => {},
+       (10, IncompatibleShutdownScript) => { (0, script, required), },
+);
+
 #[inline]
 pub(crate) fn get_onion_debug_field(error_code: u16) -> (&'static str, usize) {
        match error_code & 0xff {
index 375174f6f6afa86c556c6804586adfa52020844a..5bc8a5084f2924706bf812aad46f4c750f851bc0 100644 (file)
@@ -21,10 +21,10 @@ use crate::ln::channelmanager::{InterceptId, PaymentId};
 use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
 use crate::ln::features::ChannelTypeFeatures;
 use crate::ln::msgs;
-use crate::ln::msgs::DecodeError;
 use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 use crate::routing::gossip::NetworkUpdate;
-use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, WithoutLength, OptionDeserWrapper};
+use crate::util::errors::APIError;
+use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, RequiredWrapper, UpgradableRequired, WithoutLength};
 use crate::routing::router::{RouteHop, RouteParameters};
 
 use bitcoin::{PackedLockTime, Transaction};
@@ -46,7 +46,7 @@ use crate::sync::Arc;
 
 /// Some information provided on receipt of payment depends on whether the payment received is a
 /// spontaneous payment or a "conventional" lightning payment that's paying an invoice.
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum PaymentPurpose {
        /// Information for receiving a payment that we generated an invoice for.
        InvoicePayment {
@@ -82,6 +82,39 @@ impl_writeable_tlv_based_enum!(PaymentPurpose,
        (2, SpontaneousPayment)
 );
 
+/// When the payment path failure took place and extra details about it. [`PathFailure::OnPath`] may
+/// contain a [`NetworkUpdate`] that needs to be applied to the [`NetworkGraph`].
+///
+/// [`NetworkUpdate`]: crate::routing::gossip::NetworkUpdate
+/// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum PathFailure {
+       /// We failed to initially send the payment and no HTLC was committed to. Contains the relevant
+       /// error.
+       InitialSend {
+               /// The error surfaced from initial send.
+               err: APIError,
+       },
+       /// A hop on the path failed to forward our payment.
+       OnPath {
+               /// If present, this [`NetworkUpdate`] should be applied to the [`NetworkGraph`] so that routing
+               /// decisions can take into account the update.
+               ///
+               /// [`NetworkUpdate`]: crate::routing::gossip::NetworkUpdate
+               /// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph
+               network_update: Option<NetworkUpdate>,
+       },
+}
+
+impl_writeable_tlv_based_enum_upgradable!(PathFailure,
+       (0, OnPath) => {
+               (0, network_update, upgradable_option),
+       },
+       (2, InitialSend) => {
+               (0, err, upgradable_required),
+       },
+);
+
 #[derive(Clone, Debug, PartialEq, Eq)]
 /// The reason the channel was closed. See individual variants more details.
 pub enum ClosureReason {
@@ -257,10 +290,10 @@ pub struct HTLCDescriptor {
        /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
        pub channel_value_satoshis: u64,
        /// The necessary channel parameters that need to be provided to the re-derived
-       /// [`InMemorySigner`] through [`BaseSign::ready_channel`].
+       /// [`InMemorySigner`] through [`BaseSign::provide_channel_parameters`].
        ///
        /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
-       /// [`BaseSign::ready_channel`]: crate::chain::keysinterface::BaseSign::ready_channel
+       /// [`BaseSign::provide_channel_parameters`]: crate::chain::keysinterface::BaseSign::provide_channel_parameters
        pub channel_parameters: ChannelTransactionParameters,
        /// The txid of the commitment transaction in which the HTLC output lives.
        pub commitment_txid: Txid,
@@ -455,7 +488,7 @@ impl_writeable_tlv_based_enum!(InterceptNextHop,
 /// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use
 /// them directly as they don't round-trip exactly (for example FundingGenerationReady is never
 /// written as it makes no sense to respond to it after reconnecting to peers).
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum Event {
        /// Used to indicate that the client should generate a funding transaction with the given
        /// parameters and then call [`ChannelManager::funding_transaction_generated`].
@@ -491,10 +524,10 @@ pub enum Event {
        /// [`ChannelManager::claim_funds`] with the preimage given in [`PaymentPurpose`].
        ///
        /// Note that if the preimage is not known, you should call
-       /// [`ChannelManager::fail_htlc_backwards`] to free up resources for this HTLC and avoid
-       /// network congestion.
-       /// If you fail to call either [`ChannelManager::claim_funds`] or
-       /// [`ChannelManager::fail_htlc_backwards`] within the HTLC's timeout, the HTLC will be
+       /// [`ChannelManager::fail_htlc_backwards`] or [`ChannelManager::fail_htlc_backwards_with_reason`]
+       /// to free up resources for this HTLC and avoid network congestion.
+       /// If you fail to call either [`ChannelManager::claim_funds`], [`ChannelManager::fail_htlc_backwards`],
+       /// or [`ChannelManager::fail_htlc_backwards_with_reason`] within the HTLC's timeout, the HTLC will be
        /// automatically failed.
        ///
        /// # Note
@@ -506,6 +539,7 @@ pub enum Event {
        ///
        /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds
        /// [`ChannelManager::fail_htlc_backwards`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards
+       /// [`ChannelManager::fail_htlc_backwards_with_reason`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards_with_reason
        PaymentClaimable {
                /// The node that will receive the payment after it has been claimed.
                /// This is useful to identify payments received via [phantom nodes].
@@ -564,11 +598,9 @@ pub enum Event {
        /// Note for MPP payments: in rare cases, this event may be preceded by a `PaymentPathFailed`
        /// event. In this situation, you SHOULD treat this payment as having succeeded.
        PaymentSent {
-               /// The id returned by [`ChannelManager::send_payment`] and used with
-               /// [`ChannelManager::retry_payment`].
+               /// The id returned by [`ChannelManager::send_payment`].
                ///
                /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
-               /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
                payment_id: Option<PaymentId>,
                /// The preimage to the hash given to ChannelManager::send_payment.
                /// Note that this serves as a payment receipt, if you wish to have such a thing, you must
@@ -590,19 +622,19 @@ pub enum Event {
                fee_paid_msat: Option<u64>,
        },
        /// Indicates an outbound payment failed. Individual [`Event::PaymentPathFailed`] events
-       /// provide failure information for each MPP part in the payment.
+       /// provide failure information for each path attempt in the payment, including retries.
        ///
        /// This event is provided once there are no further pending HTLCs for the payment and the
-       /// payment is no longer retryable due to [`ChannelManager::abandon_payment`] having been
-       /// called for the corresponding payment.
+       /// payment is no longer retryable, due either to the [`Retry`] provided or
+       /// [`ChannelManager::abandon_payment`] having been called for the corresponding payment.
        ///
+       /// [`Retry`]: crate::ln::channelmanager::Retry
        /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
        PaymentFailed {
                /// The id returned by [`ChannelManager::send_payment`] and used with
-               /// [`ChannelManager::retry_payment`] and [`ChannelManager::abandon_payment`].
+               /// [`ChannelManager::abandon_payment`].
                ///
                /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
-               /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
                /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
                payment_id: PaymentId,
                /// The hash that was given to [`ChannelManager::send_payment`].
@@ -615,11 +647,9 @@ pub enum Event {
        /// Always generated after [`Event::PaymentSent`] and thus useful for scoring channels. See
        /// [`Event::PaymentSent`] for obtaining the payment preimage.
        PaymentPathSuccessful {
-               /// The id returned by [`ChannelManager::send_payment`] and used with
-               /// [`ChannelManager::retry_payment`].
+               /// The id returned by [`ChannelManager::send_payment`].
                ///
                /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
-               /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
                payment_id: PaymentId,
                /// The hash that was given to [`ChannelManager::send_payment`].
                ///
@@ -630,24 +660,21 @@ pub enum Event {
                /// May contain a closed channel if the HTLC sent along the path was fulfilled on chain.
                path: Vec<RouteHop>,
        },
-       /// Indicates an outbound HTLC we sent failed. Probably some intermediary node dropped
-       /// something. You may wish to retry with a different route.
-       ///
-       /// If you have given up retrying this payment and wish to fail it, you MUST call
-       /// [`ChannelManager::abandon_payment`] at least once for a given [`PaymentId`] or memory
-       /// related to payment tracking will leak.
+       /// Indicates an outbound HTLC we sent failed, likely due to an intermediary node being unable to
+       /// handle the HTLC.
        ///
        /// Note that this does *not* indicate that all paths for an MPP payment have failed, see
-       /// [`Event::PaymentFailed`] and [`all_paths_failed`].
+       /// [`Event::PaymentFailed`].
+       ///
+       /// See [`ChannelManager::abandon_payment`] for giving up on this payment before its retries have
+       /// been exhausted.
        ///
        /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
-       /// [`all_paths_failed`]: Self::PaymentPathFailed::all_paths_failed
        PaymentPathFailed {
                /// The id returned by [`ChannelManager::send_payment`] and used with
-               /// [`ChannelManager::retry_payment`] and [`ChannelManager::abandon_payment`].
+               /// [`ChannelManager::abandon_payment`].
                ///
                /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
-               /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
                /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
                payment_id: Option<PaymentId>,
                /// The hash that was given to [`ChannelManager::send_payment`].
@@ -655,35 +682,14 @@ pub enum Event {
                /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
                payment_hash: PaymentHash,
                /// Indicates the payment was rejected for some reason by the recipient. This implies that
-               /// the payment has failed, not just the route in question. If this is not set, you may
-               /// retry the payment via a different route.
+               /// the payment has failed, not just the route in question. If this is not set, the payment may
+               /// be retried via a different route.
                payment_failed_permanently: bool,
-               /// Any failure information conveyed via the Onion return packet by a node along the failed
-               /// payment route.
-               ///
-               /// Should be applied to the [`NetworkGraph`] so that routing decisions can take into
-               /// account the update.
+               /// Extra error details based on the failure type. May contain an update that needs to be
+               /// applied to the [`NetworkGraph`].
                ///
                /// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph
-               network_update: Option<NetworkUpdate>,
-               /// For both single-path and multi-path payments, this is set if all paths of the payment have
-               /// failed. This will be set to false if (1) this is an MPP payment and (2) other parts of the
-               /// larger MPP payment were still in flight when this event was generated.
-               ///
-               /// Note that if you are retrying individual MPP parts, using this value to determine if a
-               /// payment has fully failed is race-y. Because multiple failures can happen prior to events
-               /// being processed, you may retry in response to a first failure, with a second failure
-               /// (with `all_paths_failed` set) still pending. Then, when the second failure is processed
-               /// you will see `all_paths_failed` set even though the retry of the first failure still
-               /// has an associated in-flight HTLC. See (1) for an example of such a failure.
-               ///
-               /// If you wish to retry individual MPP parts and learn when a payment has failed, you must
-               /// call [`ChannelManager::abandon_payment`] and wait for a [`Event::PaymentFailed`] event.
-               ///
-               /// (1) <https://github.com/lightningdevkit/rust-lightning/issues/1164>
-               ///
-               /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
-               all_paths_failed: bool,
+               failure: PathFailure,
                /// The payment path that failed.
                path: Vec<RouteHop>,
                /// The channel responsible for the failed payment path.
@@ -695,12 +701,9 @@ pub enum Event {
                /// If this is `Some`, then the corresponding channel should be avoided when the payment is
                /// retried. May be `None` for older [`Event`] serializations.
                short_channel_id: Option<u64>,
-               /// Parameters needed to compute a new [`Route`] when retrying the failed payment path.
-               ///
-               /// See [`find_route`] for details.
+               /// Parameters used by LDK to compute a new [`Route`] when retrying the failed payment path.
                ///
                /// [`Route`]: crate::routing::router::Route
-               /// [`find_route`]: crate::routing::router::find_route
                retry: Option<RouteParameters>,
 #[cfg(test)]
                error_code: Option<u16>,
@@ -988,8 +991,8 @@ impl Writeable for Event {
                                });
                        },
                        &Event::PaymentPathFailed {
-                               ref payment_id, ref payment_hash, ref payment_failed_permanently, ref network_update,
-                               ref all_paths_failed, ref path, ref short_channel_id, ref retry,
+                               ref payment_id, ref payment_hash, ref payment_failed_permanently, ref failure,
+                               ref path, ref short_channel_id, ref retry,
                                #[cfg(test)]
                                ref error_code,
                                #[cfg(test)]
@@ -1002,13 +1005,14 @@ impl Writeable for Event {
                                error_data.write(writer)?;
                                write_tlv_fields!(writer, {
                                        (0, payment_hash, required),
-                                       (1, network_update, option),
+                                       (1, None::<NetworkUpdate>, option), // network_update in LDK versions prior to 0.0.114
                                        (2, payment_failed_permanently, required),
-                                       (3, all_paths_failed, required),
+                                       (3, false, required), // all_paths_failed in LDK versions prior to 0.0.114
                                        (5, *path, vec_type),
                                        (7, short_channel_id, option),
                                        (9, retry, option),
                                        (11, payment_id, option),
+                                       (13, failure, required),
                                });
                        },
                        &Event::PendingHTLCsForwardable { time_forwardable: _ } => {
@@ -1221,27 +1225,27 @@ impl MaybeReadable for Event {
                                        let mut payment_hash = PaymentHash([0; 32]);
                                        let mut payment_failed_permanently = false;
                                        let mut network_update = None;
-                                       let mut all_paths_failed = Some(true);
                                        let mut path: Option<Vec<RouteHop>> = Some(vec![]);
                                        let mut short_channel_id = None;
                                        let mut retry = None;
                                        let mut payment_id = None;
+                                       let mut failure_opt = None;
                                        read_tlv_fields!(reader, {
                                                (0, payment_hash, required),
-                                               (1, network_update, ignorable),
+                                               (1, network_update, upgradable_option),
                                                (2, payment_failed_permanently, required),
-                                               (3, all_paths_failed, option),
                                                (5, path, vec_type),
                                                (7, short_channel_id, option),
                                                (9, retry, option),
                                                (11, payment_id, option),
+                                               (13, failure_opt, upgradable_option),
                                        });
+                                       let failure = failure_opt.unwrap_or_else(|| PathFailure::OnPath { network_update });
                                        Ok(Some(Event::PaymentPathFailed {
                                                payment_id,
                                                payment_hash,
                                                payment_failed_permanently,
-                                               network_update,
-                                               all_paths_failed: all_paths_failed.unwrap(),
+                                               failure,
                                                path: path.unwrap(),
                                                short_channel_id,
                                                retry,
@@ -1307,16 +1311,15 @@ impl MaybeReadable for Event {
                        9u8 => {
                                let f = || {
                                        let mut channel_id = [0; 32];
-                                       let mut reason = None;
+                                       let mut reason = UpgradableRequired(None);
                                        let mut user_channel_id_low_opt: Option<u64> = None;
                                        let mut user_channel_id_high_opt: Option<u64> = None;
                                        read_tlv_fields!(reader, {
                                                (0, channel_id, required),
                                                (1, user_channel_id_low_opt, option),
-                                               (2, reason, ignorable),
+                                               (2, reason, upgradable_required),
                                                (3, user_channel_id_high_opt, option),
                                        });
-                                       if reason.is_none() { return Ok(None); }
 
                                        // `user_channel_id` used to be a single u64 value. In order to remain
                                        // backwards compatible with versions prior to 0.0.113, the u128 is serialized
@@ -1324,7 +1327,7 @@ impl MaybeReadable for Event {
                                        let user_channel_id = (user_channel_id_low_opt.unwrap_or(0) as u128) +
                                                ((user_channel_id_high_opt.unwrap_or(0) as u128) << 64);
 
-                                       Ok(Some(Event::ChannelClosed { channel_id, user_channel_id, reason: reason.unwrap() }))
+                                       Ok(Some(Event::ChannelClosed { channel_id, user_channel_id, reason: _init_tlv_based_struct_field!(reason, upgradable_required) }))
                                };
                                f()
                        },
@@ -1380,20 +1383,19 @@ impl MaybeReadable for Event {
                        19u8 => {
                                let f = || {
                                        let mut payment_hash = PaymentHash([0; 32]);
-                                       let mut purpose = None;
+                                       let mut purpose = UpgradableRequired(None);
                                        let mut amount_msat = 0;
                                        let mut receiver_node_id = None;
                                        read_tlv_fields!(reader, {
                                                (0, payment_hash, required),
                                                (1, receiver_node_id, option),
-                                               (2, purpose, ignorable),
+                                               (2, purpose, upgradable_required),
                                                (4, amount_msat, required),
                                        });
-                                       if purpose.is_none() { return Ok(None); }
                                        Ok(Some(Event::PaymentClaimed {
                                                receiver_node_id,
                                                payment_hash,
-                                               purpose: purpose.unwrap(),
+                                               purpose: _init_tlv_based_struct_field!(purpose, upgradable_required),
                                                amount_msat,
                                        }))
                                };
@@ -1441,22 +1443,15 @@ impl MaybeReadable for Event {
                        25u8 => {
                                let f = || {
                                        let mut prev_channel_id = [0; 32];
-                                       let mut failed_next_destination_opt = None;
+                                       let mut failed_next_destination_opt = UpgradableRequired(None);
                                        read_tlv_fields!(reader, {
                                                (0, prev_channel_id, required),
-                                               (2, failed_next_destination_opt, ignorable),
+                                               (2, failed_next_destination_opt, upgradable_required),
                                        });
-                                       if let Some(failed_next_destination) = failed_next_destination_opt {
-                                               Ok(Some(Event::HTLCHandlingFailed {
-                                                       prev_channel_id,
-                                                       failed_next_destination,
-                                               }))
-                                       } else {
-                                               // If we fail to read a `failed_next_destination` assume it's because
-                                               // `MaybeReadable::read` returned `Ok(None)`, though it's also possible we
-                                               // were simply missing the field.
-                                               Ok(None)
-                                       }
+                                       Ok(Some(Event::HTLCHandlingFailed {
+                                               prev_channel_id,
+                                               failed_next_destination: _init_tlv_based_struct_field!(failed_next_destination_opt, upgradable_required),
+                                       }))
                                };
                                f()
                        },
@@ -1465,8 +1460,8 @@ impl MaybeReadable for Event {
                                let f = || {
                                        let mut channel_id = [0; 32];
                                        let mut user_channel_id: u128 = 0;
-                                       let mut counterparty_node_id = OptionDeserWrapper(None);
-                                       let mut channel_type = OptionDeserWrapper(None);
+                                       let mut counterparty_node_id = RequiredWrapper(None);
+                                       let mut channel_type = RequiredWrapper(None);
                                        read_tlv_fields!(reader, {
                                                (0, channel_id, required),
                                                (2, user_channel_id, required),
@@ -1611,13 +1606,18 @@ pub enum MessageSendEvent {
                /// The channel_announcement which should be sent.
                msg: msgs::ChannelAnnouncement,
                /// The followup channel_update which should be sent.
-               update_msg: msgs::ChannelUpdate,
+               update_msg: Option<msgs::ChannelUpdate>,
        },
        /// Used to indicate that a channel_update should be broadcast to all peers.
        BroadcastChannelUpdate {
                /// The channel_update which should be sent.
                msg: msgs::ChannelUpdate,
        },
+       /// Used to indicate that a node_announcement should be broadcast to all peers.
+       BroadcastNodeAnnouncement {
+               /// The node_announcement which should be sent.
+               msg: msgs::NodeAnnouncement,
+       },
        /// Used to indicate that a channel_update should be sent to a single peer.
        /// In contrast to [`Self::BroadcastChannelUpdate`], this is used when the channel is a
        /// private channel and we shouldn't be informing all of our peers of channel parameters.
diff --git a/lightning/src/util/fairrwlock.rs b/lightning/src/util/fairrwlock.rs
deleted file mode 100644 (file)
index c9b3866..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-use std::sync::{LockResult, RwLock, RwLockReadGuard, RwLockWriteGuard};
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-/// Rust libstd's RwLock does not provide any fairness guarantees (and, in fact, when used on
-/// Linux with pthreads under the hood, readers trivially and completely starve writers).
-/// Because we often hold read locks while doing message processing in multiple threads which
-/// can use significant CPU time, with write locks being time-sensitive but relatively small in
-/// CPU time, we can end up with starvation completely blocking incoming connections or pings,
-/// especially during initial graph sync.
-///
-/// Thus, we need to block readers when a writer is pending, which we do with a trivial RwLock
-/// wrapper here. Its not particularly optimized, but provides some reasonable fairness by
-/// blocking readers (by taking the write lock) if there are writers pending when we go to take
-/// a read lock.
-pub struct FairRwLock<T> {
-       lock: RwLock<T>,
-       waiting_writers: AtomicUsize,
-}
-
-impl<T> FairRwLock<T> {
-       pub fn new(t: T) -> Self {
-               Self { lock: RwLock::new(t), waiting_writers: AtomicUsize::new(0) }
-       }
-
-       // Note that all atomic accesses are relaxed, as we do not rely on the atomics here for any
-       // ordering at all, instead relying on the underlying RwLock to provide ordering of unrelated
-       // memory.
-       pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
-               self.waiting_writers.fetch_add(1, Ordering::Relaxed);
-               let res = self.lock.write();
-               self.waiting_writers.fetch_sub(1, Ordering::Relaxed);
-               res
-       }
-
-       pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
-               if self.waiting_writers.load(Ordering::Relaxed) != 0 {
-                       let _write_queue_lock = self.lock.write();
-               }
-               // Note that we don't consider ensuring that an underlying RwLock allowing writers to
-               // starve readers doesn't exhibit the same behavior here. I'm not aware of any
-               // libstd-backing RwLock which exhibits this behavior, and as documented in the
-               // struct-level documentation, it shouldn't pose a significant issue for our current
-               // codebase.
-               self.lock.read()
-       }
-}
diff --git a/lightning/src/util/indexed_map.rs b/lightning/src/util/indexed_map.rs
new file mode 100644 (file)
index 0000000..2b5bbac
--- /dev/null
@@ -0,0 +1,233 @@
+//! This module has a map which can be iterated in a deterministic order. See the [`IndexedMap`].
+
+use crate::prelude::{HashMap, hash_map};
+use alloc::vec::Vec;
+use alloc::slice::Iter;
+use core::hash::Hash;
+use core::cmp::Ord;
+use core::ops::{Bound, RangeBounds};
+
+/// A map which can be iterated in a deterministic order.
+///
+/// This would traditionally be accomplished by simply using a [`BTreeMap`], however B-Trees
+/// generally have very slow lookups. Because we use a nodes+channels map while finding routes
+/// across the network graph, our network graph backing map must be as performant as possible.
+/// However, because peers expect to sync the network graph from us (and we need to support that
+/// without holding a lock on the graph for the duration of the sync or dumping the entire graph
+/// into our outbound message queue), we need an iterable map with a consistent iteration order we
+/// can jump to a starting point on.
+///
+/// Thus, we have a custom data structure here - its API mimics that of Rust's [`BTreeMap`], but is
+/// actually backed by a [`HashMap`], with some additional tracking to ensure we can iterate over
+/// keys in the order defined by [`Ord`].
+///
+/// (C-not exported) as bindings provide alternate accessors rather than exposing maps directly.
+///
+/// [`BTreeMap`]: alloc::collections::BTreeMap
+#[derive(Clone, Debug, Eq)]
+pub struct IndexedMap<K: Hash + Ord, V> {
+       map: HashMap<K, V>,
+       keys: Vec<K>,
+}
+
+impl<K: Clone + Hash + Ord, V> IndexedMap<K, V> {
+       /// Constructs a new, empty map
+       pub fn new() -> Self {
+               Self {
+                       map: HashMap::new(),
+                       keys: Vec::new(),
+               }
+       }
+
+       #[inline(always)]
+       /// Fetches the element with the given `key`, if one exists.
+       pub fn get(&self, key: &K) -> Option<&V> {
+               self.map.get(key)
+       }
+
+       /// Fetches a mutable reference to the element with the given `key`, if one exists.
+       pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
+               self.map.get_mut(key)
+       }
+
+       #[inline]
+       /// Returns true if an element with the given `key` exists in the map.
+       pub fn contains_key(&self, key: &K) -> bool {
+               self.map.contains_key(key)
+       }
+
+       /// Removes the element with the given `key`, returning it, if one exists.
+       pub fn remove(&mut self, key: &K) -> Option<V> {
+               let ret = self.map.remove(key);
+               if let Some(_) = ret {
+                       let idx = self.keys.iter().position(|k| k == key).expect("map and keys must be consistent");
+                       self.keys.remove(idx);
+               }
+               ret
+       }
+
+       /// Inserts the given `key`/`value` pair into the map, returning the element that was
+       /// previously stored at the given `key`, if one exists.
+       pub fn insert(&mut self, key: K, value: V) -> Option<V> {
+               let ret = self.map.insert(key.clone(), value);
+               if ret.is_none() {
+                       self.keys.push(key);
+               }
+               ret
+       }
+
+       /// Returns an [`Entry`] for the given `key` in the map, allowing access to the value.
+       pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
+               match self.map.entry(key.clone()) {
+                       hash_map::Entry::Vacant(entry) => {
+                               Entry::Vacant(VacantEntry {
+                                       underlying_entry: entry,
+                                       key,
+                                       keys: &mut self.keys,
+                               })
+                       },
+                       hash_map::Entry::Occupied(entry) => {
+                               Entry::Occupied(OccupiedEntry {
+                                       underlying_entry: entry,
+                                       keys: &mut self.keys,
+                               })
+                       }
+               }
+       }
+
+       /// Returns an iterator which iterates over the keys in the map, in a random order.
+       pub fn unordered_keys(&self) -> impl Iterator<Item = &K> {
+               self.map.keys()
+       }
+
+       /// Returns an iterator which iterates over the `key`/`value` pairs in a random order.
+       pub fn unordered_iter(&self) -> impl Iterator<Item = (&K, &V)> {
+               self.map.iter()
+       }
+
+       /// Returns an iterator which iterates over the `key`s and mutable references to `value`s in a
+       /// random order.
+       pub fn unordered_iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
+               self.map.iter_mut()
+       }
+
+       /// Returns an iterator which iterates over the `key`/`value` pairs in a given range.
+       pub fn range<R: RangeBounds<K>>(&mut self, range: R) -> Range<K, V> {
+               self.keys.sort_unstable();
+               let start = match range.start_bound() {
+                       Bound::Unbounded => 0,
+                       Bound::Included(key) => self.keys.binary_search(key).unwrap_or_else(|index| index),
+                       Bound::Excluded(key) => self.keys.binary_search(key).and_then(|index| Ok(index + 1)).unwrap_or_else(|index| index),
+               };
+               let end = match range.end_bound() {
+                       Bound::Unbounded => self.keys.len(),
+                       Bound::Included(key) => self.keys.binary_search(key).and_then(|index| Ok(index + 1)).unwrap_or_else(|index| index),
+                       Bound::Excluded(key) => self.keys.binary_search(key).unwrap_or_else(|index| index),
+               };
+
+               Range {
+                       inner_range: self.keys[start..end].iter(),
+                       map: &self.map,
+               }
+       }
+
+       /// Returns the number of `key`/`value` pairs in the map
+       pub fn len(&self) -> usize {
+               self.map.len()
+       }
+
+       /// Returns true if there are no elements in the map
+       pub fn is_empty(&self) -> bool {
+               self.map.is_empty()
+       }
+}
+
+impl<K: Hash + Ord + PartialEq, V: PartialEq> PartialEq for IndexedMap<K, V> {
+       fn eq(&self, other: &Self) -> bool {
+               self.map == other.map
+       }
+}
+
+/// An iterator over a range of values in an [`IndexedMap`]
+///
+/// (C-not exported) as bindings provide alternate accessors rather than exposing maps directly.
+pub struct Range<'a, K: Hash + Ord, V> {
+       inner_range: Iter<'a, K>,
+       map: &'a HashMap<K, V>,
+}
+impl<'a, K: Hash + Ord, V: 'a> Iterator for Range<'a, K, V> {
+       type Item = (&'a K, &'a V);
+       fn next(&mut self) -> Option<(&'a K, &'a V)> {
+               self.inner_range.next().map(|k| {
+                       (k, self.map.get(k).expect("map and keys must be consistent"))
+               })
+       }
+}
+
+/// An [`Entry`] for a key which currently has no value
+///
+/// (C-not exported) as bindings provide alternate accessors rather than exposing maps directly.
+pub struct VacantEntry<'a, K: Hash + Ord, V> {
+       #[cfg(feature = "hashbrown")]
+       underlying_entry: hash_map::VacantEntry<'a, K, V, hash_map::DefaultHashBuilder>,
+       #[cfg(not(feature = "hashbrown"))]
+       underlying_entry: hash_map::VacantEntry<'a, K, V>,
+       key: K,
+       keys: &'a mut Vec<K>,
+}
+
+/// An [`Entry`] for an existing key-value pair
+///
+/// (C-not exported) as bindings provide alternate accessors rather than exposing maps directly.
+pub struct OccupiedEntry<'a, K: Hash + Ord, V> {
+       #[cfg(feature = "hashbrown")]
+       underlying_entry: hash_map::OccupiedEntry<'a, K, V, hash_map::DefaultHashBuilder>,
+       #[cfg(not(feature = "hashbrown"))]
+       underlying_entry: hash_map::OccupiedEntry<'a, K, V>,
+       keys: &'a mut Vec<K>,
+}
+
+/// A mutable reference to a position in the map. This can be used to reference, add, or update the
+/// value at a fixed key.
+///
+/// (C-not exported) as bindings provide alternate accessors rather than exposing maps directly.
+pub enum Entry<'a, K: Hash + Ord, V> {
+       /// A mutable reference to a position within the map where there is no value.
+       Vacant(VacantEntry<'a, K, V>),
+       /// A mutable reference to a position within the map where there is currently a value.
+       Occupied(OccupiedEntry<'a, K, V>),
+}
+
+impl<'a, K: Hash + Ord, V> VacantEntry<'a, K, V> {
+       /// Insert a value into the position described by this entry.
+       pub fn insert(self, value: V) -> &'a mut V {
+               self.keys.push(self.key);
+               self.underlying_entry.insert(value)
+       }
+}
+
+impl<'a, K: Hash + Ord, V> OccupiedEntry<'a, K, V> {
+       /// Remove the value at the position described by this entry.
+       pub fn remove_entry(self) -> (K, V) {
+               let res = self.underlying_entry.remove_entry();
+               let idx = self.keys.iter().position(|k| k == &res.0).expect("map and keys must be consistent");
+               self.keys.remove(idx);
+               res
+       }
+
+       /// Get a reference to the value at the position described by this entry.
+       pub fn get(&self) -> &V {
+               self.underlying_entry.get()
+       }
+
+       /// Get a mutable reference to the value at the position described by this entry.
+       pub fn get_mut(&mut self) -> &mut V {
+               self.underlying_entry.get_mut()
+       }
+
+       /// Consume this entry, returning a mutable reference to the value at the position described by
+       /// this entry.
+       pub fn into_mut(self) -> &'a mut V {
+               self.underlying_entry.into_mut()
+       }
+}
index 8c2aba0c1c1cf87ac15ec95076a3a5cc05ea1330..6e98272f3171d2bc47082c4171b6e4013800e911 100644 (file)
@@ -107,7 +107,7 @@ impl<'a> core::fmt::Display for DebugTx<'a> {
                                        }
                                }
                                if num_preimage > 0 || num_timeout > 0 || num_revoked > 0 {
-                                       write!(f, "HTLC claim tx ({} preimage, {} timeout, {} revoked)",
+                                       write!(f, "HTLC claim tx ({} preimage, {} timeout, {} revoked) ",
                                                num_preimage, num_timeout, num_revoked)?;
                                }
                        }
@@ -167,17 +167,17 @@ macro_rules! log_given_level {
        ($logger: expr, $lvl:expr, $($arg:tt)+) => (
                match $lvl {
                        #[cfg(not(any(feature = "max_level_off")))]
-                       $crate::util::logger::Level::Error => log_internal!($logger, $lvl, $($arg)*),
+                       $crate::util::logger::Level::Error => $crate::log_internal!($logger, $lvl, $($arg)*),
                        #[cfg(not(any(feature = "max_level_off", feature = "max_level_error")))]
-                       $crate::util::logger::Level::Warn => log_internal!($logger, $lvl, $($arg)*),
+                       $crate::util::logger::Level::Warn => $crate::log_internal!($logger, $lvl, $($arg)*),
                        #[cfg(not(any(feature = "max_level_off", feature = "max_level_error", feature = "max_level_warn")))]
-                       $crate::util::logger::Level::Info => log_internal!($logger, $lvl, $($arg)*),
+                       $crate::util::logger::Level::Info => $crate::log_internal!($logger, $lvl, $($arg)*),
                        #[cfg(not(any(feature = "max_level_off", feature = "max_level_error", feature = "max_level_warn", feature = "max_level_info")))]
-                       $crate::util::logger::Level::Debug => log_internal!($logger, $lvl, $($arg)*),
+                       $crate::util::logger::Level::Debug => $crate::log_internal!($logger, $lvl, $($arg)*),
                        #[cfg(not(any(feature = "max_level_off", feature = "max_level_error", feature = "max_level_warn", feature = "max_level_info", feature = "max_level_debug")))]
-                       $crate::util::logger::Level::Trace => log_internal!($logger, $lvl, $($arg)*),
+                       $crate::util::logger::Level::Trace => $crate::log_internal!($logger, $lvl, $($arg)*),
                        #[cfg(not(any(feature = "max_level_off", feature = "max_level_error", feature = "max_level_warn", feature = "max_level_info", feature = "max_level_debug", feature = "max_level_trace")))]
-                       $crate::util::logger::Level::Gossip => log_internal!($logger, $lvl, $($arg)*),
+                       $crate::util::logger::Level::Gossip => $crate::log_internal!($logger, $lvl, $($arg)*),
 
                        #[cfg(any(feature = "max_level_off", feature = "max_level_error", feature = "max_level_warn", feature = "max_level_info", feature = "max_level_debug", feature = "max_level_trace"))]
                        _ => {
@@ -191,7 +191,7 @@ macro_rules! log_given_level {
 #[macro_export]
 macro_rules! log_error {
        ($logger: expr, $($arg:tt)*) => (
-               log_given_level!($logger, $crate::util::logger::Level::Error, $($arg)*);
+               $crate::log_given_level!($logger, $crate::util::logger::Level::Error, $($arg)*);
        )
 }
 
@@ -199,7 +199,7 @@ macro_rules! log_error {
 #[macro_export]
 macro_rules! log_warn {
        ($logger: expr, $($arg:tt)*) => (
-               log_given_level!($logger, $crate::util::logger::Level::Warn, $($arg)*);
+               $crate::log_given_level!($logger, $crate::util::logger::Level::Warn, $($arg)*);
        )
 }
 
@@ -207,7 +207,7 @@ macro_rules! log_warn {
 #[macro_export]
 macro_rules! log_info {
        ($logger: expr, $($arg:tt)*) => (
-               log_given_level!($logger, $crate::util::logger::Level::Info, $($arg)*);
+               $crate::log_given_level!($logger, $crate::util::logger::Level::Info, $($arg)*);
        )
 }
 
@@ -215,7 +215,7 @@ macro_rules! log_info {
 #[macro_export]
 macro_rules! log_debug {
        ($logger: expr, $($arg:tt)*) => (
-               log_given_level!($logger, $crate::util::logger::Level::Debug, $($arg)*);
+               $crate::log_given_level!($logger, $crate::util::logger::Level::Debug, $($arg)*);
        )
 }
 
@@ -223,7 +223,7 @@ macro_rules! log_debug {
 #[macro_export]
 macro_rules! log_trace {
        ($logger: expr, $($arg:tt)*) => (
-               log_given_level!($logger, $crate::util::logger::Level::Trace, $($arg)*)
+               $crate::log_given_level!($logger, $crate::util::logger::Level::Trace, $($arg)*)
        )
 }
 
@@ -231,6 +231,6 @@ macro_rules! log_trace {
 #[macro_export]
 macro_rules! log_gossip {
        ($logger: expr, $($arg:tt)*) => (
-               log_given_level!($logger, $crate::util::logger::Level::Gossip, $($arg)*);
+               $crate::log_given_level!($logger, $crate::util::logger::Level::Gossip, $($arg)*);
        )
 }
index 730131f224197dc38e5719be8db2336b92089eae..7bcbc5a41fbf72c346f6e2ed81ddebfad43ce9f1 100644 (file)
@@ -13,7 +13,7 @@
 pub(crate) mod fuzz_wrappers;
 
 #[macro_use]
-pub(crate) mod ser_macros;
+pub mod ser_macros;
 
 pub mod events;
 pub mod errors;
@@ -27,8 +27,6 @@ pub mod wakers;
 pub(crate) mod atomic_counter;
 pub(crate) mod byte_utils;
 pub(crate) mod chacha20;
-#[cfg(all(any(feature = "_bench_unstable", not(test)), feature = "std"))]
-pub(crate) mod fairrwlock;
 #[cfg(fuzzing)]
 pub mod zbase32;
 #[cfg(not(fuzzing))]
@@ -40,6 +38,8 @@ pub(crate) mod transaction_utils;
 pub(crate) mod scid_utils;
 pub(crate) mod time;
 
+pub mod indexed_map;
+
 /// Logging macro utilities.
 #[macro_use]
 pub(crate) mod macro_logger;
index 3c8d93801ccdfec149601e4ec023b5514286f571..aa705f286736ada5cf8d12635fc91f0d459dd29c 100644 (file)
@@ -16,7 +16,7 @@ use crate::routing::scoring::WriteableScore;
 use crate::chain;
 use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
 use crate::chain::chainmonitor::{Persist, MonitorUpdateId};
-use crate::chain::keysinterface::{Sign, KeysInterface, SignerProvider};
+use crate::chain::keysinterface::{EntropySource, NodeSigner, WriteableEcdsaChannelSigner, SignerProvider};
 use crate::chain::transaction::OutPoint;
 use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate};
 use crate::ln::channelmanager::ChannelManager;
@@ -34,16 +34,18 @@ pub trait KVStorePersister {
 }
 
 /// Trait that handles persisting a [`ChannelManager`], [`NetworkGraph`], and [`WriteableScore`] to disk.
-pub trait Persister<'a, M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref, S: WriteableScore<'a>>
-       where M::Target: 'static + chain::Watch<<K::Target as SignerProvider>::Signer>,
+pub trait Persister<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref, S: WriteableScore<'a>>
+       where M::Target: 'static + chain::Watch<<SP::Target as SignerProvider>::Signer>,
                T::Target: 'static + BroadcasterInterface,
-               K::Target: 'static + KeysInterface,
+               ES::Target: 'static + EntropySource,
+               NS::Target: 'static + NodeSigner,
+               SP::Target: 'static + SignerProvider,
                F::Target: 'static + FeeEstimator,
                R::Target: 'static + Router,
                L::Target: 'static + Logger,
 {
        /// Persist the given ['ChannelManager'] to disk, returning an error if persistence failed.
-       fn persist_manager(&self, channel_manager: &ChannelManager<M, T, K, F, R, L>) -> Result<(), io::Error>;
+       fn persist_manager(&self, channel_manager: &ChannelManager<M, T, ES, NS, SP, F, R, L>) -> Result<(), io::Error>;
 
        /// Persist the given [`NetworkGraph`] to disk, returning an error if persistence failed.
        fn persist_graph(&self, network_graph: &NetworkGraph<L>) -> Result<(), io::Error>;
@@ -52,16 +54,18 @@ pub trait Persister<'a, M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Der
        fn persist_scorer(&self, scorer: &S) -> Result<(), io::Error>;
 }
 
-impl<'a, A: KVStorePersister, M: Deref, T: Deref, K: Deref, F: Deref, R: Deref, L: Deref, S: WriteableScore<'a>> Persister<'a, M, T, K, F, R, L, S> for A
-       where M::Target: 'static + chain::Watch<<K::Target as SignerProvider>::Signer>,
+impl<'a, A: KVStorePersister, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref, S: WriteableScore<'a>> Persister<'a, M, T, ES, NS, SP, F, R, L, S> for A
+       where M::Target: 'static + chain::Watch<<SP::Target as SignerProvider>::Signer>,
                T::Target: 'static + BroadcasterInterface,
-               K::Target: 'static + KeysInterface,
+               ES::Target: 'static + EntropySource,
+               NS::Target: 'static + NodeSigner,
+               SP::Target: 'static + SignerProvider,
                F::Target: 'static + FeeEstimator,
                R::Target: 'static + Router,
                L::Target: 'static + Logger,
 {
        /// Persist the given ['ChannelManager'] to disk with the name "manager", returning an error if persistence failed.
-       fn persist_manager(&self, channel_manager: &ChannelManager<M, T, K, F, R, L>) -> Result<(), io::Error> {
+       fn persist_manager(&self, channel_manager: &ChannelManager<M, T, ES, NS, SP, F, R, L>) -> Result<(), io::Error> {
                self.persist("manager", channel_manager)
        }
 
@@ -76,7 +80,7 @@ impl<'a, A: KVStorePersister, M: Deref, T: Deref, K: Deref, F: Deref, R: Deref,
        }
 }
 
-impl<ChannelSigner: Sign, K: KVStorePersister> Persist<ChannelSigner> for K {
+impl<ChannelSigner: WriteableEcdsaChannelSigner, K: KVStorePersister> Persist<ChannelSigner> for K {
        // TODO: We really need a way for the persister to inform the user that its time to crash/shut
        // down once these start returning failure.
        // A PermanentFailure implies we should probably just shut down the node since we're
@@ -90,7 +94,7 @@ impl<ChannelSigner: Sign, K: KVStorePersister> Persist<ChannelSigner> for K {
                }
        }
 
-       fn update_persisted_channel(&self, funding_txo: OutPoint, _update: &Option<ChannelMonitorUpdate>, monitor: &ChannelMonitor<ChannelSigner>, _update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus {
+       fn update_persisted_channel(&self, funding_txo: OutPoint, _update: Option<&ChannelMonitorUpdate>, monitor: &ChannelMonitor<ChannelSigner>, _update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus {
                let key = format!("monitors/{}_{}", funding_txo.txid.to_hex(), funding_txo.index);
                match self.persist(&key, monitor) {
                        Ok(()) => chain::ChannelMonitorUpdateStatus::Completed,
index 3db98553af547039ecc24c8ed2fa236aadbc7d18..19e2f5527ccbcbcb7c997e8f628ef4cf292974e3 100644 (file)
@@ -68,7 +68,7 @@ pub fn scid_from_parts(block: u64, tx_index: u64, vout_index: u64) -> Result<u64
 pub(crate) mod fake_scid {
        use bitcoin::hash_types::BlockHash;
        use bitcoin::hashes::hex::FromHex;
-       use crate::chain::keysinterface::{KeysInterface, EntropySource};
+       use crate::chain::keysinterface::EntropySource;
        use crate::util::chacha20::ChaCha20;
        use crate::util::scid_utils;
 
@@ -101,13 +101,13 @@ pub(crate) mod fake_scid {
                /// between segwit activation and the current best known height, and the tx index and output
                /// index are also selected from a "reasonable" range. We add this logic because it makes it
                /// non-obvious at a glance that the scid is fake, e.g. if it appears in invoice route hints.
-               pub(crate) fn get_fake_scid<K: Deref>(&self, highest_seen_blockheight: u32, genesis_hash: &BlockHash, fake_scid_rand_bytes: &[u8; 32], keys_manager: &K) -> u64
-                       where K::Target: KeysInterface,
+               pub(crate) fn get_fake_scid<ES: Deref>(&self, highest_seen_blockheight: u32, genesis_hash: &BlockHash, fake_scid_rand_bytes: &[u8; 32], entropy_source: &ES) -> u64
+                       where ES::Target: EntropySource,
                {
                        // Ensure we haven't created a namespace that doesn't fit into the 3 bits we've allocated for
                        // namespaces.
                        assert!((*self as u8) < MAX_NAMESPACES);
-                       let rand_bytes = keys_manager.get_secure_random_bytes();
+                       let rand_bytes = entropy_source.get_secure_random_bytes();
 
                        let segwit_activation_height = segwit_activation_height(genesis_hash);
                        let mut blocks_since_segwit_activation = highest_seen_blockheight.saturating_sub(segwit_activation_height);
index 02d4a81b39e4418daf45f6cb6fc6f61180b1785e..bef192585b5e486696068174b92539c0faa895ff 100644 (file)
@@ -8,7 +8,10 @@
 // licenses.
 
 //! A very simple serialization framework which is used to serialize/deserialize messages as well
-//! as ChannelsManagers and ChannelMonitors.
+//! as [`ChannelManager`]s and [`ChannelMonitor`]s.
+//!
+//! [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
+//! [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
 
 use crate::prelude::*;
 use crate::io::{self, Read, Seek, Write};
@@ -19,6 +22,8 @@ use core::cmp;
 use core::convert::TryFrom;
 use core::ops::Deref;
 
+use alloc::collections::BTreeMap;
+
 use bitcoin::secp256k1::{PublicKey, SecretKey};
 use bitcoin::secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE, COMPACT_SIGNATURE_SIZE, SCHNORR_SIGNATURE_SIZE};
 use bitcoin::secp256k1::ecdsa;
@@ -40,8 +45,8 @@ use crate::util::byte_utils::{be48_to_array, slice_to_be48};
 /// serialization buffer size
 pub const MAX_BUF_SIZE: usize = 64 * 1024;
 
-/// A simplified version of std::io::Write that exists largely for backwards compatibility.
-/// An impl is provided for any type that also impls std::io::Write.
+/// A simplified version of [`std::io::Write`] that exists largely for backwards compatibility.
+/// An impl is provided for any type that also impls [`std::io::Write`].
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
 pub trait Writer {
@@ -84,7 +89,9 @@ impl Writer for VecWriter {
 
 /// Writer that only tracks the amount of data written - useful if you need to calculate the length
 /// of some data when serialized but don't yet need the full data.
-pub(crate) struct LengthCalculatingWriter(pub usize);
+///
+/// (C-not exported) as manual TLV building is not currently supported in bindings
+pub struct LengthCalculatingWriter(pub usize);
 impl Writer for LengthCalculatingWriter {
        #[inline]
        fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> {
@@ -93,23 +100,28 @@ impl Writer for LengthCalculatingWriter {
        }
 }
 
-/// Essentially std::io::Take but a bit simpler and with a method to walk the underlying stream
+/// Essentially [`std::io::Take`] but a bit simpler and with a method to walk the underlying stream
 /// forward to ensure we always consume exactly the fixed length specified.
-pub(crate) struct FixedLengthReader<R: Read> {
+///
+/// (C-not exported) as manual TLV building is not currently supported in bindings
+pub struct FixedLengthReader<R: Read> {
        read: R,
        bytes_read: u64,
        total_bytes: u64,
 }
 impl<R: Read> FixedLengthReader<R> {
+       /// Returns a new [`FixedLengthReader`].
        pub fn new(read: R, total_bytes: u64) -> Self {
                Self { read, bytes_read: 0, total_bytes }
        }
 
+       /// Returns whether some bytes are remaining or not.
        #[inline]
        pub fn bytes_remain(&mut self) -> bool {
                self.bytes_read != self.total_bytes
        }
 
+       /// Consumes the remaining bytes.
        #[inline]
        pub fn eat_remaining(&mut self) -> Result<(), DecodeError> {
                copy(self, &mut sink()).unwrap();
@@ -145,13 +157,17 @@ impl<R: Read> LengthRead for FixedLengthReader<R> {
        }
 }
 
-/// A Read which tracks whether any bytes have been read at all. This allows us to distinguish
+/// A [`Read`] implementation which tracks whether any bytes have been read at all. This allows us to distinguish
 /// between "EOF reached before we started" and "EOF reached mid-read".
-pub(crate) struct ReadTrackingReader<R: Read> {
+///
+/// (C-not exported) as manual TLV building is not currently supported in bindings
+pub struct ReadTrackingReader<R: Read> {
        read: R,
+       /// Returns whether we have read from this reader or not yet.
        pub have_read: bool,
 }
 impl<R: Read> ReadTrackingReader<R> {
+       /// Returns a new [`ReadTrackingReader`].
        pub fn new(read: R) -> Self {
                Self { read, have_read: false }
        }
@@ -170,21 +186,21 @@ impl<R: Read> Read for ReadTrackingReader<R> {
        }
 }
 
-/// A trait that various rust-lightning types implement allowing them to be written out to a Writer
+/// A trait that various LDK types implement allowing them to be written out to a [`Writer`].
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
 pub trait Writeable {
-       /// Writes self out to the given Writer
+       /// Writes `self` out to the given [`Writer`].
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error>;
 
-       /// Writes self out to a Vec<u8>
+       /// Writes `self` out to a `Vec<u8>`.
        fn encode(&self) -> Vec<u8> {
                let mut msg = VecWriter(Vec::new());
                self.write(&mut msg).unwrap();
                msg.0
        }
 
-       /// Writes self out to a Vec<u8>
+       /// Writes `self` out to a `Vec<u8>`.
        #[cfg(test)]
        fn encode_with_len(&self) -> Vec<u8> {
                let mut msg = VecWriter(Vec::new());
@@ -210,64 +226,64 @@ impl<'a, T: Writeable> Writeable for &'a T {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> { (*self).write(writer) }
 }
 
-/// A trait that various rust-lightning types implement allowing them to be read in from a Read
+/// A trait that various LDK types implement allowing them to be read in from a [`Read`].
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
 pub trait Readable
        where Self: Sized
 {
-       /// Reads a Self in from the given Read
+       /// Reads a `Self` in from the given [`Read`].
        fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError>;
 }
 
-/// A trait that various rust-lightning types implement allowing them to be read in from a
-/// `Read + Seek`.
+/// A trait that various LDK types implement allowing them to be read in from a
+/// [`Read`]` + `[`Seek`].
 pub(crate) trait SeekReadable where Self: Sized {
-       /// Reads a Self in from the given Read
+       /// Reads a `Self` in from the given [`Read`].
        fn read<R: Read + Seek>(reader: &mut R) -> Result<Self, DecodeError>;
 }
 
-/// A trait that various higher-level rust-lightning types implement allowing them to be read in
-/// from a Read given some additional set of arguments which is required to deserialize.
+/// A trait that various higher-level LDK types implement allowing them to be read in
+/// from a [`Read`] given some additional set of arguments which is required to deserialize.
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
 pub trait ReadableArgs<P>
        where Self: Sized
 {
-       /// Reads a Self in from the given Read
+       /// Reads a `Self` in from the given [`Read`].
        fn read<R: Read>(reader: &mut R, params: P) -> Result<Self, DecodeError>;
 }
 
-/// A std::io::Read that also provides the total bytes available to read.
+/// A [`std::io::Read`] that also provides the total bytes available to be read.
 pub(crate) trait LengthRead: Read {
-       /// The total number of bytes available to read.
+       /// The total number of bytes available to be read.
        fn total_bytes(&self) -> u64;
 }
 
-/// A trait that various higher-level rust-lightning types implement allowing them to be read in
+/// A trait that various higher-level LDK types implement allowing them to be read in
 /// from a Read given some additional set of arguments which is required to deserialize, requiring
 /// the implementer to provide the total length of the read.
 pub(crate) trait LengthReadableArgs<P> where Self: Sized
 {
-       /// Reads a Self in from the given LengthRead
+       /// Reads a `Self` in from the given [`LengthRead`].
        fn read<R: LengthRead>(reader: &mut R, params: P) -> Result<Self, DecodeError>;
 }
 
-/// A trait that various higher-level rust-lightning types implement allowing them to be read in
-/// from a Read, requiring the implementer to provide the total length of the read.
+/// A trait that various higher-level LDK types implement allowing them to be read in
+/// from a [`Read`], requiring the implementer to provide the total length of the read.
 pub(crate) trait LengthReadable where Self: Sized
 {
-       /// Reads a Self in from the given LengthRead
+       /// Reads a `Self` in from the given [`LengthRead`].
        fn read<R: LengthRead>(reader: &mut R) -> Result<Self, DecodeError>;
 }
 
-/// A trait that various rust-lightning types implement allowing them to (maybe) be read in from a Read
+/// A trait that various LDK types implement allowing them to (maybe) be read in from a [`Read`].
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
 pub trait MaybeReadable
        where Self: Sized
 {
-       /// Reads a Self in from the given Read
+       /// Reads a `Self` in from the given [`Read`].
        fn read<R: Read>(reader: &mut R) -> Result<Option<Self>, DecodeError>;
 }
 
@@ -278,18 +294,41 @@ impl<T: Readable> MaybeReadable for T {
        }
 }
 
-pub(crate) struct OptionDeserWrapper<T: Readable>(pub Option<T>);
-impl<T: Readable> Readable for OptionDeserWrapper<T> {
+/// Wrapper to read a required (non-optional) TLV record.
+///
+/// (C-not exported) as manual TLV building is not currently supported in bindings
+pub struct RequiredWrapper<T>(pub Option<T>);
+impl<T: Readable> Readable for RequiredWrapper<T> {
        #[inline]
        fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
                Ok(Self(Some(Readable::read(reader)?)))
        }
 }
-/// When handling default_values, we want to map the default-value T directly
-/// to a OptionDeserWrapper<T> in a way that works for `field: T = t;` as
+impl<A, T: ReadableArgs<A>> ReadableArgs<A> for RequiredWrapper<T> {
+       #[inline]
+       fn read<R: Read>(reader: &mut R, args: A) -> Result<Self, DecodeError> {
+               Ok(Self(Some(ReadableArgs::read(reader, args)?)))
+       }
+}
+/// When handling `default_values`, we want to map the default-value T directly
+/// to a `RequiredWrapper<T>` in a way that works for `field: T = t;` as
 /// well. Thus, we assume `Into<T> for T` does nothing and use that.
-impl<T: Readable> From<T> for OptionDeserWrapper<T> {
-       fn from(t: T) -> OptionDeserWrapper<T> { OptionDeserWrapper(Some(t)) }
+impl<T> From<T> for RequiredWrapper<T> {
+       fn from(t: T) -> RequiredWrapper<T> { RequiredWrapper(Some(t)) }
+}
+
+/// Wrapper to read a required (non-optional) TLV record that may have been upgraded without
+/// backwards compat.
+///
+/// (C-not exported) as manual TLV building is not currently supported in bindings
+pub struct UpgradableRequired<T: MaybeReadable>(pub Option<T>);
+impl<T: MaybeReadable> MaybeReadable for UpgradableRequired<T> {
+       #[inline]
+       fn read<R: Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
+               let tlv = MaybeReadable::read(reader)?;
+               if let Some(tlv) = tlv { return Ok(Some(Self(Some(tlv)))) }
+               Ok(None)
+       }
 }
 
 pub(crate) struct U48(pub u64);
@@ -308,7 +347,7 @@ impl Readable for U48 {
        }
 }
 
-/// Lightning TLV uses a custom variable-length integer called BigSize. It is similar to Bitcoin's
+/// Lightning TLV uses a custom variable-length integer called `BigSize`. It is similar to Bitcoin's
 /// variable-length integers except that it is serialized in big-endian instead of little-endian.
 ///
 /// Like Bitcoin's variable-length integer, it exhibits ambiguity in that certain values can be
@@ -372,9 +411,43 @@ impl Readable for BigSize {
        }
 }
 
+/// The lightning protocol uses u16s for lengths in most cases. As our serialization framework
+/// primarily targets that, we must as well. However, because we may serialize objects that have
+/// more than 65K entries, we need to be able to store larger values. Thus, we define a variable
+/// length integer here that is backwards-compatible for values < 0xffff. We treat 0xffff as
+/// "read eight more bytes".
+///
+/// To ensure we only have one valid encoding per value, we add 0xffff to values written as eight
+/// bytes. Thus, 0xfffe is serialized as 0xfffe, whereas 0xffff is serialized as
+/// 0xffff0000000000000000 (i.e. read-eight-bytes then zero).
+struct CollectionLength(pub u64);
+impl Writeable for CollectionLength {
+       #[inline]
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               if self.0 < 0xffff {
+                       (self.0 as u16).write(writer)
+               } else {
+                       0xffffu16.write(writer)?;
+                       (self.0 - 0xffff).write(writer)
+               }
+       }
+}
+
+impl Readable for CollectionLength {
+       #[inline]
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let mut val: u64 = <u16 as Readable>::read(r)? as u64;
+               if val == 0xffff {
+                       val = <u64 as Readable>::read(r)?
+                               .checked_add(0xffff).ok_or(DecodeError::InvalidValue)?;
+               }
+               Ok(CollectionLength(val))
+       }
+}
+
 /// In TLV we occasionally send fields which only consist of, or potentially end with, a
 /// variable-length integer which is simply truncated by skipping high zero bytes. This type
-/// encapsulates such integers implementing Readable/Writeable for them.
+/// encapsulates such integers implementing [`Readable`]/[`Writeable`] for them.
 #[cfg_attr(test, derive(PartialEq, Eq, Debug))]
 pub(crate) struct HighZeroBytesDroppedBigSize<T>(pub T);
 
@@ -526,9 +599,11 @@ impl Readable for [u16; 8] {
        }
 }
 
-/// For variable-length values within TLV record where the length is encoded as part of the record.
+/// A type for variable-length values within TLV record where the length is encoded as part of the record.
 /// Used to prevent encoding the length twice.
-pub(crate) struct WithoutLength<T>(pub T);
+///
+/// (C-not exported) as manual TLV building is not currently supported in bindings
+pub struct WithoutLength<T>(pub T);
 
 impl Writeable for WithoutLength<&String> {
        #[inline]
@@ -579,50 +654,74 @@ impl<'a, T> From<&'a Vec<T>> for WithoutLength<&'a Vec<T>> {
        fn from(v: &'a Vec<T>) -> Self { Self(v) }
 }
 
-// HashMap
-impl<K, V> Writeable for HashMap<K, V>
-       where K: Writeable + Eq + Hash,
-             V: Writeable
-{
+#[derive(Debug)]
+pub(crate) struct Iterable<'a, I: Iterator<Item = &'a T> + Clone, T: 'a>(pub I);
+
+impl<'a, I: Iterator<Item = &'a T> + Clone, T: 'a + Writeable> Writeable for Iterable<'a, I, T> {
        #[inline]
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-       (self.len() as u16).write(w)?;
-               for (key, value) in self.iter() {
-                       key.write(w)?;
-                       value.write(w)?;
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               for ref v in self.0.clone() {
+                       v.write(writer)?;
                }
                Ok(())
        }
 }
 
-impl<K, V> Readable for HashMap<K, V>
-       where K: Readable + Eq + Hash,
-             V: MaybeReadable
-{
-       #[inline]
-       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let len: u16 = Readable::read(r)?;
-               let mut ret = HashMap::with_capacity(len as usize);
-               for _ in 0..len {
-                       let k = K::read(r)?;
-                       let v_opt = V::read(r)?;
-                       if let Some(v) = v_opt {
-                               if ret.insert(k, v).is_some() {
-                                       return Err(DecodeError::InvalidValue);
+#[cfg(test)]
+impl<'a, I: Iterator<Item = &'a T> + Clone, T: 'a + PartialEq> PartialEq for Iterable<'a, I, T> {
+       fn eq(&self, other: &Self) -> bool {
+               self.0.clone().collect::<Vec<_>>() == other.0.clone().collect::<Vec<_>>()
+       }
+}
+
+macro_rules! impl_for_map {
+       ($ty: ident, $keybound: ident, $constr: expr) => {
+               impl<K, V> Writeable for $ty<K, V>
+                       where K: Writeable + Eq + $keybound, V: Writeable
+               {
+                       #[inline]
+                       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+                               CollectionLength(self.len() as u64).write(w)?;
+                               for (key, value) in self.iter() {
+                                       key.write(w)?;
+                                       value.write(w)?;
                                }
+                               Ok(())
+                       }
+               }
+
+               impl<K, V> Readable for $ty<K, V>
+                       where K: Readable + Eq + $keybound, V: MaybeReadable
+               {
+                       #[inline]
+                       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+                               let len: CollectionLength = Readable::read(r)?;
+                               let mut ret = $constr(len.0 as usize);
+                               for _ in 0..len.0 {
+                                       let k = K::read(r)?;
+                                       let v_opt = V::read(r)?;
+                                       if let Some(v) = v_opt {
+                                               if ret.insert(k, v).is_some() {
+                                                       return Err(DecodeError::InvalidValue);
+                                               }
+                                       }
+                               }
+                               Ok(ret)
                        }
                }
-               Ok(ret)
        }
 }
 
+impl_for_map!(BTreeMap, Ord, |_| BTreeMap::new());
+impl_for_map!(HashMap, Hash, |len| HashMap::with_capacity(len));
+
 // HashSet
 impl<T> Writeable for HashSet<T>
 where T: Writeable + Eq + Hash
 {
        #[inline]
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               (self.len() as u16).write(w)?;
+               CollectionLength(self.len() as u64).write(w)?;
                for item in self.iter() {
                        item.write(w)?;
                }
@@ -635,9 +734,9 @@ where T: Readable + Eq + Hash
 {
        #[inline]
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let len: u16 = Readable::read(r)?;
-               let mut ret = HashSet::with_capacity(len as usize);
-               for _ in 0..len {
+               let len: CollectionLength = Readable::read(r)?;
+               let mut ret = HashSet::with_capacity(cmp::min(len.0 as usize, MAX_BUF_SIZE / core::mem::size_of::<T>()));
+               for _ in 0..len.0 {
                        if !ret.insert(T::read(r)?) {
                                return Err(DecodeError::InvalidValue)
                        }
@@ -647,51 +746,63 @@ where T: Readable + Eq + Hash
 }
 
 // Vectors
-impl Writeable for Vec<u8> {
-       #[inline]
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               (self.len() as u16).write(w)?;
-               w.write_all(&self)
-       }
-}
+macro_rules! impl_for_vec {
+       ($ty: ty $(, $name: ident)*) => {
+               impl<$($name : Writeable),*> Writeable for Vec<$ty> {
+                       #[inline]
+                       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+                               CollectionLength(self.len() as u64).write(w)?;
+                               for elem in self.iter() {
+                                       elem.write(w)?;
+                               }
+                               Ok(())
+                       }
+               }
 
-impl Readable for Vec<u8> {
-       #[inline]
-       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let len: u16 = Readable::read(r)?;
-               let mut ret = Vec::with_capacity(len as usize);
-               ret.resize(len as usize, 0);
-               r.read_exact(&mut ret)?;
-               Ok(ret)
+               impl<$($name : Readable),*> Readable for Vec<$ty> {
+                       #[inline]
+                       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+                               let len: CollectionLength = Readable::read(r)?;
+                               let mut ret = Vec::with_capacity(cmp::min(len.0 as usize, MAX_BUF_SIZE / core::mem::size_of::<$ty>()));
+                               for _ in 0..len.0 {
+                                       if let Some(val) = MaybeReadable::read(r)? {
+                                               ret.push(val);
+                                       }
+                               }
+                               Ok(ret)
+                       }
+               }
        }
 }
-impl Writeable for Vec<ecdsa::Signature> {
+
+impl Writeable for Vec<u8> {
        #[inline]
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               (self.len() as u16).write(w)?;
-               for e in self.iter() {
-                       e.write(w)?;
-               }
-               Ok(())
+               CollectionLength(self.len() as u64).write(w)?;
+               w.write_all(&self)
        }
 }
 
-impl Readable for Vec<ecdsa::Signature> {
+impl Readable for Vec<u8> {
        #[inline]
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let len: u16 = Readable::read(r)?;
-               let byte_size = (len as usize)
-                               .checked_mul(COMPACT_SIGNATURE_SIZE)
-                               .ok_or(DecodeError::BadLengthDescriptor)?;
-               if byte_size > MAX_BUF_SIZE {
-                       return Err(DecodeError::BadLengthDescriptor);
+               let mut len: CollectionLength = Readable::read(r)?;
+               let mut ret = Vec::new();
+               while len.0 > 0 {
+                       let readamt = cmp::min(len.0 as usize, MAX_BUF_SIZE);
+                       let readstart = ret.len();
+                       ret.resize(readstart + readamt, 0);
+                       r.read_exact(&mut ret[readstart..])?;
+                       len.0 -= readamt as u64;
                }
-               let mut ret = Vec::with_capacity(len as usize);
-               for _ in 0..len { ret.push(Readable::read(r)?); }
                Ok(ret)
        }
 }
 
+impl_for_vec!(ecdsa::Signature);
+impl_for_vec!(crate::ln::channelmanager::MonitorUpdateCompletionAction);
+impl_for_vec!((A, B), A, B);
+
 impl Writeable for Script {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                (self.len() as u16).write(w)?;
@@ -1005,6 +1116,24 @@ impl<A: Writeable, B: Writeable, C: Writeable> Writeable for (A, B, C) {
        }
 }
 
+impl<A: Readable, B: Readable, C: Readable, D: Readable> Readable for (A, B, C, D) {
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let a: A = Readable::read(r)?;
+               let b: B = Readable::read(r)?;
+               let c: C = Readable::read(r)?;
+               let d: D = Readable::read(r)?;
+               Ok((a, b, c, d))
+       }
+}
+impl<A: Writeable, B: Writeable, C: Writeable, D: Writeable> Writeable for (A, B, C, D) {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               self.0.write(w)?;
+               self.1.write(w)?;
+               self.2.write(w)?;
+               self.3.write(w)
+       }
+}
+
 impl Writeable for () {
        fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
                Ok(())
@@ -1019,7 +1148,7 @@ impl Readable for () {
 impl Writeable for String {
        #[inline]
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               (self.len() as u16).write(w)?;
+               CollectionLength(self.len() as u64).write(w)?;
                w.write_all(self.as_bytes())
        }
 }
@@ -1036,7 +1165,9 @@ impl Readable for String {
 /// Only the character set and length will be validated.
 /// The character set consists of ASCII alphanumeric characters, hyphens, and periods.
 /// Its length is guaranteed to be representable by a single byte.
-/// This serialization is used by BOLT 7 hostnames.
+/// This serialization is used by [`BOLT 7`] hostnames.
+///
+/// [`BOLT 7`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Hostname(String);
 impl Hostname {
index d37a841eaff31945ecc2af27d624ca8570552006..59402f6acc8e0eab43810eb896a678186e2e9efc 100644 (file)
@@ -7,9 +7,19 @@
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
-macro_rules! encode_tlv {
+//! Some macros that implement [`Readable`]/[`Writeable`] traits for lightning messages.
+//! They also handle serialization and deserialization of TLVs.
+//!
+//! [`Readable`]: crate::util::ser::Readable
+//! [`Writeable`]: crate::util::ser::Writeable
+
+/// Implements serialization for a single TLV record.
+/// This is exported for use by other exported macros, do not use directly.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _encode_tlv {
        ($stream: expr, $type: expr, $field: expr, (default_value, $default: expr)) => {
-               encode_tlv!($stream, $type, $field, required)
+               $crate::_encode_tlv!($stream, $type, $field, required)
        };
        ($stream: expr, $type: expr, $field: expr, (static_value, $value: expr)) => {
                let _ = &$field; // Ensure we "use" the $field
@@ -20,7 +30,7 @@ macro_rules! encode_tlv {
                $field.write($stream)?;
        };
        ($stream: expr, $type: expr, $field: expr, vec_type) => {
-               encode_tlv!($stream, $type, $crate::util::ser::WithoutLength(&$field), required);
+               $crate::_encode_tlv!($stream, $type, $crate::util::ser::WithoutLength(&$field), required);
        };
        ($stream: expr, $optional_type: expr, $optional_field: expr, option) => {
                if let Some(ref field) = $optional_field {
@@ -29,25 +39,78 @@ macro_rules! encode_tlv {
                        field.write($stream)?;
                }
        };
+       ($stream: expr, $type: expr, $field: expr, upgradable_required) => {
+               $crate::_encode_tlv!($stream, $type, $field, required);
+       };
+       ($stream: expr, $type: expr, $field: expr, upgradable_option) => {
+               $crate::_encode_tlv!($stream, $type, $field, option);
+       };
        ($stream: expr, $type: expr, $field: expr, (option, encoding: ($fieldty: ty, $encoding: ident))) => {
-               encode_tlv!($stream, $type, $field.map(|f| $encoding(f)), option);
+               $crate::_encode_tlv!($stream, $type, $field.map(|f| $encoding(f)), option);
        };
        ($stream: expr, $type: expr, $field: expr, (option, encoding: $fieldty: ty)) => {
-               encode_tlv!($stream, $type, $field, option);
+               $crate::_encode_tlv!($stream, $type, $field, option);
+       };
+       ($stream: expr, $type: expr, $field: expr, (option: $trait: ident $(, $read_arg: expr)?)) => {
+               // Just a read-mapped type
+               $crate::_encode_tlv!($stream, $type, $field, option);
        };
 }
 
-
-macro_rules! check_encoded_tlv_order {
+/// Panics if the last seen TLV type is not numerically less than the TLV type currently being checked.
+/// This is exported for use by other exported macros, do not use directly.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _check_encoded_tlv_order {
        ($last_type: expr, $type: expr, (static_value, $value: expr)) => { };
        ($last_type: expr, $type: expr, $fieldty: tt) => {
                if let Some(t) = $last_type {
-                       debug_assert!(t <= $type);
+                       #[allow(unused_comparisons)] // Note that $type may be 0 making the following comparison always false
+                       (debug_assert!(t < $type))
                }
                $last_type = Some($type);
        };
 }
 
+/// Implements the TLVs serialization part in a [`Writeable`] implementation of a struct.
+///
+/// This should be called inside a method which returns `Result<_, `[`io::Error`]`>`, such as
+/// [`Writeable::write`]. It will only return an `Err` if the stream `Err`s or [`Writeable::write`]
+/// on one of the fields `Err`s.
+///
+/// `$stream` must be a `&mut `[`Writer`] which will receive the bytes for each TLV in the stream.
+///
+/// Fields MUST be sorted in `$type`-order.
+///
+/// Note that the lightning TLV requirements require that a single type not appear more than once,
+/// that TLVs are sorted in type-ascending order, and that any even types be understood by the
+/// decoder.
+///
+/// Any `option` fields which have a value of `None` will not be serialized at all.
+///
+/// For example,
+/// ```
+/// # use lightning::encode_tlv_stream;
+/// # fn write<W: lightning::util::ser::Writer> (stream: &mut W) -> Result<(), lightning::io::Error> {
+/// let mut required_value = 0u64;
+/// let mut optional_value: Option<u64> = None;
+/// encode_tlv_stream!(stream, {
+///     (0, required_value, required),
+///     (1, Some(42u64), option),
+///     (2, optional_value, option),
+/// });
+/// // At this point `required_value` has been written as a TLV of type 0, `42u64` has been written
+/// // as a TLV of type 1 (indicating the reader may ignore it if it is not understood), and *no*
+/// // TLV is written with type 2.
+/// # Ok(())
+/// # }
+/// ```
+///
+/// [`Writeable`]: crate::util::ser::Writeable
+/// [`io::Error`]: crate::io::Error
+/// [`Writeable::write`]: crate::util::ser::Writeable::write
+/// [`Writer`]: crate::util::ser::Writer
+#[macro_export]
 macro_rules! encode_tlv_stream {
        ($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => { {
                #[allow(unused_imports)]
@@ -55,10 +118,11 @@ macro_rules! encode_tlv_stream {
                        ln::msgs::DecodeError,
                        util::ser,
                        util::ser::BigSize,
+                       util::ser::Writeable,
                };
 
                $(
-                       encode_tlv!($stream, $type, $field, $fieldty);
+                       $crate::_encode_tlv!($stream, $type, $field, $fieldty);
                )*
 
                #[allow(unused_mut, unused_variables, unused_assignments)]
@@ -66,15 +130,21 @@ macro_rules! encode_tlv_stream {
                {
                        let mut last_seen: Option<u64> = None;
                        $(
-                               check_encoded_tlv_order!(last_seen, $type, $fieldty);
+                               $crate::_check_encoded_tlv_order!(last_seen, $type, $fieldty);
                        )*
                }
        } }
 }
 
-macro_rules! get_varint_length_prefixed_tlv_length {
+/// Adds the length of the serialized field to a [`LengthCalculatingWriter`].
+/// This is exported for use by other exported macros, do not use directly.
+///
+/// [`LengthCalculatingWriter`]: crate::util::ser::LengthCalculatingWriter
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _get_varint_length_prefixed_tlv_length {
        ($len: expr, $type: expr, $field: expr, (default_value, $default: expr)) => {
-               get_varint_length_prefixed_tlv_length!($len, $type, $field, required)
+               $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required)
        };
        ($len: expr, $type: expr, $field: expr, (static_value, $value: expr)) => {
        };
@@ -85,7 +155,7 @@ macro_rules! get_varint_length_prefixed_tlv_length {
                $len.0 += field_len;
        };
        ($len: expr, $type: expr, $field: expr, vec_type) => {
-               get_varint_length_prefixed_tlv_length!($len, $type, $crate::util::ser::WithoutLength(&$field), required);
+               $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $crate::util::ser::WithoutLength(&$field), required);
        };
        ($len: expr, $optional_type: expr, $optional_field: expr, option) => {
                if let Some(ref field) = $optional_field {
@@ -95,27 +165,44 @@ macro_rules! get_varint_length_prefixed_tlv_length {
                        $len.0 += field_len;
                }
        };
+       ($len: expr, $type: expr, $field: expr, (option: $trait: ident $(, $read_arg: expr)?)) => {
+               $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, option);
+       };
+       ($len: expr, $type: expr, $field: expr, upgradable_required) => {
+               $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required);
+       };
+       ($len: expr, $type: expr, $field: expr, upgradable_option) => {
+               $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, option);
+       };
 }
 
-macro_rules! encode_varint_length_prefixed_tlv {
+/// See the documentation of [`write_tlv_fields`].
+/// This is exported for use by other exported macros, do not use directly.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _encode_varint_length_prefixed_tlv {
        ($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),*}) => { {
                use $crate::util::ser::BigSize;
                let len = {
                        #[allow(unused_mut)]
                        let mut len = $crate::util::ser::LengthCalculatingWriter(0);
                        $(
-                               get_varint_length_prefixed_tlv_length!(len, $type, $field, $fieldty);
+                               $crate::_get_varint_length_prefixed_tlv_length!(len, $type, $field, $fieldty);
                        )*
                        len.0
                };
                BigSize(len as u64).write($stream)?;
-               encode_tlv_stream!($stream, { $(($type, $field, $fieldty)),* });
+               $crate::encode_tlv_stream!($stream, { $(($type, $field, $fieldty)),* });
        } }
 }
 
-macro_rules! check_decoded_tlv_order {
+/// Errors if there are missing required TLV types between the last seen type and the type currently being processed.
+/// This is exported for use by other exported macros, do not use directly.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _check_decoded_tlv_order {
        ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (default_value, $default: expr)) => {{
-               #[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always true
+               #[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always false
                let invalid_order = ($last_seen_type.is_none() || $last_seen_type.unwrap() < $type) && $typ.0 > $type;
                if invalid_order {
                        $field = $default.into();
@@ -124,19 +211,25 @@ macro_rules! check_decoded_tlv_order {
        ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (static_value, $value: expr)) => {
        };
        ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required) => {{
-               #[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always true
+               #[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always false
                let invalid_order = ($last_seen_type.is_none() || $last_seen_type.unwrap() < $type) && $typ.0 > $type;
                if invalid_order {
                        return Err(DecodeError::InvalidValue);
                }
        }};
+       ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
+               $crate::_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required);
+       }};
        ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, option) => {{
                // no-op
        }};
        ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, vec_type) => {{
                // no-op
        }};
-       ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, ignorable) => {{
+       ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, upgradable_required) => {{
+               _check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required)
+       }};
+       ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, upgradable_option) => {{
                // no-op
        }};
        ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
@@ -147,9 +240,13 @@ macro_rules! check_decoded_tlv_order {
        }};
 }
 
-macro_rules! check_missing_tlv {
+/// Errors if there are missing required TLV types after the last seen type.
+/// This is exported for use by other exported macros, do not use directly.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _check_missing_tlv {
        ($last_seen_type: expr, $type: expr, $field: ident, (default_value, $default: expr)) => {{
-               #[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always true
+               #[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always false
                let missing_req_type = $last_seen_type.is_none() || $last_seen_type.unwrap() < $type;
                if missing_req_type {
                        $field = $default.into();
@@ -159,19 +256,25 @@ macro_rules! check_missing_tlv {
                $field = $value;
        };
        ($last_seen_type: expr, $type: expr, $field: ident, required) => {{
-               #[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always true
+               #[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always false
                let missing_req_type = $last_seen_type.is_none() || $last_seen_type.unwrap() < $type;
                if missing_req_type {
                        return Err(DecodeError::InvalidValue);
                }
        }};
+       ($last_seen_type: expr, $type: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
+               $crate::_check_missing_tlv!($last_seen_type, $type, $field, required);
+       }};
        ($last_seen_type: expr, $type: expr, $field: ident, vec_type) => {{
                // no-op
        }};
        ($last_seen_type: expr, $type: expr, $field: ident, option) => {{
                // no-op
        }};
-       ($last_seen_type: expr, $type: expr, $field: ident, ignorable) => {{
+       ($last_seen_type: expr, $type: expr, $field: ident, upgradable_required) => {{
+               _check_missing_tlv!($last_seen_type, $type, $field, required)
+       }};
+       ($last_seen_type: expr, $type: expr, $field: ident, upgradable_option) => {{
                // no-op
        }};
        ($last_seen_type: expr, $type: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
@@ -182,15 +285,22 @@ macro_rules! check_missing_tlv {
        }};
 }
 
-macro_rules! decode_tlv {
+/// Implements deserialization for a single TLV record.
+/// This is exported for use by other exported macros, do not use directly.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _decode_tlv {
        ($reader: expr, $field: ident, (default_value, $default: expr)) => {{
-               decode_tlv!($reader, $field, required)
+               $crate::_decode_tlv!($reader, $field, required)
        }};
        ($reader: expr, $field: ident, (static_value, $value: expr)) => {{
        }};
        ($reader: expr, $field: ident, required) => {{
                $field = $crate::util::ser::Readable::read(&mut $reader)?;
        }};
+       ($reader: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
+               $field = $trait::read(&mut $reader $(, $read_arg)*)?;
+       }};
        ($reader: expr, $field: ident, vec_type) => {{
                let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::Readable::read(&mut $reader)?;
                $field = Some(f.0);
@@ -198,12 +308,28 @@ macro_rules! decode_tlv {
        ($reader: expr, $field: ident, option) => {{
                $field = Some($crate::util::ser::Readable::read(&mut $reader)?);
        }};
-       ($reader: expr, $field: ident, ignorable) => {{
+       // `upgradable_required` indicates we're reading a required TLV that may have been upgraded
+       // without backwards compat. We'll error if the field is missing, and return `Ok(None)` if the
+       // field is present but we can no longer understand it.
+       // Note that this variant can only be used within a `MaybeReadable` read.
+       ($reader: expr, $field: ident, upgradable_required) => {{
+               $field = match $crate::util::ser::MaybeReadable::read(&mut $reader)? {
+                       Some(res) => res,
+                       _ => return Ok(None)
+               };
+       }};
+       // `upgradable_option` indicates we're reading an Option-al TLV that may have been upgraded
+       // without backwards compat. $field will be None if the TLV is missing or if the field is present
+       // but we can no longer understand it.
+       ($reader: expr, $field: ident, upgradable_option) => {{
                $field = $crate::util::ser::MaybeReadable::read(&mut $reader)?;
        }};
        ($reader: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
                $field = Some($trait::read(&mut $reader $(, $read_arg)*)?);
        }};
+       ($reader: expr, $field: ident, (option, encoding: ($fieldty: ty, $encoding: ident, $encoder:ty))) => {{
+               $crate::_decode_tlv!($reader, $field, (option, encoding: ($fieldty, $encoding)));
+       }};
        ($reader: expr, $field: ident, (option, encoding: ($fieldty: ty, $encoding: ident))) => {{
                $field = {
                        let field: $encoding<$fieldty> = ser::Readable::read(&mut $reader)?;
@@ -211,31 +337,86 @@ macro_rules! decode_tlv {
                };
        }};
        ($reader: expr, $field: ident, (option, encoding: $fieldty: ty)) => {{
-               decode_tlv!($reader, $field, option);
+               $crate::_decode_tlv!($reader, $field, option);
        }};
 }
 
+/// Checks if `$val` matches `$type`.
+/// This is exported for use by other exported macros, do not use directly.
+#[doc(hidden)]
+#[macro_export]
 macro_rules! _decode_tlv_stream_match_check {
        ($val: ident, $type: expr, (static_value, $value: expr)) => { false };
        ($val: ident, $type: expr, $fieldty: tt) => { $val == $type }
 }
 
-// `$decode_custom_tlv` is a closure that may be optionally provided to handle custom message types.
-// If it is provided, it will be called with the custom type and the `FixedLengthReader` containing
-// the message contents. It should return `Ok(true)` if the custom message is successfully parsed,
-// `Ok(false)` if the message type is unknown, and `Err(DecodeError)` if parsing fails.
+/// Implements the TLVs deserialization part in a [`Readable`] implementation of a struct.
+///
+/// This should be called inside a method which returns `Result<_, `[`DecodeError`]`>`, such as
+/// [`Readable::read`]. It will either return an `Err` or ensure all `required` fields have been
+/// read and optionally read `optional` fields.
+///
+/// `$stream` must be a [`Read`] and will be fully consumed, reading until no more bytes remain
+/// (i.e. it returns [`DecodeError::ShortRead`]).
+///
+/// Fields MUST be sorted in `$type`-order.
+///
+/// Note that the lightning TLV requirements require that a single type not appear more than once,
+/// that TLVs are sorted in type-ascending order, and that any even types be understood by the
+/// decoder.
+///
+/// For example,
+/// ```
+/// # use lightning::decode_tlv_stream;
+/// # fn read<R: lightning::io::Read> (stream: R) -> Result<(), lightning::ln::msgs::DecodeError> {
+/// let mut required_value = 0u64;
+/// let mut optional_value: Option<u64> = None;
+/// decode_tlv_stream!(stream, {
+///     (0, required_value, required),
+///     (2, optional_value, option),
+/// });
+/// // At this point, `required_value` has been overwritten with the TLV with type 0.
+/// // `optional_value` may have been overwritten, setting it to `Some` if a TLV with type 2 was
+/// // present.
+/// # Ok(())
+/// # }
+/// ```
+///
+/// [`Readable`]: crate::util::ser::Readable
+/// [`DecodeError`]: crate::ln::msgs::DecodeError
+/// [`Readable::read`]: crate::util::ser::Readable::read
+/// [`Read`]: crate::io::Read
+/// [`DecodeError::ShortRead`]: crate::ln::msgs::DecodeError::ShortRead
+#[macro_export]
 macro_rules! decode_tlv_stream {
+       ($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
+               let rewind = |_, _| { unreachable!() };
+               $crate::_decode_tlv_stream_range!($stream, .., rewind, {$(($type, $field, $fieldty)),*});
+       }
+}
+
+/// Similar to [`decode_tlv_stream`] with a custom TLV decoding capabilities.
+///
+/// `$decode_custom_tlv` is a closure that may be optionally provided to handle custom message types.
+/// If it is provided, it will be called with the custom type and the [`FixedLengthReader`] containing
+/// the message contents. It should return `Ok(true)` if the custom message is successfully parsed,
+/// `Ok(false)` if the message type is unknown, and `Err(`[`DecodeError`]`)` if parsing fails.
+///
+/// [`FixedLengthReader`]: crate::util::ser::FixedLengthReader
+/// [`DecodeError`]: crate::ln::msgs::DecodeError
+macro_rules! decode_tlv_stream_with_custom_tlv_decode {
        ($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
         $(, $decode_custom_tlv: expr)?) => { {
                let rewind = |_, _| { unreachable!() };
-               use core::ops::RangeBounds;
-               decode_tlv_stream_range!(
+               _decode_tlv_stream_range!(
                        $stream, .., rewind, {$(($type, $field, $fieldty)),*} $(, $decode_custom_tlv)?
                );
        } }
 }
 
-macro_rules! decode_tlv_stream_range {
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _decode_tlv_stream_range {
        ($stream: expr, $range: expr, $rewind: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
         $(, $decode_custom_tlv: expr)?) => { {
                use $crate::ln::msgs::DecodeError;
@@ -249,7 +430,7 @@ macro_rules! decode_tlv_stream_range {
                                // We track whether any bytes were read during the consensus_decode call to
                                // determine whether we should break or return ShortRead if we get an
                                // UnexpectedEof. This should in every case be largely cosmetic, but its nice to
-                               // pass the TLV test vectors exactly, which requre this distinction.
+                               // pass the TLV test vectors exactly, which require this distinction.
                                let mut tracking_reader = ser::ReadTrackingReader::new(&mut stream_ref);
                                match <$crate::util::ser::BigSize as $crate::util::ser::Readable>::read(&mut tracking_reader) {
                                        Err(DecodeError::ShortRead) => {
@@ -260,7 +441,7 @@ macro_rules! decode_tlv_stream_range {
                                                }
                                        },
                                        Err(e) => return Err(e),
-                                       Ok(t) => if $range.contains(&t.0) { t } else {
+                                       Ok(t) => if core::ops::RangeBounds::contains(&$range, &t.0) { t } else {
                                                drop(tracking_reader);
 
                                                // Assumes the type id is minimally encoded, which is enforced on read.
@@ -279,9 +460,9 @@ macro_rules! decode_tlv_stream_range {
                                },
                                _ => {},
                        }
-                       // As we read types, make sure we hit every required type:
+                       // As we read types, make sure we hit every required type between `last_seen_type` and `typ`:
                        $({
-                               check_decoded_tlv_order!(last_seen_type, typ, $type, $field, $fieldty);
+                               $crate::_check_decoded_tlv_order!(last_seen_type, typ, $type, $field, $fieldty);
                        })*
                        last_seen_type = Some(typ.0);
 
@@ -289,8 +470,8 @@ macro_rules! decode_tlv_stream_range {
                        let length: ser::BigSize = $crate::util::ser::Readable::read(&mut stream_ref)?;
                        let mut s = ser::FixedLengthReader::new(&mut stream_ref, length.0);
                        match typ.0 {
-                               $(_t if _decode_tlv_stream_match_check!(_t, $type, $fieldty) => {
-                                       decode_tlv!(s, $field, $fieldty);
+                               $(_t if $crate::_decode_tlv_stream_match_check!(_t, $type, $fieldty) => {
+                                       $crate::_decode_tlv!(s, $field, $fieldty);
                                        if s.bytes_remain() {
                                                s.eat_remaining()?; // Return ShortRead if there's actually not enough bytes
                                                return Err(DecodeError::InvalidValue);
@@ -314,25 +495,55 @@ macro_rules! decode_tlv_stream_range {
                }
                // Make sure we got to each required type after we've read every TLV:
                $({
-                       check_missing_tlv!(last_seen_type, $type, $field, $fieldty);
+                       $crate::_check_missing_tlv!(last_seen_type, $type, $field, $fieldty);
                })*
        } }
 }
 
+/// Implements [`Readable`]/[`Writeable`] for a message struct that may include non-TLV and
+/// TLV-encoded parts.
+///
+/// This is useful to implement a [`CustomMessageReader`].
+///
+/// Currently `$fieldty` may only be `option`, i.e., `$tlvfield` is optional field.
+///
+/// For example,
+/// ```
+/// # use lightning::impl_writeable_msg;
+/// struct MyCustomMessage {
+///    pub field_1: u32,
+///    pub field_2: bool,
+///    pub field_3: String,
+///    pub tlv_optional_integer: Option<u32>,
+/// }
+///
+/// impl_writeable_msg!(MyCustomMessage, {
+///    field_1,
+///    field_2,
+///    field_3
+/// }, {
+///    (1, tlv_optional_integer, option),
+/// });
+/// ```
+///
+/// [`Readable`]: crate::util::ser::Readable
+/// [`Writeable`]: crate::util::ser::Writeable
+/// [`CustomMessageReader`]: crate::ln::wire::CustomMessageReader
+#[macro_export]
 macro_rules! impl_writeable_msg {
        ($st:ident, {$($field:ident),* $(,)*}, {$(($type: expr, $tlvfield: ident, $fieldty: tt)),* $(,)*}) => {
                impl $crate::util::ser::Writeable for $st {
                        fn write<W: $crate::util::ser::Writer>(&self, w: &mut W) -> Result<(), $crate::io::Error> {
                                $( self.$field.write(w)?; )*
-                               encode_tlv_stream!(w, {$(($type, self.$tlvfield, $fieldty)),*});
+                               $crate::encode_tlv_stream!(w, {$(($type, self.$tlvfield, $fieldty)),*});
                                Ok(())
                        }
                }
                impl $crate::util::ser::Readable for $st {
                        fn read<R: $crate::io::Read>(r: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
                                $(let $field = $crate::util::ser::Readable::read(r)?;)*
-                               $(init_tlv_field_var!($tlvfield, $fieldty);)*
-                               decode_tlv_stream!(r, {$(($type, $tlvfield, $fieldty)),*});
+                               $($crate::_init_tlv_field_var!($tlvfield, $fieldty);)*
+                               $crate::decode_tlv_stream!(r, {$(($type, $tlvfield, $fieldty)),*});
                                Ok(Self {
                                        $($field),*,
                                        $($tlvfield),*
@@ -369,18 +580,20 @@ macro_rules! impl_writeable {
 }
 
 /// Write out two bytes to indicate the version of an object.
+///
 /// $this_version represents a unique version of a type. Incremented whenever the type's
-///               serialization format has changed or has a new interpretation. Used by a type's
-///               reader to determine how to interpret fields or if it can understand a serialized
-///               object.
+/// serialization format has changed or has a new interpretation. Used by a type's reader to
+/// determine how to interpret fields or if it can understand a serialized object.
+///
 /// $min_version_that_can_read_this is the minimum reader version which can understand this
-///                                 serialized object. Previous versions will simply err with a
-///                                 DecodeError::UnknownVersion.
+/// serialized object. Previous versions will simply err with a [`DecodeError::UnknownVersion`].
 ///
-/// Updates to either $this_version or $min_version_that_can_read_this should be included in
+/// Updates to either `$this_version` or `$min_version_that_can_read_this` should be included in
 /// release notes.
 ///
 /// Both version fields can be specific to this type of object.
+///
+/// [`DecodeError::UnknownVersion`]: crate::ln::msgs::DecodeError::UnknownVersion
 macro_rules! write_ver_prefix {
        ($stream: expr, $this_version: expr, $min_version_that_can_read_this: expr) => {
                $stream.write_all(&[$this_version; 1])?;
@@ -388,23 +601,26 @@ macro_rules! write_ver_prefix {
        }
 }
 
-/// Writes out a suffix to an object which contains potentially backwards-compatible, optional
-/// fields which old nodes can happily ignore.
+/// Writes out a suffix to an object as a length-prefixed TLV stream which contains potentially
+/// backwards-compatible, optional fields which old nodes can happily ignore.
 ///
 /// It is written out in TLV format and, as with all TLV fields, unknown even fields cause a
-/// DecodeError::UnknownRequiredFeature error, with unknown odd fields ignored.
+/// [`DecodeError::UnknownRequiredFeature`] error, with unknown odd fields ignored.
 ///
 /// This is the preferred method of adding new fields that old nodes can ignore and still function
 /// correctly.
+///
+/// [`DecodeError::UnknownRequiredFeature`]: crate::ln::msgs::DecodeError::UnknownRequiredFeature
+#[macro_export]
 macro_rules! write_tlv_fields {
        ($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => {
-               encode_varint_length_prefixed_tlv!($stream, {$(($type, $field, $fieldty)),*})
+               $crate::_encode_varint_length_prefixed_tlv!($stream, {$(($type, $field, $fieldty)),*})
        }
 }
 
-/// Reads a prefix added by write_ver_prefix!(), above. Takes the current version of the
+/// Reads a prefix added by [`write_ver_prefix`], above. Takes the current version of the
 /// serialization logic for this object. This is compared against the
-/// $min_version_that_can_read_this added by write_ver_prefix!().
+/// `$min_version_that_can_read_this` added by [`write_ver_prefix`].
 macro_rules! read_ver_prefix {
        ($stream: expr, $this_version: expr) => { {
                let ver: u8 = Readable::read($stream)?;
@@ -416,17 +632,25 @@ macro_rules! read_ver_prefix {
        } }
 }
 
-/// Reads a suffix added by write_tlv_fields.
+/// Reads a suffix added by [`write_tlv_fields`].
+///
+/// [`write_tlv_fields`]: crate::write_tlv_fields
+#[macro_export]
 macro_rules! read_tlv_fields {
        ($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { {
                let tlv_len: $crate::util::ser::BigSize = $crate::util::ser::Readable::read($stream)?;
                let mut rd = $crate::util::ser::FixedLengthReader::new($stream, tlv_len.0);
-               decode_tlv_stream!(&mut rd, {$(($type, $field, $fieldty)),*});
+               $crate::decode_tlv_stream!(&mut rd, {$(($type, $field, $fieldty)),*});
                rd.eat_remaining().map_err(|_| $crate::ln::msgs::DecodeError::ShortRead)?;
        } }
 }
 
-macro_rules! init_tlv_based_struct_field {
+/// Initializes the struct fields.
+///
+/// This is exported for use by other exported macros, do not use directly.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _init_tlv_based_struct_field {
        ($field: ident, (default_value, $default: expr)) => {
                $field.0.unwrap()
        };
@@ -436,6 +660,15 @@ macro_rules! init_tlv_based_struct_field {
        ($field: ident, option) => {
                $field
        };
+       ($field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {
+               $crate::_init_tlv_based_struct_field!($field, option)
+       };
+       ($field: ident, upgradable_required) => {
+               $field.0.unwrap()
+       };
+       ($field: ident, upgradable_option) => {
+               $field
+       };
        ($field: ident, required) => {
                $field.0.unwrap()
        };
@@ -444,15 +677,23 @@ macro_rules! init_tlv_based_struct_field {
        };
 }
 
-macro_rules! init_tlv_field_var {
+/// Initializes the variable we are going to read the TLV into.
+///
+/// This is exported for use by other exported macros, do not use directly.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _init_tlv_field_var {
        ($field: ident, (default_value, $default: expr)) => {
-               let mut $field = $crate::util::ser::OptionDeserWrapper(None);
+               let mut $field = $crate::util::ser::RequiredWrapper(None);
        };
        ($field: ident, (static_value, $value: expr)) => {
                let $field;
        };
        ($field: ident, required) => {
-               let mut $field = $crate::util::ser::OptionDeserWrapper(None);
+               let mut $field = $crate::util::ser::RequiredWrapper(None);
+       };
+       ($field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {
+               $crate::_init_tlv_field_var!($field, required);
        };
        ($field: ident, vec_type) => {
                let mut $field = Some(Vec::new());
@@ -460,30 +701,66 @@ macro_rules! init_tlv_field_var {
        ($field: ident, option) => {
                let mut $field = None;
        };
+       ($field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {
+               $crate::_init_tlv_field_var!($field, option);
+       };
+       ($field: ident, upgradable_required) => {
+               let mut $field = $crate::util::ser::UpgradableRequired(None);
+       };
+       ($field: ident, upgradable_option) => {
+               let mut $field = None;
+       };
 }
 
-macro_rules! init_and_read_tlv_fields {
+/// Equivalent to running [`_init_tlv_field_var`] then [`read_tlv_fields`].
+///
+/// This is exported for use by other exported macros, do not use directly.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _init_and_read_tlv_fields {
        ($reader: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
                $(
-                       init_tlv_field_var!($field, $fieldty);
+                       $crate::_init_tlv_field_var!($field, $fieldty);
                )*
 
-               read_tlv_fields!($reader, {
+               $crate::read_tlv_fields!($reader, {
                        $(($type, $field, $fieldty)),*
                });
        }
 }
 
-/// Implements Readable/Writeable for a struct storing it as a set of TLVs
-/// If $fieldty is `required`, then $field is a required field that is not an Option nor a Vec.
-/// If $fieldty is `option`, then $field is optional field.
-/// if $fieldty is `vec_type`, then $field is a Vec, which needs to have its individual elements
-/// serialized.
+/// Implements [`Readable`]/[`Writeable`] for a struct storing it as a set of TLVs
+/// If `$fieldty` is `required`, then `$field` is a required field that is not an [`Option`] nor a [`Vec`].
+/// If `$fieldty` is `(default_value, $default)`, then `$field` will be set to `$default` if not present.
+/// If `$fieldty` is `option`, then `$field` is optional field.
+/// If `$fieldty` is `vec_type`, then `$field` is a [`Vec`], which needs to have its individual elements serialized.
+///
+/// For example,
+/// ```
+/// # use lightning::impl_writeable_tlv_based;
+/// struct LightningMessage {
+///    tlv_integer: u32,
+///    tlv_default_integer: u32,
+///    tlv_optional_integer: Option<u32>,
+///    tlv_vec_type_integer: Vec<u32>,
+/// }
+///
+/// impl_writeable_tlv_based!(LightningMessage, {
+///    (0, tlv_integer, required),
+///    (1, tlv_default_integer, (default_value, 7)),
+///    (2, tlv_optional_integer, option),
+///    (3, tlv_vec_type_integer, vec_type),
+/// });
+/// ```
+///
+/// [`Readable`]: crate::util::ser::Readable
+/// [`Writeable`]: crate::util::ser::Writeable
+#[macro_export]
 macro_rules! impl_writeable_tlv_based {
        ($st: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
                impl $crate::util::ser::Writeable for $st {
                        fn write<W: $crate::util::ser::Writer>(&self, writer: &mut W) -> Result<(), $crate::io::Error> {
-                               write_tlv_fields!(writer, {
+                               $crate::write_tlv_fields!(writer, {
                                        $(($type, self.$field, $fieldty)),*
                                });
                                Ok(())
@@ -496,7 +773,7 @@ macro_rules! impl_writeable_tlv_based {
                                        #[allow(unused_mut)]
                                        let mut len = $crate::util::ser::LengthCalculatingWriter(0);
                                        $(
-                                               get_varint_length_prefixed_tlv_length!(len, $type, self.$field, $fieldty);
+                                               $crate::_get_varint_length_prefixed_tlv_length!(len, $type, self.$field, $fieldty);
                                        )*
                                        len.0
                                };
@@ -508,12 +785,12 @@ macro_rules! impl_writeable_tlv_based {
 
                impl $crate::util::ser::Readable for $st {
                        fn read<R: $crate::io::Read>(reader: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
-                               init_and_read_tlv_fields!(reader, {
+                               $crate::_init_and_read_tlv_fields!(reader, {
                                        $(($type, $field, $fieldty)),*
                                });
                                Ok(Self {
                                        $(
-                                               $field: init_tlv_based_struct_field!($field, $fieldty)
+                                               $field: $crate::_init_tlv_based_struct_field!($field, $fieldty)
                                        ),*
                                })
                        }
@@ -541,7 +818,8 @@ macro_rules! tlv_stream {
                        )*
                }
 
-               #[derive(Debug, PartialEq)]
+               #[cfg_attr(test, derive(PartialEq))]
+               #[derive(Debug)]
                pub(super) struct $nameref<'a> {
                        $(
                                pub(super) $field: Option<tlv_record_ref_type!($fieldty)>,
@@ -560,12 +838,12 @@ macro_rules! tlv_stream {
                impl $crate::util::ser::SeekReadable for $name {
                        fn read<R: $crate::io::Read + $crate::io::Seek>(reader: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
                                $(
-                                       init_tlv_field_var!($field, option);
+                                       _init_tlv_field_var!($field, option);
                                )*
                                let rewind = |cursor: &mut R, offset: usize| {
                                        cursor.seek($crate::io::SeekFrom::Current(-(offset as i64))).expect("");
                                };
-                               decode_tlv_stream_range!(reader, $range, rewind, {
+                               _decode_tlv_stream_range!(reader, $range, rewind, {
                                        $(($type, $field, (option, encoding: $fieldty))),*
                                });
 
@@ -581,6 +859,7 @@ macro_rules! tlv_stream {
 
 macro_rules! tlv_record_type {
        (($type:ty, $wrapper:ident)) => { $type };
+       (($type:ty, $wrapper:ident, $encoder:ty)) => { $type };
        ($type:ty) => { $type };
 }
 
@@ -591,6 +870,7 @@ macro_rules! tlv_record_ref_type {
        ((u32, $wrapper: ident)) => { u32 };
        ((u64, $wrapper: ident)) => { u64 };
        (($type:ty, $wrapper:ident)) => { &'a $type };
+       (($type:ty, $wrapper:ident, $encoder:ty)) => { $encoder };
        ($type:ty) => { &'a $type };
 }
 
@@ -621,98 +901,110 @@ macro_rules! _impl_writeable_tlv_based_enum_common {
        }
 }
 
-/// Implement MaybeReadable and Writeable for an enum, with struct variants stored as TLVs and
-/// tuple variants stored directly.
+/// Implement [`Readable`] and [`Writeable`] for an enum, with struct variants stored as TLVs and tuple
+/// variants stored directly.
+/// The format is, for example
+/// ```ignore
+/// impl_writeable_tlv_based_enum!(EnumName,
+///   (0, StructVariantA) => {(0, required_variant_field, required), (1, optional_variant_field, option)},
+///   (1, StructVariantB) => {(0, variant_field_a, required), (1, variant_field_b, required), (2, variant_vec_field, vec_type)};
+///   (2, TupleVariantA), (3, TupleVariantB),
+/// );
+/// ```
+/// The type is written as a single byte, followed by any variant data.
+/// Attempts to read an unknown type byte result in [`DecodeError::UnknownRequiredFeature`].
 ///
-/// This is largely identical to `impl_writeable_tlv_based_enum`, except that odd variants will
-/// return `Ok(None)` instead of `Err(UnknownRequiredFeature)`. It should generally be preferred
-/// when `MaybeReadable` is practical instead of just `Readable` as it provides an upgrade path for
-/// new variants to be added which are simply ignored by existing clients.
-macro_rules! impl_writeable_tlv_based_enum_upgradable {
+/// [`Readable`]: crate::util::ser::Readable
+/// [`Writeable`]: crate::util::ser::Writeable
+/// [`DecodeError::UnknownRequiredFeature`]: crate::ln::msgs::DecodeError::UnknownRequiredFeature
+#[macro_export]
+macro_rules! impl_writeable_tlv_based_enum {
        ($st: ident, $(($variant_id: expr, $variant_name: ident) =>
                {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
-       ),* $(,)*
-       $(;
-       $(($tuple_variant_id: expr, $tuple_variant_name: ident)),*  $(,)*)*) => {
+       ),* $(,)*;
+       $(($tuple_variant_id: expr, $tuple_variant_name: ident)),*  $(,)*) => {
                _impl_writeable_tlv_based_enum_common!($st,
                        $(($variant_id, $variant_name) => {$(($type, $field, $fieldty)),*}),*;
-                       $($(($tuple_variant_id, $tuple_variant_name)),*)*);
+                       $(($tuple_variant_id, $tuple_variant_name)),*);
 
-               impl $crate::util::ser::MaybeReadable for $st {
-                       fn read<R: $crate::io::Read>(reader: &mut R) -> Result<Option<Self>, $crate::ln::msgs::DecodeError> {
+               impl $crate::util::ser::Readable for $st {
+                       fn read<R: $crate::io::Read>(reader: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
                                let id: u8 = $crate::util::ser::Readable::read(reader)?;
                                match id {
                                        $($variant_id => {
                                                // Because read_tlv_fields creates a labeled loop, we cannot call it twice
                                                // in the same function body. Instead, we define a closure and call it.
                                                let f = || {
-                                                       init_and_read_tlv_fields!(reader, {
+                                                       _init_and_read_tlv_fields!(reader, {
                                                                $(($type, $field, $fieldty)),*
                                                        });
-                                                       Ok(Some($st::$variant_name {
+                                                       Ok($st::$variant_name {
                                                                $(
-                                                                       $field: init_tlv_based_struct_field!($field, $fieldty)
+                                                                       $field: _init_tlv_based_struct_field!($field, $fieldty)
                                                                ),*
-                                                       }))
+                                                       })
                                                };
                                                f()
                                        }),*
-                                       $($($tuple_variant_id => {
-                                               Ok(Some($st::$tuple_variant_name(Readable::read(reader)?)))
-                                       }),*)*
-                                       _ if id % 2 == 1 => Ok(None),
-                                       _ => Err(DecodeError::UnknownRequiredFeature),
+                                       $($tuple_variant_id => {
+                                               Ok($st::$tuple_variant_name(Readable::read(reader)?))
+                                       }),*
+                                       _ => {
+                                               Err($crate::ln::msgs::DecodeError::UnknownRequiredFeature)
+                                       },
                                }
                        }
                }
-
        }
 }
 
-/// Implement Readable and Writeable for an enum, with struct variants stored as TLVs and tuple
-/// variants stored directly.
-/// The format is, for example
-/// impl_writeable_tlv_based_enum!(EnumName,
-///   (0, StructVariantA) => {(0, required_variant_field, required), (1, optional_variant_field, option)},
-///   (1, StructVariantB) => {(0, variant_field_a, required), (1, variant_field_b, required), (2, variant_vec_field, vec_type)};
-///   (2, TupleVariantA), (3, TupleVariantB),
-/// );
-/// The type is written as a single byte, followed by any variant data.
-/// Attempts to read an unknown type byte result in DecodeError::UnknownRequiredFeature.
-macro_rules! impl_writeable_tlv_based_enum {
+/// Implement [`MaybeReadable`] and [`Writeable`] for an enum, with struct variants stored as TLVs and
+/// tuple variants stored directly.
+///
+/// This is largely identical to [`impl_writeable_tlv_based_enum`], except that odd variants will
+/// return `Ok(None)` instead of `Err(`[`DecodeError::UnknownRequiredFeature`]`)`. It should generally be preferred
+/// when [`MaybeReadable`] is practical instead of just [`Readable`] as it provides an upgrade path for
+/// new variants to be added which are simply ignored by existing clients.
+///
+/// [`MaybeReadable`]: crate::util::ser::MaybeReadable
+/// [`Writeable`]: crate::util::ser::Writeable
+/// [`DecodeError::UnknownRequiredFeature`]: crate::ln::msgs::DecodeError::UnknownRequiredFeature
+/// [`Readable`]: crate::util::ser::Readable
+#[macro_export]
+macro_rules! impl_writeable_tlv_based_enum_upgradable {
        ($st: ident, $(($variant_id: expr, $variant_name: ident) =>
                {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
-       ),* $(,)*;
-       $(($tuple_variant_id: expr, $tuple_variant_name: ident)),*  $(,)*) => {
+       ),* $(,)*
+       $(;
+       $(($tuple_variant_id: expr, $tuple_variant_name: ident)),*  $(,)*)*) => {
                _impl_writeable_tlv_based_enum_common!($st,
                        $(($variant_id, $variant_name) => {$(($type, $field, $fieldty)),*}),*;
-                       $(($tuple_variant_id, $tuple_variant_name)),*);
+                       $($(($tuple_variant_id, $tuple_variant_name)),*)*);
 
-               impl $crate::util::ser::Readable for $st {
-                       fn read<R: $crate::io::Read>(reader: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
+               impl $crate::util::ser::MaybeReadable for $st {
+                       fn read<R: $crate::io::Read>(reader: &mut R) -> Result<Option<Self>, $crate::ln::msgs::DecodeError> {
                                let id: u8 = $crate::util::ser::Readable::read(reader)?;
                                match id {
                                        $($variant_id => {
                                                // Because read_tlv_fields creates a labeled loop, we cannot call it twice
                                                // in the same function body. Instead, we define a closure and call it.
                                                let f = || {
-                                                       init_and_read_tlv_fields!(reader, {
+                                                       _init_and_read_tlv_fields!(reader, {
                                                                $(($type, $field, $fieldty)),*
                                                        });
-                                                       Ok($st::$variant_name {
+                                                       Ok(Some($st::$variant_name {
                                                                $(
-                                                                       $field: init_tlv_based_struct_field!($field, $fieldty)
+                                                                       $field: _init_tlv_based_struct_field!($field, $fieldty)
                                                                ),*
-                                                       })
+                                                       }))
                                                };
                                                f()
                                        }),*
-                                       $($tuple_variant_id => {
-                                               Ok($st::$tuple_variant_name(Readable::read(reader)?))
-                                       }),*
-                                       _ => {
-                                               Err($crate::ln::msgs::DecodeError::UnknownRequiredFeature)
-                                       },
+                                       $($($tuple_variant_id => {
+                                               Ok(Some($st::$tuple_variant_name(Readable::read(reader)?)))
+                                       }),*)*
+                                       _ if id % 2 == 1 => Ok(None),
+                                       _ => Err($crate::ln::msgs::DecodeError::UnknownRequiredFeature),
                                }
                        }
                }
@@ -792,6 +1084,47 @@ mod tests {
                        (0xdeadbeef1badbeef, 0x1bad1dea, Some(0x01020304)));
        }
 
+       #[derive(Debug, PartialEq)]
+       struct TestUpgradable {
+               a: u32,
+               b: u32,
+               c: Option<u32>,
+       }
+
+       fn upgradable_tlv_reader(s: &[u8]) -> Result<Option<TestUpgradable>, DecodeError> {
+               let mut s = Cursor::new(s);
+               let mut a = 0;
+               let mut b = 0;
+               let mut c: Option<u32> = None;
+               decode_tlv_stream!(&mut s, {(2, a, upgradable_required), (3, b, upgradable_required), (4, c, upgradable_option)});
+               Ok(Some(TestUpgradable { a, b, c, }))
+       }
+
+       #[test]
+       fn upgradable_tlv_simple_good_cases() {
+               assert_eq!(upgradable_tlv_reader(&::hex::decode(
+                       concat!("0204deadbeef", "03041bad1dea", "0404deadbeef")
+               ).unwrap()[..]).unwrap(),
+               Some(TestUpgradable { a: 0xdeadbeef, b: 0x1bad1dea, c: Some(0xdeadbeef) }));
+
+               assert_eq!(upgradable_tlv_reader(&::hex::decode(
+                       concat!("0204deadbeef", "03041bad1dea")
+               ).unwrap()[..]).unwrap(),
+               Some(TestUpgradable { a: 0xdeadbeef, b: 0x1bad1dea, c: None}));
+       }
+
+       #[test]
+       fn missing_required_upgradable() {
+               if let Err(DecodeError::InvalidValue) = upgradable_tlv_reader(&::hex::decode(
+                       concat!("0100", "0204deadbeef")
+                       ).unwrap()[..]) {
+               } else { panic!(); }
+               if let Err(DecodeError::InvalidValue) = upgradable_tlv_reader(&::hex::decode(
+                       concat!("0100", "03041bad1dea")
+               ).unwrap()[..]) {
+               } else { panic!(); }
+       }
+
        // BOLT TLV test cases
        fn tlv_reader_n1(s: &[u8]) -> Result<(Option<HighZeroBytesDroppedBigSize<u64>>, Option<u64>, Option<(PublicKey, u64, u64)>, Option<u16>), DecodeError> {
                let mut s = Cursor::new(s);
@@ -910,27 +1243,27 @@ mod tests {
                let mut stream = VecWriter(Vec::new());
 
                stream.0.clear();
-               encode_varint_length_prefixed_tlv!(&mut stream, {(1, 1u8, required), (42, None::<u64>, option)});
+               _encode_varint_length_prefixed_tlv!(&mut stream, {(1, 1u8, required), (42, None::<u64>, option)});
                assert_eq!(stream.0, ::hex::decode("03010101").unwrap());
 
                stream.0.clear();
-               encode_varint_length_prefixed_tlv!(&mut stream, {(1, Some(1u8), option)});
+               _encode_varint_length_prefixed_tlv!(&mut stream, {(1, Some(1u8), option)});
                assert_eq!(stream.0, ::hex::decode("03010101").unwrap());
 
                stream.0.clear();
-               encode_varint_length_prefixed_tlv!(&mut stream, {(4, 0xabcdu16, required), (42, None::<u64>, option)});
+               _encode_varint_length_prefixed_tlv!(&mut stream, {(4, 0xabcdu16, required), (42, None::<u64>, option)});
                assert_eq!(stream.0, ::hex::decode("040402abcd").unwrap());
 
                stream.0.clear();
-               encode_varint_length_prefixed_tlv!(&mut stream, {(42, None::<u64>, option), (0xff, 0xabcdu16, required)});
+               _encode_varint_length_prefixed_tlv!(&mut stream, {(42, None::<u64>, option), (0xff, 0xabcdu16, required)});
                assert_eq!(stream.0, ::hex::decode("06fd00ff02abcd").unwrap());
 
                stream.0.clear();
-               encode_varint_length_prefixed_tlv!(&mut stream, {(0, 1u64, required), (42, None::<u64>, option), (0xff, HighZeroBytesDroppedBigSize(0u64), required)});
+               _encode_varint_length_prefixed_tlv!(&mut stream, {(0, 1u64, required), (42, None::<u64>, option), (0xff, HighZeroBytesDroppedBigSize(0u64), required)});
                assert_eq!(stream.0, ::hex::decode("0e00080000000000000001fd00ff00").unwrap());
 
                stream.0.clear();
-               encode_varint_length_prefixed_tlv!(&mut stream, {(0, Some(1u64), option), (0xff, HighZeroBytesDroppedBigSize(0u64), required)});
+               _encode_varint_length_prefixed_tlv!(&mut stream, {(0, Some(1u64), option), (0xff, HighZeroBytesDroppedBigSize(0u64), required)});
                assert_eq!(stream.0, ::hex::decode("0e00080000000000000001fd00ff00").unwrap());
 
                Ok(())
index 5b101e345e22aa8e889f67a8e700c2155305a21b..344f5b4c62d01736afd85654064735c68f0456bd 100644 (file)
@@ -20,10 +20,13 @@ use crate::chain::keysinterface;
 use crate::ln::channelmanager;
 use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
 use crate::ln::{msgs, wire};
+use crate::ln::msgs::LightningError;
 use crate::ln::script::ShutdownScript;
-use crate::routing::gossip::NetworkGraph;
+use crate::routing::gossip::{EffectiveCapacity, NetworkGraph, NodeId};
+use crate::routing::utxo::{UtxoLookup, UtxoLookupError, UtxoResult};
 use crate::routing::router::{find_route, InFlightHtlcs, Route, RouteHop, RouteParameters, Router, ScorerAccountingForInFlightHtlcs};
-use crate::routing::scoring::FixedPenaltyScorer;
+use crate::routing::scoring::{ChannelUsage, Score};
+use crate::util::config::UserConfig;
 use crate::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
 use crate::util::events;
 use crate::util::logger::{Logger, Level, Record};
@@ -45,12 +48,13 @@ use regex;
 
 use crate::io;
 use crate::prelude::*;
+use core::cell::RefCell;
 use core::time::Duration;
 use crate::sync::{Mutex, Arc};
 use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
 use core::mem;
 use bitcoin::bech32::u5;
-use crate::chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider};
+use crate::chain::keysinterface::{InMemorySigner, Recipient, EntropySource, NodeSigner, SignerProvider};
 
 #[cfg(feature = "std")]
 use std::time::{SystemTime, UNIX_EPOCH};
@@ -75,11 +79,18 @@ impl chaininterface::FeeEstimator for TestFeeEstimator {
 
 pub struct TestRouter<'a> {
        pub network_graph: Arc<NetworkGraph<&'a TestLogger>>,
+       pub next_routes: Mutex<VecDeque<(RouteParameters, Result<Route, LightningError>)>>,
+       pub scorer: &'a Mutex<TestScorer>,
 }
 
 impl<'a> TestRouter<'a> {
-       pub fn new(network_graph: Arc<NetworkGraph<&'a TestLogger>>) -> Self {
-               Self { network_graph }
+       pub fn new(network_graph: Arc<NetworkGraph<&'a TestLogger>>, scorer: &'a Mutex<TestScorer>) -> Self {
+               Self { network_graph, next_routes: Mutex::new(VecDeque::new()), scorer }
+       }
+
+       pub fn expect_find_route(&self, query: RouteParameters, result: Result<Route, LightningError>) {
+               let mut expected_routes = self.next_routes.lock().unwrap();
+               expected_routes.push_back((query, result));
        }
 }
 
@@ -88,17 +99,53 @@ impl<'a> Router for TestRouter<'a> {
                &self, payer: &PublicKey, params: &RouteParameters, first_hops: Option<&[&channelmanager::ChannelDetails]>,
                inflight_htlcs: &InFlightHtlcs
        ) -> Result<Route, msgs::LightningError> {
+               if let Some((find_route_query, find_route_res)) = self.next_routes.lock().unwrap().pop_front() {
+                       assert_eq!(find_route_query, *params);
+                       if let Ok(ref route) = find_route_res {
+                               let locked_scorer = self.scorer.lock().unwrap();
+                               let scorer = ScorerAccountingForInFlightHtlcs::new(locked_scorer, inflight_htlcs);
+                               for path in &route.paths {
+                                       let mut aggregate_msat = 0u64;
+                                       for (idx, hop) in path.iter().rev().enumerate() {
+                                               aggregate_msat += hop.fee_msat;
+                                               let usage = ChannelUsage {
+                                                       amount_msat: aggregate_msat,
+                                                       inflight_htlc_msat: 0,
+                                                       effective_capacity: EffectiveCapacity::Unknown,
+                                               };
+
+                                               // Since the path is reversed, the last element in our iteration is the first
+                                               // hop.
+                                               if idx == path.len() - 1 {
+                                                       scorer.channel_penalty_msat(hop.short_channel_id, &NodeId::from_pubkey(payer), &NodeId::from_pubkey(&hop.pubkey), usage);
+                                               } else {
+                                                       let curr_hop_path_idx = path.len() - 1 - idx;
+                                                       scorer.channel_penalty_msat(hop.short_channel_id, &NodeId::from_pubkey(&path[curr_hop_path_idx - 1].pubkey), &NodeId::from_pubkey(&hop.pubkey), usage);
+                                               }
+                                       }
+                               }
+                       }
+                       return find_route_res;
+               }
                let logger = TestLogger::new();
+               let scorer = self.scorer.lock().unwrap();
                find_route(
                        payer, params, &self.network_graph, first_hops, &logger,
-                       &ScorerAccountingForInFlightHtlcs::new(TestScorer::with_penalty(0), &inflight_htlcs),
+                       &ScorerAccountingForInFlightHtlcs::new(scorer, &inflight_htlcs),
                        &[42; 32]
                )
        }
-       fn notify_payment_path_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
-       fn notify_payment_path_successful(&self, _path: &[&RouteHop]) {}
-       fn notify_payment_probe_successful(&self, _path: &[&RouteHop]) {}
-       fn notify_payment_probe_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
+}
+
+impl<'a> Drop for TestRouter<'a> {
+       fn drop(&mut self) {
+               #[cfg(feature = "std")] {
+                       if std::thread::panicking() {
+                               return;
+                       }
+               }
+               assert!(self.next_routes.lock().unwrap().is_empty());
+       }
 }
 
 pub struct OnlyReadsKeysInterface {}
@@ -106,17 +153,6 @@ pub struct OnlyReadsKeysInterface {}
 impl EntropySource for OnlyReadsKeysInterface {
        fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }}
 
-impl NodeSigner for OnlyReadsKeysInterface {
-       fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> { unreachable!(); }
-       fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
-               let secp_ctx = Secp256k1::signing_only();
-               Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
-       }
-       fn ecdh(&self, _recipient: Recipient, _other_key: &PublicKey, _tweak: Option<&Scalar>) -> Result<SharedSecret, ()> { unreachable!(); }
-       fn get_inbound_payment_key_material(&self) -> KeyMaterial { unreachable!(); }
-       fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> { unreachable!(); }
-}
-
 impl SignerProvider for OnlyReadsKeysInterface {
        type Signer = EnforcingSigner;
 
@@ -125,8 +161,7 @@ impl SignerProvider for OnlyReadsKeysInterface {
        fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer { unreachable!(); }
 
        fn read_chan_signer(&self, mut reader: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
-               let dummy_sk = SecretKey::from_slice(&[42; 32]).unwrap();
-               let inner: InMemorySigner = ReadableArgs::read(&mut reader, dummy_sk)?;
+               let inner: InMemorySigner = Readable::read(&mut reader)?;
                let state = Arc::new(Mutex::new(EnforcementState::new()));
 
                Ok(EnforcingSigner::new_with_revoked(
@@ -140,9 +175,6 @@ impl SignerProvider for OnlyReadsKeysInterface {
        fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!(); }
 }
 
-impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
-}
-
 pub struct TestChainMonitor<'a> {
        pub added_monitors: Mutex<Vec<(OutPoint, channelmonitor::ChannelMonitor<EnforcingSigner>)>>,
        pub monitor_updates: Mutex<HashMap<[u8; 32], Vec<channelmonitor::ChannelMonitorUpdate>>>,
@@ -178,7 +210,7 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
                let mut w = TestVecWriter(Vec::new());
                monitor.write(&mut w).unwrap();
                let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
-                       &mut io::Cursor::new(&w.0), self.keys_manager).unwrap().1;
+                       &mut io::Cursor::new(&w.0), (self.keys_manager, self.keys_manager)).unwrap().1;
                assert!(new_monitor == monitor);
                self.latest_monitor_update_id.lock().unwrap().insert(funding_txo.to_channel_id(),
                        (funding_txo, monitor.get_latest_update_id(), MonitorUpdateId::from_new_monitor(&monitor)));
@@ -186,12 +218,12 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
                self.chain_monitor.watch_channel(funding_txo, new_monitor)
        }
 
-       fn update_channel(&self, funding_txo: OutPoint, update: channelmonitor::ChannelMonitorUpdate) -> chain::ChannelMonitorUpdateStatus {
+       fn update_channel(&self, funding_txo: OutPoint, update: &channelmonitor::ChannelMonitorUpdate) -> chain::ChannelMonitorUpdateStatus {
                // Every monitor update should survive roundtrip
                let mut w = TestVecWriter(Vec::new());
                update.write(&mut w).unwrap();
                assert!(channelmonitor::ChannelMonitorUpdate::read(
-                               &mut io::Cursor::new(&w.0)).unwrap() == update);
+                               &mut io::Cursor::new(&w.0)).unwrap() == *update);
 
                self.monitor_updates.lock().unwrap().entry(funding_txo.to_channel_id()).or_insert(Vec::new()).push(update.clone());
 
@@ -204,7 +236,7 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
                }
 
                self.latest_monitor_update_id.lock().unwrap().insert(funding_txo.to_channel_id(),
-                       (funding_txo, update.update_id, MonitorUpdateId::from_monitor_update(&update)));
+                       (funding_txo, update.update_id, MonitorUpdateId::from_monitor_update(update)));
                let update_res = self.chain_monitor.update_channel(funding_txo, update);
                // At every point where we get a monitor update, we should be able to send a useful monitor
                // to a watchtower and disk...
@@ -212,7 +244,7 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
                w.0.clear();
                monitor.write(&mut w).unwrap();
                let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
-                       &mut io::Cursor::new(&w.0), self.keys_manager).unwrap().1;
+                       &mut io::Cursor::new(&w.0), (self.keys_manager, self.keys_manager)).unwrap().1;
                assert!(new_monitor == *monitor);
                self.added_monitors.lock().unwrap().push((funding_txo, new_monitor));
                update_res
@@ -248,7 +280,7 @@ impl TestPersister {
                self.update_rets.lock().unwrap().push_back(next_ret);
        }
 }
-impl<Signer: keysinterface::Sign> chainmonitor::Persist<Signer> for TestPersister {
+impl<Signer: keysinterface::WriteableEcdsaChannelSigner> chainmonitor::Persist<Signer> for TestPersister {
        fn persist_new_channel(&self, _funding_txo: OutPoint, _data: &channelmonitor::ChannelMonitor<Signer>, _id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus {
                if let Some(update_ret) = self.update_rets.lock().unwrap().pop_front() {
                        return update_ret
@@ -256,7 +288,7 @@ impl<Signer: keysinterface::Sign> chainmonitor::Persist<Signer> for TestPersiste
                chain::ChannelMonitorUpdateStatus::Completed
        }
 
-       fn update_persisted_channel(&self, funding_txo: OutPoint, update: &Option<channelmonitor::ChannelMonitorUpdate>, _data: &channelmonitor::ChannelMonitor<Signer>, update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus {
+       fn update_persisted_channel(&self, funding_txo: OutPoint, update: Option<&channelmonitor::ChannelMonitorUpdate>, _data: &channelmonitor::ChannelMonitor<Signer>, update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus {
                let mut ret = chain::ChannelMonitorUpdateStatus::Completed;
                if let Some(update_ret) = self.update_rets.lock().unwrap().pop_front() {
                        ret = update_ret;
@@ -299,6 +331,7 @@ impl chaininterface::BroadcasterInterface for TestBroadcaster {
 pub struct TestChannelMessageHandler {
        pub pending_events: Mutex<Vec<events::MessageSendEvent>>,
        expected_recv_msgs: Mutex<Option<Vec<wire::Message<()>>>>,
+       connected_peers: Mutex<HashSet<PublicKey>>,
 }
 
 impl TestChannelMessageHandler {
@@ -306,6 +339,7 @@ impl TestChannelMessageHandler {
                TestChannelMessageHandler {
                        pending_events: Mutex::new(Vec::new()),
                        expected_recv_msgs: Mutex::new(None),
+                       connected_peers: Mutex::new(HashSet::new()),
                }
        }
 
@@ -339,10 +373,10 @@ impl Drop for TestChannelMessageHandler {
 }
 
 impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
-       fn handle_open_channel(&self, _their_node_id: &PublicKey, _their_features: InitFeatures, msg: &msgs::OpenChannel) {
+       fn handle_open_channel(&self, _their_node_id: &PublicKey, msg: &msgs::OpenChannel) {
                self.received_msg(wire::Message::OpenChannel(msg.clone()));
        }
-       fn handle_accept_channel(&self, _their_node_id: &PublicKey, _their_features: InitFeatures, msg: &msgs::AcceptChannel) {
+       fn handle_accept_channel(&self, _their_node_id: &PublicKey, msg: &msgs::AcceptChannel) {
                self.received_msg(wire::Message::AcceptChannel(msg.clone()));
        }
        fn handle_funding_created(&self, _their_node_id: &PublicKey, msg: &msgs::FundingCreated) {
@@ -354,7 +388,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
        fn handle_channel_ready(&self, _their_node_id: &PublicKey, msg: &msgs::ChannelReady) {
                self.received_msg(wire::Message::ChannelReady(msg.clone()));
        }
-       fn handle_shutdown(&self, _their_node_id: &PublicKey, _their_features: &InitFeatures, msg: &msgs::Shutdown) {
+       fn handle_shutdown(&self, _their_node_id: &PublicKey, msg: &msgs::Shutdown) {
                self.received_msg(wire::Message::Shutdown(msg.clone()));
        }
        fn handle_closing_signed(&self, _their_node_id: &PublicKey, msg: &msgs::ClosingSigned) {
@@ -390,8 +424,11 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
        fn handle_channel_reestablish(&self, _their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) {
                self.received_msg(wire::Message::ChannelReestablish(msg.clone()));
        }
-       fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {}
-       fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &msgs::Init) -> Result<(), ()> {
+       fn peer_disconnected(&self, their_node_id: &PublicKey) {
+               assert!(self.connected_peers.lock().unwrap().remove(their_node_id));
+       }
+       fn peer_connected(&self, their_node_id: &PublicKey, _msg: &msgs::Init, _inbound: bool) -> Result<(), ()> {
+               assert!(self.connected_peers.lock().unwrap().insert(their_node_id.clone()));
                // Don't bother with `received_msg` for Init as its auto-generated and we don't want to
                // bother re-generating the expected Init message in all tests.
                Ok(())
@@ -400,10 +437,10 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
                self.received_msg(wire::Message::Error(msg.clone()));
        }
        fn provided_node_features(&self) -> NodeFeatures {
-               channelmanager::provided_node_features()
+               channelmanager::provided_node_features(&UserConfig::default())
        }
        fn provided_init_features(&self, _their_init_features: &PublicKey) -> InitFeatures {
-               channelmanager::provided_init_features()
+               channelmanager::provided_init_features(&UserConfig::default())
        }
 }
 
@@ -428,10 +465,10 @@ fn get_dummy_channel_announcement(short_chan_id: u64) -> msgs::ChannelAnnounceme
                features: ChannelFeatures::empty(),
                chain_hash: genesis_block(network).header.block_hash(),
                short_channel_id: short_chan_id,
-               node_id_1: PublicKey::from_secret_key(&secp_ctx, &node_1_privkey),
-               node_id_2: PublicKey::from_secret_key(&secp_ctx, &node_2_privkey),
-               bitcoin_key_1: PublicKey::from_secret_key(&secp_ctx, &node_1_btckey),
-               bitcoin_key_2: PublicKey::from_secret_key(&secp_ctx, &node_2_btckey),
+               node_id_1: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_1_privkey)),
+               node_id_2: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_2_privkey)),
+               bitcoin_key_1: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_1_btckey)),
+               bitcoin_key_2: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_2_btckey)),
                excess_data: Vec::new(),
        };
 
@@ -503,11 +540,11 @@ impl msgs::RoutingMessageHandler for TestRoutingMessageHandler {
                Some((chan_ann, Some(chan_upd_1), Some(chan_upd_2)))
        }
 
-       fn get_next_node_announcement(&self, _starting_point: Option<&PublicKey>) -> Option<msgs::NodeAnnouncement> {
+       fn get_next_node_announcement(&self, _starting_point: Option<&NodeId>) -> Option<msgs::NodeAnnouncement> {
                None
        }
 
-       fn peer_connected(&self, their_node_id: &PublicKey, init_msg: &msgs::Init) -> Result<(), ()> {
+       fn peer_connected(&self, their_node_id: &PublicKey, init_msg: &msgs::Init, _inbound: bool) -> Result<(), ()> {
                if !init_msg.features.supports_gossip_queries() {
                        return Ok(());
                }
@@ -563,6 +600,8 @@ impl msgs::RoutingMessageHandler for TestRoutingMessageHandler {
                features.set_gossip_queries_optional();
                features
        }
+
+       fn processing_queue_high(&self) -> bool { false }
 }
 
 impl events::MessageSendEventsProvider for TestRoutingMessageHandler {
@@ -634,6 +673,49 @@ impl Logger for TestLogger {
        }
 }
 
+pub struct TestNodeSigner {
+       node_secret: SecretKey,
+}
+
+impl TestNodeSigner {
+       pub fn new(node_secret: SecretKey) -> Self {
+               Self { node_secret }
+       }
+}
+
+impl NodeSigner for TestNodeSigner {
+       fn get_inbound_payment_key_material(&self) -> crate::chain::keysinterface::KeyMaterial {
+               unreachable!()
+       }
+
+       fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
+               let node_secret = match recipient {
+                       Recipient::Node => Ok(&self.node_secret),
+                       Recipient::PhantomNode => Err(())
+               }?;
+               Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret))
+       }
+
+       fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&bitcoin::secp256k1::Scalar>) -> Result<SharedSecret, ()> {
+               let mut node_secret = match recipient {
+                       Recipient::Node => Ok(self.node_secret.clone()),
+                       Recipient::PhantomNode => Err(())
+               }?;
+               if let Some(tweak) = tweak {
+                       node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
+               }
+               Ok(SharedSecret::new(other_key, &node_secret))
+       }
+
+       fn sign_invoice(&self, _: &[u8], _: &[bitcoin::bech32::u5], _: Recipient) -> Result<bitcoin::secp256k1::ecdsa::RecoverableSignature, ()> {
+               unreachable!()
+       }
+
+       fn sign_gossip_message(&self, _msg: msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
+               unreachable!()
+       }
+}
+
 pub struct TestKeysInterface {
        pub backing: keysinterface::PhantomKeysManager,
        pub override_random_bytes: Mutex<Option<[u8; 32]>>,
@@ -653,10 +735,6 @@ impl EntropySource for TestKeysInterface {
 }
 
 impl NodeSigner for TestKeysInterface {
-       fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
-               self.backing.get_node_secret(recipient)
-       }
-
        fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
                self.backing.get_node_id(recipient)
        }
@@ -672,6 +750,10 @@ impl NodeSigner for TestKeysInterface {
        fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
                self.backing.sign_invoice(hrp_bytes, invoice_data, recipient)
        }
+
+       fn sign_gossip_message(&self, msg: msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
+               self.backing.sign_gossip_message(msg)
+       }
 }
 
 impl SignerProvider for TestKeysInterface {
@@ -690,7 +772,7 @@ impl SignerProvider for TestKeysInterface {
        fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
                let mut reader = io::Cursor::new(buffer);
 
-               let inner: InMemorySigner = ReadableArgs::read(&mut reader, self.get_node_secret(Recipient::Node).unwrap())?;
+               let inner: InMemorySigner = Readable::read(&mut reader)?;
                let state = self.make_enforcement_state_cell(inner.commitment_seed);
 
                Ok(EnforcingSigner::new_with_revoked(
@@ -713,8 +795,6 @@ impl SignerProvider for TestKeysInterface {
        }
 }
 
-impl keysinterface::KeysInterface for TestKeysInterface {}
-
 impl TestKeysInterface {
        pub fn new(seed: &[u8; 32], network: Network) -> Self {
                let now = Duration::from_secs(genesis_block(network).header.time as u64);
@@ -790,7 +870,8 @@ impl core::fmt::Debug for OnGetShutdownScriptpubkey {
 
 pub struct TestChainSource {
        pub genesis_hash: BlockHash,
-       pub utxo_ret: Mutex<Result<TxOut, chain::AccessError>>,
+       pub utxo_ret: Mutex<UtxoResult>,
+       pub get_utxo_call_count: AtomicUsize,
        pub watched_txn: Mutex<HashSet<(Txid, Script)>>,
        pub watched_outputs: Mutex<HashSet<(OutPoint, Script)>>,
 }
@@ -800,17 +881,19 @@ impl TestChainSource {
                let script_pubkey = Builder::new().push_opcode(opcodes::OP_TRUE).into_script();
                Self {
                        genesis_hash: genesis_block(network).block_hash(),
-                       utxo_ret: Mutex::new(Ok(TxOut { value: u64::max_value(), script_pubkey })),
+                       utxo_ret: Mutex::new(UtxoResult::Sync(Ok(TxOut { value: u64::max_value(), script_pubkey }))),
+                       get_utxo_call_count: AtomicUsize::new(0),
                        watched_txn: Mutex::new(HashSet::new()),
                        watched_outputs: Mutex::new(HashSet::new()),
                }
        }
 }
 
-impl chain::Access for TestChainSource {
-       fn get_utxo(&self, genesis_hash: &BlockHash, _short_channel_id: u64) -> Result<TxOut, chain::AccessError> {
+impl UtxoLookup for TestChainSource {
+       fn get_utxo(&self, genesis_hash: &BlockHash, _short_channel_id: u64) -> UtxoResult {
+               self.get_utxo_call_count.fetch_add(1, Ordering::Relaxed);
                if self.genesis_hash != *genesis_hash {
-                       return Err(chain::AccessError::UnknownChain);
+                       return UtxoResult::Sync(Err(UtxoLookupError::UnknownChain));
                }
 
                self.utxo_ret.lock().unwrap().clone()
@@ -835,5 +918,65 @@ impl Drop for TestChainSource {
        }
 }
 
-/// A scorer useful in testing, when the passage of time isn't a concern.
-pub type TestScorer = FixedPenaltyScorer;
+pub struct TestScorer {
+       /// Stores a tuple of (scid, ChannelUsage)
+       scorer_expectations: RefCell<Option<VecDeque<(u64, ChannelUsage)>>>,
+}
+
+impl TestScorer {
+       pub fn new() -> Self {
+               Self {
+                       scorer_expectations: RefCell::new(None),
+               }
+       }
+
+       pub fn expect_usage(&self, scid: u64, expectation: ChannelUsage) {
+               self.scorer_expectations.borrow_mut().get_or_insert_with(|| VecDeque::new()).push_back((scid, expectation));
+       }
+}
+
+#[cfg(c_bindings)]
+impl crate::util::ser::Writeable for TestScorer {
+       fn write<W: crate::util::ser::Writer>(&self, _: &mut W) -> Result<(), crate::io::Error> { unreachable!(); }
+}
+
+impl Score for TestScorer {
+       fn channel_penalty_msat(
+               &self, short_channel_id: u64, _source: &NodeId, _target: &NodeId, usage: ChannelUsage
+       ) -> u64 {
+               if let Some(scorer_expectations) = self.scorer_expectations.borrow_mut().as_mut() {
+                       match scorer_expectations.pop_front() {
+                               Some((scid, expectation)) => {
+                                       assert_eq!(expectation, usage);
+                                       assert_eq!(scid, short_channel_id);
+                               },
+                               None => {},
+                       }
+               }
+               0
+       }
+
+       fn payment_path_failed(&mut self, _actual_path: &[&RouteHop], _actual_short_channel_id: u64) {}
+
+       fn payment_path_successful(&mut self, _actual_path: &[&RouteHop]) {}
+
+       fn probe_failed(&mut self, _actual_path: &[&RouteHop], _: u64) {}
+
+       fn probe_successful(&mut self, _actual_path: &[&RouteHop]) {}
+}
+
+impl Drop for TestScorer {
+       fn drop(&mut self) {
+               #[cfg(feature = "std")] {
+                       if std::thread::panicking() {
+                               return;
+                       }
+               }
+
+               if let Some(scorer_expectations) = self.scorer_expectations.borrow().as_ref() {
+                       if !scorer_expectations.is_empty() {
+                               panic!("Unsatisfied scorer expectations: {:?}", scorer_expectations)
+                       }
+               }
+       }
+}
index fdbc22f116600b7162bdbdcafa4a6f314af944e1..f86fc376cee0202323b9924057157aaf8379f86a 100644 (file)
@@ -105,7 +105,10 @@ impl Notifier {
        pub(crate) fn notify(&self) {
                let mut lock = self.notify_pending.lock().unwrap();
                if let Some(future_state) = &lock.1 {
-                       future_state.lock().unwrap().complete();
+                       if future_state.lock().unwrap().complete() {
+                               lock.1 = None;
+                               return;
+                       }
                }
                lock.0 = true;
                mem::drop(lock);
@@ -161,12 +164,13 @@ pub(crate) struct FutureState {
 }
 
 impl FutureState {
-       fn complete(&mut self) {
+       fn complete(&mut self) -> bool {
                for (counts_as_call, callback) in self.callbacks.drain(..) {
                        callback.call();
                        self.callbacks_made |= counts_as_call;
                }
                self.complete = true;
+               self.callbacks_made
        }
 }
 
@@ -469,4 +473,63 @@ mod tests {
                assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Ready(()));
                assert!(!notifier.wait_timeout(Duration::from_millis(1)));
        }
+
+       #[test]
+       fn test_poll_post_notify_completes() {
+               // Tests that if we have a future state that has completed, and we haven't yet requested a
+               // new future, if we get a notify prior to requesting that second future it is generated
+               // pre-completed.
+               let notifier = Notifier::new();
+
+               notifier.notify();
+               let mut future = notifier.get_future();
+               let (woken, waker) = create_waker();
+               assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Ready(()));
+               assert!(!woken.load(Ordering::SeqCst));
+
+               notifier.notify();
+               let mut future = notifier.get_future();
+               let (woken, waker) = create_waker();
+               assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Ready(()));
+               assert!(!woken.load(Ordering::SeqCst));
+
+               let mut future = notifier.get_future();
+               let (woken, waker) = create_waker();
+               assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Pending);
+               assert!(!woken.load(Ordering::SeqCst));
+
+               notifier.notify();
+               assert!(woken.load(Ordering::SeqCst));
+               assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Ready(()));
+       }
+
+       #[test]
+       fn test_poll_post_notify_completes_initial_notified() {
+               // Identical to the previous test, but the first future completes via a wake rather than an
+               // immediate `Poll::Ready`.
+               let notifier = Notifier::new();
+
+               let mut future = notifier.get_future();
+               let (woken, waker) = create_waker();
+               assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Pending);
+
+               notifier.notify();
+               assert!(woken.load(Ordering::SeqCst));
+               assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Ready(()));
+
+               notifier.notify();
+               let mut future = notifier.get_future();
+               let (woken, waker) = create_waker();
+               assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Ready(()));
+               assert!(!woken.load(Ordering::SeqCst));
+
+               let mut future = notifier.get_future();
+               let (woken, waker) = create_waker();
+               assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Pending);
+               assert!(!woken.load(Ordering::SeqCst));
+
+               notifier.notify();
+               assert!(woken.load(Ordering::SeqCst));
+               assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Ready(()));
+       }
 }
index 947838633c50267e12493dc5fb4b9e5a523185ed..16d2fc110e2a42252dbc83afb623f6a76bff570d 100644 (file)
@@ -10,3 +10,8 @@ default = ["lightning/no-std", "lightning-invoice/no-std", "lightning-rapid-goss
 lightning = { path = "../lightning", default-features = false }
 lightning-invoice = { path = "../lightning-invoice", default-features = false }
 lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync", default-features = false }
+lightning-background-processor = { path = "../lightning-background-processor", features = ["futures"], default-features = false }
+
+# Obviously lightning-transaction-sync doesn't support no-std, but it should build
+# even if lightning is built with no-std.
+lightning-transaction-sync = { path = "../lightning-transaction-sync", optional = true }
diff --git a/pending_changelog/1878.txt b/pending_changelog/1878.txt
new file mode 100644 (file)
index 0000000..775c46e
--- /dev/null
@@ -0,0 +1,11 @@
+## API Updates
+- The functions `inbound_payment::{create, create_from_hash}` and
+  `channelmanager::{create_inbound_payment, create_inbound_payment_for_hash}` now accept a
+  `min_final_cltv_expiry_delta` argument. This encodes the `min_final_cltv_expiry_delta` in the
+  payment secret metadata bytes to be validated on payment receipt.
+
+## Backwards Compatibility
+- If `min_final_cltv_expiry_delta` set for any of `inbound_payment::{create, create_from_hash}` or
+  `channelmanager::{create_inbound_payment, create_inbound_payment_for_hash}` then the payment will
+  not be receivable on versions of LDK prior to 0.0.114.
+
diff --git a/pending_changelog/2043.txt b/pending_changelog/2043.txt
new file mode 100644 (file)
index 0000000..bcd460e
--- /dev/null
@@ -0,0 +1,16 @@
+## API Updates
+- `Event::PaymentPathFailed::network_update` has been replaced by a new `Failure` enum, which may
+       contain the `network_update` within it. See `Event::PaymentPathFailed::failure` and `Failure` docs
+       for more
+- `Event::PaymentPathFailed::all_paths_failed` has been removed, as we've dropped support for manual
+       payment retries.
+
+## Backwards Compatibility
+- If downgrading from 0.0.114 to a previous version, `Event::PaymentPathFailed::network_update` will
+       always be `None`.
+- If downgrading from 0.0.114 to a previous version, `Event::PaymentPathFailed::all_paths_failed`
+       will always be set to `false`. Users who wish to support downgrading and currently rely on the
+       field should should first migrate to always calling `ChannelManager::abandon_payment` and awaiting
+       `PaymentFailed` events before retrying (see the field docs for more info on this approach:
+       <https://docs.rs/lightning/0.0.113/lightning/util/events/enum.Event.html#variant.PaymentPathFailed.field.all_paths_failed>),
+       and then migrate to 0.0.114.