Merge pull request #2703 from wpaulino/retryable-commitment-broadcast
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Wed, 13 Dec 2023 05:15:54 +0000 (05:15 +0000)
committerGitHub <noreply@github.com>
Wed, 13 Dec 2023 05:15:54 +0000 (05:15 +0000)
Refactor commitment broadcast to always go through OnchainTxHandler

40 files changed:
.github/workflows/build.yml
CONTRIBUTING.md
Cargo.toml
bench/Cargo.toml
ci/check-cfg-flags.py [new file with mode: 0755]
ci/ci-tests.sh
fuzz/Cargo.toml
lightning-background-processor/Cargo.toml
lightning-background-processor/src/lib.rs
lightning-block-sync/Cargo.toml
lightning-block-sync/src/lib.rs
lightning-invoice/Cargo.toml
lightning-invoice/fuzz/Cargo.toml
lightning-invoice/fuzz/fuzz_targets/serde_data_part.rs
lightning-invoice/src/lib.rs
lightning-net-tokio/Cargo.toml
lightning-net-tokio/src/lib.rs
lightning-persister/Cargo.toml
lightning-persister/src/lib.rs
lightning-rapid-gossip-sync/Cargo.toml
lightning-rapid-gossip-sync/src/lib.rs
lightning-transaction-sync/Cargo.toml
lightning-transaction-sync/src/lib.rs
lightning/Cargo.toml
lightning/src/chain/chaininterface.rs
lightning/src/chain/chainmonitor.rs
lightning/src/chain/channelmonitor.rs
lightning/src/chain/mod.rs
lightning/src/events/bump_transaction.rs
lightning/src/lib.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/payment_tests.rs
lightning/src/ln/peer_handler.rs
lightning/src/onion_message/messenger.rs
lightning/src/util/logger.rs
lightning/src/util/ser.rs
lightning/src/util/test_utils.rs
msrv-no-dev-deps-check/Cargo.toml
no-std-check/Cargo.toml

index 00ef76f787e188e0e23fc94b2244bb1cbca8673f..65be3faef8b5578e0e44b84a6e3651be360af01f 100644 (file)
@@ -18,19 +18,7 @@ jobs:
       fail-fast: false
       matrix:
         platform: [ ubuntu-latest, windows-latest, macos-latest ]
-        toolchain: [ stable, beta ]
-        include:
-          - toolchain: stable
-            platform: ubuntu-latest
-          # 1.48.0 is the MSRV for all crates except lightning-transaction-sync and Win/Mac
-          - toolchain: 1.48.0
-            platform: ubuntu-latest
-          # Windows requires 1.49.0 because that's the MSRV for supported Tokio
-          - toolchain: 1.49.0
-            platform: windows-latest
-          # MacOS-latest requires 1.54.0 because that's what's required for linking to work properly
-          - toolchain: 1.54.0
-            platform: macos-latest
+        toolchain: [ stable, beta, 1.63.0 ] # 1.63.0 is the MSRV for all crates.
     runs-on: ${{ matrix.platform }}
     steps:
       - name: Checkout source code
@@ -44,6 +32,8 @@ jobs:
         run: |
           rustup target add thumbv7m-none-eabi
           sudo apt-get -y install gcc-arm-none-eabi
+      - name: Check for unknown cfg tags
+        run: ci/check-cfg-flags.py
       - name: shellcheck the CI script
         if: "matrix.platform == 'ubuntu-latest'"
         run: |
@@ -168,13 +158,13 @@ jobs:
         run: |
           cargo check --release
           cargo check --no-default-features --features=no-std --release
-          cargo check --no-default-features --features=futures --release
+          cargo check --no-default-features --features=futures,std --release
           cargo doc --release
       - name: Run cargo check for Taproot build.
         run: |
           cargo check --release
           cargo check --no-default-features --features=no-std --release
-          cargo check --no-default-features --features=futures --release
+          cargo check --no-default-features --features=futures,std --release
           cargo doc --release
         env:
           RUSTFLAGS: '--cfg=taproot'
index 350415af24cc0ad86d200a0199797c53a0518572..78c515007d03a75ba2b0261d25ebc74f46531244 100644 (file)
@@ -88,7 +88,7 @@ be covered by functional tests.
 When refactoring, structure your PR to make it easy to review and don't
 hesitate to split it into multiple small, focused PRs.
 
-The Minimum Supported Rust Version (MSRV) currently is 1.48.0 (enforced by
+The Minimum Supported Rust Version (MSRV) currently is 1.63.0 (enforced by
 our GitHub Actions). We support reading serialized LDK objects written by any
 version of LDK 0.0.99 and above. We support LDK versions 0.0.113 and above
 reading serialized LDK objects written by modern LDK. Any expected issues with
index 8614cb48c1f15207023d9fd00b952600804d4e1b..a12f6ff9ff3de2ded9fbc368029aba53f945f066 100644 (file)
@@ -1,4 +1,5 @@
 [workspace]
+resolver = "2"
 
 members = [
     "lightning",
@@ -7,11 +8,11 @@ members = [
     "lightning-net-tokio",
     "lightning-persister",
     "lightning-background-processor",
-    "lightning-rapid-gossip-sync"
+    "lightning-rapid-gossip-sync",
+    "lightning-custom-message",
 ]
 
 exclude = [
-    "lightning-custom-message",
     "lightning-transaction-sync",
     "no-std-check",
     "msrv-no-dev-deps-check",
index e582d29da8108981ac4b42cf712e5d04624ed854..05354890c2a8fb4f5f0e9233fa273d444aac7cd9 100644 (file)
@@ -2,7 +2,7 @@
 name = "lightning-bench"
 version = "0.0.1"
 authors = ["Matt Corallo"]
-edition = "2018"
+edition = "2021"
 
 [[bench]]
 name = "bench"
diff --git a/ci/check-cfg-flags.py b/ci/check-cfg-flags.py
new file mode 100755 (executable)
index 0000000..85cbde8
--- /dev/null
@@ -0,0 +1,152 @@
+#!/usr/bin/env python3
+# Rust is fairly relaxed in checking the validity of arguments passed to #[cfg].
+# While it should probably be more strict when checking features, it cannot be
+# strict when checking loose cfg tags, because those can be anything and are
+# simply passed to rustc via unconstrained arguments.
+#
+# Thus, we do it for rustc manually, but scanning all our source and checking
+# that all our cfg tags match a known cfg tag.
+import sys, glob, re
+
+def check_feature(feature):
+    if feature == "std":
+        pass
+    elif feature == "no-std":
+        pass
+    elif feature == "hashbrown":
+        pass
+    elif feature == "backtrace":
+        pass
+    elif feature == "grind_signatures":
+        pass
+    elif feature == "unsafe_revoked_tx_signing":
+        pass
+    elif feature == "futures":
+        pass
+    elif feature == "tokio":
+        pass
+    elif feature == "rest-client":
+        pass
+    elif feature == "rpc-client":
+        pass
+    elif feature == "serde":
+        pass
+    elif feature == "esplora-blocking":
+        pass
+    elif feature == "esplora-async":
+        pass
+    elif feature == "async-interface":
+        pass
+    elif feature == "electrum":
+        pass
+    elif feature == "_test_utils":
+        pass
+    elif feature == "_test_vectors":
+        pass
+    elif feature == "afl":
+        pass
+    elif feature == "honggfuzz":
+        pass
+    elif feature == "libfuzzer_fuzz":
+        pass
+    elif feature == "stdin_fuzz":
+        pass
+    elif feature == "max_level_off":
+        pass
+    elif feature == "max_level_error":
+        pass
+    elif feature == "max_level_warn":
+        pass
+    elif feature == "max_level_info":
+        pass
+    elif feature == "max_level_debug":
+        pass
+    elif feature == "max_level_trace":
+        pass
+    else:
+        print("Bad feature: " + feature)
+        assert False
+
+def check_target_os(os):
+    if os == "windows":
+        pass
+    else:
+        assert False
+
+def check_cfg_tag(cfg):
+    if cfg == "fuzzing":
+        pass
+    elif cfg == "test":
+        pass
+    elif cfg == "debug_assertions":
+        pass
+    elif cfg == "c_bindings":
+        pass
+    elif cfg == "ldk_bench":
+        pass
+    elif cfg == "taproot":
+        pass
+    elif cfg == "require_route_graph_test":
+        pass
+    else:
+        print("Bad cfg tag: " + cfg)
+        assert False
+
+def check_cfg_args(cfg):
+    if cfg.startswith("all(") or cfg.startswith("any(") or cfg.startswith("not("):
+        brackets = 1
+        pos = 4
+        while pos < len(cfg):
+            if cfg[pos] == "(":
+                brackets += 1
+            elif cfg[pos] == ")":
+                brackets -= 1
+                if brackets == 0:
+                    check_cfg_args(cfg[4:pos])
+                    if pos + 1 != len(cfg):
+                        assert cfg[pos + 1] == ","
+                        check_cfg_args(cfg[pos + 2:].strip())
+                    return
+            pos += 1
+        assert False
+        assert(cfg.endswith(")"))
+        check_cfg_args(cfg[4:len(cfg)-1])
+    else:
+        parts = [part.strip() for part in cfg.split(",", 1)]
+        if len(parts) > 1:
+            for part in parts:
+                check_cfg_args(part)
+        elif cfg.startswith("feature") or cfg.startswith("target_os") or cfg.startswith("target_pointer_width"):
+            arg = cfg
+            if cfg.startswith("feature"):
+                arg = arg[7:].strip()
+            elif cfg.startswith("target_os"):
+                arg = arg[9:].strip()
+            else:
+                arg = arg[20:].strip()
+            assert arg.startswith("=")
+            arg = arg[1:].strip()
+            assert arg.startswith("\"")
+            assert arg.endswith("\"")
+            arg = arg[1:len(arg)-1]
+            assert not "\"" in arg
+            if cfg.startswith("feature"):
+                check_feature(arg)
+            elif cfg.startswith("target_os"):
+                check_target_os(arg)
+            else:
+                assert arg == "32" or arg == "64"
+        else:
+            check_cfg_tag(cfg.strip())
+
+cfg_regex = re.compile("#\[cfg\((.*)\)\]")
+for path in glob.glob(sys.path[0] + "/../**/*.rs", recursive = True):
+    with open(path, "r") as file:
+        while True:
+            line = file.readline()
+            if not line:
+                break
+            if "#[cfg(" in line:
+                if not line.strip().startswith("//"):
+                    cfg_part = cfg_regex.match(line.strip()).group(1)
+                    check_cfg_args(cfg_part)
index 2db32a1081c2c07d5a4f7e30c03e40ce79fbe9ff..11934a8307a6f0723aeeb7a5094f3853a0c0a981 100755 (executable)
@@ -8,38 +8,60 @@ HOST_PLATFORM="$(rustc --version --verbose | grep "host:" | awk '{ print $2 }')"
 # which we do here.
 # Further crates which appear only as dev-dependencies are pinned further down.
 function PIN_RELEASE_DEPS {
-       # Tokio MSRV on versions 1.17 through 1.26 is rustc 1.49. Above 1.26 MSRV is 1.56.
-       [ "$RUSTC_MINOR_VERSION" -lt 49 ] && cargo update -p tokio --precise "1.14.1" --verbose
-       [[ "$RUSTC_MINOR_VERSION" -gt 48  &&  "$RUSTC_MINOR_VERSION" -lt 56 ]] && cargo update -p tokio --precise "1.25.1" --verbose
-
-       # Sadly the log crate is always a dependency of tokio until 1.20, and has no reasonable MSRV guarantees
-       [ "$RUSTC_MINOR_VERSION" -lt 49 ] && cargo update -p log --precise "0.4.18" --verbose
-
-       # The serde_json crate switched to Rust edition 2021 starting with v1.0.101, i.e., has MSRV of 1.56
-       [ "$RUSTC_MINOR_VERSION" -lt 56 ] && cargo update -p serde_json --precise "1.0.100" --verbose
-
        return 0 # Don't fail the script if our rustc is higher than the last check
 }
 
-PIN_RELEASE_DEPS # pin the release dependencies in our main workspace
-
-# The addr2line v0.20 crate (a dependency of `backtrace` starting with 0.3.68) relies on 1.55+
-[ "$RUSTC_MINOR_VERSION" -lt 55 ] && cargo update -p backtrace --precise "0.3.67" --verbose
-
-# The quote crate switched to Rust edition 2021 starting with v1.0.31, i.e., has MSRV of 1.56
-[ "$RUSTC_MINOR_VERSION" -lt 56 ] && cargo update -p quote --precise "1.0.30" --verbose
+# The tests of `lightning-transaction-sync` require `electrs` and `bitcoind`
+# binaries. Here, we download the binaries, validate them, and export their
+# location via `ELECTRS_EXE`/`BITCOIND_EXE` which will be used by the
+# `electrsd`/`bitcoind` crates in our tests.
+function DOWNLOAD_ELECTRS_AND_BITCOIND {
+       ELECTRS_DL_ENDPOINT="https://github.com/RCasatta/electrsd/releases/download/electrs_releases"
+       ELECTRS_VERSION="esplora_a33e97e1a1fc63fa9c20a116bb92579bbf43b254"
+       BITCOIND_DL_ENDPOINT="https://bitcoincore.org/bin/"
+       BITCOIND_VERSION="25.1"
+       if [[ "$HOST_PLATFORM" == *linux* ]]; then
+               ELECTRS_DL_FILE_NAME=electrs_linux_"$ELECTRS_VERSION".zip
+               ELECTRS_DL_HASH="865e26a96e8df77df01d96f2f569dcf9622fc87a8d99a9b8fe30861a4db9ddf1"
+               BITCOIND_DL_FILE_NAME=bitcoin-"$BITCOIND_VERSION"-x86_64-linux-gnu.tar.gz
+               BITCOIND_DL_HASH="a978c407b497a727f0444156e397b50491ce862d1f906fef9b521415b3611c8b"
+       elif [[ "$HOST_PLATFORM" == *darwin* ]]; then
+               ELECTRS_DL_FILE_NAME=electrs_macos_"$ELECTRS_VERSION".zip
+               ELECTRS_DL_HASH="2d5ff149e8a2482d3658e9b386830dfc40c8fbd7c175ca7cbac58240a9505bcd"
+               BITCOIND_DL_FILE_NAME=bitcoin-"$BITCOIND_VERSION"-x86_64-apple-darwin.tar.gz
+               BITCOIND_DL_HASH="1acfde0ec3128381b83e3e5f54d1c7907871d324549129592144dd12a821eff1"
+       else
+               echo -e "\n\nUnsupported platform. Exiting.."
+               exit 1
+       fi
+
+       DL_TMP_DIR=$(mktemp -d)
+       trap 'rm -rf -- "$DL_TMP_DIR"' EXIT
+
+       pushd "$DL_TMP_DIR"
+       ELECTRS_DL_URL="$ELECTRS_DL_ENDPOINT"/"$ELECTRS_DL_FILE_NAME"
+       curl -L -o "$ELECTRS_DL_FILE_NAME" "$ELECTRS_DL_URL"
+       echo "$ELECTRS_DL_HASH  $ELECTRS_DL_FILE_NAME"|shasum -a 256 -c
+       unzip "$ELECTRS_DL_FILE_NAME"
+       export ELECTRS_EXE="$DL_TMP_DIR"/electrs
+       chmod +x "$ELECTRS_EXE"
+
+       BITCOIND_DL_URL="$BITCOIND_DL_ENDPOINT"/bitcoin-core-"$BITCOIND_VERSION"/"$BITCOIND_DL_FILE_NAME"
+       curl -L -o "$BITCOIND_DL_FILE_NAME" "$BITCOIND_DL_URL"
+       echo "$BITCOIND_DL_HASH  $BITCOIND_DL_FILE_NAME"|shasum -a 256 -c
+       tar xzf "$BITCOIND_DL_FILE_NAME"
+       export BITCOIND_EXE="$DL_TMP_DIR"/bitcoin-"$BITCOIND_VERSION"/bin/bitcoind
+       chmod +x "$BITCOIND_EXE"
+       popd
+}
 
-# The syn crate depends on too-new proc-macro2 starting with v2.0.33, i.e., has MSRV of 1.56
-if [ "$RUSTC_MINOR_VERSION" -lt 56 ]; then
-       SYN_2_DEP=$(grep -o '"syn 2.*' Cargo.lock | tr -d '",' | tr ' ' ':')
-       cargo update -p "$SYN_2_DEP" --precise "2.0.32" --verbose
-fi
+PIN_RELEASE_DEPS # pin the release dependencies in our main workspace
 
-# The proc-macro2 crate switched to Rust edition 2021 starting with v1.0.66, i.e., has MSRV of 1.56
-[ "$RUSTC_MINOR_VERSION" -lt 56 ] && cargo update -p proc-macro2 --precise "1.0.65" --verbose
+# Starting with version 1.10.0, the `regex` crate has an MSRV of rustc 1.65.0.
+[ "$RUSTC_MINOR_VERSION" -lt 65 ] && cargo update -p regex --precise "1.9.6" --verbose
 
-# The memchr crate switched to an MSRV of 1.60 starting with v2.6.0
-[ "$RUSTC_MINOR_VERSION" -lt 60 ] && cargo update -p memchr --precise "2.5.0" --verbose
+# The addr2line v0.21 crate (a dependency of `backtrace` starting with 0.3.69) relies on rustc 1.65
+[ "$RUSTC_MINOR_VERSION" -lt 65 ] && cargo update -p backtrace --precise "0.3.68" --verbose
 
 export RUST_BACKTRACE=1
 
@@ -59,17 +81,26 @@ cargo test --verbose --color always --features rpc-client,rest-client,tokio
 cargo check --verbose --color always --features rpc-client,rest-client,tokio
 popd
 
-if [[ $RUSTC_MINOR_VERSION -gt 67 && "$HOST_PLATFORM" != *windows* ]]; then
+if [[ "$HOST_PLATFORM" != *windows* ]]; then
        echo -e "\n\nBuilding and testing Transaction Sync Clients with features"
        pushd lightning-transaction-sync
-       cargo test --verbose --color always --features esplora-blocking
-       cargo check --verbose --color always --features esplora-blocking
-       cargo test --verbose --color always --features esplora-async
-       cargo check --verbose --color always --features esplora-async
-       cargo test --verbose --color always --features esplora-async-https
-       cargo check --verbose --color always --features esplora-async-https
-       cargo test --verbose --color always --features electrum
-       cargo check --verbose --color always --features electrum
+
+       # reqwest 0.11.21 had a regression that broke its 1.63.0 MSRV
+       [ "$RUSTC_MINOR_VERSION" -lt 65 ] && cargo update -p reqwest --precise "0.11.20" --verbose
+       # Starting with version 1.10.0, the `regex` crate has an MSRV of rustc 1.65.0.
+       [ "$RUSTC_MINOR_VERSION" -lt 65 ] && cargo update -p regex --precise "1.9.6" --verbose
+
+       DOWNLOAD_ELECTRS_AND_BITCOIND
+
+       RUSTFLAGS="--cfg no_download" cargo test --verbose --color always --features esplora-blocking
+       RUSTFLAGS="--cfg no_download" cargo check --verbose --color always --features esplora-blocking
+       RUSTFLAGS="--cfg no_download" cargo test --verbose --color always --features esplora-async
+       RUSTFLAGS="--cfg no_download" cargo check --verbose --color always --features esplora-async
+       RUSTFLAGS="--cfg no_download" cargo test --verbose --color always --features esplora-async-https
+       RUSTFLAGS="--cfg no_download" cargo check --verbose --color always --features esplora-async-https
+       RUSTFLAGS="--cfg no_download" cargo test --verbose --color always --features electrum
+       RUSTFLAGS="--cfg no_download" cargo check --verbose --color always --features electrum
+
        popd
 fi
 
@@ -78,20 +109,16 @@ pushd lightning-background-processor
 cargo test --verbose --color always --features futures
 popd
 
-if [ "$RUSTC_MINOR_VERSION" -gt 55 ]; then
-       echo -e "\n\nTest Custom Message Macros"
-       pushd lightning-custom-message
-       cargo test --verbose --color always
-       [ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
-       popd
-fi
+echo -e "\n\nTest Custom Message Macros"
+pushd lightning-custom-message
+cargo test --verbose --color always
+[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
+popd
 
-if [ "$RUSTC_MINOR_VERSION" -gt 51 ]; then # Current `object` MSRV, subject to change
-       echo -e "\n\nTest backtrace-debug builds"
-       pushd lightning
-       cargo test --verbose --color always --features backtrace
-       popd
-fi
+echo -e "\n\nTest backtrace-debug builds"
+pushd lightning
+cargo test --verbose --color always --features backtrace
+popd
 
 echo -e "\n\nBuilding with all Log-Limiting features"
 pushd lightning
@@ -102,13 +129,14 @@ popd
 
 echo -e "\n\nTesting no-std flags in various combinations"
 for DIR in lightning lightning-invoice lightning-rapid-gossip-sync; do
-       [ "$RUSTC_MINOR_VERSION" -gt 50 ] && cargo test -p $DIR --verbose --color always --no-default-features --features no-std
+       cargo test -p $DIR --verbose --color always --no-default-features --features no-std
        # check if there is a conflict between no-std and the default std feature
-       [ "$RUSTC_MINOR_VERSION" -gt 50 ] && cargo test -p $DIR --verbose --color always --features no-std
+       cargo test -p $DIR --verbose --color always --features no-std
 done
+
 for DIR in lightning lightning-invoice lightning-rapid-gossip-sync; do
        # check if there is a conflict between no-std and the c_bindings cfg
-       [ "$RUSTC_MINOR_VERSION" -gt 50 ] && RUSTFLAGS="--cfg=c_bindings" cargo test -p $DIR --verbose --color always --no-default-features --features=no-std
+       RUSTFLAGS="--cfg=c_bindings" cargo test -p $DIR --verbose --color always --no-default-features --features=no-std
 done
 RUSTFLAGS="--cfg=c_bindings" cargo test --verbose --color always
 
@@ -125,16 +153,7 @@ popd
 echo -e "\n\nTesting no-std build on a downstream no-std crate"
 # check no-std compatibility across dependencies
 pushd no-std-check
-if [[ $RUSTC_MINOR_VERSION -gt 67 ]]; then
-       # lightning-transaction-sync's MSRV is 1.67
-       cargo check --verbose --color always --features lightning-transaction-sync
-else
-       # The memchr crate switched to an MSRV of 1.60 starting with v2.6.0
-       # This is currently only a release dependency via core2, which we intend to work with
-       # rust-bitcoin to remove soon.
-       [ "$RUSTC_MINOR_VERSION" -lt 60 ] && cargo update -p memchr --precise "2.5.0" --verbose
-       cargo check --verbose --color always
-fi
+cargo check --verbose --color always --features lightning-transaction-sync
 [ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
 popd
 
index 573096efdfcfb3983fa94448c57453e9b21cdde4..0c279a015c7398fe2ba0d8ba5e5b7ec49f2a154a 100644 (file)
@@ -3,7 +3,7 @@ name = "lightning-fuzz"
 version = "0.0.1"
 authors = ["Automatically generated"]
 publish = false
-edition = "2018"
+edition = "2021"
 # Because the function is unused it gets dropped before we link lightning, so
 # we have to duplicate build.rs here. Note that this is only required for
 # fuzzing mode.
index 933cbc466a677a8cd1f93e9d5e63219682477870..53358d43c9e8d8335cd2e6ecd1b6b55c83b74557 100644 (file)
@@ -7,7 +7,7 @@ repository = "https://github.com/lightningdevkit/rust-lightning"
 description = """
 Utilities to perform required background tasks for Rust Lightning.
 """
-edition = "2018"
+edition = "2021"
 
 [package.metadata.docs.rs]
 all-features = true
index 449891ba07f2d09e1dd4fa155f8322591e15b3dd..62c03b81dfe89288e726ae1ee89f383322ce68ae 100644 (file)
@@ -2,9 +2,8 @@
 //! running properly, and (2) either can or should be run in the background. See docs for
 //! [`BackgroundProcessor`] for more details on the nitty-gritty.
 
-// 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(rustdoc::broken_intra_doc_links)]
+#![deny(rustdoc::private_intra_doc_links)]
 
 #![deny(missing_docs)]
 #![cfg_attr(not(feature = "futures"), deny(unsafe_code))]
@@ -904,7 +903,7 @@ mod tests {
        use lightning::ln::functional_test_utils::*;
        use lightning::ln::msgs::{ChannelMessageHandler, Init};
        use lightning::ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler};
-       use lightning::routing::gossip::{NetworkGraph, NodeId, P2PGossipSync};
+       use lightning::routing::gossip::{NetworkGraph, P2PGossipSync};
        use lightning::routing::scoring::{ChannelUsage, ScoreUpdate, ScoreLookUp, LockableScore};
        use lightning::routing::router::{DefaultRouter, Path, RouteHop, CandidateRouteHop};
        use lightning::util::config::UserConfig;
index 5a8f887c1d82b2b9acb9739bd9055b96653340f5..c7f7191ed55e2704b11e2be5e9e740668c42cc62 100644 (file)
@@ -7,7 +7,7 @@ repository = "https://github.com/lightningdevkit/rust-lightning"
 description = """
 Utilities to fetch the chain data from a block source and feed them into Rust Lightning.
 """
-edition = "2018"
+edition = "2021"
 
 [package.metadata.docs.rs]
 all-features = true
@@ -21,7 +21,7 @@ rpc-client = [ "serde_json", "chunked_transfer" ]
 bitcoin = "0.30.2"
 hex = { package = "hex-conservative", version = "0.1.1", default-features = false }
 lightning = { version = "0.0.118", path = "../lightning" }
-tokio = { version = "1.0", features = [ "io-util", "net", "time" ], optional = true }
+tokio = { version = "1.0", features = [ "io-util", "net", "time", "rt" ], optional = true }
 serde_json = { version = "1.0", optional = true }
 chunked_transfer = { version = "1.4", optional = true }
 
index 77ff3f0810b6f4a3bd6addd98a11faa383660b9d..4a01d4673b31e91d56c3cb350d995c1b7a3d7403 100644 (file)
@@ -13,9 +13,8 @@
 //! Both features support either blocking I/O using `std::net::TcpStream` or, with feature `tokio`,
 //! non-blocking I/O using `tokio::net::TcpStream` from inside a Tokio runtime.
 
-// 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(rustdoc::broken_intra_doc_links)]
+#![deny(rustdoc::private_intra_doc_links)]
 
 #![deny(missing_docs)]
 #![deny(unsafe_code)]
index 0b45fa41e6cbcdede6a5bea5c71446a5f0d0f239..5377b7ef3356313d46aec61bf40275a0d4e04a4a 100644 (file)
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
 keywords = [ "lightning", "bitcoin", "invoice", "BOLT11" ]
 readme = "README.md"
 repository = "https://github.com/lightningdevkit/rust-lightning/"
-edition = "2018"
+edition = "2021"
 
 [package.metadata.docs.rs]
 all-features = true
index 0d5fbb365ba3063fefa0b189bb858e7b7c843091..746fe63ba03d0d38e983212fa01f37a4a6d07551 100644 (file)
@@ -3,7 +3,7 @@ name = "lightning-invoice-fuzz"
 version = "0.0.1"
 authors = ["Automatically generated"]
 publish = false
-edition = "2018"
+edition = "2021"
 
 [package.metadata]
 cargo-fuzz = true
index 406f96764e9971ad97abc4f7dbdfb352e94cad35..871c6c7d755ee4dad7656f7649a0681ada25f3c5 100644 (file)
@@ -48,9 +48,9 @@ mod tests {
         for (idx, c) in hex.as_bytes().iter().filter(|&&c| c != b'\n').enumerate() {
             b <<= 4;
             match *c {
-                b'A'...b'F' => b |= c - b'A' + 10,
-                b'a'...b'f' => b |= c - b'a' + 10,
-                b'0'...b'9' => b |= c - b'0',
+                b'A'..=b'F' => b |= c - b'A' + 10,
+                b'a'..=b'f' => b |= c - b'a' + 10,
+                b'0'..=b'9' => b |= c - b'0',
                 _ => panic!("Bad hex"),
             }
             if (idx & 1) == 1 {
index d87c6c89372080b5696fd754f35fb8eeddf1c75d..89763aa758915dff924fd6155604f5a27f308bcf 100644 (file)
@@ -1,6 +1,5 @@
-// 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(rustdoc::broken_intra_doc_links)]
+#![deny(rustdoc::private_intra_doc_links)]
 
 #![deny(missing_docs)]
 #![deny(non_upper_case_globals)]
index 247481fcfc853e5da507cd91b2cb96e0c016fd5d..e491dec5d458f413038592ff7db26e5849eb28f6 100644 (file)
@@ -8,7 +8,7 @@ description = """
 Implementation of the rust-lightning network stack using Tokio.
 For Rust-Lightning clients which wish to make direct connections to Lightning P2P nodes, this is a simple alternative to implementing the required network stack, especially for those already using Tokio.
 """
-edition = "2018"
+edition = "2021"
 
 [package.metadata.docs.rs]
 all-features = true
index d02f23fdd2cfd8649e9238cdda5a8fba470ace5c..1aa2cc25a13cc0772ee2e958da66aca602ce0eb4 100644 (file)
@@ -22,9 +22,8 @@
 //!
 //! [`PeerManager`]: lightning::ln::peer_handler::PeerManager
 
-// 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(rustdoc::broken_intra_doc_links)]
+#![deny(rustdoc::private_intra_doc_links)]
 
 #![deny(missing_docs)]
 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
index 387366bff0e9f4826af513633f126d42b1e9253c..4206b5f2226401430e5d9c28a474af4d656077f0 100644 (file)
@@ -7,7 +7,7 @@ repository = "https://github.com/lightningdevkit/rust-lightning"
 description = """
 Utilities for LDK data persistence and retrieval.
 """
-edition = "2018"
+edition = "2021"
 
 [package.metadata.docs.rs]
 all-features = true
index ae258e137d742f32ce1067d6508ad133e02bd67a..8e7d9055a6aae014b80daf6d9280717fda1a713f 100644 (file)
@@ -1,8 +1,7 @@
 //! Provides utilities for LDK data persistence and retrieval.
-//
-// TODO: 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(rustdoc::broken_intra_doc_links)]
+#![deny(rustdoc::private_intra_doc_links)]
 
 #![deny(missing_docs)]
 
index 2018e3b24836094684c9b5f4848b6f28c808abee..006725b196bb111a7dc9cfbaf22b8805b5745296 100644 (file)
@@ -4,7 +4,7 @@ version = "0.0.118"
 authors = ["Arik Sosman <git@arik.io>"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/lightningdevkit/rust-lightning"
-edition = "2018"
+edition = "2021"
 description = """
 Utility to process gossip routing data from Rapid Gossip Sync Server.
 """
index c15eedabbe19b3a8f70d6a15d64c1d2ca705ae6c..0561975f82151e0deae7782c4893b1056da4b0d5 100644 (file)
@@ -1,6 +1,5 @@
-// 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(rustdoc::broken_intra_doc_links)]
+#![deny(rustdoc::private_intra_doc_links)]
 
 #![deny(missing_docs)]
 #![deny(unsafe_code)]
index 20e03ce6c2767721295e139bef579ff5e1fa63be..d712229b0a820b841579f883594dcfed7a5f44ac 100644 (file)
@@ -7,7 +7,7 @@ repository = "https://github.com/lightningdevkit/rust-lightning"
 description = """
 Utilities for syncing LDK via the transaction-based `Confirm` interface.
 """
-edition = "2018"
+edition = "2021"
 
 [package.metadata.docs.rs]
 all-features = true
@@ -22,7 +22,7 @@ electrum = ["electrum-client"]
 async-interface = []
 
 [dependencies]
-lightning = { version = "0.0.118", path = "../lightning", default-features = false }
+lightning = { version = "0.0.118", path = "../lightning", default-features = false, features = ["std"] }
 bitcoin = { version = "0.30.2", default-features = false }
 bdk-macros = "0.6"
 futures = { version = "0.3", optional = true }
@@ -30,6 +30,11 @@ esplora-client = { version = "0.6", default-features = false, optional = true }
 electrum-client = { version = "0.18.0", optional = true }
 
 [dev-dependencies]
-lightning = { version = "0.0.118", path = "../lightning", features = ["std", "_test_utils"] }
-electrsd = { version = "0.26.0", features = ["legacy", "esplora_a33e97e1", "bitcoind_25_0"] }
+lightning = { version = "0.0.118", path = "../lightning", default-features = false, features = ["std", "_test_utils"] }
 tokio = { version = "1.14.0", features = ["full"] }
+
+[target.'cfg(not(no_download))'.dev-dependencies]
+electrsd = { version = "0.26.0", default-features = false, features = ["legacy", "esplora_a33e97e1", "bitcoind_25_0"] }
+
+[target.'cfg(no_download)'.dev-dependencies]
+electrsd = { version = "0.26.0", default-features = false, features = ["legacy"] }
index 21b6a4e97c15d0e3261251db829dc1c38e7c9c92..7bd4b4aee3f0784d5ad5aa92c7638e49b08790aa 100644 (file)
@@ -58,9 +58,8 @@
 //! [`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(rustdoc::broken_intra_doc_links)]
+#![deny(rustdoc::private_intra_doc_links)]
 
 #![deny(missing_docs)]
 #![deny(unsafe_code)]
index 76d751af39192754c67575bdc27650ab89aa88e3..3c3912e2b32fc29a130b9d78d504a6826b17cb54 100644 (file)
@@ -9,7 +9,7 @@ A Bitcoin Lightning library in Rust.
 Does most of the hard work, without implying a specific runtime, requiring clients implement basic network logic, chain interactions and disk storage.
 Still missing tons of error-handling. See GitHub issues for suggested projects if you want to contribute. Don't have to bother telling you not to use this for anything serious, because you'd have to build a client around it to even try.
 """
-edition = "2018"
+edition = "2021"
 
 [package.metadata.docs.rs]
 features = ["std"]
index 2d7f0c18af395b12eff9fa87863c77e57c9567e1..1f42dc2fe4251a26be3c7b659bae89505893b6e3 100644 (file)
@@ -40,7 +40,7 @@ pub trait BroadcasterInterface {
        /// be sure to manage both cases correctly.
        ///
        /// Bitcoin transaction packages are defined in BIP 331 and here:
-       /// https://github.com/bitcoin/bitcoin/blob/master/doc/policy/packages.md
+       /// <https://github.com/bitcoin/bitcoin/blob/master/doc/policy/packages.md>
        fn broadcast_transactions(&self, txs: &[&Transaction]);
 }
 
index 1fe3fcd9ff11a8046de0a64f2e95ae7968fdb662..09a32b6e2145e79a16121819f3112a31335ae5ca 100644 (file)
@@ -402,7 +402,8 @@ where C::Target: chain::Filter,
                                                outpoint: OutPoint { txid, index: idx as u16 },
                                                script_pubkey: output.script_pubkey,
                                        };
-                                       chain_source.register_output(output)
+                                       log_trace!(logger, "Adding monitoring for spends of outpoint {} to the filter", output.outpoint);
+                                       chain_source.register_output(output);
                                }
                        }
                }
@@ -741,7 +742,7 @@ where C::Target: chain::Filter,
                        },
                }
                if let Some(ref chain_source) = self.chain_source {
-                       monitor.load_outputs_to_watch(chain_source);
+                       monitor.load_outputs_to_watch(chain_source , &self.logger);
                }
                entry.insert(MonitorHolder {
                        monitor,
index e862b5cdde52636019dc548e720caa8f145c1352..244384faa224f68bafd5df1b02cda326ec722493 100644 (file)
@@ -1382,15 +1382,22 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
        /// Loads the funding txo and outputs to watch into the given `chain::Filter` by repeatedly
        /// calling `chain::Filter::register_output` and `chain::Filter::register_tx` until all outputs
        /// have been registered.
-       pub fn load_outputs_to_watch<F: Deref>(&self, filter: &F) where F::Target: chain::Filter {
+       pub fn load_outputs_to_watch<F: Deref, L: Deref>(&self, filter: &F, logger: &L) 
+       where 
+               F::Target: chain::Filter, L::Target: Logger,
+       {
                let lock = self.inner.lock().unwrap();
+               let logger = WithChannelMonitor::from_impl(logger, &*lock);
+               log_trace!(&logger, "Registering funding outpoint {}", &lock.get_funding_txo().0);
                filter.register_tx(&lock.get_funding_txo().0.txid, &lock.get_funding_txo().1);
                for (txid, outputs) in lock.get_outputs_to_watch().iter() {
                        for (index, script_pubkey) in outputs.iter() {
                                assert!(*index <= u16::max_value() as u32);
+                               let outpoint = OutPoint { txid: *txid, index: *index as u16 };
+                               log_trace!(logger, "Registering outpoint {} with the filter for monitoring spends", outpoint);
                                filter.register_output(WatchedOutput {
                                        block_hash: None,
-                                       outpoint: OutPoint { txid: *txid, index: *index as u16 },
+                                       outpoint,
                                        script_pubkey: script_pubkey.clone(),
                                });
                        }
@@ -2284,7 +2291,7 @@ macro_rules! fail_unbroadcast_htlcs {
                                                        // broadcastable commitment transaction has the HTLC in it, but it
                                                        // cannot currently change after channel initialization, so we don't
                                                        // need to here.
-                                                       let confirmed_htlcs_iter: &mut Iterator<Item = (&HTLCOutputInCommitment, Option<&HTLCSource>)> = &mut $confirmed_htlcs_list;
+                                                       let confirmed_htlcs_iter: &mut dyn Iterator<Item = (&HTLCOutputInCommitment, Option<&HTLCSource>)> = &mut $confirmed_htlcs_list;
 
                                                        let mut matched_htlc = false;
                                                        for (ref broadcast_htlc, ref broadcast_source) in confirmed_htlcs_iter {
@@ -3532,9 +3539,11 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
 
                if height > self.best_block.height() {
                        self.best_block = BestBlock::new(block_hash, height);
+                       log_trace!(logger, "Connecting new block {} at height {}", block_hash, height);
                        self.block_confirmed(height, block_hash, vec![], vec![], vec![], &broadcaster, &fee_estimator, logger)
                } else if block_hash != self.best_block.block_hash() {
                        self.best_block = BestBlock::new(block_hash, height);
+                       log_trace!(logger, "Best block re-orged, replaced with new block {} at height {}", block_hash, height);
                        self.onchain_events_awaiting_threshold_conf.retain(|ref entry| entry.height <= height);
                        self.onchain_tx_handler.block_disconnected(height + 1, broadcaster, fee_estimator, logger);
                        Vec::new()
@@ -3571,6 +3580,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                let mut claimable_outpoints = Vec::new();
                'tx_iter: for tx in &txn_matched {
                        let txid = tx.txid();
+                       log_trace!(logger, "Transaction {} confirmed in block {}", txid , block_hash);
                        // If a transaction has already been confirmed, ensure we don't bother processing it duplicatively.
                        if Some(txid) == self.funding_spend_confirmed {
                                log_debug!(logger, "Skipping redundant processing of funding-spend tx {} as it was previously confirmed", txid);
index 2a9583f2edfcb26a17667839894f056a657a79a2..dafce03ddb0d76ca1ca7f828f71b59c557345bab 100644 (file)
@@ -357,7 +357,7 @@ pub struct WatchedOutput {
        pub script_pubkey: ScriptBuf,
 }
 
-impl<T: Listen> Listen for core::ops::Deref<Target = T> {
+impl<T: Listen> Listen for dyn core::ops::Deref<Target = T> {
        fn filtered_block_connected(&self, header: &Header, txdata: &TransactionData, height: u32) {
                (**self).filtered_block_connected(header, txdata, height);
        }
index 8c6390302f10c945754792189f0b02f4421fd616..1b019ba349e0ae8687a190b92ebd144fe164f6f9 100644 (file)
@@ -35,6 +35,7 @@ use bitcoin::{OutPoint, PubkeyHash, Sequence, ScriptBuf, Transaction, TxIn, TxOu
 use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR;
 use bitcoin::blockdata::locktime::absolute::LockTime;
 use bitcoin::consensus::Encodable;
+use bitcoin::psbt::PartiallySignedTransaction;
 use bitcoin::secp256k1;
 use bitcoin::secp256k1::Secp256k1;
 use bitcoin::secp256k1::ecdsa::Signature;
@@ -343,7 +344,10 @@ pub trait CoinSelectionSource {
        ) -> Result<CoinSelection, ()>;
        /// Signs and provides the full witness for all inputs within the transaction known to the
        /// trait (i.e., any provided via [`CoinSelectionSource::select_confirmed_utxos`]).
-       fn sign_tx(&self, tx: Transaction) -> Result<Transaction, ()>;
+       ///
+       /// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
+       /// unsigned transaction and then sign it with your wallet.
+       fn sign_psbt(&self, psbt: PartiallySignedTransaction) -> Result<Transaction, ()>;
 }
 
 /// An alternative to [`CoinSelectionSource`] that can be implemented and used along [`Wallet`] to
@@ -357,7 +361,10 @@ pub trait WalletSource {
        /// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within
        /// the transaction known to the wallet (i.e., any provided via
        /// [`WalletSource::list_confirmed_utxos`]).
-       fn sign_tx(&self, tx: Transaction) -> Result<Transaction, ()>;
+       ///
+       /// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
+       /// unsigned transaction and then sign it with your wallet.
+       fn sign_psbt(&self, psbt: PartiallySignedTransaction) -> Result<Transaction, ()>;
 }
 
 /// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
@@ -504,8 +511,8 @@ where
                        .or_else(|_| do_coin_selection(true, true))
        }
 
-       fn sign_tx(&self, tx: Transaction) -> Result<Transaction, ()> {
-               self.source.sign_tx(tx)
+       fn sign_psbt(&self, psbt: PartiallySignedTransaction) -> Result<Transaction, ()> {
+               self.source.sign_psbt(psbt)
        }
 }
 
@@ -549,8 +556,8 @@ where
        }
 
        /// Updates a transaction with the result of a successful coin selection attempt.
-       fn process_coin_selection(&self, tx: &mut Transaction, mut coin_selection: CoinSelection) {
-               for utxo in coin_selection.confirmed_utxos.drain(..) {
+       fn process_coin_selection(&self, tx: &mut Transaction, coin_selection: &CoinSelection) {
+               for utxo in coin_selection.confirmed_utxos.iter() {
                        tx.input.push(TxIn {
                                previous_output: utxo.outpoint,
                                script_sig: ScriptBuf::new(),
@@ -558,7 +565,7 @@ where
                                witness: Witness::new(),
                        });
                }
-               if let Some(change_output) = coin_selection.change_output.take() {
+               if let Some(change_output) = coin_selection.change_output.clone() {
                        tx.output.push(change_output);
                } else if tx.output.is_empty() {
                        // We weren't provided a change output, likely because the input set was a perfect
@@ -595,7 +602,7 @@ where
 
                log_debug!(self.logger, "Peforming coin selection for commitment package (commitment and anchor transaction) targeting {} sat/kW",
                        package_target_feerate_sat_per_1000_weight);
-               let coin_selection = self.utxo_source.select_confirmed_utxos(
+               let coin_selection: CoinSelection = self.utxo_source.select_confirmed_utxos(
                        claim_id, must_spend, &[], package_target_feerate_sat_per_1000_weight,
                )?;
 
@@ -613,15 +620,29 @@ where
                let total_input_amount = must_spend_amount +
                        coin_selection.confirmed_utxos.iter().map(|utxo| utxo.output.value).sum::<u64>();
 
-               self.process_coin_selection(&mut anchor_tx, coin_selection);
+               self.process_coin_selection(&mut anchor_tx, &coin_selection);
                let anchor_txid = anchor_tx.txid();
 
-               debug_assert_eq!(anchor_tx.output.len(), 1);
+               // construct psbt
+               let mut anchor_psbt = PartiallySignedTransaction::from_unsigned_tx(anchor_tx).unwrap();
+               // add witness_utxo to anchor input
+               anchor_psbt.inputs[0].witness_utxo = Some(anchor_descriptor.previous_utxo());
+               // add witness_utxo to remaining inputs
+               for (idx, utxo) in coin_selection.confirmed_utxos.into_iter().enumerate() {
+                       // add 1 to skip the anchor input
+                       let index = idx + 1;
+                       debug_assert_eq!(anchor_psbt.unsigned_tx.input[index].previous_output, utxo.outpoint);
+                       if utxo.output.script_pubkey.is_witness_program() {
+                               anchor_psbt.inputs[index].witness_utxo = Some(utxo.output);
+                       }
+               }
+
+               debug_assert_eq!(anchor_psbt.unsigned_tx.output.len(), 1);
                #[cfg(debug_assertions)]
-               let unsigned_tx_weight = anchor_tx.weight().to_wu() - (anchor_tx.input.len() as u64 * EMPTY_SCRIPT_SIG_WEIGHT);
+               let unsigned_tx_weight = anchor_psbt.unsigned_tx.weight().to_wu() - (anchor_psbt.unsigned_tx.input.len() as u64 * EMPTY_SCRIPT_SIG_WEIGHT);
 
                log_debug!(self.logger, "Signing anchor transaction {}", anchor_txid);
-               anchor_tx = self.utxo_source.sign_tx(anchor_tx)?;
+               anchor_tx = self.utxo_source.sign_psbt(anchor_psbt)?;
 
                let signer = anchor_descriptor.derive_channel_signer(&self.signer_provider);
                let anchor_sig = signer.sign_holder_anchor_input(&anchor_tx, 0, &self.secp)?;
@@ -690,7 +711,7 @@ where
                #[cfg(debug_assertions)]
                let must_spend_amount = must_spend.iter().map(|input| input.previous_utxo.value).sum::<u64>();
 
-               let coin_selection = self.utxo_source.select_confirmed_utxos(
+               let coin_selection: CoinSelection = self.utxo_source.select_confirmed_utxos(
                        claim_id, must_spend, &htlc_tx.output, target_feerate_sat_per_1000_weight,
                )?;
 
@@ -701,13 +722,30 @@ where
                let total_input_amount = must_spend_amount +
                        coin_selection.confirmed_utxos.iter().map(|utxo| utxo.output.value).sum::<u64>();
 
-               self.process_coin_selection(&mut htlc_tx, coin_selection);
+               self.process_coin_selection(&mut htlc_tx, &coin_selection);
+
+               // construct psbt
+               let mut htlc_psbt = PartiallySignedTransaction::from_unsigned_tx(htlc_tx).unwrap();
+               // add witness_utxo to htlc inputs
+               for (i, htlc_descriptor) in htlc_descriptors.iter().enumerate() {
+                       debug_assert_eq!(htlc_psbt.unsigned_tx.input[i].previous_output, htlc_descriptor.outpoint());
+                       htlc_psbt.inputs[i].witness_utxo = Some(htlc_descriptor.previous_utxo(&self.secp));
+               }
+               // add witness_utxo to remaining inputs
+               for (idx, utxo) in coin_selection.confirmed_utxos.into_iter().enumerate() {
+                       // offset to skip the htlc inputs
+                       let index = idx + htlc_descriptors.len();
+                       debug_assert_eq!(htlc_psbt.unsigned_tx.input[index].previous_output, utxo.outpoint);
+                       if utxo.output.script_pubkey.is_witness_program() {
+                               htlc_psbt.inputs[index].witness_utxo = Some(utxo.output);
+                       }
+               }
 
                #[cfg(debug_assertions)]
-               let unsigned_tx_weight = htlc_tx.weight().to_wu() - (htlc_tx.input.len() as u64 * EMPTY_SCRIPT_SIG_WEIGHT);
+               let unsigned_tx_weight = htlc_psbt.unsigned_tx.weight().to_wu() - (htlc_psbt.unsigned_tx.input.len() as u64 * EMPTY_SCRIPT_SIG_WEIGHT);
 
-               log_debug!(self.logger, "Signing HTLC transaction {}", htlc_tx.txid());
-               htlc_tx = self.utxo_source.sign_tx(htlc_tx)?;
+               log_debug!(self.logger, "Signing HTLC transaction {}", htlc_psbt.unsigned_tx.txid());
+               htlc_tx = self.utxo_source.sign_psbt(htlc_psbt)?;
 
                let mut signers = BTreeMap::new();
                for (idx, htlc_descriptor) in htlc_descriptors.iter().enumerate() {
index df1bb1a2a2f2ef807f55e72f9bb50f96380e17c7..c42f66da5764ec95c656a9b72e6fe10c6c66d771 100644 (file)
@@ -40,9 +40,8 @@
 #![cfg_attr(not(any(test, fuzzing, feature = "_test_utils")), deny(missing_docs))]
 #![cfg_attr(not(any(test, feature = "_test_utils")), forbid(unsafe_code))]
 
-// 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(rustdoc::broken_intra_doc_links)]
+#![deny(rustdoc::private_intra_doc_links)]
 
 // In general, rust is absolutely horrid at supporting users doing things like,
 // for example, compiling Rust code for real environments. Disable useless lints
index 582f67878e60d8e59d4a36b567e12a8fcded0798..8cff537bbfc1417c5b0fb64aa097c3cf179aeaf1 100644 (file)
@@ -5383,7 +5383,7 @@ impl<SP: Deref> Channel<SP> where
                        // 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.context.update_time_counter;
-                       match self.do_best_block_updated(reorg_height, best_time, None::<(ChainHash, &&NodeSigner, &UserConfig)>, logger) {
+                       match self.do_best_block_updated(reorg_height, best_time, None::<(ChainHash, &&dyn 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?");
@@ -8797,7 +8797,7 @@ mod tests {
                assert_eq!(decoded_chan.context.holding_cell_htlc_updates, holding_cell_htlc_updates);
        }
 
-       #[cfg(feature = "_test_vectors")]
+       #[cfg(all(feature = "_test_vectors", not(feature = "grind_signatures")))]
        #[test]
        fn outbound_commitment_test() {
                use bitcoin::sighash;
@@ -8818,7 +8818,7 @@ mod tests {
 
                // Test vectors from BOLT 3 Appendices C and F (anchors):
                let feeest = TestFeeEstimator{fee_est: 15000};
-               let logger : Arc<Logger> = Arc::new(test_utils::TestLogger::new());
+               let logger : Arc<dyn Logger> = Arc::new(test_utils::TestLogger::new());
                let secp_ctx = Secp256k1::new();
 
                let mut signer = InMemorySigner::new(
index 7c6ee1e429c1d1a325759d22c0a73207fa50d730..da95e3b618c472fc0620b23bd57fb94beb615887 100644 (file)
@@ -1521,13 +1521,11 @@ pub const MIN_FINAL_CLTV_EXPIRY_DELTA: u16 = HTLC_FAIL_BACK_BUFFER as u16 + 3;
 // then waiting ANTI_REORG_DELAY to be reorg-safe on the outbound HLTC and
 // failing the corresponding htlc backward, and us now seeing the last block of ANTI_REORG_DELAY before
 // LATENCY_GRACE_PERIOD_BLOCKS.
-#[deny(const_err)]
 #[allow(dead_code)]
 const CHECK_CLTV_EXPIRY_SANITY: u32 = MIN_CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - CLTV_CLAIM_BUFFER - ANTI_REORG_DELAY - LATENCY_GRACE_PERIOD_BLOCKS;
 
 // Check for ability of an attacker to make us fail on-chain by delaying an HTLC claim. See
 // ChannelMonitor::should_broadcast_holder_commitment_txn for a description of why this is needed.
-#[deny(const_err)]
 #[allow(dead_code)]
 const CHECK_CLTV_EXPIRY_SANITY_2: u32 = MIN_CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - 2*CLTV_CLAIM_BUFFER;
 
@@ -10497,7 +10495,6 @@ where
                        // 0.0.102+
                        for (_, monitor) in args.channel_monitors.iter() {
                                let counterparty_opt = id_to_peer.get(&monitor.get_funding_txo().0.to_channel_id());
-                               let chan_id = monitor.get_funding_txo().0.to_channel_id();
                                if counterparty_opt.is_none() {
                                        let logger = WithChannelMonitor::from(&args.logger, monitor);
                                        for (htlc_source, (htlc, _)) in monitor.get_pending_or_resolved_outbound_htlcs() {
index 1b7041c9fa23ef42443dbe5fa34c989894c113a6..6af0e63c98bf421bade346f89f1fff303f48e764 100644 (file)
@@ -3354,6 +3354,7 @@ fn test_threaded_payment_retries() {
                // 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_ref;
                        let node_a = unsafe { &*node_ref.0 };
                        while Instant::now() < end_time {
                                node_a.node.get_and_clear_pending_events(); // wipe the PendingHTLCsForwardable
index 6a935acf00d7b6cbb1cebbf4e633db05d65db3b0..a4e0042414f8996f95c08deb72d7a578322fff97 100644 (file)
@@ -2488,7 +2488,6 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
        // broadcast_node_announcement panics) of the maximum-length addresses would fit in a 64KB
        // message...
        const HALF_MESSAGE_IS_ADDRS: u32 = ::core::u16::MAX as u32 / (SocketAddress::MAX_LEN as u32 + 1) / 2;
-       #[deny(const_err)]
        #[allow(dead_code)]
        // ...by failing to compile if the number of addresses that would be half of a message is
        // smaller than 100:
index 21a1b302da09b76fa3f73cbc70953fa46919c3c6..8a44eb2a5beebf3128582bdbce23cc8edfbda381 100644 (file)
@@ -914,7 +914,8 @@ where
        fn peer_disconnected(&self, their_node_id: &PublicKey) {
                match self.message_recipients.lock().unwrap().remove(their_node_id) {
                        Some(OnionMessageRecipient::ConnectedPeer(..)) => {},
-                       _ => debug_assert!(false),
+                       Some(_) => debug_assert!(false),
+                       None => {},
                }
        }
 
index 8ca5333f63daabf21a5baed562ec8d0ae2053327..92ea8ffed55a91c218c4481e01a83f924536585d 100644 (file)
@@ -254,11 +254,11 @@ mod tests {
        }
 
        struct WrapperLog {
-               logger: Arc<Logger>
+               logger: Arc<dyn Logger>
        }
 
        impl WrapperLog {
-               fn new(logger: Arc<Logger>) -> WrapperLog {
+               fn new(logger: Arc<dyn Logger>) -> WrapperLog {
                        WrapperLog {
                                logger,
                        }
@@ -278,7 +278,7 @@ mod tests {
        fn test_logging_macros() {
                let mut logger = TestLogger::new();
                logger.enable(Level::Gossip);
-               let logger : Arc<Logger> = Arc::new(logger);
+               let logger : Arc<dyn Logger> = Arc::new(logger);
                let wrapper = WrapperLog::new(Arc::clone(&logger));
                wrapper.call_macros();
        }
index 0d5cfc81906fddacfe24ae97d202fe3f20f7383e..484d603404297d6aaf4e6c59f8f46af2a86fb4dc 100644 (file)
@@ -371,14 +371,14 @@ impl Writeable for BigSize {
        #[inline]
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                match self.0 {
-                       0...0xFC => {
+                       0..=0xFC => {
                                (self.0 as u8).write(writer)
                        },
-                       0xFD...0xFFFF => {
+                       0xFD..=0xFFFF => {
                                0xFDu8.write(writer)?;
                                (self.0 as u16).write(writer)
                        },
-                       0x10000...0xFFFFFFFF => {
+                       0x10000..=0xFFFFFFFF => {
                                0xFEu8.write(writer)?;
                                (self.0 as u32).write(writer)
                        },
index 664deb9fa1566f6aa2628150458385673fd16cc8..557be65d5fa8ddb9f35db92bdeab9c79630e4e03 100644 (file)
@@ -71,6 +71,7 @@ use crate::sign::{InMemorySigner, Recipient, EntropySource, NodeSigner, SignerPr
 
 #[cfg(feature = "std")]
 use std::time::{SystemTime, UNIX_EPOCH};
+use bitcoin::psbt::PartiallySignedTransaction;
 use bitcoin::Sequence;
 
 pub fn pubkey(byte: u8) -> PublicKey {
@@ -234,7 +235,7 @@ pub struct TestChainMonitor<'a> {
        pub added_monitors: Mutex<Vec<(OutPoint, channelmonitor::ChannelMonitor<TestChannelSigner>)>>,
        pub monitor_updates: Mutex<HashMap<ChannelId, Vec<channelmonitor::ChannelMonitorUpdate>>>,
        pub latest_monitor_update_id: Mutex<HashMap<ChannelId, (OutPoint, u64, MonitorUpdateId)>>,
-       pub chain_monitor: chainmonitor::ChainMonitor<TestChannelSigner, &'a TestChainSource, &'a chaininterface::BroadcasterInterface, &'a TestFeeEstimator, &'a TestLogger, &'a chainmonitor::Persist<TestChannelSigner>>,
+       pub chain_monitor: chainmonitor::ChainMonitor<TestChannelSigner, &'a TestChainSource, &'a dyn chaininterface::BroadcasterInterface, &'a TestFeeEstimator, &'a TestLogger, &'a dyn chainmonitor::Persist<TestChannelSigner>>,
        pub keys_manager: &'a TestKeysInterface,
        /// If this is set to Some(), the next update_channel call (not watch_channel) must be a
        /// ChannelForceClosed event for the given channel_id with should_broadcast set to the given
@@ -245,7 +246,7 @@ pub struct TestChainMonitor<'a> {
        pub expect_monitor_round_trip_fail: Mutex<Option<ChannelId>>,
 }
 impl<'a> TestChainMonitor<'a> {
-       pub fn new(chain_source: Option<&'a TestChainSource>, broadcaster: &'a chaininterface::BroadcasterInterface, logger: &'a TestLogger, fee_estimator: &'a TestFeeEstimator, persister: &'a chainmonitor::Persist<TestChannelSigner>, keys_manager: &'a TestKeysInterface) -> Self {
+       pub fn new(chain_source: Option<&'a TestChainSource>, broadcaster: &'a dyn chaininterface::BroadcasterInterface, logger: &'a TestLogger, fee_estimator: &'a TestFeeEstimator, persister: &'a dyn chainmonitor::Persist<TestChannelSigner>, keys_manager: &'a TestKeysInterface) -> Self {
                Self {
                        added_monitors: Mutex::new(Vec::new()),
                        monitor_updates: Mutex::new(HashMap::new()),
@@ -1417,7 +1418,8 @@ impl WalletSource for TestWalletSource {
                Ok(ScriptBuf::new_p2pkh(&public_key.pubkey_hash()))
        }
 
-       fn sign_tx(&self, mut tx: Transaction) -> Result<Transaction, ()> {
+       fn sign_psbt(&self, psbt: PartiallySignedTransaction) -> Result<Transaction, ()> {
+               let mut tx = psbt.extract_tx();
                let utxos = self.utxos.borrow();
                for i in 0..tx.input.len() {
                        if let Some(utxo) = utxos.iter().find(|utxo| utxo.outpoint == tx.input[i].previous_output) {
index d73360749dfaa0d9fb9aed985ef3121e6beaa543..3a4acc675e6be5bbe915e70311d3ee7e7d2c328e 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "msrv-check"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 lightning = { path = "../lightning" }
@@ -11,3 +11,4 @@ lightning-net-tokio = { path = "../lightning-net-tokio" }
 lightning-persister = { path = "../lightning-persister" }
 lightning-background-processor = { path = "../lightning-background-processor", features = ["futures"] }
 lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync" }
+lightning-custom-message = { path = "../lightning-custom-message" }
index 16d2fc110e2a42252dbc83afb623f6a76bff570d..c9d404c922f86012b87e1b961ca451e60c49e0bb 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "no-std-check"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [features]
 default = ["lightning/no-std", "lightning-invoice/no-std", "lightning-rapid-gossip-sync/no-std"]