diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index d32c55cd5d..e2ae378dd7 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -19,8 +19,8 @@ jobs: runs-on: ${{ matrix.platform }} steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Run security audit - uses: rustsec/audit-check@v1.4.1 + uses: rustsec/audit-check@v2 with: token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index ef049ad851..79f204757c 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -13,20 +13,20 @@ jobs: TOOLCHAIN: stable steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Install Rust toolchain run: | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain stable rustup override set stable - name: Enable caching for bitcoind id: cache-bitcoind - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: bin/bitcoind-${{ runner.os }}-${{ runner.arch }} key: bitcoind-${{ runner.os }}-${{ runner.arch }} - name: Enable caching for electrs id: cache-electrs - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: bin/electrs-${{ runner.os }}-${{ runner.arch }} key: electrs-${{ runner.os }}-${{ runner.arch }} @@ -34,7 +34,7 @@ jobs: if: "(steps.cache-bitcoind.outputs.cache-hit != 'true' || steps.cache-electrs.outputs.cache-hit != 'true')" run: | source ./scripts/download_bitcoind_electrs.sh - mkdir bin + mkdir -p bin mv "$BITCOIND_EXE" bin/bitcoind-${{ runner.os }}-${{ runner.arch }} mv "$ELECTRS_EXE" bin/electrs-${{ runner.os }}-${{ runner.arch }} - name: Set bitcoind/electrs environment variables diff --git a/.github/workflows/cln-integration.yml b/.github/workflows/cln-integration.yml index 32e7b74c02..87c8b411e0 100644 --- a/.github/workflows/cln-integration.yml +++ b/.github/workflows/cln-integration.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install dependencies run: | diff --git a/.github/workflows/cron-weekly-rustfmt.yml b/.github/workflows/cron-weekly-rustfmt.yml index d6326f03bd..9e54ab9f32 100644 --- a/.github/workflows/cron-weekly-rustfmt.yml +++ b/.github/workflows/cron-weekly-rustfmt.yml @@ -13,7 +13,7 @@ jobs: name: Nightly rustfmt runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@nightly with: components: rustfmt @@ -23,7 +23,7 @@ jobs: - name: Get the current date run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_ENV - name: Create Pull Request - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@v8 with: author: Fmt Bot title: Automated nightly rustfmt (${{ env.date }}) diff --git a/.github/workflows/kotlin.yml b/.github/workflows/kotlin.yml index 01a840d600..627051c31a 100644 --- a/.github/workflows/kotlin.yml +++ b/.github/workflows/kotlin.yml @@ -16,10 +16,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: distribution: temurin java-version: 11 diff --git a/.github/workflows/lnd-integration.yml b/.github/workflows/lnd-integration.yml index f913e92ad5..5fbb58508f 100644 --- a/.github/workflows/lnd-integration.yml +++ b/.github/workflows/lnd-integration.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Check and install CMake if needed # lnd_grpc_rust (via prost-build v0.10.4) requires CMake >= 3.5 but is incompatible with CMake >= 4.0. diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index d9bc978d14..1443a8048b 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -15,10 +15,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v6 with: python-version: '3.10' diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 87249bd720..32bb5e19e9 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -8,6 +8,9 @@ concurrency: jobs: build: + defaults: + run: + shell: bash strategy: matrix: platform: [ @@ -34,25 +37,40 @@ jobs: runs-on: ${{ matrix.platform }} steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Install Rust ${{ matrix.toolchain }} toolchain run: | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain ${{ matrix.toolchain }} - name: Check formatting on Rust ${{ matrix.toolchain }} if: matrix.check-fmt run: rustup component add rustfmt && cargo fmt --all -- --check + - name: Pin packages to allow for MSRV + if: matrix.msrv + run: | + cargo update -p idna_adapter --precise "1.2.0" --verbose # idna_adapter 1.2.1 uses ICU4X 2.2.0, requiring 1.86 and newer + cargo update -p encoding_rs --precise "0.8.35" --verbose # encoding_rs 0.8.40 and newer require 1.88 and newer + cargo update -p proptest --precise "1.11.0" --verbose # proptest 1.12.0 requires Rust 1.88 - name: Set RUSTFLAGS to deny warnings + id: rustflags if: "matrix.toolchain == 'stable'" - run: echo "RUSTFLAGS=-D warnings" >> "$GITHUB_ENV" + run: | + echo "RUSTFLAGS=-D warnings" >> "$GITHUB_ENV" + version=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "ldk-node") | .version') + # Preserve the deprecated FeeRate constructor in the 0.7 bindings. + if [[ "$version" == 0.7.* ]]; then + echo "uniffi=-D warnings -A deprecated" >> "$GITHUB_OUTPUT" + else + echo "uniffi=-D warnings" >> "$GITHUB_OUTPUT" + fi - name: Enable caching for bitcoind id: cache-bitcoind - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: bin/bitcoind-${{ runner.os }}-${{ runner.arch }} key: bitcoind-${{ runner.os }}-${{ runner.arch }} - name: Enable caching for electrs id: cache-electrs - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: bin/electrs-${{ runner.os }}-${{ runner.arch }} key: electrs-${{ runner.os }}-${{ runner.arch }} @@ -60,7 +78,7 @@ jobs: if: "matrix.platform != 'windows-latest' && (steps.cache-bitcoind.outputs.cache-hit != 'true' || steps.cache-electrs.outputs.cache-hit != 'true')" run: | source ./scripts/download_bitcoind_electrs.sh - mkdir bin + mkdir -p bin mv "$BITCOIND_EXE" bin/bitcoind-${{ runner.os }}-${{ runner.arch }} mv "$ELECTRS_EXE" bin/electrs-${{ runner.os }}-${{ runner.arch }} - name: Set bitcoind/electrs environment variables @@ -71,6 +89,8 @@ jobs: run: cargo build --verbose --color always - name: Build with UniFFI support on Rust ${{ matrix.toolchain }} if: matrix.build-uniffi + env: + RUSTFLAGS: ${{ steps.rustflags.outputs.uniffi }} run: cargo build --features uniffi --verbose --color always - name: Build documentation on Rust ${{ matrix.toolchain }} if: "matrix.platform != 'windows-latest' || matrix.toolchain != '1.85.0'" @@ -81,6 +101,8 @@ jobs: run: cargo check --release --verbose --color always - name: Check release build with UniFFI support on Rust ${{ matrix.toolchain }} if: matrix.build-uniffi + env: + RUSTFLAGS: ${{ steps.rustflags.outputs.uniffi }} run: cargo check --release --features uniffi --verbose --color always - name: Test on Rust ${{ matrix.toolchain }} if: "matrix.platform != 'windows-latest'" diff --git a/.github/workflows/semver.yml b/.github/workflows/semver.yml index 8472cbd2aa..cdbd90acdb 100644 --- a/.github/workflows/semver.yml +++ b/.github/workflows/semver.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout source code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust stable toolchain run: | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain stable diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 3410d09aa2..c1e385e2d3 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set default Rust version to stable run: rustup default stable diff --git a/.github/workflows/vss-integration.yml b/.github/workflows/vss-integration.yml index 8473ed4138..54e118c1a7 100644 --- a/.github/workflows/vss-integration.yml +++ b/.github/workflows/vss-integration.yml @@ -27,19 +27,25 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v6 with: path: ldk-node - name: Checkout VSS - uses: actions/checkout@v3 + uses: actions/checkout@v6 with: repository: lightningdevkit/vss-server path: vss-server - name: Build and Deploy VSS Server run: | - cd vss-server/rust - cargo run server/vss-server-config.toml& + version=$(cargo metadata --no-deps --format-version 1 --manifest-path ldk-node/Cargo.toml | jq -r '.packages[] | select(.name == "ldk-node") | .version') + cd vss-server + # The 0.7 tests use fixed headers without authentication. + if [[ "$version" == 0.7.* ]]; then + RUSTFLAGS="--cfg noop_authorizer" cargo run --no-default-features server/vss-server-config.toml& + else + cargo run server/vss-server-config.toml& + fi - name: Run VSS Integration tests run: | cd ldk-node diff --git a/src/event.rs b/src/event.rs index 41f76f216d..f64710d508 100644 --- a/src/event.rs +++ b/src/event.rs @@ -601,14 +601,14 @@ where self.logger, "Failed to process funding transaction as channel went away before we could fund it: {}", err - ) + ); }, Err(err) => { log_error!( self.logger, "Failed to process funding transaction: {:?}", err - ) + ); }, } }, @@ -1151,7 +1151,7 @@ where "Channel request rejected".to_string(), ) .unwrap_or_else(|e| { - log_error!(self.logger, "Failed to reject channel: {:?}", e) + log_error!(self.logger, "Failed to reject channel: {:?}", e); }); return Ok(()); } @@ -1195,7 +1195,7 @@ where "Channel request rejected".to_string(), ) .unwrap_or_else(|e| { - log_error!(self.logger, "Failed to reject channel: {:?}", e) + log_error!(self.logger, "Failed to reject channel: {:?}", e); }); return Ok(()); } @@ -1212,7 +1212,7 @@ where "Channel request rejected".to_string(), ) .unwrap_or_else(|e| { - log_error!(self.logger, "Failed to reject channel: {:?}", e) + log_error!(self.logger, "Failed to reject channel: {:?}", e); }); return Ok(()); } @@ -1704,7 +1704,9 @@ where }, } }, - Err(()) => log_error!(self.logger, "Failed signing funding transaction"), + Err(()) => { + log_error!(self.logger, "Failed signing funding transaction"); + }, }, LdkEvent::SplicePending { channel_id, diff --git a/src/lib.rs b/src/lib.rs index c0b02ae2f5..2fdcdddbf4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -300,7 +300,7 @@ impl Node { gossip_sync_logger, "Background sync of RGS gossip data failed: {}", e - ) + ); } } } @@ -1054,7 +1054,7 @@ impl Node { match self.peer_store.remove_peer(&counterparty_node_id) { Ok(()) => {}, Err(e) => { - log_error!(self.logger, "Failed to remove peer {}: {}", counterparty_node_id, e) + log_error!(self.logger, "Failed to remove peer {}: {}", counterparty_node_id, e); }, } diff --git a/src/payment/unified_qr.rs b/src/payment/unified_qr.rs index 6ebf25563a..d3c879cba1 100644 --- a/src/payment/unified_qr.rs +++ b/src/payment/unified_qr.rs @@ -155,7 +155,9 @@ impl UnifiedQrPayment { let offer = maybe_wrap(offer); match self.bolt12_payment.send(&offer, None, None, route_parameters) { Ok(payment_id) => return Ok(QrPaymentResult::Bolt12 { payment_id }), - Err(e) => log_error!(self.logger, "Failed to send BOLT12 offer: {:?}. This is part of a unified QR code payment. Falling back to the BOLT11 invoice.", e), + Err(e) => { + log_error!(self.logger, "Failed to send BOLT12 offer: {:?}. This is part of a unified QR code payment. Falling back to the BOLT11 invoice.", e); + }, } } @@ -163,7 +165,9 @@ impl UnifiedQrPayment { let invoice = maybe_wrap(invoice); match self.bolt11_invoice.send(&invoice, route_parameters) { Ok(payment_id) => return Ok(QrPaymentResult::Bolt11 { payment_id }), - Err(e) => log_error!(self.logger, "Failed to send BOLT11 invoice: {:?}. This is part of a unified QR code payment. Falling back to the on-chain transaction.", e), + Err(e) => { + log_error!(self.logger, "Failed to send BOLT11 invoice: {:?}. This is part of a unified QR code payment. Falling back to the on-chain transaction.", e); + }, } } diff --git a/src/runtime.rs b/src/runtime.rs index 1e9883ae4b..dd5d895f8f 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -176,7 +176,9 @@ impl Runtime { match timeout_res { Ok(stop_res) => match stop_res { - Ok(()) => log_debug!(self.logger, "Stopped background processing of events."), + Ok(()) => { + log_debug!(self.logger, "Stopped background processing of events."); + }, Err(e) => { abort_handle.abort(); log_error!( diff --git a/tests/integration_tests_lnd.rs b/tests/integration_tests_lnd.rs index 311a11c3ca..f94e35c1ce 100755 --- a/tests/integration_tests_lnd.rs +++ b/tests/integration_tests_lnd.rs @@ -15,11 +15,13 @@ use ldk_node::lightning::ln::msgs::SocketAddress; use ldk_node::{Builder, Event}; use lightning_invoice::{Bolt11InvoiceDescription, Description}; use lnd_grpc_rust::lnrpc::invoice::InvoiceState::Settled as LndInvoiceStateSettled; +use lnd_grpc_rust::lnrpc::payment::PaymentStatus as LndPaymentStatus; use lnd_grpc_rust::lnrpc::{ GetInfoRequest as LndGetInfoRequest, GetInfoResponse as LndGetInfoResponse, Invoice as LndInvoice, ListInvoiceRequest as LndListInvoiceRequest, - QueryRoutesRequest as LndQueryRoutesRequest, Route as LndRoute, SendRequest as LndSendRequest, + QueryRoutesRequest as LndQueryRoutesRequest, Route as LndRoute, }; +use lnd_grpc_rust::routerrpc::SendPaymentRequest as LndSendPaymentRequest; use lnd_grpc_rust::{connect, LndClient}; use tokio::fs; @@ -200,25 +202,33 @@ impl TestLndClient { } async fn pay_invoice(&mut self, invoice_str: &str) { - let send_req = - LndSendRequest { payment_request: invoice_str.to_string(), ..Default::default() }; - let response = self + let send_req = LndSendPaymentRequest { + payment_request: invoice_str.to_string(), + timeout_seconds: 60, + no_inflight_updates: true, + ..Default::default() + }; + let mut stream = self .client - .lightning() - .send_payment_sync(send_req) + .router() + .send_payment_v2(send_req) .await .expect("Failed to pay invoice on LND") .into_inner(); - if !response.payment_error.is_empty() || response.payment_preimage.is_empty() { - panic!( - "LND payment failed: {}", - if response.payment_error.is_empty() { - "No preimage returned" - } else { - &response.payment_error - } - ); + while let Some(payment) = stream.message().await.expect("Failed to read LND payment update") + { + match LndPaymentStatus::try_from(payment.status) { + Ok(LndPaymentStatus::Succeeded) => { + assert!(!payment.payment_preimage.is_empty(), "No preimage returned"); + return; + }, + Ok(LndPaymentStatus::Failed) => { + panic!("LND payment failed: {:?}", payment.failure_reason); + }, + _ => {}, + } } + panic!("LND payment stream ended without terminal status"); } }