Skip to content

Commit 506cb91

Browse files
author
Matt Corallo
committed
Merge PR '[0.3] Backport merged PRs' (#4770)
from 2026-07-0.3-backports-1 into 0.3 Reviewed-on: https://git.rust-bitcoin.org/lightningdevkit/rust-lightning/pulls/4770 Reviewed-by: wpaulino <wpaulino@noreply.gitea.bitcoin.ninja>
2 parents 3dfcc4c + abb5e35 commit 506cb91

59 files changed

Lines changed: 3521 additions & 548 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.forgejo/workflows/audit.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Security Audit
2+
on:
3+
workflow_dispatch:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
7+
jobs:
8+
audit:
9+
runs-on: debian-trixie
10+
steps:
11+
- name: Checkout source code
12+
uses: https://data.forgejo.org/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
13+
- name: Install Rust stable toolchain
14+
run: |
15+
rustup default stable
16+
- name: Install cargo-audit
17+
run: cargo install cargo-audit --locked
18+
- name: Run cargo audit
19+
# RUSTSEC-2021-0145 pertains `atty`, which is a depencency of
20+
# `criterion`. While the latter removed the depencency in its
21+
# newest version, it would also require a higher `rustc`. We
22+
# therefore avoid bumping it to allow benchmarking with our
23+
# `rustc` 1.63 MSRV.
24+
run: cargo audit --ignore RUSTSEC-2021-0145

.forgejo/workflows/build.yml

Lines changed: 503 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: CI check_commits
2+
3+
on:
4+
pull_request:
5+
branches-ignore:
6+
- master
7+
8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
cancel-in-progress: true
11+
12+
jobs:
13+
check_commits:
14+
runs-on: debian-trixie
15+
env:
16+
TOOLCHAIN: stable
17+
steps:
18+
- name: Checkout source code
19+
uses: https://data.forgejo.org/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
20+
with:
21+
fetch-depth: 0
22+
- name: Install Rust ${{ env.TOOLCHAIN }} toolchain
23+
run: |
24+
rustup default ${{ env.TOOLCHAIN }}
25+
- name: Fetch full tree and rebase on upstream
26+
run: |
27+
git remote add upstream https://git.rust-bitcoin.org/lightningdevkit/rust-lightning
28+
git fetch upstream
29+
export GIT_COMMITTER_EMAIL="rl-ci@example.com"
30+
export GIT_COMMITTER_NAME="RL CI"
31+
git rebase upstream/${{ github.base_ref }}
32+
- name: For each commit, run cargo check (including in fuzz)
33+
run: ci/check-each-commit.sh upstream/${{ github.base_ref }}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Unicode listing up to date
2+
on:
3+
workflow_dispatch:
4+
schedule:
5+
- cron: '42 3 * * *'
6+
7+
jobs:
8+
check-unicode:
9+
runs-on: debian-trixie
10+
steps:
11+
- name: Checkout source code
12+
uses: https://data.forgejo.org/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
13+
- name: Configure fj credentials
14+
# `fj` reads its token from keys.json; it has no token environment
15+
# variable, so write the automatic Actions token there for the API call.
16+
env:
17+
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
18+
FORGEJO_USER: ${{ github.actor }}
19+
run: |
20+
install -d -m 700 "$HOME/.local/share/forgejo-cli"
21+
printf '{"hosts":{"git.rust-bitcoin.org":{"type":"Application","name":"%s","token":"%s"}}}' "$FORGEJO_USER" "$FORGEJO_TOKEN" > "$HOME/.local/share/forgejo-cli/keys.json"
22+
chmod 600 "$HOME/.local/share/forgejo-cli/keys.json"
23+
- name: Check unicode file state
24+
env:
25+
HOST: git.rust-bitcoin.org
26+
REPO: ${{ github.repository }}
27+
run: |
28+
curl --proto '=https' --tlsv1.2 -fsSL -o /tmp/UnicodeData.txt https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
29+
contrib/gen_unicode_general_category.py /tmp/UnicodeData.txt -o /tmp/unicode.rs
30+
if ! diff -u lightning-types/src/unicode.rs /tmp/unicode.rs; then
31+
TITLE="Unicode listing out of date: ${{ github.workflow }}"
32+
RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}"
33+
BODY="The unicode character listing is out of date, see $RUN_URL"
34+
fj -H "$HOST" issue create "$TITLE" --body "$BODY" --repo "$REPO"
35+
fi

.forgejo/workflows/ci-build.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: CI Build Job
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
script:
7+
description: CI script to run (relative to repo root)
8+
required: true
9+
type: string
10+
11+
jobs:
12+
build:
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
platform: >-
17+
${{ github.event_name == 'push' && github.ref == 'refs/heads/main'
18+
&& fromJSON('["debian-trixie","windows","macos"]')
19+
|| fromJSON('["debian-trixie"]') }}
20+
toolchain: >-
21+
${{ github.event_name == 'push' && github.ref == 'refs/heads/main'
22+
&& fromJSON('["stable","beta","1.75.0"]')
23+
|| fromJSON('["1.75.0"]') }}
24+
exclude:
25+
- platform: windows
26+
- platform: macos
27+
runs-on: ${{ matrix.platform }}
28+
steps:
29+
- name: Checkout source code
30+
uses: https://data.forgejo.org/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
31+
- name: Install Rust ${{ matrix.toolchain }} toolchain
32+
run: |
33+
rustup default ${{ matrix.toolchain }}
34+
- name: Use rust-lld linker on Windows
35+
if: matrix.platform == 'windows'
36+
shell: bash
37+
run: echo "RUSTFLAGS=-C linker=rust-lld" >> "$GITHUB_ENV"
38+
- name: Set RUSTFLAGS to deny warnings
39+
if: "matrix.toolchain == '1.75.0'"
40+
run: echo "RUSTFLAGS=-D warnings" >> "$GITHUB_ENV"
41+
- name: Install no-std-check dependencies for ARM Embedded
42+
if: matrix.platform == 'debian-trixie'
43+
run: |
44+
rustup target add thumbv7m-none-eabi
45+
- name: Enable caching for bitcoind
46+
if: matrix.platform != 'windows'
47+
id: cache-bitcoind
48+
uses: https://data.forgejo.org/actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
49+
with:
50+
path: bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
51+
key: bitcoind-${{ runner.os }}-${{ runner.arch }}
52+
- name: Enable caching for electrs
53+
if: matrix.platform != 'windows'
54+
id: cache-electrs
55+
uses: https://data.forgejo.org/actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
56+
with:
57+
path: bin/electrs-${{ runner.os }}-${{ runner.arch }}
58+
key: electrs-${{ runner.os }}-${{ runner.arch }}
59+
- name: Download bitcoind/electrs
60+
if: >-
61+
matrix.platform != 'windows'
62+
&& (steps.cache-bitcoind.outputs.cache-hit != 'true'
63+
|| steps.cache-electrs.outputs.cache-hit != 'true')
64+
run: |
65+
source ./contrib/download_bitcoind_electrs.sh
66+
mkdir bin
67+
mv "$BITCOIND_EXE" bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
68+
mv "$ELECTRS_EXE" bin/electrs-${{ runner.os }}-${{ runner.arch }}
69+
- name: Set bitcoind/electrs environment variables
70+
if: matrix.platform != 'windows'
71+
run: |
72+
echo "BITCOIND_EXE=$( pwd )/bin/bitcoind-${{ runner.os }}-${{ runner.arch }}" >> "$GITHUB_ENV"
73+
echo "ELECTRS_EXE=$( pwd )/bin/electrs-${{ runner.os }}-${{ runner.arch }}" >> "$GITHUB_ENV"
74+
- name: Run CI script
75+
shell: bash
76+
run: CI_ENV=1 CI_MINIMIZE_DISK_USAGE=1 ./${{ inputs.script }}

.forgejo/workflows/semver.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: SemVer checks
2+
on:
3+
push:
4+
branches-ignore:
5+
- master
6+
pull_request:
7+
branches-ignore:
8+
- master
9+
10+
jobs:
11+
semver-checks:
12+
runs-on: debian-trixie
13+
steps:
14+
- name: Checkout source code
15+
uses: https://data.forgejo.org/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
16+
with:
17+
fetch-depth: 0
18+
- name: Install Rust stable toolchain
19+
run: |
20+
rustup default stable
21+
rustup override set stable
22+
- name: Install SemVer Checker
23+
run: cargo install cargo-semver-checks --locked
24+
- name: Check SemVer with all features
25+
run: cargo semver-checks
26+
- name: Check SemVer without any non-default features
27+
run: cargo semver-checks --only-explicit-features

ci/ci-tests-common.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,7 @@ PIN_RELEASE_DEPS # pin the release dependencies in our main workspace
2323
# Starting with version 0.27.8, the `hyper-rustls` crate has an MSRV of rustc 1.85.0.
2424
[ "$RUSTC_MINOR_VERSION" -lt 85 ] && cargo update -p hyper-rustls --precise "0.27.7" --quiet
2525

26+
# Starting with version 1.9.0, the `zeroize` crate uses Rust 2024.
27+
[ "$RUSTC_MINOR_VERSION" -lt 85 ] && cargo update -p zeroize --precise "1.8.2" --quiet
28+
2629
export RUST_BACKTRACE=1

fuzz/src/chanmon_consistency.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ use std::sync::atomic;
102102
use std::sync::{Arc, Mutex};
103103

104104
const MAX_FEE: u32 = 10_000;
105+
const MAX_SETTLE_ITERATIONS: usize = 256;
105106
struct FuzzEstimator {
106107
ret_val: atomic::AtomicU32,
107108
}
@@ -2759,9 +2760,20 @@ impl<'a, Out: Output + MaybeSend + MaybeSync> Harness<'a, Out> {
27592760
..
27602761
} => {
27612762
let signed_tx = nodes[node_idx].wallet.sign_tx(unsigned_transaction).unwrap();
2762-
nodes[node_idx]
2763-
.funding_transaction_signed(&channel_id, &counterparty_node_id, signed_tx)
2764-
.unwrap();
2763+
match nodes[node_idx].funding_transaction_signed(
2764+
&channel_id,
2765+
&counterparty_node_id,
2766+
signed_tx,
2767+
) {
2768+
Ok(()) => {},
2769+
Err(APIError::APIMisuseError { ref err })
2770+
if err.contains("not expecting funding signatures") =>
2771+
{
2772+
// A queued signing event can be invalidated by a later `tx_abort`
2773+
// before the application handles it.
2774+
},
2775+
Err(e) => panic!("{e:?}"),
2776+
}
27652777
},
27662778
events::Event::SpliceNegotiated { new_funding_txo, .. } => {
27672779
let mut txs = nodes[node_idx].broadcaster.txn_broadcasted.borrow_mut();
@@ -2799,9 +2811,9 @@ impl<'a, Out: Output + MaybeSend + MaybeSync> Harness<'a, Out> {
27992811
fn process_all_events(&mut self) {
28002812
let mut last_pass_no_updates = false;
28012813
for i in 0..std::usize::MAX {
2802-
if i == 100 {
2814+
if i == MAX_SETTLE_ITERATIONS {
28032815
panic!(
2804-
"It may take may iterations to settle the state, but it should not take forever"
2816+
"It may take many iterations to settle the state, but it should not take forever"
28052817
);
28062818
}
28072819
let mut made_progress = self.checkpoint_manager_persistences();

lightning-custom-message/src/lib.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,12 @@ macro_rules! composite_custom_message_handler {
358358
match message_type {
359359
$(
360360
$pattern => match <$type>::read(&self.$field, message_type, buffer)? {
361-
None => unreachable!(),
361+
// A sub-handler returns `None` for a `message_type` it doesn't
362+
// recognize. The composite's pattern can be broader than the types
363+
// the sub-handler decodes (e.g. a range), and `message_type` is
364+
// peer-provided, so report the message as unknown rather than
365+
// treating this as unreachable and panicking.
366+
None => Ok(None),
362367
Some(message) => Ok(Some($message::$variant(message))),
363368
},
364369
)*
@@ -501,6 +506,71 @@ mod tests {
501506
}
502507
);
503508

509+
struct ReservedBlockHandler;
510+
impl CustomMessageReader for ReservedBlockHandler {
511+
type CustomMessage = Foo;
512+
fn read<R: LengthLimitedRead>(
513+
&self, message_type: u16, _b: &mut R,
514+
) -> Result<Option<Foo>, DecodeError> {
515+
// This build defines only the message at 32768; the rest of the block its
516+
// protocol reserved (32768..=32777) is for types future versions may add.
517+
// A not-yet-defined type is unknown to this build, so per the
518+
// `CustomMessageReader` contract it returns `Ok(None)` -- a newer peer can
519+
// send one and this older node will treat it as an unknown message.
520+
match message_type {
521+
32768 => Ok(Some(Foo)),
522+
_ => Ok(None),
523+
}
524+
}
525+
}
526+
impl CustomMessageHandler for ReservedBlockHandler {
527+
fn handle_custom_message(&self, _msg: Foo, _: PublicKey) -> Result<(), LightningError> {
528+
Ok(())
529+
}
530+
fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Foo)> {
531+
vec![]
532+
}
533+
fn peer_disconnected(&self, _: PublicKey) {}
534+
fn peer_connected(&self, _: PublicKey, _: &Init, _: bool) -> Result<(), ()> {
535+
Ok(())
536+
}
537+
fn provided_node_features(&self) -> NodeFeatures {
538+
NodeFeatures::empty()
539+
}
540+
fn provided_init_features(&self, _: PublicKey) -> InitFeatures {
541+
InitFeatures::empty()
542+
}
543+
}
544+
545+
composite_custom_message_handler!(
546+
struct ReservedBlockComposite {
547+
proto: ReservedBlockHandler,
548+
}
549+
550+
enum ReservedBlockMessage {
551+
Proto(32768..=32777),
552+
}
553+
);
554+
555+
#[test]
556+
fn read_treats_a_reserved_in_range_type_as_unknown() {
557+
// A sub-handler may own a block of type ids (declared here as a range) yet only
558+
// decode the subset its build defines, returning `Ok(None)` for reserved or
559+
// not-yet-defined types in the block -- exactly what a node does on receiving a
560+
// newer peer's message. `read` must surface that as an unknown message, not
561+
// panic.
562+
let composite = ReservedBlockComposite { proto: ReservedBlockHandler };
563+
let mut buffer: &[u8] = &[];
564+
// The message this build defines decodes to its variant.
565+
assert!(matches!(
566+
composite.read(32768, &mut buffer),
567+
Ok(Some(ReservedBlockMessage::Proto(_)))
568+
));
569+
// A reserved type from the same block is reported unknown, not panicked
570+
// (pre-fix the matched arm hit `unreachable!()`).
571+
assert!(matches!(composite.read(32770, &mut buffer), Ok(None)));
572+
}
573+
504574
#[test]
505575
fn peer_connected_failure_does_not_leak_subhandler_state() {
506576
let composite = CompositeHandler {

0 commit comments

Comments
 (0)