diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b68d545ac3e..61df2601d92 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,7 +93,8 @@ jobs: # Could you use this to fake the coverage report for your PR? Sure. # Will anyone be impressed by your amazing coverage? No # Maybe if codecov wasn't broken we wouldn't need to do this... - ./codecov --verbose upload-process --disable-search --fail-on-error -f fuzz-codecov.json -t "f421b687-4dc2-4387-ac3d-dc3b2528af57" -F 'fuzzing' + ./codecov --verbose upload-process --disable-search --fail-on-error -f fuzz-fake-hashes-codecov.json -t "f421b687-4dc2-4387-ac3d-dc3b2528af57" -F 'fuzzing-fake-hashes' + ./codecov --verbose upload-process --disable-search --fail-on-error -f fuzz-real-hashes-codecov.json -t "f421b687-4dc2-4387-ac3d-dc3b2528af57" -F 'fuzzing-real-hashes' benchmark: runs-on: ubuntu-latest @@ -218,7 +219,8 @@ jobs: - name: Sanity check fuzz targets on Rust ${{ env.TOOLCHAIN }} run: | cd fuzz - cargo test --quiet --color always --lib --bins -j8 + RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" cargo test --manifest-path fuzz-fake-hashes/Cargo.toml --quiet --color always --bins -j8 + RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz" cargo test --manifest-path fuzz-real-hashes/Cargo.toml --quiet --color always --bins -j8 fuzz: runs-on: self-hosted diff --git a/ci/check-compiles.sh b/ci/check-compiles.sh index a067861fb56..cd1e0759c63 100755 --- a/ci/check-compiles.sh +++ b/ci/check-compiles.sh @@ -5,6 +5,10 @@ echo "Testing $(git log -1 --oneline)" cargo check cargo doc cargo doc --document-private-items -cd fuzz && RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" cargo check --features=stdin_fuzz +cd fuzz +RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" \ + cargo check --manifest-path fuzz-fake-hashes/Cargo.toml --features=stdin_fuzz +RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz" \ + cargo check --manifest-path fuzz-real-hashes/Cargo.toml --features=stdin_fuzz cd ../lightning && cargo check --no-default-features cd .. && RUSTC_BOOTSTRAP=1 RUSTFLAGS="--cfg=c_bindings" cargo check -Z avoid-dev-deps diff --git a/contrib/generate_fuzz_coverage.sh b/contrib/generate_fuzz_coverage.sh index 6be9956bbca..790fdb25f01 100755 --- a/contrib/generate_fuzz_coverage.sh +++ b/contrib/generate_fuzz_coverage.sh @@ -55,18 +55,37 @@ fi # Create output directory if it doesn't exist mkdir -p "$OUTPUT_DIR" +generate_coverage_report() { + local manifest_path="$1" + local output_path="$2" + local rustflags="$3" + + cargo llvm-cov clean --workspace + RUSTFLAGS="$rustflags" cargo llvm-cov --manifest-path "$manifest_path" --codecov \ + --dep-coverage lightning,lightning-invoice,lightning-liquidity,lightning-rapid-gossip-sync,lightning-persister \ + --no-default-ignore-filename-regex \ + --ignore-filename-regex "(\.cargo/registry|\.rustup/toolchains|/fuzz/)" \ + --output-path "$output_path" --tests +} + # dont run this command when running in CI if [ "$OUTPUT_CODECOV_JSON" = "0" ]; then - cargo llvm-cov --html \ + cargo llvm-cov clean --workspace + RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" \ + cargo llvm-cov --manifest-path fuzz-fake-hashes/Cargo.toml --html \ --dep-coverage lightning,lightning-invoice,lightning-liquidity,lightning-rapid-gossip-sync,lightning-persister \ --no-default-ignore-filename-regex \ --ignore-filename-regex "(\.cargo/registry|\.rustup/toolchains|/fuzz/)" \ - --output-dir "$OUTPUT_DIR" - echo "Coverage report generated in $OUTPUT_DIR/html/index.html" -else - # Clean previous coverage artifacts to ensure a fresh run. + --output-dir "$OUTPUT_DIR/fake-hashes" --tests cargo llvm-cov clean --workspace - + RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz" \ + cargo llvm-cov --manifest-path fuzz-real-hashes/Cargo.toml --html \ + --dep-coverage lightning,lightning-invoice,lightning-liquidity,lightning-rapid-gossip-sync,lightning-persister \ + --no-default-ignore-filename-regex \ + --ignore-filename-regex "(\.cargo/registry|\.rustup/toolchains|/fuzz/)" \ + --output-dir "$OUTPUT_DIR/real-hashes" --tests + echo "Coverage reports generated in $OUTPUT_DIR/fake-hashes and $OUTPUT_DIR/real-hashes" +else # Import honggfuzz corpus if the artifact was downloaded. if [ -d "hfuzz_workspace" ]; then echo "Importing corpus from hfuzz_workspace..." @@ -82,11 +101,14 @@ else fi echo "Replaying imported corpus (if found) via tests to generate coverage..." - cargo llvm-cov -j8 --codecov \ - --dep-coverage lightning,lightning-invoice,lightning-liquidity,lightning-rapid-gossip-sync,lightning-persister \ - --no-default-ignore-filename-regex \ - --ignore-filename-regex "(\.cargo/registry|\.rustup/toolchains|/fuzz/)" \ - --output-path "$OUTPUT_DIR/fuzz-codecov.json" --tests + generate_coverage_report \ + "fuzz-fake-hashes/Cargo.toml" \ + "$OUTPUT_DIR/fuzz-fake-hashes-codecov.json" \ + "--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" + generate_coverage_report \ + "fuzz-real-hashes/Cargo.toml" \ + "$OUTPUT_DIR/fuzz-real-hashes-codecov.json" \ + "--cfg=fuzzing --cfg=secp256k1_fuzz" - echo "Fuzz codecov report available at $OUTPUT_DIR/fuzz-codecov.json" + echo "Fuzz codecov reports available at $OUTPUT_DIR/fuzz-fake-hashes-codecov.json and $OUTPUT_DIR/fuzz-real-hashes-codecov.json" fi diff --git a/fc-crashes.md b/fc-crashes.md new file mode 100644 index 00000000000..a257e7966ba --- /dev/null +++ b/fc-crashes.md @@ -0,0 +1,162 @@ +# Force-close fuzzer LDK crashes + +Minimized crash sequences found by the chanmon_consistency fuzzer with +force-close support. All crashes are `debug_assert` or `panic!` inside +LDK, not in the fuzzer harness. Byte 0 encodes monitor styles (bits +0-2) and channel type (bits 3-4: 0=Legacy, 1=KeyedAnchors). + +## 1. channelmonitor.rs:2727 - HTLC input not found in transaction + +``` +debug_assert!(htlc_input_idx_opt.is_some()); +``` + +When resolving an HTLC spend, the monitor searches for the HTLC +outpoint in the spending transaction's inputs but doesn't find it. +Falls back to index 0 in release mode, which would produce incorrect +tracking. + +Minimized (17 bytes): +``` +0x40 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xdc 0xde 0xff +``` + +Byte 0 = 0x40: Legacy channels, no async monitors. The sequence is +mostly 0xff (settlement) repeated, with height advances (0xdc, 0xde) +near the end. This suggests the crash happens during settlement when +processing on-chain HTLC spends after repeated settlement attempts. + +## 2. onchaintx.rs:913 - Duplicate claim ID in pending requests + +``` +debug_assert!(self.pending_claim_requests.get(&claim_id).is_none()); +``` + +The OnchainTxHandler registers a claim event with a claim_id that +already exists in the pending_claim_requests map. + +Minimized (10 bytes): +``` +0x08 0xd2 0x70 0x70 0x71 0x70 0x10 0x19 0xde 0xff +``` + +Byte 0 = 0x08: KeyedAnchors channels, no async monitors. +- 0xd2: B force-closes the A-B channel +- 0x70/0x71: disconnect/reconnect peers +- 0x10, 0x19: process messages on nodes A and B +- 0xde: advance chain 200 blocks +- 0xff: settle + +B force-closes, peers disconnect and reconnect, messages are exchanged, +then height advances and settlement triggers the duplicate claim. + +## 3. onchaintx.rs:1025 - Inconsistent internal maps + +``` +panic!("Inconsistencies between pending_claim_requests map and claimable_outpoints map"); +``` + +The OnchainTxHandler detects that its `pending_claim_requests` and +`claimable_outpoints` maps are out of sync. + +Minimized (14 bytes): +``` +0x00 0x3c 0x11 0x19 0xd0 0xde 0xff 0xff 0x19 0x21 0x19 0xde 0x26 0xff +``` + +Byte 0 = 0x00: Legacy channels, all monitors completed. +- 0x3c: send hop payment A->B->C (1M msat) +- 0x11, 0x19: process messages to commit HTLC on A-B +- 0xd0: A force-closes A-B +- 0xde: advance 200 blocks +- 0xff: settle (first round) +- 0xff: settle again (second round, processes more messages) +- 0x19, 0x21, 0x19: continue processing B and C messages +- 0xde: advance 200 more blocks +- 0x26: process events on node C +- 0xff: settle (third round) + +A hop payment partially committed, then A force-closes. Multiple +settlement rounds with continued message processing in between triggers +the internal map inconsistency. + +## 4. test_channel_signer.rs:395 - Signing revoked commitment + +``` +panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={}") +``` + +The test channel signer is asked to sign an HTLC transaction for a +commitment number that has already been revoked. + +Minimized (18 bytes): +``` +0x22 0x71 0x71 0x71 0x71 0x71 0x71 0x71 0xff 0xff 0xff 0xff 0xff 0xff 0xde 0xde 0xb5 0xff +``` + +Byte 0 = 0x22: Legacy channels, async monitors on node B. +- 0x71: disconnect B-C peers (repeated, only first effective) +- 0xff: settle (repeated 6 times) +- 0xde 0xde: advance 400 blocks +- 0xb5: restart node B with alternate monitor state +- 0xff: settle + +Async monitors on B with peer disconnection, repeated settlements, +height advances, and a node restart with a different monitor state. +The stale monitor combined with the restart puts B's signer in a state +where it's asked to sign for an already-revoked commitment. + +## 5. channelmanager.rs:9836 - Payment blocker not found + +``` +debug_assert!(found_blocker); +``` + +During payment processing, the ChannelManager expects to find a +specific blocker entry for an in-flight payment but it's missing. + +Minimized (13 bytes): +``` +0x00 0x3c 0x11 0x19 0x11 0x1f 0x19 0x21 0x19 0x27 0x27 0xde 0xff +``` + +Byte 0 = 0x00: Legacy channels, all monitors completed. +- 0x3c: send hop A->B->C (1M msat) +- 0x11, 0x19, 0x11: commit HTLC on A-B +- 0x1f: B processes events (forwards HTLC to C) +- 0x19, 0x21, 0x19: commit HTLC on B-C +- 0x27, 0x27: C processes events (claims payment) +- 0xde: advance 200 blocks +- 0xff: settle + +A straightforward A->B->C hop payment that completes normally (C +claims), followed by a height advance and settlement. No force-close +in this sequence, so the height advance before settlement may cause +HTLC timeout processing that conflicts with the claim path. + +## 6. channelmanager.rs:19484 - Monitor update ID ordering violation + +``` +debug_assert!(update.update_id >= pending_update.update_id); +``` + +A ChannelMonitorUpdate has an update_id that is less than a pending +update's id, violating the expected monotonic ordering. + +Minimized (10 bytes): +``` +0x84 0x70 0x11 0x19 0x11 0x1f 0xd0 0x11 0x1f 0xba +``` + +Byte 0 = 0x84: Legacy channels, no async monitors, high bits set +(bits 3-4 = 0, bits 7 and 2 set). +- 0x70: disconnect A-B peers +- 0x11, 0x19, 0x11: process messages (likely reestablish after setup) +- 0x1f: process B events +- 0xd0: A force-closes A-B channel +- 0x11: process A messages +- 0x1f: process B events +- 0xba: restart node B with alternate monitor state + +A force-close followed by continued message/event processing and a +node B restart triggers a monitor update with an out-of-order ID. diff --git a/fuzz/.cargo/config.toml b/fuzz/.cargo/config.toml deleted file mode 100644 index 86513788566..00000000000 --- a/fuzz/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[build] -rustflags = ["--cfg=fuzzing", "--cfg=secp256k1_fuzz", "--cfg=hashes_fuzz"] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 252946be458..8cafdd1f2fb 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -4,18 +4,6 @@ version = "0.0.1" authors = ["Automatically generated"] publish = false 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. - -[package.metadata] -cargo-fuzz = true - -[features] -afl_fuzz = ["afl"] -honggfuzz_fuzz = ["honggfuzz"] -libfuzzer_fuzz = ["libfuzzer-sys"] -stdin_fuzz = [] [dependencies] lightning = { path = "../lightning", features = ["regex", "_test_utils"] } @@ -27,16 +15,9 @@ bech32 = "0.11.0" bitcoin = { version = "0.32.4", features = ["secp-lowmemory"] } tokio = { version = "~1.35", default-features = false, features = ["rt-multi-thread"] } -afl = { version = "0.12", optional = true } -honggfuzz = { version = "0.5", optional = true, default-features = false } -libfuzzer-sys = { version = "0.4", optional = true } - -[build-dependencies] -cc = "1.0" - # Prevent this from interfering with workspaces [workspace] -members = ["."] +members = [".", "fuzz-fake-hashes", "fuzz-real-hashes", "write-seeds"] [profile.release] panic = "abort" diff --git a/fuzz/FC-INFO.md b/fuzz/FC-INFO.md new file mode 100644 index 00000000000..3a83b8befb4 --- /dev/null +++ b/fuzz/FC-INFO.md @@ -0,0 +1,332 @@ +# Force-Close Fuzzing Notes + +This document captures the practical lessons from stabilizing force-close coverage in +`chanmon_consistency`. + +It is aimed at future changes to the harness, not at explaining force-close in Lightning +generally. + +## Goal + +The goal of force-close fuzzing here is: + +- exercise realistic off-chain to on-chain transitions +- keep races possible, but exceptional +- ensure the harness actually drives the system to resolution +- avoid spending most corpus coverage on harness-created nonsense + +The important distinction is: + +- a protocol race is useful +- a harness starvation artifact is mostly noise + +## What Realism Means Here + +For this harness, realistic means: + +- queued messages get a chance to move before huge chain jumps +- monitor updates complete in plausible places +- payment claims propagate before we declare everything timed out +- on-chain resolution follows the actual balances and broadcasts that exist + +What was unrealistic: + +- queue HTLC state changes +- skip delivery for many blocks +- jump height by 50, 100, or 200 in one shot +- then observe a timeout force-close everywhere + +That created lots of fake claim-vs-timeout races. + +## Main Harness Rules That Worked + +### 1. Drain progress around height advancement + +Large height jumps now advance one block at a time, with bounded progress draining before and +after each block. + +Why: + +- this gives queued off-chain state a chance to settle +- it keeps timeout races possible, but not dominant +- it is the smallest realism improvement that materially helped + +The key helper is `advance_chain_carefully!` in +[chanmon_consistency.rs](/Users/joost/repo/rust-lightning-fuzz-force-close/fuzz/src/chanmon_consistency.rs). + +### 2. Stop early if nothing actionable remains + +Blindly honoring a `+50` or `+200` block jump wastes time and creates noise. + +We now stop early when there is no pending work: + +- no peer-message backlog +- no broadcaster backlog +- no pending monitor updates +- no timed balances that still need height progress + +### 3. Distinguish timed work from passive confirmations + +`ClaimableAwaitingConfirmations` should not, by itself, keep the pre-advance drain alive. + +That balance means: + +- something already happened on-chain +- we are mostly waiting for confirmations + +It is not the same kind of "active timed work" as: + +- `ContentiousClaimable` +- `MaybeTimeoutClaimableHTLC` +- `MaybePreimageClaimableHTLC` +- `CounterpartyRevokedOutputClaimable` + +Treating `ClaimableAwaitingConfirmations` as active timed work caused settle churn. + +### 4. Reconcile harness bookkeeping with live node state + +The harness tracks `pending_payments`, but after restarts the real source of truth is the +`ChannelManager` state exposed by `list_recent_payments()`. + +Important lesson: + +- local caches in the harness can become stale across restart/replay flows +- final invariants should reflect live node state, not only local bookkeeping + +The harness now reconciles cached pending payments against `list_recent_payments()` before final +assertions. + +## Force-Close Specific Pitfalls + +### Announcement preference mismatch + +The trusted-peer open path can override `announce_for_forwarding`, while node defaults still prefer +announced channels. + +If `force_announced_channel_preference` remains enabled, channels can fail to open before the +fuzzer ever reaches force-close resolution. + +For this harness, keeping: + +- `force_announced_channel_preference = false` + +is necessary to preserve the intended force-close scenarios. + +### Startup replay ordering for closed channels + +On restart, a regenerated startup force-close update can coexist with older in-flight closed-channel +monitor updates. + +Watch out for: + +- assuming startup-generated force-close updates always have the highest update id + +That assumption was wrong. The correct behavior is: + +- do not assert on strict ordering +- if needed, renumber the regenerated update after the already-pending one +- drop duplicate force-close updates when one already exists + +This was fixed in +[channelmanager.rs](/Users/joost/repo/rust-lightning-fuzz-force-close/lightning/src/ln/channelmanager.rs). + +The in-tree reproducer for this is +[test_reload_handles_new_force_close_below_pending_closed_channel_update](/Users/joost/repo/rust-lightning-fuzz-force-close/lightning/src/ln/chanmon_update_fail_tests.rs:4657). + +What that test is actually proving: + +- the close update itself has already completed before restart +- the channel has already been removed from `channel_by_id` +- we reload against stale monitor bytes from before the close +- a later closed-channel update is still in flight + +The concrete update-id sequence in the reproducer is: + +- the stale serialized monitor is at update `2` +- the close update already completed at `3` +- a later closed-channel `PaymentPreimage` update is still in flight at `4` + +On reload, startup reconstructs two background events for the same closed channel: + +- a regenerated `ChannelForceClosed` update at `3`, derived from the stale monitor bytes +- the replayed in-flight preimage update at `4` + +The old merge logic assumed the newly generated close update could not be older than any already +pending update for that channel and asserted on that ordering before renumbering: + +```rust +debug_assert!(update.update_id >= pending_update.update_id); +``` + +That assumption is wrong in exactly this stale-monitor restart state. The current fix keeps the +deduplication for already-pending force-close replays, but otherwise preserves ascending +same-channel `update_id` order. In the concrete reproducer, startup applies the regenerated close +update `3` before replaying the later preimage update `4`. + +One subtlety matters here: + +- if the close update at `3` is also kept `InProgress`, startup sees an already-pending + force-close replay and deduplicates the regenerated close update + +That means "make update 3 stay pending too" masks this bug instead of disproving it. The failing +case is specifically: + +- close update `3` completed +- stale monitor still at `2` +- later closed-channel update `4` still pending + +### Wallet state must track confirmed transactions + +The harness uses a wallet source for bumping and external-funding claims. + +If confirmed transactions update `ChainState` but not the wallet view, then: + +- spent inputs may still look available +- change outputs may be missing +- rebroadcasted claim transactions can become nonsense + +That caused repeated claim rebroadcasts and fake non-quiescence. + +The wallet must be kept in sync with: + +- confirmed spends +- newly created change outputs + +### Child-before-parent vs stale conflicting broadcasts + +Not every failed confirmation should be retried forever. + +Two distinct cases exist: + +1. Child-before-parent +- retrying later is correct + +2. Stale conflicting commitment or claim tx +- retrying forever is wrong + +The confirmation drain must: + +- retry deferred transactions while something in the batch still makes progress +- only keep transactions that could become valid later +- drop permanently invalid stale conflicts + +## Signature and Weight Lessons Under Fuzzing + +Two fuzz-specific adjustments were necessary and appear justified: + +### Skip low-R grinding under fuzzing + +Under `cfg(fuzzing)` and `cfg(secp256k1_fuzz)`, signature generation can behave unlike production. + +If low-R grinding stays enabled, signing can become pathologically expensive or effectively stall. + +So under fuzzing: + +- use plain signing, not low-R grinding + +This keeps the path under test while avoiding artificial hangs. + +### Relax signed-weight debug assertions under fuzzing + +Signed transaction weight depends on signature sizes. + +Under fuzzing, signature-size assumptions no longer match production distributions reliably. + +So fuzz-only relaxation of "actual signed weight must not exceed estimate" assertions is reasonable. + +This should stay fuzz-only. + +## What To Preserve + +If you change the force-close harness, preserve these behaviors: + +- per-block draining around large height advances +- bounded settle loops with actionable assertions +- wallet synchronization with confirmed transactions +- reconciliation of cached payment bookkeeping against live node state +- startup replay handling for closed-channel monitor updates +- fuzz-only signing and weight accommodations + +These were all required to get the corpus stable. + +## What To Be Careful About + +### Do not overuse global modes + +A mode system was considered, but the harness improved enough without it. + +The current approach is better: + +- keep the opcode space broad +- add realism locally where it matters +- drive settlement more carefully + +That preserves coverage without over-structuring the fuzzer. + +### Do not make late-claim races impossible + +The harness should strongly prefer realistic progress before timeouts, but it should not make +late-claim races impossible. + +The right balance is: + +- default behavior is realistic claim propagation +- rare races still happen because of interleavings, async monitor behavior, and restart timing + +### Do not assume pending payments imply unresolved protocol state + +Sometimes they do. + +Sometimes they are just stale harness bookkeeping after restart and replay. + +Always check: + +- message queues +- monitor updates +- claimable balances +- broadcaster state +- live `list_recent_payments()` + +before concluding a payment is truly stuck. + +### Do not reintroduce big blind height jumps + +This is the easiest way to make the corpus noisy again. + +If height advancement changes, keep asking: + +- are we giving off-chain state a fair chance before timing HTLCs out? + +## Good Debugging Workflow + +When force-close fuzzing regresses: + +1. Run the corpus with `fuzz-runner`. +2. Isolate one failing case. +3. Check whether the failure is: + - real protocol or restart ordering + - stale harness bookkeeping + - wallet/view desynchronization + - over-broad settle criteria +4. Prefer fixing harness realism before adding more timeouts or more iterations. +5. Re-run the isolated case, then the full corpus. + +The runner lives in `~/repo/rl-tools/fuzz-runner` now. +Use `~/repo/rl-tools/run_fuzz_runner.sh` from any directory inside a +rust-lightning checkout. + +## Current Stable Verification + +The key verification command is: + +```bash +~/repo/rl-tools/run_fuzz_runner.sh --timeout-secs 20 +``` + +At the time these notes were written, the full corpus completed with: + +- `ok: 366` +- `failed: 0` +- `timed_out: 0` + +That should be rechecked after any meaningful force-close harness change. diff --git a/fuzz/README.md b/fuzz/README.md index 4af70390d7d..e4bd3b49ca4 100644 --- a/fuzz/README.md +++ b/fuzz/README.md @@ -10,6 +10,11 @@ configured for. Fuzzing is further only effective with a lot of CPU time, indica scenarios are discovered on CI with its low runtime constraints, the crash is caused relatively easily. +The `fuzz/` directory now contains three crates: +- `fuzz/`, the shared fuzz target logic and corpus directories +- `fuzz/fuzz-fake-hashes`, the fuzz targets that require `--cfg=hashes_fuzz` +- `fuzz/fuzz-real-hashes`, the real-hashes fuzz targets, currently `chanmon_consistency_target` + ## How do I run fuzz tests locally? We support multiple fuzzing engines such as `honggfuzz`, `libFuzzer` and `AFL`. You typically won't @@ -47,34 +52,45 @@ cargo install --force cargo-fuzz To run fuzzing using `honggfuzz`, do ```shell +cd fuzz export CPU_COUNT=1 # replace as needed export HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz" export HFUZZ_RUN_ARGS="-n $CPU_COUNT --exit_upon_crash" export TARGET="msg_ping_target" # replace with the target to be fuzzed -cargo hfuzz run $TARGET +export RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" +cargo hfuzz run --manifest-path fuzz-fake-hashes/Cargo.toml $TARGET ``` -(Or, for a prettier output, replace the last line with `cargo --color always hfuzz run $TARGET`.) +(For `fuzz-real-hashes`, use +`RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz" cargo hfuzz run --manifest-path fuzz-real-hashes/Cargo.toml chanmon_consistency_target`.) +For a prettier output, replace the last line with +`cargo --color always hfuzz run --manifest-path fuzz-fake-hashes/Cargo.toml $TARGET`. #### cargo-fuzz / libFuzzer To run fuzzing using `cargo-fuzz / libFuzzer`, run ```shell rustup install nightly # Note: libFuzzer requires a nightly version of rust. +cd fuzz export RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" -cargo +nightly fuzz run --features "libfuzzer_fuzz" msg_ping_target +cargo +nightly fuzz run --manifest-path fuzz-fake-hashes/Cargo.toml --features "libfuzzer_fuzz" msg_ping_target ``` Note: If you encounter a `SIGKILL` during run/build check for OOM in kernel logs and consider increasing RAM size for VM. +For `fuzz-real-hashes`, use +`RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz" cargo +nightly fuzz run --manifest-path fuzz-real-hashes/Cargo.toml --features "libfuzzer_fuzz" chanmon_consistency_target`. + ##### Fast builds for development The default build uses LTO and single codegen unit, which is slow. For faster iteration during development, use the `-D` (dev) flag: ```shell -cargo +nightly fuzz run --features "libfuzzer_fuzz" -D msg_ping_target +cd fuzz +RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" \ + cargo +nightly fuzz run --manifest-path fuzz-fake-hashes/Cargo.toml --features "libfuzzer_fuzz" -D msg_ping_target ``` The `-D` flag builds in development mode with faster compilation (still has optimizations via @@ -83,7 +99,9 @@ sanitizer instrumentation, but subsequent builds will be fast. If you wish to just generate fuzzing binary executables for `libFuzzer` and not run them: ```shell -cargo +nightly fuzz build --features "libfuzzer_fuzz" msg_ping_target +cd fuzz +RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" \ + cargo +nightly fuzz build --manifest-path fuzz-fake-hashes/Cargo.toml --features "libfuzzer_fuzz" msg_ping_target # Generates binary artifact in path ./target/aarch64-unknown-linux-gnu/release/msg_ping_target # Exact path depends on your system architecture. ``` @@ -93,7 +111,8 @@ You can upload the build artifact generated above to `ClusterFuzz` for distribut To see a list of available fuzzing targets, run: ```shell -ls ./src/bin/ +ls ./fuzz-fake-hashes/src/bin/ +ls ./fuzz-real-hashes/src/bin/ ``` ## A fuzz test failed, what do I do? @@ -134,7 +153,8 @@ mkdir -p ./test_cases/$TARGET echo $HEX | xxd -r -p > ./test_cases/$TARGET/any_filename_works export RUST_BACKTRACE=1 -cargo test +RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" \ + cargo test --manifest-path fuzz-fake-hashes/Cargo.toml --bin "${TARGET}_target" ``` Note that if the fuzz test failed locally, moving the offending run's trace @@ -151,7 +171,10 @@ Alternatively, you can use the `stdin_fuzz` feature to pipe the crash input dire creating test case files on disk: ```shell -echo -ne '\x2d\x31\x36\x38\x37\x34\x09\x01...' | cargo run --features stdin_fuzz --bin full_stack_target +cd fuzz +echo -ne '\x2d\x31\x36\x38\x37\x34\x09\x01...' | \ + RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" \ + cargo run --manifest-path fuzz-fake-hashes/Cargo.toml --features stdin_fuzz --bin full_stack_target ``` Panics will abort the process directly (the crate uses `panic = "abort"`), resulting in a @@ -171,10 +194,13 @@ file are `do_test`, `my_fuzzy_experiment_test`, and `my_fuzzy_experiment_run`. 3. Adjust the body (not the signature!) of `do_test` as necessary for the new fuzz test. -4. In `fuzz/src/bin/gen_target.sh`, add a line reading `GEN_TEST my_fuzzy_experiment` to the -first group of `GEN_TEST` lines (starting in line 9). +4. In `fuzz/src/bin/gen_target.sh`, add a line reading `GEN_FAKE_HASHES_TEST my_fuzzy_experiment` +to the appropriate target list. Use `GEN_REAL_HASHES_TEST` only for targets that must run without +`hashes_fuzz`. 5. If your test relies on a new local crate, add that crate as a dependency to `fuzz/Cargo.toml`. +If the dependency is only needed by a specific runner crate or fuzz engine setup, add it to the +matching target crate under `fuzz/fuzz-fake-hashes/Cargo.toml` or `fuzz/fuzz-real-hashes/Cargo.toml` instead. 6. In `fuzz/src/lib.rs`, add the line `pub mod my_fuzzy_experiment`. Additionally, if you added a new crate dependency, add the `extern crate […]` import line. diff --git a/fuzz/ci-fuzz.sh b/fuzz/ci-fuzz.sh index 47bf41ba620..3fc206bd0ee 100755 --- a/fuzz/ci-fuzz.sh +++ b/fuzz/ci-fuzz.sh @@ -8,16 +8,16 @@ rm msg_*.rs [ "$(git diff)" != "" ] && exit 1 popd pushd src/bin -rm *_target.rs +rm -f ../../fuzz-fake-hashes/src/bin/*_target.rs ../../fuzz-real-hashes/src/bin/*_target.rs ./gen_target.sh [ "$(git diff)" != "" ] && exit 1 popd -export RUSTFLAGS="--cfg=secp256k1_fuzz --cfg=hashes_fuzz" +export RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" mkdir -p hfuzz_workspace/full_stack_target/input pushd write-seeds -RUSTFLAGS="$RUSTFLAGS --cfg=fuzzing" cargo run ../hfuzz_workspace/full_stack_target/input +cargo run ../hfuzz_workspace/full_stack_target/input cargo clean popd @@ -27,57 +27,70 @@ cargo install --color always --force honggfuzz --no-default-features # compiler optimizations aren't necessary, so we turn off LTO sed -i 's/lto = true//' Cargo.toml -export HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz" - -cargo --color always hfuzz build -j8 - SUMMARY="" check_crash() { - local FILE=$1 - if [ -f "hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT" ]; then - cat "hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT" - for CASE in "hfuzz_workspace/$FILE"/SIG*; do + local WORKSPACE_DIR=$1 + local FILE=$2 + if [ -f "$WORKSPACE_DIR/$FILE/HONGGFUZZ.REPORT.TXT" ]; then + cat "$WORKSPACE_DIR/$FILE/HONGGFUZZ.REPORT.TXT" + for CASE in "$WORKSPACE_DIR/$FILE"/SIG*; do cat "$CASE" | xxd -p done exit 1 fi } -for TARGET in src/bin/*.rs; do - FILENAME=$(basename $TARGET) - FILE="${FILENAME%.*}" - CORPUS_DIR="hfuzz_workspace/$FILE/input" - CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l) - # Run 8x the corpus size plus a baseline, ensuring full corpus replay - # with room for new mutations. The 10-minute hard cap (--run_time 600) - # prevents slow-per-iteration targets from running too long. - ITERATIONS=$((CORPUS_COUNT * 8 + 1000)) - HFUZZ_RUN_ARGS="--exit_upon_crash -q -n8 -t 3 -N $ITERATIONS --run_time 600" - if [ "$FILE" = "chanmon_consistency_target" -o "$FILE" = "fs_store_target" ]; then - HFUZZ_RUN_ARGS="$HFUZZ_RUN_ARGS -F 64" - fi - export HFUZZ_RUN_ARGS - FUZZ_START=$(date +%s) - cargo --color always hfuzz run $FILE - FUZZ_END=$(date +%s) - FUZZ_TIME=$((FUZZ_END - FUZZ_START)) - FUZZ_CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l) - check_crash "$FILE" - if [ "$GITHUB_REF" = "refs/heads/main" ] || [ "$FUZZ_MINIMIZE" = "true" ]; then - HFUZZ_RUN_ARGS="-M -q -n8 -t 3" +run_targets() { + local CRATE_DIR=$1 + local TARGET_RUSTFLAGS=$2 + + pushd "$CRATE_DIR" + export HFUZZ_WORKSPACE="../hfuzz_workspace" + export HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz" + export RUSTFLAGS="$TARGET_RUSTFLAGS" + cargo --color always hfuzz build -j8 + + for TARGET in src/bin/*.rs; do + FILENAME=$(basename "$TARGET") + FILE="${FILENAME%.*}" + CORPUS_DIR="$HFUZZ_WORKSPACE/$FILE/input" + CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l) + # Run 8x the corpus size plus a baseline, ensuring full corpus replay + # with room for new mutations. The 10-minute hard cap (--run_time 600) + # prevents slow-per-iteration targets from running too long. + ITERATIONS=$((CORPUS_COUNT * 8 + 1000)) + HFUZZ_RUN_ARGS="--exit_upon_crash -q -n8 -t 3 -N $ITERATIONS --run_time 600" + if [ "$FILE" = "chanmon_consistency_target" -o "$FILE" = "fs_store_target" ]; then + HFUZZ_RUN_ARGS="$HFUZZ_RUN_ARGS -F 64" + fi export HFUZZ_RUN_ARGS - MIN_START=$(date +%s) - cargo --color always hfuzz run $FILE - MIN_END=$(date +%s) - MIN_TIME=$((MIN_END - MIN_START)) - MIN_CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l) - check_crash "$FILE" - SUMMARY="${SUMMARY}${FILE}|${ITERATIONS}|${CORPUS_COUNT}|${FUZZ_CORPUS_COUNT}|${FUZZ_TIME}|${MIN_CORPUS_COUNT}|${MIN_TIME}\n" - else - SUMMARY="${SUMMARY}${FILE}|${ITERATIONS}|${CORPUS_COUNT}|${FUZZ_CORPUS_COUNT}|${FUZZ_TIME}|-|-\n" - fi -done + FUZZ_START=$(date +%s) + cargo --color always hfuzz run "$FILE" + FUZZ_END=$(date +%s) + FUZZ_TIME=$((FUZZ_END - FUZZ_START)) + FUZZ_CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l) + check_crash "$HFUZZ_WORKSPACE" "$FILE" + if [ "$GITHUB_REF" = "refs/heads/main" ] || [ "$FUZZ_MINIMIZE" = "true" ]; then + HFUZZ_RUN_ARGS="-M -q -n8 -t 3" + export HFUZZ_RUN_ARGS + MIN_START=$(date +%s) + cargo --color always hfuzz run "$FILE" + MIN_END=$(date +%s) + MIN_TIME=$((MIN_END - MIN_START)) + MIN_CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l) + check_crash "$HFUZZ_WORKSPACE" "$FILE" + SUMMARY="${SUMMARY}${FILE}|${ITERATIONS}|${CORPUS_COUNT}|${FUZZ_CORPUS_COUNT}|${FUZZ_TIME}|${MIN_CORPUS_COUNT}|${MIN_TIME}\n" + else + SUMMARY="${SUMMARY}${FILE}|${ITERATIONS}|${CORPUS_COUNT}|${FUZZ_CORPUS_COUNT}|${FUZZ_TIME}|-|-\n" + fi + done + + popd +} + +run_targets fuzz-fake-hashes "--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" +run_targets fuzz-real-hashes "--cfg=fuzzing --cfg=secp256k1_fuzz" fmt_time() { local secs=$1 diff --git a/fuzz/fails.zip b/fuzz/fails.zip new file mode 100644 index 00000000000..41f12dbec2f Binary files /dev/null and b/fuzz/fails.zip differ diff --git a/fuzz/fuzz-fake-hashes/Cargo.toml b/fuzz/fuzz-fake-hashes/Cargo.toml new file mode 100644 index 00000000000..d027540a056 --- /dev/null +++ b/fuzz/fuzz-fake-hashes/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "lightning-fuzz-fake-hashes" +version = "0.0.1" +authors = ["Automatically generated"] +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[features] +afl_fuzz = ["afl"] +honggfuzz_fuzz = ["honggfuzz"] +libfuzzer_fuzz = ["libfuzzer-sys"] +stdin_fuzz = [] + +[dependencies] +lightning-fuzz = { path = ".." } + +afl = { version = "0.12", optional = true } +honggfuzz = { version = "0.5", optional = true, default-features = false } +libfuzzer-sys = { version = "0.4", optional = true } + +[lints.rust.unexpected_cfgs] +level = "forbid" +# When adding a new cfg attribute, ensure that it is added to this list. +check-cfg = [ + "cfg(fuzzing)", + "cfg(secp256k1_fuzz)", + "cfg(hashes_fuzz)", +] diff --git a/fuzz/src/bin/base32_target.rs b/fuzz/fuzz-fake-hashes/src/bin/base32_target.rs similarity index 95% rename from fuzz/src/bin/base32_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/base32_target.rs index e79e6db7380..e3cd1a66dd2 100644 --- a/fuzz/src/bin/base32_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/base32_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - base32_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + base32_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/base32") { + if let Ok(tests) = fs::read_dir("../test_cases/base32") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/bech32_parse_target.rs b/fuzz/fuzz-fake-hashes/src/bin/bech32_parse_target.rs similarity index 95% rename from fuzz/src/bin/bech32_parse_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/bech32_parse_target.rs index f9493bb1bc1..226ff19c472 100644 --- a/fuzz/src/bin/bech32_parse_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/bech32_parse_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - bech32_parse_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + bech32_parse_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } 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") { + if let Ok(tests) = fs::read_dir("../test_cases/bech32_parse") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/bolt11_deser_target.rs b/fuzz/fuzz-fake-hashes/src/bin/bolt11_deser_target.rs similarity index 95% rename from fuzz/src/bin/bolt11_deser_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/bolt11_deser_target.rs index 28b1e2db679..befa78fc105 100644 --- a/fuzz/src/bin/bolt11_deser_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/bolt11_deser_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - bolt11_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + bolt11_deser_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/bolt11_deser") { + if let Ok(tests) = fs::read_dir("../test_cases/bolt11_deser") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/chanmon_deser_target.rs b/fuzz/fuzz-fake-hashes/src/bin/chanmon_deser_target.rs similarity index 95% rename from fuzz/src/bin/chanmon_deser_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/chanmon_deser_target.rs index d3cf30b86e3..259f9d36ad2 100644 --- a/fuzz/src/bin/chanmon_deser_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/chanmon_deser_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - chanmon_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + chanmon_deser_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/chanmon_deser") { + if let Ok(tests) = fs::read_dir("../test_cases/chanmon_deser") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/feature_flags_target.rs b/fuzz/fuzz-fake-hashes/src/bin/feature_flags_target.rs similarity index 95% rename from fuzz/src/bin/feature_flags_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/feature_flags_target.rs index b1f35f8820f..d54bba994e8 100644 --- a/fuzz/src/bin/feature_flags_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/feature_flags_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - feature_flags_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + feature_flags_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/feature_flags") { + if let Ok(tests) = fs::read_dir("../test_cases/feature_flags") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/fromstr_to_netaddress_target.rs b/fuzz/fuzz-fake-hashes/src/bin/fromstr_to_netaddress_target.rs similarity index 94% rename from fuzz/src/bin/fromstr_to_netaddress_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/fromstr_to_netaddress_target.rs index 8f3e5c3dc7f..94cedd91157 100644 --- a/fuzz/src/bin/fromstr_to_netaddress_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/fromstr_to_netaddress_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - fromstr_to_netaddress_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + fromstr_to_netaddress_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/fromstr_to_netaddress") { + if let Ok(tests) = fs::read_dir("../test_cases/fromstr_to_netaddress") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/fs_store_target.rs b/fuzz/fuzz-fake-hashes/src/bin/fs_store_target.rs similarity index 95% rename from fuzz/src/bin/fs_store_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/fs_store_target.rs index 8d84aad7b6b..e34cab13def 100644 --- a/fuzz/src/bin/fs_store_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/fs_store_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - fs_store_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + fs_store_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/fs_store") { + if let Ok(tests) = fs::read_dir("../test_cases/fs_store") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/full_stack_target.rs b/fuzz/fuzz-fake-hashes/src/bin/full_stack_target.rs similarity index 95% rename from fuzz/src/bin/full_stack_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/full_stack_target.rs index c1f20b10af4..81a49776b4b 100644 --- a/fuzz/src/bin/full_stack_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/full_stack_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - full_stack_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + full_stack_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/full_stack") { + if let Ok(tests) = fs::read_dir("../test_cases/full_stack") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/gossip_discovery_target.rs b/fuzz/fuzz-fake-hashes/src/bin/gossip_discovery_target.rs similarity index 95% rename from fuzz/src/bin/gossip_discovery_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/gossip_discovery_target.rs index 960ba80ec8c..470ad17fe26 100644 --- a/fuzz/src/bin/gossip_discovery_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/gossip_discovery_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - gossip_discovery_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + gossip_discovery_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/gossip_discovery") { + if let Ok(tests) = fs::read_dir("../test_cases/gossip_discovery") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/indexedmap_target.rs b/fuzz/fuzz-fake-hashes/src/bin/indexedmap_target.rs similarity index 95% rename from fuzz/src/bin/indexedmap_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/indexedmap_target.rs index 3bc4390fee4..e8d7626a238 100644 --- a/fuzz/src/bin/indexedmap_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/indexedmap_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - indexedmap_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + indexedmap_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/indexedmap") { + if let Ok(tests) = fs::read_dir("../test_cases/indexedmap") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/invoice_deser_target.rs b/fuzz/fuzz-fake-hashes/src/bin/invoice_deser_target.rs similarity index 95% rename from fuzz/src/bin/invoice_deser_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/invoice_deser_target.rs index 44bf1851a40..c1338f62e0e 100644 --- a/fuzz/src/bin/invoice_deser_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/invoice_deser_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - invoice_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + invoice_deser_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } 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") { + if let Ok(tests) = fs::read_dir("../test_cases/invoice_deser") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/invoice_request_deser_target.rs b/fuzz/fuzz-fake-hashes/src/bin/invoice_request_deser_target.rs similarity index 94% rename from fuzz/src/bin/invoice_request_deser_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/invoice_request_deser_target.rs index 06d8f87fa55..2198b64b207 100644 --- a/fuzz/src/bin/invoice_request_deser_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/invoice_request_deser_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - invoice_request_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + invoice_request_deser_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } 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") { + if let Ok(tests) = fs::read_dir("../test_cases/invoice_request_deser") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/lsps_message_target.rs b/fuzz/fuzz-fake-hashes/src/bin/lsps_message_target.rs similarity index 95% rename from fuzz/src/bin/lsps_message_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/lsps_message_target.rs index 37e6f103fb4..68e1c8b0e06 100644 --- a/fuzz/src/bin/lsps_message_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/lsps_message_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - lsps_message_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + lsps_message_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/lsps_message") { + if let Ok(tests) = fs::read_dir("../test_cases/lsps_message") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_accept_channel_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_accept_channel_target.rs similarity index 95% rename from fuzz/src/bin/msg_accept_channel_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_accept_channel_target.rs index ee08a5fc344..798e2d9e5aa 100644 --- a/fuzz/src/bin/msg_accept_channel_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_accept_channel_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_accept_channel_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_accept_channel_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_accept_channel") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_accept_channel") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_accept_channel_v2_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_accept_channel_v2_target.rs similarity index 94% rename from fuzz/src/bin/msg_accept_channel_v2_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_accept_channel_v2_target.rs index 2903e111f56..eff73d11ded 100644 --- a/fuzz/src/bin/msg_accept_channel_v2_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_accept_channel_v2_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_accept_channel_v2_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_accept_channel_v2_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_accept_channel_v2") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_accept_channel_v2") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_announcement_signatures_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_announcement_signatures_target.rs similarity index 94% rename from fuzz/src/bin/msg_announcement_signatures_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_announcement_signatures_target.rs index 064880abc18..09b76396873 100644 --- a/fuzz/src/bin/msg_announcement_signatures_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_announcement_signatures_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_announcement_signatures_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_announcement_signatures_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_announcement_signatures") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_announcement_signatures") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_blinded_message_path_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_blinded_message_path_target.rs similarity index 94% rename from fuzz/src/bin/msg_blinded_message_path_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_blinded_message_path_target.rs index 277e04c9656..92c0976dc79 100644 --- a/fuzz/src/bin/msg_blinded_message_path_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_blinded_message_path_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_blinded_message_path_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_blinded_message_path_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_blinded_message_path") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_blinded_message_path") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_channel_announcement_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_channel_announcement_target.rs similarity index 94% rename from fuzz/src/bin/msg_channel_announcement_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_channel_announcement_target.rs index 42e72d54b72..482dbbc4345 100644 --- a/fuzz/src/bin/msg_channel_announcement_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_channel_announcement_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_channel_announcement_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_channel_announcement_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } 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_announcement") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_channel_announcement") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_channel_details_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_channel_details_target.rs similarity index 94% rename from fuzz/src/bin/msg_channel_details_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_channel_details_target.rs index a03a7a44920..04af6755917 100644 --- a/fuzz/src/bin/msg_channel_details_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_channel_details_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_channel_details_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_channel_details_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } 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") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_channel_details") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_channel_ready_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_channel_ready_target.rs similarity index 95% rename from fuzz/src/bin/msg_channel_ready_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_channel_ready_target.rs index a0457815036..34511509f39 100644 --- a/fuzz/src/bin/msg_channel_ready_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_channel_ready_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_channel_ready_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_channel_ready_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } 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_ready") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_channel_ready") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_channel_reestablish_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_channel_reestablish_target.rs similarity index 94% rename from fuzz/src/bin/msg_channel_reestablish_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_channel_reestablish_target.rs index b5449a90e37..0541cedafe2 100644 --- a/fuzz/src/bin/msg_channel_reestablish_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_channel_reestablish_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_channel_reestablish_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_channel_reestablish_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } 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_reestablish") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_channel_reestablish") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_channel_update_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_channel_update_target.rs similarity index 95% rename from fuzz/src/bin/msg_channel_update_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_channel_update_target.rs index 9feb6e6c6b4..7d08ee24005 100644 --- a/fuzz/src/bin/msg_channel_update_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_channel_update_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_channel_update_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_channel_update_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } 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_update") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_channel_update") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_closing_complete_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_closing_complete_target.rs similarity index 94% rename from fuzz/src/bin/msg_closing_complete_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_closing_complete_target.rs index 22dd97c79c9..7bcb76d2fbd 100644 --- a/fuzz/src/bin/msg_closing_complete_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_closing_complete_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_closing_complete_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_closing_complete_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_closing_complete") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_closing_complete") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_closing_sig_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_closing_sig_target.rs similarity index 95% rename from fuzz/src/bin/msg_closing_sig_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_closing_sig_target.rs index 26058a5277d..54669e259c3 100644 --- a/fuzz/src/bin/msg_closing_sig_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_closing_sig_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_closing_sig_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_closing_sig_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_closing_sig") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_closing_sig") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_closing_signed_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_closing_signed_target.rs similarity index 95% rename from fuzz/src/bin/msg_closing_signed_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_closing_signed_target.rs index 94408bc2ba9..f5813a7919d 100644 --- a/fuzz/src/bin/msg_closing_signed_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_closing_signed_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_closing_signed_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_closing_signed_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_closing_signed") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_closing_signed") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_commitment_signed_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_commitment_signed_target.rs similarity index 94% rename from fuzz/src/bin/msg_commitment_signed_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_commitment_signed_target.rs index e8987848417..a62449b1673 100644 --- a/fuzz/src/bin/msg_commitment_signed_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_commitment_signed_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_commitment_signed_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_commitment_signed_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_commitment_signed") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_commitment_signed") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_decoded_onion_error_packet_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_decoded_onion_error_packet_target.rs similarity index 94% rename from fuzz/src/bin/msg_decoded_onion_error_packet_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_decoded_onion_error_packet_target.rs index 47d8970b453..75e37116d79 100644 --- a/fuzz/src/bin/msg_decoded_onion_error_packet_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_decoded_onion_error_packet_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_decoded_onion_error_packet_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_decoded_onion_error_packet_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_decoded_onion_error_packet") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_decoded_onion_error_packet") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_error_message_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_error_message_target.rs similarity index 95% rename from fuzz/src/bin/msg_error_message_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_error_message_target.rs index ee3904a724e..23c9524478d 100644 --- a/fuzz/src/bin/msg_error_message_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_error_message_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_error_message_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_error_message_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_error_message") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_error_message") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_funding_created_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_funding_created_target.rs similarity index 94% rename from fuzz/src/bin/msg_funding_created_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_funding_created_target.rs index 028aa17ad8a..c423e6e9c24 100644 --- a/fuzz/src/bin/msg_funding_created_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_funding_created_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_funding_created_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_funding_created_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_funding_created") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_funding_created") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_funding_signed_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_funding_signed_target.rs similarity index 95% rename from fuzz/src/bin/msg_funding_signed_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_funding_signed_target.rs index 4894c66df0b..de10f0e71dc 100644 --- a/fuzz/src/bin/msg_funding_signed_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_funding_signed_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_funding_signed_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_funding_signed_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_funding_signed") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_funding_signed") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_gossip_timestamp_filter_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_gossip_timestamp_filter_target.rs similarity index 94% rename from fuzz/src/bin/msg_gossip_timestamp_filter_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_gossip_timestamp_filter_target.rs index 6da383b2e6f..cef5bc576c2 100644 --- a/fuzz/src/bin/msg_gossip_timestamp_filter_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_gossip_timestamp_filter_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_gossip_timestamp_filter_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_gossip_timestamp_filter_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_gossip_timestamp_filter") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_gossip_timestamp_filter") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_init_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_init_target.rs similarity index 95% rename from fuzz/src/bin/msg_init_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_init_target.rs index f1d17c99289..7e51e6e63e5 100644 --- a/fuzz/src/bin/msg_init_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_init_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_init_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_init_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_init") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_init") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_node_announcement_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_node_announcement_target.rs similarity index 94% rename from fuzz/src/bin/msg_node_announcement_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_node_announcement_target.rs index b0615f3c5e5..c7aaecb644a 100644 --- a/fuzz/src/bin/msg_node_announcement_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_node_announcement_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_node_announcement_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_node_announcement_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_node_announcement") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_node_announcement") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_open_channel_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_open_channel_target.rs similarity index 95% rename from fuzz/src/bin/msg_open_channel_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_open_channel_target.rs index b3dbf388c08..bb49be7d994 100644 --- a/fuzz/src/bin/msg_open_channel_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_open_channel_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_open_channel_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_open_channel_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_open_channel") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_open_channel") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_open_channel_v2_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_open_channel_v2_target.rs similarity index 94% rename from fuzz/src/bin/msg_open_channel_v2_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_open_channel_v2_target.rs index 0df11adf32e..a6d45dc3a45 100644 --- a/fuzz/src/bin/msg_open_channel_v2_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_open_channel_v2_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_open_channel_v2_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_open_channel_v2_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_open_channel_v2") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_open_channel_v2") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_ping_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_ping_target.rs similarity index 95% rename from fuzz/src/bin/msg_ping_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_ping_target.rs index 48f855985de..70bb751c594 100644 --- a/fuzz/src/bin/msg_ping_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_ping_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_ping_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_ping_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_ping") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_ping") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_pong_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_pong_target.rs similarity index 95% rename from fuzz/src/bin/msg_pong_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_pong_target.rs index 434e9cfe310..74df6d86474 100644 --- a/fuzz/src/bin/msg_pong_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_pong_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_pong_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_pong_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_pong") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_pong") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_query_channel_range_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_query_channel_range_target.rs similarity index 94% rename from fuzz/src/bin/msg_query_channel_range_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_query_channel_range_target.rs index cb87260e1ef..e497491083f 100644 --- a/fuzz/src/bin/msg_query_channel_range_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_query_channel_range_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_query_channel_range_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_query_channel_range_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_query_channel_range") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_query_channel_range") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_query_short_channel_ids_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_query_short_channel_ids_target.rs similarity index 94% rename from fuzz/src/bin/msg_query_short_channel_ids_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_query_short_channel_ids_target.rs index bc286a7e523..31169f9e665 100644 --- a/fuzz/src/bin/msg_query_short_channel_ids_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_query_short_channel_ids_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_query_short_channel_ids_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_query_short_channel_ids_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_query_short_channel_ids") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_query_short_channel_ids") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_reply_channel_range_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_reply_channel_range_target.rs similarity index 94% rename from fuzz/src/bin/msg_reply_channel_range_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_reply_channel_range_target.rs index c7df076c6c6..a0aaadf321d 100644 --- a/fuzz/src/bin/msg_reply_channel_range_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_reply_channel_range_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_reply_channel_range_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_reply_channel_range_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_reply_channel_range") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_reply_channel_range") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_reply_short_channel_ids_end_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_reply_short_channel_ids_end_target.rs similarity index 94% rename from fuzz/src/bin/msg_reply_short_channel_ids_end_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_reply_short_channel_ids_end_target.rs index 2c73d866bd9..8931538e4f5 100644 --- a/fuzz/src/bin/msg_reply_short_channel_ids_end_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_reply_short_channel_ids_end_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_reply_short_channel_ids_end_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_reply_short_channel_ids_end_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_reply_short_channel_ids_end") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_reply_short_channel_ids_end") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_revoke_and_ack_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_revoke_and_ack_target.rs similarity index 95% rename from fuzz/src/bin/msg_revoke_and_ack_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_revoke_and_ack_target.rs index 6379d39591f..6ed40d3ab91 100644 --- a/fuzz/src/bin/msg_revoke_and_ack_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_revoke_and_ack_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_revoke_and_ack_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_revoke_and_ack_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_revoke_and_ack") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_revoke_and_ack") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_shutdown_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_shutdown_target.rs similarity index 95% rename from fuzz/src/bin/msg_shutdown_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_shutdown_target.rs index 6bf0409b7b5..a731a1dd91f 100644 --- a/fuzz/src/bin/msg_shutdown_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_shutdown_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_shutdown_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_shutdown_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_shutdown") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_shutdown") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_splice_ack_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_splice_ack_target.rs similarity index 95% rename from fuzz/src/bin/msg_splice_ack_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_splice_ack_target.rs index 96f373d5a1c..20625fc759c 100644 --- a/fuzz/src/bin/msg_splice_ack_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_splice_ack_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_splice_ack_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_splice_ack_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_splice_ack") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_splice_ack") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_splice_init_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_splice_init_target.rs similarity index 95% rename from fuzz/src/bin/msg_splice_init_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_splice_init_target.rs index 73d4319c44a..b3d30a660a1 100644 --- a/fuzz/src/bin/msg_splice_init_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_splice_init_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_splice_init_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_splice_init_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_splice_init") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_splice_init") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_splice_locked_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_splice_locked_target.rs similarity index 95% rename from fuzz/src/bin/msg_splice_locked_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_splice_locked_target.rs index 9210113a0c8..deb57b61974 100644 --- a/fuzz/src/bin/msg_splice_locked_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_splice_locked_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_splice_locked_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_splice_locked_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_splice_locked") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_splice_locked") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_stfu_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_stfu_target.rs similarity index 95% rename from fuzz/src/bin/msg_stfu_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_stfu_target.rs index d00536c7bcd..de3a64f542b 100644 --- a/fuzz/src/bin/msg_stfu_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_stfu_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_stfu_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_stfu_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_stfu") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_stfu") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_tx_abort_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_abort_target.rs similarity index 95% rename from fuzz/src/bin/msg_tx_abort_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_tx_abort_target.rs index 8f216b46e63..0b335c23b18 100644 --- a/fuzz/src/bin/msg_tx_abort_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_abort_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_tx_abort_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_tx_abort_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_tx_abort") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_tx_abort") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_tx_ack_rbf_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_ack_rbf_target.rs similarity index 95% rename from fuzz/src/bin/msg_tx_ack_rbf_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_tx_ack_rbf_target.rs index 90b34c7f93f..d69077c9075 100644 --- a/fuzz/src/bin/msg_tx_ack_rbf_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_ack_rbf_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_tx_ack_rbf_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_tx_ack_rbf_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_tx_ack_rbf") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_tx_ack_rbf") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_tx_add_input_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_add_input_target.rs similarity index 95% rename from fuzz/src/bin/msg_tx_add_input_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_tx_add_input_target.rs index ce9700bd344..8dff0a621c9 100644 --- a/fuzz/src/bin/msg_tx_add_input_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_add_input_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_tx_add_input_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_tx_add_input_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_tx_add_input") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_tx_add_input") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_tx_add_output_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_add_output_target.rs similarity index 95% rename from fuzz/src/bin/msg_tx_add_output_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_tx_add_output_target.rs index 02682194e13..f6808399aba 100644 --- a/fuzz/src/bin/msg_tx_add_output_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_add_output_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_tx_add_output_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_tx_add_output_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_tx_add_output") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_tx_add_output") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_tx_complete_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_complete_target.rs similarity index 95% rename from fuzz/src/bin/msg_tx_complete_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_tx_complete_target.rs index 48864f053c8..2edccfbf690 100644 --- a/fuzz/src/bin/msg_tx_complete_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_complete_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_tx_complete_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_tx_complete_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_tx_complete") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_tx_complete") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_tx_init_rbf_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_init_rbf_target.rs similarity index 95% rename from fuzz/src/bin/msg_tx_init_rbf_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_tx_init_rbf_target.rs index a8b613cdfca..80acf0f11c8 100644 --- a/fuzz/src/bin/msg_tx_init_rbf_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_init_rbf_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_tx_init_rbf_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_tx_init_rbf_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_tx_init_rbf") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_tx_init_rbf") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_tx_remove_input_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_remove_input_target.rs similarity index 94% rename from fuzz/src/bin/msg_tx_remove_input_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_tx_remove_input_target.rs index 1e46c547dbf..b1555a2412a 100644 --- a/fuzz/src/bin/msg_tx_remove_input_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_remove_input_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_tx_remove_input_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_tx_remove_input_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_tx_remove_input") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_tx_remove_input") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_tx_remove_output_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_remove_output_target.rs similarity index 94% rename from fuzz/src/bin/msg_tx_remove_output_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_tx_remove_output_target.rs index 3a9c178e75f..a8e5b20d06d 100644 --- a/fuzz/src/bin/msg_tx_remove_output_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_remove_output_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_tx_remove_output_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_tx_remove_output_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_tx_remove_output") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_tx_remove_output") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_tx_signatures_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_signatures_target.rs similarity index 95% rename from fuzz/src/bin/msg_tx_signatures_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_tx_signatures_target.rs index 77f34cc1f6a..2a1fbf9d16e 100644 --- a/fuzz/src/bin/msg_tx_signatures_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_tx_signatures_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_tx_signatures_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_tx_signatures_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_tx_signatures") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_tx_signatures") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_update_add_htlc_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_update_add_htlc_target.rs similarity index 94% rename from fuzz/src/bin/msg_update_add_htlc_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_update_add_htlc_target.rs index 3ff5cf83dbe..d3b45d589eb 100644 --- a/fuzz/src/bin/msg_update_add_htlc_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_update_add_htlc_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_update_add_htlc_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_update_add_htlc_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_update_add_htlc") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_update_add_htlc") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_update_fail_htlc_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_update_fail_htlc_target.rs similarity index 94% rename from fuzz/src/bin/msg_update_fail_htlc_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_update_fail_htlc_target.rs index 5b8a7e55dcb..bec5bc9e331 100644 --- a/fuzz/src/bin/msg_update_fail_htlc_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_update_fail_htlc_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_update_fail_htlc_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_update_fail_htlc_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_update_fail_htlc") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_update_fail_htlc") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_update_fail_malformed_htlc_target.rs similarity index 94% rename from fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_update_fail_malformed_htlc_target.rs index e3e8918e492..190412bc0a7 100644 --- a/fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_update_fail_malformed_htlc_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_update_fail_malformed_htlc_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_update_fail_malformed_htlc_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_update_fail_malformed_htlc") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_update_fail_malformed_htlc") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_update_fee_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_update_fee_target.rs similarity index 95% rename from fuzz/src/bin/msg_update_fee_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_update_fee_target.rs index 98e51181c79..386db47ae9f 100644 --- a/fuzz/src/bin/msg_update_fee_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_update_fee_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_update_fee_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_update_fee_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_update_fee") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_update_fee") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/msg_update_fulfill_htlc_target.rs b/fuzz/fuzz-fake-hashes/src/bin/msg_update_fulfill_htlc_target.rs similarity index 94% rename from fuzz/src/bin/msg_update_fulfill_htlc_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/msg_update_fulfill_htlc_target.rs index cb156448e13..ab49c21043e 100644 --- a/fuzz/src/bin/msg_update_fulfill_htlc_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/msg_update_fulfill_htlc_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - msg_update_fulfill_htlc_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + msg_update_fulfill_htlc_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/msg_update_fulfill_htlc") { + if let Ok(tests) = fs::read_dir("../test_cases/msg_update_fulfill_htlc") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/offer_deser_target.rs b/fuzz/fuzz-fake-hashes/src/bin/offer_deser_target.rs similarity index 95% rename from fuzz/src/bin/offer_deser_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/offer_deser_target.rs index c4a03f628b3..25eda5618f0 100644 --- a/fuzz/src/bin/offer_deser_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/offer_deser_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - offer_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + offer_deser_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } 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") { + if let Ok(tests) = fs::read_dir("../test_cases/offer_deser") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/onion_hop_data_target.rs b/fuzz/fuzz-fake-hashes/src/bin/onion_hop_data_target.rs similarity index 95% rename from fuzz/src/bin/onion_hop_data_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/onion_hop_data_target.rs index 3b9b55bbfa9..05ce4d76aeb 100644 --- a/fuzz/src/bin/onion_hop_data_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/onion_hop_data_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - onion_hop_data_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + onion_hop_data_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/onion_hop_data") { + if let Ok(tests) = fs::read_dir("../test_cases/onion_hop_data") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/onion_message_target.rs b/fuzz/fuzz-fake-hashes/src/bin/onion_message_target.rs similarity index 95% rename from fuzz/src/bin/onion_message_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/onion_message_target.rs index bb343e9de83..f5a0eb60171 100644 --- a/fuzz/src/bin/onion_message_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/onion_message_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - onion_message_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + onion_message_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/onion_message") { + if let Ok(tests) = fs::read_dir("../test_cases/onion_message") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/peer_crypt_target.rs b/fuzz/fuzz-fake-hashes/src/bin/peer_crypt_target.rs similarity index 95% rename from fuzz/src/bin/peer_crypt_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/peer_crypt_target.rs index c68111deb06..3095f2a870c 100644 --- a/fuzz/src/bin/peer_crypt_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/peer_crypt_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - peer_crypt_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + peer_crypt_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/peer_crypt") { + if let Ok(tests) = fs::read_dir("../test_cases/peer_crypt") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/process_network_graph_target.rs b/fuzz/fuzz-fake-hashes/src/bin/process_network_graph_target.rs similarity index 94% rename from fuzz/src/bin/process_network_graph_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/process_network_graph_target.rs index 7da2aafe3c8..36ea42bcb6a 100644 --- a/fuzz/src/bin/process_network_graph_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/process_network_graph_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - process_network_graph_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + process_network_graph_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/process_network_graph") { + if let Ok(tests) = fs::read_dir("../test_cases/process_network_graph") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/process_onion_failure_target.rs b/fuzz/fuzz-fake-hashes/src/bin/process_onion_failure_target.rs similarity index 94% rename from fuzz/src/bin/process_onion_failure_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/process_onion_failure_target.rs index 9e1cc8aa6d0..1d6c64c5863 100644 --- a/fuzz/src/bin/process_onion_failure_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/process_onion_failure_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - process_onion_failure_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + process_onion_failure_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/process_onion_failure") { + if let Ok(tests) = fs::read_dir("../test_cases/process_onion_failure") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/refund_deser_target.rs b/fuzz/fuzz-fake-hashes/src/bin/refund_deser_target.rs similarity index 95% rename from fuzz/src/bin/refund_deser_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/refund_deser_target.rs index 13837d2be73..a5295b8d793 100644 --- a/fuzz/src/bin/refund_deser_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/refund_deser_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - refund_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + refund_deser_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } 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") { + if let Ok(tests) = fs::read_dir("../test_cases/refund_deser") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/router_target.rs b/fuzz/fuzz-fake-hashes/src/bin/router_target.rs similarity index 95% rename from fuzz/src/bin/router_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/router_target.rs index 52a8c3408ff..ecf6dbe9b57 100644 --- a/fuzz/src/bin/router_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/router_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - router_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + router_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/router") { + if let Ok(tests) = fs::read_dir("../test_cases/router") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/static_invoice_deser_target.rs b/fuzz/fuzz-fake-hashes/src/bin/static_invoice_deser_target.rs similarity index 94% rename from fuzz/src/bin/static_invoice_deser_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/static_invoice_deser_target.rs index 477f7869e7f..787817de00e 100644 --- a/fuzz/src/bin/static_invoice_deser_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/static_invoice_deser_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - static_invoice_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + static_invoice_deser_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/static_invoice_deser") { + if let Ok(tests) = fs::read_dir("../test_cases/static_invoice_deser") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/zbase32_target.rs b/fuzz/fuzz-fake-hashes/src/bin/zbase32_target.rs similarity index 95% rename from fuzz/src/bin/zbase32_target.rs rename to fuzz/fuzz-fake-hashes/src/bin/zbase32_target.rs index 68c8cf3e19c..1007df19acf 100644 --- a/fuzz/src/bin/zbase32_target.rs +++ b/fuzz/fuzz-fake-hashes/src/bin/zbase32_target.rs @@ -17,7 +17,7 @@ compile_error!("Fuzz targets need cfg=fuzzing"); #[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +compile_error!("Fuzz target does not support cfg(not(hashes_fuzz))"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - zbase32_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + zbase32_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/zbase32") { + if let Ok(tests) = fs::read_dir("../test_cases/zbase32") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/fuzz-real-hashes/Cargo.toml b/fuzz/fuzz-real-hashes/Cargo.toml new file mode 100644 index 00000000000..a6d77d28137 --- /dev/null +++ b/fuzz/fuzz-real-hashes/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "lightning-fuzz-real-hashes" +version = "0.0.1" +authors = ["Automatically generated"] +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[features] +afl_fuzz = ["afl"] +honggfuzz_fuzz = ["honggfuzz"] +libfuzzer_fuzz = ["libfuzzer-sys"] +stdin_fuzz = [] + +[dependencies] +lightning-fuzz = { path = ".." } + +afl = { version = "0.12", optional = true } +honggfuzz = { version = "0.5", optional = true, default-features = false } +libfuzzer-sys = { version = "0.4", optional = true } + +[lints.rust.unexpected_cfgs] +level = "forbid" +# When adding a new cfg attribute, ensure that it is added to this list. +check-cfg = [ + "cfg(fuzzing)", + "cfg(secp256k1_fuzz)", + "cfg(hashes_fuzz)", +] diff --git a/fuzz/src/bin/chanmon_consistency_target.rs b/fuzz/fuzz-real-hashes/src/bin/chanmon_consistency_target.rs similarity index 94% rename from fuzz/src/bin/chanmon_consistency_target.rs rename to fuzz/fuzz-real-hashes/src/bin/chanmon_consistency_target.rs index 7649900bae5..335c8169c75 100644 --- a/fuzz/src/bin/chanmon_consistency_target.rs +++ b/fuzz/fuzz-real-hashes/src/bin/chanmon_consistency_target.rs @@ -16,8 +16,8 @@ #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); -#[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +#[cfg(hashes_fuzz)] +compile_error!("Fuzz target does not support cfg(hashes_fuzz)"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - chanmon_consistency_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + chanmon_consistency_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/chanmon_consistency") { + if let Ok(tests) = fs::read_dir("../test_cases/chanmon_consistency") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/bin/gen_target.sh b/fuzz/src/bin/gen_target.sh index fd308a1f10e..868a07652c6 100755 --- a/fuzz/src/bin/gen_target.sh +++ b/fuzz/src/bin/gen_target.sh @@ -2,88 +2,103 @@ echo "#include " > ../../targets.h GEN_TEST() { - cat target_template.txt | sed s/TARGET_NAME/$1/ | sed s/TARGET_MOD/$2$1/ > $1_target.rs - echo "void $1_run(const unsigned char* data, size_t data_len);" >> ../../targets.h + dest_dir=$1 + target_name=$2 + target_mod=$3 + hashes_flag=$4 + + mkdir -p "$dest_dir" + sed "s/TARGET_NAME/$target_name/g; s|TARGET_MOD|$target_mod$target_name|g; s/HASHES_FLAG/$hashes_flag/g" \ + target_template.txt > "$dest_dir/${target_name}_target.rs" + echo "void ${target_name}_run(const unsigned char* data, size_t data_len);" >> ../../targets.h +} + +GEN_FAKE_HASHES_TEST() { + GEN_TEST ../../fuzz-fake-hashes/src/bin "$1" "$2" "not(hashes_fuzz)" +} + +GEN_REAL_HASHES_TEST() { + GEN_TEST ../../fuzz-real-hashes/src/bin "$1" "$2" "hashes_fuzz" } -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 bolt11_deser -GEN_TEST static_invoice_deser -GEN_TEST onion_message -GEN_TEST peer_crypt -GEN_TEST process_network_graph -GEN_TEST process_onion_failure -GEN_TEST refund_deser -GEN_TEST router -GEN_TEST zbase32 -GEN_TEST indexedmap -GEN_TEST onion_hop_data -GEN_TEST base32 -GEN_TEST fromstr_to_netaddress -GEN_TEST feature_flags -GEN_TEST lsps_message -GEN_TEST fs_store -GEN_TEST gossip_discovery +GEN_FAKE_HASHES_TEST bech32_parse +GEN_FAKE_HASHES_TEST chanmon_deser +GEN_REAL_HASHES_TEST chanmon_consistency +GEN_FAKE_HASHES_TEST full_stack +GEN_FAKE_HASHES_TEST invoice_deser +GEN_FAKE_HASHES_TEST invoice_request_deser +GEN_FAKE_HASHES_TEST offer_deser +GEN_FAKE_HASHES_TEST bolt11_deser +GEN_FAKE_HASHES_TEST static_invoice_deser +GEN_FAKE_HASHES_TEST onion_message +GEN_FAKE_HASHES_TEST peer_crypt +GEN_FAKE_HASHES_TEST process_network_graph +GEN_FAKE_HASHES_TEST process_onion_failure +GEN_FAKE_HASHES_TEST refund_deser +GEN_FAKE_HASHES_TEST router +GEN_FAKE_HASHES_TEST zbase32 +GEN_FAKE_HASHES_TEST indexedmap +GEN_FAKE_HASHES_TEST onion_hop_data +GEN_FAKE_HASHES_TEST base32 +GEN_FAKE_HASHES_TEST fromstr_to_netaddress +GEN_FAKE_HASHES_TEST feature_flags +GEN_FAKE_HASHES_TEST lsps_message +GEN_FAKE_HASHES_TEST fs_store +GEN_FAKE_HASHES_TEST gossip_discovery -GEN_TEST msg_accept_channel msg_targets:: -GEN_TEST msg_announcement_signatures msg_targets:: -GEN_TEST msg_channel_reestablish msg_targets:: -GEN_TEST msg_closing_signed msg_targets:: -GEN_TEST msg_closing_complete msg_targets:: -GEN_TEST msg_closing_sig msg_targets:: -GEN_TEST msg_commitment_signed msg_targets:: -GEN_TEST msg_decoded_onion_error_packet msg_targets:: -GEN_TEST msg_funding_created msg_targets:: -GEN_TEST msg_channel_ready msg_targets:: -GEN_TEST msg_funding_signed msg_targets:: -GEN_TEST msg_init msg_targets:: -GEN_TEST msg_open_channel msg_targets:: -GEN_TEST msg_revoke_and_ack msg_targets:: -GEN_TEST msg_shutdown msg_targets:: -GEN_TEST msg_update_fail_htlc msg_targets:: -GEN_TEST msg_update_fail_malformed_htlc msg_targets:: -GEN_TEST msg_update_fee msg_targets:: -GEN_TEST msg_update_fulfill_htlc msg_targets:: +GEN_FAKE_HASHES_TEST msg_accept_channel msg_targets:: +GEN_FAKE_HASHES_TEST msg_announcement_signatures msg_targets:: +GEN_FAKE_HASHES_TEST msg_channel_reestablish msg_targets:: +GEN_FAKE_HASHES_TEST msg_closing_signed msg_targets:: +GEN_FAKE_HASHES_TEST msg_closing_complete msg_targets:: +GEN_FAKE_HASHES_TEST msg_closing_sig msg_targets:: +GEN_FAKE_HASHES_TEST msg_commitment_signed msg_targets:: +GEN_FAKE_HASHES_TEST msg_decoded_onion_error_packet msg_targets:: +GEN_FAKE_HASHES_TEST msg_funding_created msg_targets:: +GEN_FAKE_HASHES_TEST msg_channel_ready msg_targets:: +GEN_FAKE_HASHES_TEST msg_funding_signed msg_targets:: +GEN_FAKE_HASHES_TEST msg_init msg_targets:: +GEN_FAKE_HASHES_TEST msg_open_channel msg_targets:: +GEN_FAKE_HASHES_TEST msg_revoke_and_ack msg_targets:: +GEN_FAKE_HASHES_TEST msg_shutdown msg_targets:: +GEN_FAKE_HASHES_TEST msg_update_fail_htlc msg_targets:: +GEN_FAKE_HASHES_TEST msg_update_fail_malformed_htlc msg_targets:: +GEN_FAKE_HASHES_TEST msg_update_fee msg_targets:: +GEN_FAKE_HASHES_TEST msg_update_fulfill_htlc msg_targets:: -GEN_TEST msg_channel_announcement msg_targets:: -GEN_TEST msg_node_announcement msg_targets:: -GEN_TEST msg_query_short_channel_ids msg_targets:: -GEN_TEST msg_reply_short_channel_ids_end msg_targets:: -GEN_TEST msg_query_channel_range msg_targets:: -GEN_TEST msg_reply_channel_range msg_targets:: -GEN_TEST msg_gossip_timestamp_filter msg_targets:: +GEN_FAKE_HASHES_TEST msg_channel_announcement msg_targets:: +GEN_FAKE_HASHES_TEST msg_node_announcement msg_targets:: +GEN_FAKE_HASHES_TEST msg_query_short_channel_ids msg_targets:: +GEN_FAKE_HASHES_TEST msg_reply_short_channel_ids_end msg_targets:: +GEN_FAKE_HASHES_TEST msg_query_channel_range msg_targets:: +GEN_FAKE_HASHES_TEST msg_reply_channel_range msg_targets:: +GEN_FAKE_HASHES_TEST msg_gossip_timestamp_filter msg_targets:: -GEN_TEST msg_update_add_htlc msg_targets:: -GEN_TEST msg_error_message msg_targets:: -GEN_TEST msg_channel_update msg_targets:: +GEN_FAKE_HASHES_TEST msg_update_add_htlc msg_targets:: +GEN_FAKE_HASHES_TEST msg_error_message msg_targets:: +GEN_FAKE_HASHES_TEST msg_channel_update msg_targets:: -GEN_TEST msg_ping msg_targets:: -GEN_TEST msg_pong msg_targets:: +GEN_FAKE_HASHES_TEST msg_ping msg_targets:: +GEN_FAKE_HASHES_TEST msg_pong msg_targets:: -GEN_TEST msg_channel_details msg_targets:: +GEN_FAKE_HASHES_TEST msg_channel_details msg_targets:: -GEN_TEST msg_open_channel_v2 msg_targets:: -GEN_TEST msg_accept_channel_v2 msg_targets:: -GEN_TEST msg_tx_add_input msg_targets:: -GEN_TEST msg_tx_add_output msg_targets:: -GEN_TEST msg_tx_remove_input msg_targets:: -GEN_TEST msg_tx_remove_output msg_targets:: -GEN_TEST msg_tx_complete msg_targets:: -GEN_TEST msg_tx_signatures msg_targets:: -GEN_TEST msg_tx_init_rbf msg_targets:: -GEN_TEST msg_tx_ack_rbf msg_targets:: -GEN_TEST msg_tx_abort msg_targets:: +GEN_FAKE_HASHES_TEST msg_open_channel_v2 msg_targets:: +GEN_FAKE_HASHES_TEST msg_accept_channel_v2 msg_targets:: +GEN_FAKE_HASHES_TEST msg_tx_add_input msg_targets:: +GEN_FAKE_HASHES_TEST msg_tx_add_output msg_targets:: +GEN_FAKE_HASHES_TEST msg_tx_remove_input msg_targets:: +GEN_FAKE_HASHES_TEST msg_tx_remove_output msg_targets:: +GEN_FAKE_HASHES_TEST msg_tx_complete msg_targets:: +GEN_FAKE_HASHES_TEST msg_tx_signatures msg_targets:: +GEN_FAKE_HASHES_TEST msg_tx_init_rbf msg_targets:: +GEN_FAKE_HASHES_TEST msg_tx_ack_rbf msg_targets:: +GEN_FAKE_HASHES_TEST msg_tx_abort msg_targets:: -GEN_TEST msg_stfu msg_targets:: +GEN_FAKE_HASHES_TEST msg_stfu msg_targets:: -GEN_TEST msg_splice_init msg_targets:: -GEN_TEST msg_splice_ack msg_targets:: -GEN_TEST msg_splice_locked msg_targets:: +GEN_FAKE_HASHES_TEST msg_splice_init msg_targets:: +GEN_FAKE_HASHES_TEST msg_splice_ack msg_targets:: +GEN_FAKE_HASHES_TEST msg_splice_locked msg_targets:: -GEN_TEST msg_blinded_message_path msg_targets:: +GEN_FAKE_HASHES_TEST msg_blinded_message_path msg_targets:: diff --git a/fuzz/src/bin/target_template.txt b/fuzz/src/bin/target_template.txt index 9b0dff8eb8c..78bc7f37d87 100644 --- a/fuzz/src/bin/target_template.txt +++ b/fuzz/src/bin/target_template.txt @@ -16,8 +16,8 @@ #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); -#[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); +#[cfg(HASHES_FLAG)] +compile_error!("Fuzz target does not support cfg(HASHES_FLAG)"); #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); @@ -71,7 +71,7 @@ fn main() { let mut data = Vec::with_capacity(8192); std::io::stdin().read_to_end(&mut data).unwrap(); - TARGET_NAME_test(&data, lightning_fuzz::utils::test_logger::Stdout {}); + TARGET_NAME_test(&data, test_logger::Stdout {}); } #[test] @@ -87,7 +87,7 @@ fn run_test_cases() { } let mut threads = Vec::new(); let threads_running = Arc::new(atomic::AtomicUsize::new(0)); - if let Ok(tests) = fs::read_dir("test_cases/TARGET_NAME") { + if let Ok(tests) = fs::read_dir("../test_cases/TARGET_NAME") { for test in tests { let mut data: Vec = Vec::new(); let path = test.unwrap().path(); diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index d4a0e560887..25739d94ca5 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -15,8 +15,8 @@ //! actions such as sending payments, handling events, or changing monitor update return values on //! a per-node basis. This should allow it to find any cases where the ordering of actions results //! in us getting out of sync with ourselves, and, assuming at least one of our recieve- or -//! send-side handling is correct, other peers. We consider it a failure if any action results in a -//! channel being force-closed. +//! send-side handling is correct, other peers. The fuzzer also exercises user-initiated +//! force-closes with on-chain commitment transaction confirmation. use bitcoin::amount::Amount; use bitcoin::constants::genesis_block; @@ -27,6 +27,7 @@ use bitcoin::script::{Builder, ScriptBuf}; use bitcoin::transaction::Version; use bitcoin::transaction::{Transaction, TxOut}; use bitcoin::FeeRate; +use bitcoin::OutPoint as BitcoinOutPoint; use bitcoin::block::Header; use bitcoin::hash_types::Txid; @@ -41,12 +42,12 @@ use lightning::chain; use lightning::chain::chaininterface::{ BroadcasterInterface, ConfirmationTarget, FeeEstimator, TransactionType, }; -use lightning::chain::channelmonitor::{ChannelMonitor, MonitorEvent}; +use lightning::chain::channelmonitor::{Balance, ChannelMonitor, MonitorEvent}; use lightning::chain::transaction::OutPoint; use lightning::chain::{ chainmonitor, channelmonitor, BestBlock, ChannelMonitorUpdateStatus, Confirm, Watch, }; -use lightning::events; +use lightning::events::{self, EventsProvider}; use lightning::ln::channel::{ FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MAX_STD_OUTPUT_DUST_LIMIT_SATOSHIS, }; @@ -85,6 +86,8 @@ use lightning::util::test_channel_signer::{EnforcementState, SignerOp, TestChann use lightning::util::test_utils::TestWalletSource; use lightning::util::wallet_utils::{WalletSourceSync, WalletSync}; +use lightning::events::bump_transaction::sync::BumpTransactionEventHandlerSync; + use lightning_invoice::RawBolt11Invoice; use crate::utils::test_logger::{self, Output}; @@ -186,13 +189,22 @@ impl BroadcasterInterface for TestBroadcaster { struct ChainState { blocks: Vec<(Header, Vec)>, confirmed_txids: HashSet, + /// Tracks unspent outputs created by confirmed transactions. Only + /// transactions that spend existing UTXOs can be confirmed, which + /// prevents fuzz hash collisions from creating phantom spends of + /// outputs that were never actually created. + utxos: HashSet, } impl ChainState { fn new() -> Self { let genesis_hash = genesis_block(Network::Bitcoin).block_hash(); let genesis_header = create_dummy_header(genesis_hash, 42); - Self { blocks: vec![(genesis_header, Vec::new())], confirmed_txids: HashSet::new() } + Self { + blocks: vec![(genesis_header, Vec::new())], + confirmed_txids: HashSet::new(), + utxos: HashSet::new(), + } } fn tip_height(&self) -> u32 { @@ -204,7 +216,39 @@ impl ChainState { if self.confirmed_txids.contains(&txid) { return false; } + // Reject timelocked transactions before their lock_time, matching + // consensus rules. Commitment txs encode an obscured commitment + // number with bit 29 set, which is not a real timelock. + let lock_time = tx.lock_time.to_consensus_u32(); + if lock_time > 0 + && lock_time < 500_000_000 + && lock_time & (1 << 29) == 0 + && self.tip_height() < lock_time + { + return false; + } + // Validate that all inputs spend existing, unspent outputs. This + // rejects both double-spends and spends of outputs that were never + // created (e.g. due to fuzz txid hash collisions where a different + // transaction was confirmed under the same txid). + let is_coinbase = tx.is_coinbase(); + if !is_coinbase { + for input in &tx.input { + if !self.utxos.contains(&input.previous_output) { + return false; + } + } + } self.confirmed_txids.insert(txid); + if !is_coinbase { + for input in &tx.input { + self.utxos.remove(&input.previous_output); + } + } + // Add this transaction's outputs as new UTXOs. + for idx in 0..tx.output.len() { + self.utxos.insert(BitcoinOutPoint { txid, vout: idx as u32 }); + } let prev_hash = self.blocks.last().unwrap().0.block_hash(); let header = create_dummy_header(prev_hash, 42); @@ -218,6 +262,14 @@ impl ChainState { true } + fn advance_height(&mut self, num_blocks: u32) { + for _ in 0..num_blocks { + let prev_hash = self.blocks.last().unwrap().0.block_hash(); + let header = create_dummy_header(prev_hash, 42); + self.blocks.push((header, Vec::new())); + } + } + fn block_at(&self, height: u32) -> &(Header, Vec) { &self.blocks[height as usize] } @@ -500,12 +552,12 @@ impl SignerProvider for KeyProvider { } } -// Since this fuzzer is only concerned with live-channel operations, we don't need to worry about -// any signer operations that come after a force close. -const SUPPORTED_SIGNER_OPS: [SignerOp; 3] = [ +const SUPPORTED_SIGNER_OPS: [SignerOp; 5] = [ SignerOp::SignCounterpartyCommitment, SignerOp::GetPerCommitmentPoint, SignerOp::ReleaseCommitmentSecret, + SignerOp::SignHolderCommitment, + SignerOp::SignHolderHtlcTransaction, ]; impl KeyProvider { @@ -568,12 +620,18 @@ type ChanMan<'a> = ChannelManager< >; #[inline] -fn get_payment_secret_hash(dest: &ChanMan, payment_ctr: &mut u64) -> (PaymentSecret, PaymentHash) { +fn get_payment_secret_hash( + dest: &ChanMan, payment_ctr: &mut u64, + payment_preimages: &RefCell>, +) -> (PaymentSecret, PaymentHash) { *payment_ctr += 1; - let payment_hash = PaymentHash(Sha256::hash(&[*payment_ctr as u8]).to_byte_array()); + let mut payment_preimage = PaymentPreimage([0; 32]); + payment_preimage.0[0..8].copy_from_slice(&payment_ctr.to_be_bytes()); + let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).to_byte_array()); let payment_secret = dest .create_inbound_payment_for_hash(payment_hash, None, 3600, None) .expect("create_inbound_payment_for_hash failed"); + assert!(payment_preimages.borrow_mut().insert(payment_hash, payment_preimage).is_none()); (payment_secret, payment_hash) } @@ -705,24 +763,25 @@ fn send_mpp_payment( source: &ChanMan, dest: &ChanMan, dest_chan_ids: &[ChannelId], amt: u64, payment_secret: PaymentSecret, payment_hash: PaymentHash, payment_id: PaymentId, ) -> bool { - let num_paths = dest_chan_ids.len(); + let mut paths = Vec::new(); + + let dest_chans = dest.list_channels(); + let dest_scids: Vec<_> = dest_chan_ids + .iter() + .filter_map(|chan_id| { + dest_chans + .iter() + .find(|chan| chan.channel_id == *chan_id) + .and_then(|chan| chan.short_channel_id) + }) + .collect(); + let num_paths = dest_scids.len(); if num_paths == 0 { return false; } - let amt_per_path = amt / num_paths as u64; - let mut paths = Vec::with_capacity(num_paths); - let dest_chans = dest.list_channels(); - let dest_scids = dest_chan_ids.iter().map(|chan_id| { - dest_chans - .iter() - .find(|chan| chan.channel_id == *chan_id) - .and_then(|chan| chan.short_channel_id) - .unwrap() - }); - - for (i, dest_scid) in dest_scids.enumerate() { + for (i, dest_scid) in dest_scids.into_iter().enumerate() { let path_amt = if i == num_paths - 1 { amt - amt_per_path * (num_paths as u64 - 1) } else { @@ -764,41 +823,38 @@ fn send_mpp_hop_payment( dest_chan_ids: &[ChannelId], amt: u64, payment_secret: PaymentSecret, payment_hash: PaymentHash, payment_id: PaymentId, ) -> bool { - // Create paths by pairing middle_scids with dest_scids - let num_paths = middle_chan_ids.len().max(dest_chan_ids.len()); - if num_paths == 0 { - return false; - } - - let first_hop_fee = 50_000; - let amt_per_path = amt / num_paths as u64; - let fee_per_path = first_hop_fee / num_paths as u64; - let mut paths = Vec::with_capacity(num_paths); - let middle_chans = middle.list_channels(); let middle_scids: Vec<_> = middle_chan_ids .iter() - .map(|chan_id| { + .filter_map(|chan_id| { middle_chans .iter() .find(|chan| chan.channel_id == *chan_id) .and_then(|chan| chan.short_channel_id) - .unwrap() }) .collect(); let dest_chans = dest.list_channels(); let dest_scids: Vec<_> = dest_chan_ids .iter() - .map(|chan_id| { + .filter_map(|chan_id| { dest_chans .iter() .find(|chan| chan.channel_id == *chan_id) .and_then(|chan| chan.short_channel_id) - .unwrap() }) .collect(); + let num_paths = middle_scids.len().max(dest_scids.len()); + if middle_scids.is_empty() || dest_scids.is_empty() { + return false; + } + + let first_hop_fee = 50_000; + let amt_per_path = amt / num_paths as u64; + let fee_per_path = first_hop_fee / num_paths as u64; + let mut paths = Vec::with_capacity(num_paths); + for i in 0..num_paths { let middle_scid = middle_scids[i % middle_scids.len()]; let dest_scid = dest_scids[i % dest_scids.len()]; @@ -852,17 +908,6 @@ fn send_mpp_hop_payment( } } -#[inline] -fn assert_action_timeout_awaiting_response(action: &msgs::ErrorAction) { - // Since sending/receiving messages may be delayed, `timer_tick_occurred` may cause a node to - // disconnect their counterparty if they're expecting a timely response. - assert!(matches!( - action, - msgs::ErrorAction::DisconnectPeerWithWarning { msg } - if msg.data.contains("Disconnecting due to timeout awaiting response") - )); -} - enum ChanType { Legacy, KeyedAnchors, @@ -907,6 +952,43 @@ pub fn do_test(data: &[u8], out: Out) { let mut node_height_a: u32 = 0; let mut node_height_b: u32 = 0; let mut node_height_c: u32 = 0; + let has_timed_balance = |balances: &[Balance]| { + balances.iter().any(|balance| { + matches!( + balance, + // Force-close settlement only needs to stretch height when + // there is still time-sensitive work that may release new + // on-chain claims. `ClaimableAwaitingConfirmations` is not in + // that bucket, it means some transaction already exists and we + // are mostly waiting for more confirms on it. + Balance::ContentiousClaimable { .. } + | Balance::MaybeTimeoutClaimableHTLC { .. } + | Balance::MaybePreimageClaimableHTLC { .. } + | Balance::CounterpartyRevokedOutputClaimable { .. } + ) + }) + }; + let summarize_balances = |balances: &[Balance]| -> String { + let mut on_close = 0; + let mut awaiting = 0; + let mut contentious = 0; + let mut maybe_timeout = 0; + let mut maybe_preimage = 0; + let mut revoked = 0; + for balance in balances { + match balance { + Balance::ClaimableOnChannelClose { .. } => on_close += 1, + Balance::ClaimableAwaitingConfirmations { .. } => awaiting += 1, + Balance::ContentiousClaimable { .. } => contentious += 1, + Balance::MaybeTimeoutClaimableHTLC { .. } => maybe_timeout += 1, + Balance::MaybePreimageClaimableHTLC { .. } => maybe_preimage += 1, + Balance::CounterpartyRevokedOutputClaimable { .. } => revoked += 1, + } + } + format!( + "on_close={on_close} awaiting={awaiting} contentious={contentious} maybe_timeout={maybe_timeout} maybe_preimage={maybe_preimage} revoked={revoked}" + ) + }; macro_rules! make_node { ($node_id: expr, $fee_estimator: expr, $broadcaster: expr) => {{ @@ -935,6 +1017,11 @@ pub fn do_test(data: &[u8], out: Out) { let mut config = UserConfig::default(); config.channel_config.forwarding_fee_proportional_millionths = 0; config.channel_handshake_config.announce_for_forwarding = true; + // The harness mutates open flows aggressively and may create + // force-close scenarios from channels that would fail the normal + // "prefer announced channels" policy check. Keep that check off + // here or we lose coverage before any close logic executes. + config.channel_handshake_limits.force_announced_channel_preference = false; config.reject_inbound_splices = false; match chan_type { ChanType::Legacy => { @@ -998,6 +1085,11 @@ pub fn do_test(data: &[u8], out: Out) { let mut config = UserConfig::default(); config.channel_config.forwarding_fee_proportional_millionths = 0; config.channel_handshake_config.announce_for_forwarding = true; + // Restarts must preserve the same relaxed open policy as fresh + // nodes. Otherwise replayed peers can refuse the same channels that + // were already open before the restart and the harness diverges for + // reasons unrelated to force-close handling. + config.channel_handshake_limits.force_announced_channel_preference = false; config.reject_inbound_splices = false; match chan_type { ChanType::Legacy => { @@ -1042,9 +1134,10 @@ pub fn do_test(data: &[u8], out: Out) { // Update the latest `ChannelMonitor` state to match what we just told LDK. prev_state.persisted_monitor = serialized_mon; prev_state.persisted_monitor_id = mon_id; - // Wipe any `ChannelMonitor`s which we never told LDK we finished persisting, - // considering them discarded. LDK should replay these for us as they're stored in - // the `ChannelManager`. + // Drop any newer monitor blobs that the harness never marked as + // durably persisted. Restart testing depends on LDK replaying + // those updates from the `ChannelManager`; if we keep them here we + // stop exercising the stale-monitor recovery path entirely. prev_state.pending_monitors.clear(); chain_monitor.latest_monitors.lock().unwrap().insert(channel_id, prev_state); } @@ -1070,13 +1163,24 @@ pub fn do_test(data: &[u8], out: Out) { let manager = <(BestBlock, ChanMan)>::read(&mut &ser[..], read_args).expect("Failed to read manager"); let res = (manager.1, chain_monitor.clone()); + let expected_status = *mon_style[node_id as usize].borrow(); + *chain_monitor.persister.update_ret.lock().unwrap() = expected_status.clone(); for (channel_id, mon) in monitors.drain() { + let monitor_id = mon.get_latest_update_id(); assert_eq!( chain_monitor.chain_monitor.watch_channel(channel_id, mon), - Ok(ChannelMonitorUpdateStatus::Completed) + Ok(expected_status.clone()) ); + // We call the inner `ChainMonitor::watch_channel` directly during + // restart, so mirror its initial in-progress update in + // `latest_monitors` for the harness bookkeeping. + if expected_status == chain::ChannelMonitorUpdateStatus::InProgress { + let mut map = chain_monitor.latest_monitors.lock().unwrap(); + if let Some(state) = map.get_mut(&channel_id) { + state.pending_monitors.push((monitor_id, state.persisted_monitor.clone())); + } + } } - *chain_monitor.persister.update_ret.lock().unwrap() = *mon_style[node_id as usize].borrow(); res }; @@ -1111,22 +1215,18 @@ pub fn do_test(data: &[u8], out: Out) { } macro_rules! make_channel { ($source: expr, $dest: expr, $source_monitor: expr, $dest_monitor: expr, $dest_keys_manager: expr, $chan_id: expr, $trusted_open: expr, $trusted_accept: expr) => {{ - if $trusted_open { - $source - .create_channel_to_trusted_peer_0reserve( - $dest.get_our_node_id(), - 100_000, - 42, - 0, - None, - None, - ) - .unwrap(); + let user_config = if $trusted_open { + let mut user_config = UserConfig::default(); + user_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = false; + user_config.channel_handshake_config.announce_for_forwarding = false; + user_config.channel_handshake_limits.trust_own_funding_0conf = true; + Some(user_config) } else { - $source - .create_channel($dest.get_our_node_id(), 100_000, 42, 0, None, None) - .unwrap(); - } + None + }; + $source + .create_channel($dest.get_our_node_id(), 100_000, 42, 0, None, user_config) + .unwrap(); let open_channel = { let events = $source.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -1216,6 +1316,131 @@ pub fn do_test(data: &[u8], out: Out) { } } + let funding_created = { + let events = $source.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + if let MessageSendEvent::SendFundingCreated { ref msg, .. } = events[0] { + msg.clone() + } else { + panic!("Wrong event type"); + } + }; + $dest.handle_funding_created($source.get_our_node_id(), &funding_created); + complete_all_pending_monitor_updates!($dest_monitor); + + let (funding_signed, channel_id) = { + let events = $dest.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + if let MessageSendEvent::SendFundingSigned { ref msg, .. } = events[0] { + (msg.clone(), msg.channel_id.clone()) + } else { + panic!("Wrong event type"); + } + }; + let events = $dest.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + if let events::Event::ChannelPending { ref counterparty_node_id, .. } = events[0] { + assert_eq!(counterparty_node_id, &$source.get_our_node_id()); + } else { + panic!("Wrong event type"); + } + + $source.handle_funding_signed($dest.get_our_node_id(), &funding_signed); + complete_all_pending_monitor_updates!($source_monitor); + + let events = $source.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + if let events::Event::ChannelPending { + ref counterparty_node_id, + channel_id: ref event_channel_id, + .. + } = events[0] + { + assert_eq!(counterparty_node_id, &$dest.get_our_node_id()); + assert_eq!(*event_channel_id, channel_id); + } else { + panic!("Wrong event type"); + } + }}; + ($source: expr, $dest: expr, $source_monitor: expr, $dest_monitor: expr, $dest_keys_manager: expr, $chan_id: expr) => {{ + $source.create_channel($dest.get_our_node_id(), 100_000, 42, 0, None, None).unwrap(); + let open_channel = { + let events = $source.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + if let MessageSendEvent::SendOpenChannel { ref msg, .. } = events[0] { + msg.clone() + } else { + panic!("Wrong event type"); + } + }; + + $dest.handle_open_channel($source.get_our_node_id(), &open_channel); + let accept_channel = { + let events = $dest.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + if let events::Event::OpenChannelRequest { + ref temporary_channel_id, + ref counterparty_node_id, + .. + } = events[0] + { + let mut random_bytes = [0u8; 16]; + random_bytes + .copy_from_slice(&$dest_keys_manager.get_secure_random_bytes()[..16]); + let user_channel_id = u128::from_be_bytes(random_bytes); + $dest + .accept_inbound_channel( + temporary_channel_id, + counterparty_node_id, + user_channel_id, + None, + ) + .unwrap(); + } else { + panic!("Wrong event type"); + } + let events = $dest.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + if let MessageSendEvent::SendAcceptChannel { ref msg, .. } = events[0] { + msg.clone() + } else { + panic!("Wrong event type"); + } + }; + + $source.handle_accept_channel($dest.get_our_node_id(), &accept_channel); + { + let mut events = $source.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + if let events::Event::FundingGenerationReady { + temporary_channel_id, + channel_value_satoshis, + output_script, + .. + } = events.pop().unwrap() + { + let tx = Transaction { + version: Version($chan_id), + lock_time: LockTime::ZERO, + input: Vec::new(), + output: vec![TxOut { + value: Amount::from_sat(channel_value_satoshis), + script_pubkey: output_script, + }], + }; + $source + .funding_transaction_generated( + temporary_channel_id, + $dest.get_our_node_id(), + tx.clone(), + ) + .unwrap(); + chain_state.confirm_tx(tx); + } else { + panic!("Wrong event type"); + } + } + let funding_created = { let events = $source.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -1281,7 +1506,7 @@ pub fn do_test(data: &[u8], out: Out) { } } } else { - panic!("Wrong event type"); + panic!("Wrong event type in first lock_fundings pass: {:?}", event); } } } @@ -1289,9 +1514,18 @@ pub fn do_test(data: &[u8], out: Out) { for node in $nodes.iter() { let events = node.get_and_clear_pending_msg_events(); for event in events { - if let MessageSendEvent::SendAnnouncementSignatures { .. } = event { - } else { - panic!("Wrong event type"); + match event { + MessageSendEvent::SendAnnouncementSignatures { .. } => {}, + MessageSendEvent::SendChannelUpdate { ref node_id, ref msg } => { + for dest_node in $nodes.iter() { + if dest_node.get_our_node_id() == *node_id { + dest_node.handle_channel_update(node.get_our_node_id(), msg); + } + } + }, + _ => { + panic!("Wrong event type in second lock_fundings pass: {:?}", event); + }, } } } @@ -1303,21 +1537,55 @@ pub fn do_test(data: &[u8], out: Out) { let wallet_c = TestWalletSource::new(SecretKey::from_slice(&[3; 32]).unwrap()); let wallets = vec![wallet_a, wallet_b, wallet_c]; - let coinbase_tx = bitcoin::Transaction { - version: bitcoin::transaction::Version::TWO, - lock_time: bitcoin::absolute::LockTime::ZERO, - input: vec![bitcoin::TxIn { ..Default::default() }], - output: wallets - .iter() - .map(|w| TxOut { - value: Amount::from_sat(100_000), - script_pubkey: w.get_change_script().unwrap(), - }) - .collect(), + // Create wallet UTXOs for each node. Each anchor-channel HTLC claim + // needs a wallet input for fees, so we create enough UTXOs to cover + // multiple concurrent claims. + let num_wallet_utxos = 50; + for (wallet_idx, w) in wallets.iter().enumerate() { + let coinbase_tx = bitcoin::Transaction { + version: bitcoin::transaction::Version(wallet_idx as i32 + 100), + lock_time: bitcoin::absolute::LockTime::ZERO, + input: vec![bitcoin::TxIn { ..Default::default() }], + output: (0..num_wallet_utxos) + .map(|_| TxOut { + value: Amount::from_sat(100_000), + script_pubkey: w.get_change_script().unwrap(), + }) + .collect(), + }; + for vout in 0..num_wallet_utxos { + w.add_utxo(coinbase_tx.clone(), vout); + } + chain_state.confirm_tx(coinbase_tx); + } + let sync_wallets_with_confirmed_tx = |tx: &Transaction| { + for wallet in &wallets { + let change_script = wallet.get_change_script().unwrap(); + for input in &tx.input { + wallet.remove_utxo(input.previous_output); + } + for (vout, output) in tx.output.iter().enumerate() { + if output.script_pubkey == change_script { + wallet.add_utxo(tx.clone(), vout as u32); + } + } + } + }; + let confirm_tx_and_sync_wallets = |chain_state: &mut ChainState, tx: Transaction| -> bool { + if chain_state.confirm_tx(tx.clone()) { + sync_wallets_with_confirmed_tx(&tx); + true + } else { + false + } + }; + let should_retry_confirm_later = |chain_state: &ChainState, tx: &Transaction| { + let lock_time = tx.lock_time.to_consensus_u32(); + lock_time > 0 + && lock_time < 500_000_000 + && lock_time & (1 << 29) == 0 + && chain_state.tip_height() < lock_time }; - wallets.iter().enumerate().for_each(|(i, w)| { - w.add_utxo(coinbase_tx.clone(), i as u32); - }); let fee_est_a = Arc::new(FuzzEstimator { ret_val: atomic::AtomicU32::new(253) }); let mut last_htlc_clear_fee_a = 253; @@ -1344,10 +1612,11 @@ pub fn do_test(data: &[u8], out: Out) { // Create 3 channels between A-B and 3 channels between B-C (6 total). // - // Use version numbers 1-6 to avoid txid collisions under fuzz hashing. - // Fuzz mode uses XOR-based hashing (all bytes XOR to one byte), and - // versions 0-5 cause collisions between A-B and B-C channel pairs - // (e.g., A-B with Version(1) collides with B-C with Version(3)). + // Use distinct version numbers 1-6 so each test channel gets its own txid and funding + // outpoint, and to avoid txid collisions under fuzz hashing. + // Fuzz mode uses XOR-based hashing (all bytes XOR to one byte), and versions 0-5 cause + // collisions between A-B and B-C channel pairs (e.g., A-B with Version(1) collides with + // B-C with Version(3)). // A-B: channel 2 A and B have 0-reserve (trusted open + trusted accept), // channel 3 A has 0-reserve (trusted accept) make_channel!(nodes[0], nodes[1], monitor_a, monitor_b, keys_manager_b, 1, false, false); @@ -1367,6 +1636,7 @@ pub fn do_test(data: &[u8], out: Out) { let sync_with_chain_state = |chain_state: &ChainState, node: &ChannelManager<_, _, _, _, _, _, _, _, _>, + monitor: &TestChainMonitor, node_height: &mut u32, num_blocks: Option| { let target_height = if let Some(num_blocks) = num_blocks { @@ -1376,20 +1646,39 @@ pub fn do_test(data: &[u8], out: Out) { }; while *node_height < target_height { - *node_height += 1; + let mut next_height = *node_height + 1; + while next_height <= target_height && chain_state.block_at(next_height).1.is_empty() { + next_height += 1; + } + if next_height > target_height { + *node_height = target_height; + let (header, _) = chain_state.block_at(*node_height); + monitor.chain_monitor.best_block_updated(header, *node_height); + node.best_block_updated(header, *node_height); + break; + } + if next_height > *node_height + 1 { + *node_height = next_height - 1; + let (header, _) = chain_state.block_at(*node_height); + monitor.chain_monitor.best_block_updated(header, *node_height); + node.best_block_updated(header, *node_height); + } + *node_height = next_height; let (header, txn) = chain_state.block_at(*node_height); let txdata: Vec<_> = txn.iter().enumerate().map(|(i, tx)| (i + 1, tx)).collect(); if !txdata.is_empty() { + monitor.chain_monitor.transactions_confirmed(header, &txdata, *node_height); node.transactions_confirmed(header, &txdata, *node_height); } + monitor.chain_monitor.best_block_updated(header, *node_height); node.best_block_updated(header, *node_height); } }; // Sync all nodes to tip to lock the funding. - sync_with_chain_state(&mut chain_state, &nodes[0], &mut node_height_a, None); - sync_with_chain_state(&mut chain_state, &nodes[1], &mut node_height_b, None); - sync_with_chain_state(&mut chain_state, &nodes[2], &mut node_height_c, None); + sync_with_chain_state(&mut chain_state, &nodes[0], &monitor_a, &mut node_height_a, None); + sync_with_chain_state(&mut chain_state, &nodes[1], &monitor_b, &mut node_height_b, None); + sync_with_chain_state(&mut chain_state, &nodes[2], &monitor_c, &mut node_height_c, None); lock_fundings!(nodes); @@ -1424,18 +1713,20 @@ pub fn do_test(data: &[u8], out: Out) { let resolved_payments: RefCell<[HashMap>; 3]> = RefCell::new([new_hash_map(), new_hash_map(), new_hash_map()]); let claimed_payment_hashes: RefCell> = RefCell::new(HashSet::new()); + let payment_preimages: RefCell> = + RefCell::new(new_hash_map()); + let closed_channels: RefCell> = RefCell::new(HashSet::new()); macro_rules! test_return { () => {{ - assert_eq!(nodes[0].list_channels().len(), 3); - assert_eq!(nodes[1].list_channels().len(), 6); - assert_eq!(nodes[2].list_channels().len(), 3); + assert!(nodes[0].list_channels().len() <= 3); + assert!(nodes[1].list_channels().len() <= 6); + assert!(nodes[2].list_channels().len() <= 3); - // All broadcasters should be empty (all broadcast transactions should be handled - // explicitly). - assert!(broadcast_a.txn_broadcasted.borrow().is_empty()); - assert!(broadcast_b.txn_broadcasted.borrow().is_empty()); - assert!(broadcast_c.txn_broadcasted.borrow().is_empty()); + // Drain broadcasters since force-closes produce commitment transactions. + broadcast_a.txn_broadcasted.borrow_mut().clear(); + broadcast_b.txn_broadcasted.borrow_mut().clear(); + broadcast_c.txn_broadcasted.borrow_mut().clear(); return; }}; @@ -1616,7 +1907,13 @@ pub fn do_test(data: &[u8], out: Out) { *node_id == a_id }, MessageSendEvent::HandleError { ref action, ref node_id } => { - assert_action_timeout_awaiting_response(action); + match action { + msgs::ErrorAction::DisconnectPeerWithWarning { msg } + if msg.data.contains("Disconnecting due to timeout awaiting response") => {}, + msgs::ErrorAction::DisconnectPeer { .. } => {}, + msgs::ErrorAction::SendErrorMessage { .. } => {}, + _ => panic!("Unexpected HandleError action {:?}", action), + } if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); } *node_id == a_id }, @@ -1734,6 +2031,17 @@ pub fn do_test(data: &[u8], out: Out) { } }, MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } => { + if msg.next_local_commitment_number == 0 + && msg.next_remote_commitment_number == 0 + { + // Skip bogus reestablish (lnd workaround). All fuzzer + // nodes are LDK and will already force-close via the + // error message path. Delivering these between LDK + // nodes creates an infinite ping-pong since both sides + // respond with another bogus reestablish for the + // unknown channel. + continue; + } for (idx, dest) in nodes.iter().enumerate() { if dest.get_our_node_id() == *node_id { out.locked_write(format!("Delivering channel_reestablish from node {} to node {}.\n", $node, idx).as_bytes()); @@ -1845,22 +2153,51 @@ pub fn do_test(data: &[u8], out: Out) { } } }, - MessageSendEvent::HandleError { ref action, .. } => { - assert_action_timeout_awaiting_response(action); - }, - MessageSendEvent::SendChannelReady { .. } => { - // Can be generated as a reestablish response - }, - MessageSendEvent::SendAnnouncementSignatures { .. } => { - // Can be generated as a reestablish response - }, - MessageSendEvent::SendChannelUpdate { .. } => { - // Can be generated as a reestablish response + MessageSendEvent::HandleError { ref action, ref node_id } => { + match action { + msgs::ErrorAction::DisconnectPeerWithWarning { msg } + if msg.data.contains("Disconnecting due to timeout awaiting response") => {}, + msgs::ErrorAction::DisconnectPeer { .. } => {}, + msgs::ErrorAction::SendErrorMessage { ref msg } => { + for dest in nodes.iter() { + if dest.get_our_node_id() == *node_id { + dest.handle_error(nodes[$node].get_our_node_id(), msg); + } + } + }, + _ => panic!("Unexpected HandleError action {:?}", action), + } }, + MessageSendEvent::SendChannelReady { ref node_id, ref msg } => { + for (idx, dest) in nodes.iter().enumerate() { + if dest.get_our_node_id() == *node_id { + out.locked_write(format!("Delivering channel_ready from node {} to node {}.\n", $node, idx).as_bytes()); + dest.handle_channel_ready(nodes[$node].get_our_node_id(), msg); + } + } + }, + MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => { + for (idx, dest) in nodes.iter().enumerate() { + if dest.get_our_node_id() == *node_id { + out.locked_write(format!("Delivering announcement_signatures from node {} to node {}.\n", $node, idx).as_bytes()); + dest.handle_announcement_signatures(nodes[$node].get_our_node_id(), msg); + } + } + }, + MessageSendEvent::SendChannelUpdate { ref node_id, ref msg } => { + for (idx, dest) in nodes.iter().enumerate() { + if dest.get_our_node_id() == *node_id { + out.locked_write(format!("Delivering channel_update from node {} to node {}.\n", $node, idx).as_bytes()); + dest.handle_channel_update(nodes[$node].get_our_node_id(), msg); + } + } + }, MessageSendEvent::BroadcastChannelUpdate { .. } => { // Can be generated as a result of calling `timer_tick_occurred` enough // times while peers are disconnected }, + MessageSendEvent::BroadcastChannelAnnouncement { .. } => {}, + MessageSendEvent::BroadcastNodeAnnouncement { .. } => {}, _ => panic!("Unhandled message event {:?}", event), } if $limit_events != ProcessMessages::AllMessages { @@ -1898,9 +2235,17 @@ pub fn do_test(data: &[u8], out: Out) { MessageSendEvent::SendChannelReady { .. } => {}, MessageSendEvent::SendAnnouncementSignatures { .. } => {}, MessageSendEvent::BroadcastChannelUpdate { .. } => {}, + MessageSendEvent::BroadcastChannelAnnouncement { .. } => {}, + MessageSendEvent::BroadcastNodeAnnouncement { .. } => {}, MessageSendEvent::SendChannelUpdate { .. } => {}, - MessageSendEvent::HandleError { ref action, .. } => { - assert_action_timeout_awaiting_response(action); + MessageSendEvent::HandleError { ref action, .. } => match action { + msgs::ErrorAction::DisconnectPeerWithWarning { msg } + if msg.data.contains( + "Disconnecting due to timeout awaiting response", + ) => {}, + msgs::ErrorAction::DisconnectPeer { .. } => {}, + msgs::ErrorAction::SendErrorMessage { .. } => {}, + _ => panic!("Unexpected HandleError action {:?}", action), }, _ => panic!("Unhandled message event"), } @@ -1921,9 +2266,17 @@ pub fn do_test(data: &[u8], out: Out) { MessageSendEvent::SendChannelReady { .. } => {}, MessageSendEvent::SendAnnouncementSignatures { .. } => {}, MessageSendEvent::BroadcastChannelUpdate { .. } => {}, + MessageSendEvent::BroadcastChannelAnnouncement { .. } => {}, + MessageSendEvent::BroadcastNodeAnnouncement { .. } => {}, MessageSendEvent::SendChannelUpdate { .. } => {}, - MessageSendEvent::HandleError { ref action, .. } => { - assert_action_timeout_awaiting_response(action); + MessageSendEvent::HandleError { ref action, .. } => match action { + msgs::ErrorAction::DisconnectPeerWithWarning { msg } + if msg.data.contains( + "Disconnecting due to timeout awaiting response", + ) => {}, + msgs::ErrorAction::DisconnectPeer { .. } => {}, + msgs::ErrorAction::SendErrorMessage { .. } => {}, + _ => panic!("Unexpected HandleError action {:?}", action), }, _ => panic!("Unhandled message event"), } @@ -1940,9 +2293,8 @@ pub fn do_test(data: &[u8], out: Out) { macro_rules! process_events { ($node: expr, $fail: expr) => {{ - // In case we get 256 payments we may have a hash collision, resulting in the - // second claim/fail call not finding the duplicate-hash HTLC, so we have to - // deduplicate the calls here. + // Multiple HTLCs can resolve for the same payment hash, so deduplicate + // claim/fail handling per event batch. let mut claim_set = new_hash_map(); let mut events = nodes[$node].get_and_clear_pending_events(); let had_events = !events.is_empty(); @@ -1955,7 +2307,11 @@ pub fn do_test(data: &[u8], out: Out) { if $fail { nodes[$node].fail_htlc_backwards(&payment_hash); } else { - nodes[$node].claim_funds(PaymentPreimage(payment_hash.0)); + let payment_preimage = *payment_preimages + .borrow() + .get(&payment_hash) + .expect("PaymentClaimable for unknown payment hash"); + nodes[$node].claim_funds(payment_preimage); claimed_payment_hashes.borrow_mut().insert(payment_hash); } } @@ -2003,6 +2359,16 @@ pub fn do_test(data: &[u8], out: Out) { events::Event::PaymentPathFailed { .. } => {}, events::Event::PaymentForwarded { .. } if $node == 1 => {}, events::Event::ChannelReady { .. } => {}, + events::Event::HTLCHandlingFailed { + failure_type: events::HTLCHandlingFailureType::Receive { payment_hash }, + .. + } => { + // The receiver failed to handle this HTLC (e.g., HTLC + // timeout won the race against the claim). Remove it from + // claimed hashes so we don't assert that the sender must + // have received PaymentSent. + claimed_payment_hashes.borrow_mut().remove(&payment_hash); + }, events::Event::HTLCHandlingFailed { .. } => {}, events::Event::FundingTransactionReadyForSigning { @@ -2021,22 +2387,32 @@ pub fn do_test(data: &[u8], out: Out) { .unwrap(); }, events::Event::SplicePending { new_funding_txo, .. } => { - let broadcaster = match $node { - 0 => &broadcast_a, - 1 => &broadcast_b, - _ => &broadcast_c, - }; - let mut txs = broadcaster.txn_broadcasted.borrow_mut(); - assert!(txs.len() >= 1); - let splice_tx = txs.remove(0); - assert_eq!(new_funding_txo.txid, splice_tx.compute_txid()); - chain_state.confirm_tx(splice_tx); + if !chain_state.confirmed_txids.contains(&new_funding_txo.txid) { + let broadcaster = match $node { + 0 => &broadcast_a, + 1 => &broadcast_b, + _ => &broadcast_c, + }; + let mut txs = broadcaster.txn_broadcasted.borrow_mut(); + if let Some(pos) = txs + .iter() + .position(|tx| new_funding_txo.txid == tx.compute_txid()) + { + let splice_tx = txs.remove(pos); + confirm_tx_and_sync_wallets(&mut chain_state, splice_tx); + } + // If not found, the settlement drain loop already + // removed it from the broadcaster but confirm_tx + // rejected it (e.g. inputs already spent). + } }, events::Event::SpliceFailed { .. } => {}, - events::Event::DiscardFunding { - funding_info: events::FundingInfo::Contribution { .. }, - .. - } => {}, + events::Event::ChannelClosed { channel_id, .. } => { + closed_channels.borrow_mut().insert(channel_id); + }, + events::Event::DiscardFunding { .. } => {}, + events::Event::SpendableOutputs { .. } => {}, + events::Event::BumpTransaction(..) => {}, _ => panic!("Unhandled event"), } @@ -2067,7 +2443,7 @@ pub fn do_test(data: &[u8], out: Out) { ); if let Some((id, data)) = compl_selector(&mut state.pending_monitors) { monitor.chain_monitor.channel_monitor_updated(*chan_funding, id).unwrap(); - if id > state.persisted_monitor_id { + if id >= state.persisted_monitor_id { state.persisted_monitor_id = id; state.persisted_monitor = data; } @@ -2076,26 +2452,29 @@ pub fn do_test(data: &[u8], out: Out) { }; let complete_all_monitor_updates = |monitor: &Arc, chan_id| { + let mut completed_any = false; if let Some(state) = monitor.latest_monitors.lock().unwrap().get_mut(chan_id) { assert!( state.pending_monitors.windows(2).all(|pair| pair[0].0 < pair[1].0), "updates should be sorted by id" ); for (id, data) in state.pending_monitors.drain(..) { + completed_any = true; monitor.chain_monitor.channel_monitor_updated(*chan_id, id).unwrap(); - if id > state.persisted_monitor_id { + if id >= state.persisted_monitor_id { state.persisted_monitor_id = id; state.persisted_monitor = data; } } } + completed_any }; let send = |source_idx: usize, dest_idx: usize, dest_chan_id, amt, payment_ctr: &mut u64| { let source = &nodes[source_idx]; let dest = &nodes[dest_idx]; - let (secret, hash) = get_payment_secret_hash(dest, payment_ctr); + let (secret, hash) = get_payment_secret_hash(dest, payment_ctr, &payment_preimages); let mut id = PaymentId([0; 32]); id.0[0..8].copy_from_slice(&payment_ctr.to_ne_bytes()); let succeeded = send_payment(source, dest, dest_chan_id, amt, secret, hash, id); @@ -2118,7 +2497,7 @@ pub fn do_test(data: &[u8], out: Out) { let source = &nodes[source_idx]; let middle = &nodes[middle_idx]; let dest = &nodes[dest_idx]; - let (secret, hash) = get_payment_secret_hash(dest, payment_ctr); + let (secret, hash) = get_payment_secret_hash(dest, payment_ctr, &payment_preimages); let mut id = PaymentId([0; 32]); id.0[0..8].copy_from_slice(&payment_ctr.to_ne_bytes()); let succeeded = send_hop_payment( @@ -2145,7 +2524,7 @@ pub fn do_test(data: &[u8], out: Out) { payment_ctr: &mut u64| { let source = &nodes[source_idx]; let dest = &nodes[dest_idx]; - let (secret, hash) = get_payment_secret_hash(dest, payment_ctr); + let (secret, hash) = get_payment_secret_hash(dest, payment_ctr, &payment_preimages); let mut id = PaymentId([0; 32]); id.0[0..8].copy_from_slice(&payment_ctr.to_ne_bytes()); let succeeded = send_mpp_payment(source, dest, dest_chan_ids, amt, secret, hash, id); @@ -2165,7 +2544,7 @@ pub fn do_test(data: &[u8], out: Out) { let source = &nodes[source_idx]; let middle = &nodes[middle_idx]; let dest = &nodes[dest_idx]; - let (secret, hash) = get_payment_secret_hash(dest, payment_ctr); + let (secret, hash) = get_payment_secret_hash(dest, payment_ctr, &payment_preimages); let mut id = PaymentId([0; 32]); id.0[0..8].copy_from_slice(&payment_ctr.to_ne_bytes()); let succeeded = send_mpp_hop_payment( @@ -2184,6 +2563,321 @@ pub fn do_test(data: &[u8], out: Out) { } }; + macro_rules! has_pending_monitor_updates { + () => {{ + [&monitor_a, &monitor_b, &monitor_c].iter().any(|monitor| { + monitor + .latest_monitors + .lock() + .unwrap() + .values() + .any(|state| !state.pending_monitors.is_empty()) + }) + }}; + } + macro_rules! has_time_dependent_work { + () => {{ + let open_channels = nodes[0] + .list_channels() + .iter() + .chain(nodes[1].list_channels().iter()) + .chain(nodes[2].list_channels().iter()) + .cloned() + .collect::>(); + let open_refs: Vec<&_> = open_channels.iter().collect(); + [&monitor_a, &monitor_b, &monitor_c].iter().any(|monitor| { + monitor.chain_monitor.get_claimable_balances(&open_refs).iter().any(|balance| { + matches!( + balance, + Balance::ContentiousClaimable { .. } + | Balance::MaybeTimeoutClaimableHTLC { .. } + | Balance::MaybePreimageClaimableHTLC { .. } + | Balance::CounterpartyRevokedOutputClaimable { .. } + ) + }) + }) + }}; + } + macro_rules! has_pending_work { + () => {{ + !ab_events.is_empty() + || !ba_events.is_empty() + || !bc_events.is_empty() + || !cb_events.is_empty() + || !broadcast_a.txn_broadcasted.borrow().is_empty() + || !broadcast_b.txn_broadcasted.borrow().is_empty() + || !broadcast_c.txn_broadcasted.borrow().is_empty() + || has_pending_monitor_updates!() + || has_time_dependent_work!() + }}; + } + macro_rules! pending_work_summary { + () => {{ + let open_channels = nodes[0] + .list_channels() + .iter() + .chain(nodes[1].list_channels().iter()) + .chain(nodes[2].list_channels().iter()) + .cloned() + .collect::>(); + let open_refs: Vec<&_> = open_channels.iter().collect(); + let balances_a = monitor_a.chain_monitor.get_claimable_balances(&open_refs); + let balances_b = monitor_b.chain_monitor.get_claimable_balances(&open_refs); + let balances_c = monitor_c.chain_monitor.get_claimable_balances(&open_refs); + format!( + "queues ab={} ba={} bc={} cb={} bcast=({},{},{}) pending=({},{},{}) monitor_updates={} timed_work={} heights=({},{},{}) tip={} balances_a=[{}] balances_b=[{}] balances_c=[{}]", + ab_events.len(), + ba_events.len(), + bc_events.len(), + cb_events.len(), + broadcast_a.txn_broadcasted.borrow().len(), + broadcast_b.txn_broadcasted.borrow().len(), + broadcast_c.txn_broadcasted.borrow().len(), + pending_payments.borrow()[0].len(), + pending_payments.borrow()[1].len(), + pending_payments.borrow()[2].len(), + has_pending_monitor_updates!(), + has_time_dependent_work!(), + node_height_a, + node_height_b, + node_height_c, + chain_state.tip_height(), + summarize_balances(&balances_a), + summarize_balances(&balances_b), + summarize_balances(&balances_c), + ) + }}; + } + + macro_rules! flush_progress { + ($max_iters: expr) => {{ + let mut last_pass_no_updates = false; + for _ in 0..$max_iters { + let mut completed_monitor_update = false; + for id in &chan_ab_ids { + completed_monitor_update |= complete_all_monitor_updates(&monitor_a, id); + completed_monitor_update |= complete_all_monitor_updates(&monitor_b, id); + } + for id in &chan_bc_ids { + completed_monitor_update |= complete_all_monitor_updates(&monitor_b, id); + completed_monitor_update |= complete_all_monitor_updates(&monitor_c, id); + } + let mut had_msg_or_ev = false; + if process_msg_events!(0, false, ProcessMessages::AllMessages) { + had_msg_or_ev = true; + } + if process_msg_events!(1, false, ProcessMessages::AllMessages) { + had_msg_or_ev = true; + } + if process_msg_events!(2, false, ProcessMessages::AllMessages) { + had_msg_or_ev = true; + } + if process_events!(0, false) { + had_msg_or_ev = true; + } + if process_events!(1, false) { + had_msg_or_ev = true; + } + if process_events!(2, false) { + had_msg_or_ev = true; + } + sync_with_chain_state( + &chain_state, + &nodes[0], + &monitor_a, + &mut node_height_a, + None, + ); + sync_with_chain_state( + &chain_state, + &nodes[1], + &monitor_b, + &mut node_height_b, + None, + ); + sync_with_chain_state( + &chain_state, + &nodes[2], + &monitor_c, + &mut node_height_c, + None, + ); + { + let monitors = [&monitor_a, &monitor_b, &monitor_c]; + let broadcasters: [&Arc; 3] = + [&broadcast_a, &broadcast_b, &broadcast_c]; + let keys_managers = [&keys_manager_a, &keys_manager_b, &keys_manager_c]; + for (idx, monitor) in monitors.iter().enumerate() { + let wallet = WalletSync::new(&wallets[idx], Arc::clone(&loggers[idx])); + let handler = BumpTransactionEventHandlerSync::new( + broadcasters[idx].as_ref(), + &wallet, + keys_managers[idx].as_ref(), + Arc::clone(&loggers[idx]), + ); + let broadcaster = broadcasters[idx]; + monitor.chain_monitor.process_pending_events( + &|event: events::Event| { + if let events::Event::BumpTransaction(ref bump) = event { + match bump { + // Commitment transactions are already + // fully assembled by LDK when a channel + // closes, so the harness can broadcast + // them directly. + events::bump_transaction::BumpTransactionEvent::ChannelClose { + commitment_tx, + channel_id, + counterparty_node_id, + .. + } => { + broadcaster.broadcast_transactions(&[( + commitment_tx, + lightning::chain::chaininterface::TransactionType::UnilateralClose { + counterparty_node_id: *counterparty_node_id, + channel_id: *channel_id, + }, + )]); + }, + // HTLC resolution events need wallet-backed + // coin selection and signer access. Route + // those through the sync bump handler so the + // resulting claims look like real post-close + // transactions. + events::bump_transaction::BumpTransactionEvent::HTLCResolution { .. } => { + handler.handle_event(bump); + }, + } + } + Ok(()) + }, + ); + } + } + let mut had_new_txs = false; + for confirm_iter in 0..32 { + let mut found = false; + let mut pending_txs: Vec = Vec::new(); + for tx in broadcast_a.txn_broadcasted.borrow_mut().drain(..) { + pending_txs.push(tx); + } + for tx in broadcast_b.txn_broadcasted.borrow_mut().drain(..) { + pending_txs.push(tx); + } + for tx in broadcast_c.txn_broadcasted.borrow_mut().drain(..) { + pending_txs.push(tx); + } + pending_txs.sort_by_key(|tx| tx.lock_time.to_consensus_u32()); + let mut deferred_txs = pending_txs; + loop { + let mut next_deferred_txs = Vec::new(); + let mut progressed = false; + for tx in deferred_txs { + if confirm_tx_and_sync_wallets(&mut chain_state, tx.clone()) { + found = true; + progressed = true; + } else { + next_deferred_txs.push(tx); + } + } + if !progressed { + // Keep only transactions that could become + // valid later, e.g. children waiting on their + // parent or timelocked claims waiting on height. + // Permanently stale conflicting spends should be + // dropped here or they create fake non-quiescence. + deferred_txs = next_deferred_txs + .into_iter() + .filter(|tx| should_retry_confirm_later(&chain_state, tx)) + .collect(); + break; + } + deferred_txs = next_deferred_txs; + } + if !deferred_txs.is_empty() { + broadcast_a + .txn_broadcasted + .borrow_mut() + .extend(deferred_txs.into_iter()); + } + if !found { + break; + } + assert!( + confirm_iter < 31, + "flush_progress tx confirmation loop failed to quiesce: {}", + pending_work_summary!() + ); + had_new_txs = true; + sync_with_chain_state( + &chain_state, + &nodes[0], + &monitor_a, + &mut node_height_a, + None, + ); + sync_with_chain_state( + &chain_state, + &nodes[1], + &monitor_b, + &mut node_height_b, + None, + ); + sync_with_chain_state( + &chain_state, + &nodes[2], + &monitor_c, + &mut node_height_c, + None, + ); + } + if completed_monitor_update || had_new_txs || had_msg_or_ev { + last_pass_no_updates = false; + continue; + } + if last_pass_no_updates { + break; + } + last_pass_no_updates = true; + } + assert!( + !has_pending_work!() || last_pass_no_updates, + "flush_progress exhausted {} iterations without quiescing: {}", + $max_iters, + pending_work_summary!() + ); + assert!( + !has_pending_work!() || !last_pass_no_updates || $max_iters > 0, + "flush_progress made no progress: {}", + pending_work_summary!() + ); + }}; + } + + macro_rules! advance_chain_carefully { + ($num_blocks: expr) => {{ + for _ in 0..$num_blocks { + // The force-close corpus used to jump 50/100/200 blocks in + // one shot, which made timeout paths dominate simply because + // queued messages, monitor completions, and claim propagation + // never got a chance to run. Advancing one block at a time + // with a bounded drain on both sides keeps those races + // possible without making them the default outcome. + flush_progress!(32); + if !has_pending_work!() { + // Stop early once there is nothing left that another + // empty block could unlock. Blindly consuming the entire + // requested jump mostly adds noise. + break; + } + chain_state.advance_height(1); + flush_progress!(32); + if !has_pending_work!() { + break; + } + } + }}; + } + let v = get_slice!(1)[0]; out.locked_write(format!("READ A BYTE! HANDLING INPUT {:x}...........\n", v).as_bytes()); match v { @@ -2506,13 +3200,49 @@ pub fn do_test(data: &[u8], out: Out) { }, // Sync node by 1 block to cover confirmation of a transaction. - 0xa8 => sync_with_chain_state(&mut chain_state, &nodes[0], &mut node_height_a, Some(1)), - 0xa9 => sync_with_chain_state(&mut chain_state, &nodes[1], &mut node_height_b, Some(1)), - 0xaa => sync_with_chain_state(&mut chain_state, &nodes[2], &mut node_height_c, Some(1)), + 0xa8 => sync_with_chain_state( + &mut chain_state, + &nodes[0], + &monitor_a, + &mut node_height_a, + Some(1), + ), + 0xa9 => sync_with_chain_state( + &mut chain_state, + &nodes[1], + &monitor_b, + &mut node_height_b, + Some(1), + ), + 0xaa => sync_with_chain_state( + &mut chain_state, + &nodes[2], + &monitor_c, + &mut node_height_c, + Some(1), + ), // Sync node to chain tip to cover confirmation of a transaction post-reorg-risk. - 0xab => sync_with_chain_state(&mut chain_state, &nodes[0], &mut node_height_a, None), - 0xac => sync_with_chain_state(&mut chain_state, &nodes[1], &mut node_height_b, None), - 0xad => sync_with_chain_state(&mut chain_state, &nodes[2], &mut node_height_c, None), + 0xab => sync_with_chain_state( + &mut chain_state, + &nodes[0], + &monitor_a, + &mut node_height_a, + None, + ), + 0xac => sync_with_chain_state( + &mut chain_state, + &nodes[1], + &monitor_b, + &mut node_height_b, + None, + ), + 0xad => sync_with_chain_state( + &mut chain_state, + &nodes[2], + &monitor_c, + &mut node_height_c, + None, + ), 0xb0 | 0xb1 | 0xb2 => { // Restart node A, picking among the in-flight `ChannelMonitor`s to use based on @@ -2603,55 +3333,137 @@ pub fn do_test(data: &[u8], out: Out) { }, 0xc4 => { keys_manager_b.enable_op_for_all_signers(SignerOp::SignCounterpartyCommitment); - let filter = Some((nodes[0].get_our_node_id(), chan_a_id)); - nodes[1].signer_unblocked(filter); + nodes[1].signer_unblocked(None); }, 0xc5 => { - keys_manager_b.enable_op_for_all_signers(SignerOp::SignCounterpartyCommitment); - let filter = Some((nodes[2].get_our_node_id(), chan_b_id)); - nodes[1].signer_unblocked(filter); - }, - 0xc6 => { keys_manager_c.enable_op_for_all_signers(SignerOp::SignCounterpartyCommitment); nodes[2].signer_unblocked(None); }, - 0xc7 => { + 0xc6 => { keys_manager_a.enable_op_for_all_signers(SignerOp::GetPerCommitmentPoint); nodes[0].signer_unblocked(None); }, - 0xc8 => { - keys_manager_b.enable_op_for_all_signers(SignerOp::GetPerCommitmentPoint); - let filter = Some((nodes[0].get_our_node_id(), chan_a_id)); - nodes[1].signer_unblocked(filter); - }, - 0xc9 => { + 0xc7 => { keys_manager_b.enable_op_for_all_signers(SignerOp::GetPerCommitmentPoint); - let filter = Some((nodes[2].get_our_node_id(), chan_b_id)); - nodes[1].signer_unblocked(filter); + nodes[1].signer_unblocked(None); }, - 0xca => { + 0xc8 => { keys_manager_c.enable_op_for_all_signers(SignerOp::GetPerCommitmentPoint); nodes[2].signer_unblocked(None); }, - 0xcb => { + 0xc9 => { keys_manager_a.enable_op_for_all_signers(SignerOp::ReleaseCommitmentSecret); nodes[0].signer_unblocked(None); }, - 0xcc => { + 0xca => { keys_manager_b.enable_op_for_all_signers(SignerOp::ReleaseCommitmentSecret); - let filter = Some((nodes[0].get_our_node_id(), chan_a_id)); - nodes[1].signer_unblocked(filter); + nodes[1].signer_unblocked(None); + }, + 0xcb => { + keys_manager_c.enable_op_for_all_signers(SignerOp::ReleaseCommitmentSecret); + nodes[2].signer_unblocked(None); + }, + 0xcc => { + keys_manager_a.enable_op_for_all_signers(SignerOp::SignHolderCommitment); + nodes[0].signer_unblocked(None); }, 0xcd => { - keys_manager_b.enable_op_for_all_signers(SignerOp::ReleaseCommitmentSecret); - let filter = Some((nodes[2].get_our_node_id(), chan_b_id)); - nodes[1].signer_unblocked(filter); + keys_manager_b.enable_op_for_all_signers(SignerOp::SignHolderCommitment); + nodes[1].signer_unblocked(None); }, 0xce => { - keys_manager_c.enable_op_for_all_signers(SignerOp::ReleaseCommitmentSecret); + keys_manager_c.enable_op_for_all_signers(SignerOp::SignHolderCommitment); + nodes[2].signer_unblocked(None); + }, + 0xcf => { + keys_manager_a.enable_op_for_all_signers(SignerOp::SignHolderHtlcTransaction); + keys_manager_b.enable_op_for_all_signers(SignerOp::SignHolderHtlcTransaction); + keys_manager_c.enable_op_for_all_signers(SignerOp::SignHolderHtlcTransaction); + nodes[0].signer_unblocked(None); + nodes[1].signer_unblocked(None); nodes[2].signer_unblocked(None); }, + // User-triggered force-close opcodes. These are only the start of + // the interesting behavior: they enqueue commitment broadcasts, + // monitor updates, close events, and later HTLC claims. The settle + // opcode below is what drives those consequences to quiescence. + 0xd0 => { + if nodes[0] + .force_close_broadcasting_latest_txn( + &chan_a_id, + &nodes[1].get_our_node_id(), + "]]]]]]]]".to_string(), + ) + .is_ok() + { + closed_channels.borrow_mut().insert(chan_a_id); + } + }, + 0xd1 => { + if nodes[1] + .force_close_broadcasting_latest_txn( + &chan_b_id, + &nodes[2].get_our_node_id(), + "]]]]]]]".to_string(), + ) + .is_ok() + { + closed_channels.borrow_mut().insert(chan_b_id); + } + }, + 0xd2 => { + if nodes[1] + .force_close_broadcasting_latest_txn( + &chan_a_id, + &nodes[0].get_our_node_id(), + "]]]]]]".to_string(), + ) + .is_ok() + { + closed_channels.borrow_mut().insert(chan_a_id); + } + }, + 0xd3 => { + if nodes[2] + .force_close_broadcasting_latest_txn( + &chan_b_id, + &nodes[1].get_our_node_id(), + "]]]]]".to_string(), + ) + .is_ok() + { + closed_channels.borrow_mut().insert(chan_b_id); + } + }, + + // Low-level confirmation helpers. These are intentionally blunt; + // they let the fuzzer force individual broadcasters onto chain, + // while `0xff` performs the more realistic multi-round settle. + 0xd8 => { + for tx in broadcast_a.txn_broadcasted.borrow_mut().drain(..) { + confirm_tx_and_sync_wallets(&mut chain_state, tx); + } + }, + 0xd9 => { + for tx in broadcast_b.txn_broadcasted.borrow_mut().drain(..) { + confirm_tx_and_sync_wallets(&mut chain_state, tx); + } + }, + 0xda => { + for tx in broadcast_c.txn_broadcasted.borrow_mut().drain(..) { + confirm_tx_and_sync_wallets(&mut chain_state, tx); + } + }, + + // Large synthetic height jumps. These exist so the corpus can + // reach CLTV and CSV-based force-close resolution states, but the + // helper above keeps them from becoming unrealistic "skip the + // network and time everything out" buttons. + 0xdc => advance_chain_carefully!(50), + 0xdd => advance_chain_carefully!(100), + 0xde => advance_chain_carefully!(200), + 0xf0 => { for id in &chan_ab_ids { complete_monitor_update(&monitor_a, id, &complete_first); @@ -2761,45 +3573,219 @@ pub fn do_test(data: &[u8], out: Out) { nodes[1].signer_unblocked(None); nodes[2].signer_unblocked(None); + // Restarts may intentionally reload an older persisted monitor. + // Before settling, catch those monitors up to the harness' + // current height without rewinding the `ChannelManager`. This + // preserves the stale-monitor replay scenario while avoiding a + // fake reorg inside the node itself. + for (monitor, node_height) in [ + (&monitor_a, &node_height_a), + (&monitor_b, &node_height_b), + (&monitor_c, &node_height_c), + ] { + let mut min_monitor_height = *node_height; + for chan_id in monitor.chain_monitor.list_monitors() { + if let Ok(mon) = monitor.chain_monitor.get_monitor(chan_id) { + min_monitor_height = + std::cmp::min(min_monitor_height, mon.current_best_block().height); + } + } + let mut h = min_monitor_height; + while h < *node_height { + let mut next_height = h + 1; + while next_height <= *node_height + && chain_state.block_at(next_height).1.is_empty() + { + next_height += 1; + } + if next_height > *node_height { + h = *node_height; + let (header, _) = chain_state.block_at(h); + monitor.chain_monitor.best_block_updated(header, h); + break; + } + if next_height > h + 1 { + h = next_height - 1; + let (header, _) = chain_state.block_at(h); + monitor.chain_monitor.best_block_updated(header, h); + } + h = next_height; + let (header, txn) = chain_state.block_at(h); + let txdata: Vec<_> = + txn.iter().enumerate().map(|(i, tx)| (i + 1, tx)).collect(); + if !txdata.is_empty() { + monitor.chain_monitor.transactions_confirmed(header, &txdata, h); + } + monitor.chain_monitor.best_block_updated(header, h); + } + } + macro_rules! process_all_events { - () => { { + () => {{ + let mut settled = false; let mut last_pass_no_updates = false; - for i in 0..std::usize::MAX { - if i == 100 { - panic!("It may take may iterations to settle the state, but it should not take forever"); - } - // Next, make sure no monitor updates are pending + for i in 0..100 { + // Settle in rounds: first unblock monitors, then let + // nodes emit messages and events, then confirm any + // transactions they broadcast. Force-close flows need + // all three because each step may unlock the next. + let mut completed_monitor_update = false; for id in &chan_ab_ids { - complete_all_monitor_updates(&monitor_a, id); - complete_all_monitor_updates(&monitor_b, id); + completed_monitor_update |= complete_all_monitor_updates(&monitor_a, id); + completed_monitor_update |= complete_all_monitor_updates(&monitor_b, id); } for id in &chan_bc_ids { - complete_all_monitor_updates(&monitor_b, id); - complete_all_monitor_updates(&monitor_c, id); - } - // Then, make sure any current forwards make their way to their destination - if process_msg_events!(0, false, ProcessMessages::AllMessages) { - last_pass_no_updates = false; - continue; - } - if process_msg_events!(1, false, ProcessMessages::AllMessages) { - last_pass_no_updates = false; - continue; - } - if process_msg_events!(2, false, ProcessMessages::AllMessages) { - last_pass_no_updates = false; - continue; - } - // ...making sure any payments are claimed. - if process_events!(0, false) { - last_pass_no_updates = false; - continue; - } - if process_events!(1, false) { - last_pass_no_updates = false; - continue; + completed_monitor_update |= complete_all_monitor_updates(&monitor_b, id); + completed_monitor_update |= complete_all_monitor_updates(&monitor_c, id); } - if process_events!(2, false) { + // Process messages and events first so nodes + // learn preimages before on-chain txs are + // confirmed. A monitor that already has a + // preimage when it sees the counterparty + // commitment tx will broadcast the claim + // directly, but one that sees the commitment + // tx first and only later gets the preimage + // will not re-check for claimable outputs. + let mut had_msg_or_ev = false; + let node0_msgs = process_msg_events!(0, false, ProcessMessages::AllMessages); + if node0_msgs { + had_msg_or_ev = true; + } + let node1_msgs = process_msg_events!(1, false, ProcessMessages::AllMessages); + if node1_msgs { + had_msg_or_ev = true; + } + let node2_msgs = process_msg_events!(2, false, ProcessMessages::AllMessages); + if node2_msgs { + had_msg_or_ev = true; + } + let node0_evs = process_events!(0, false); + if node0_evs { + had_msg_or_ev = true; + } + let node1_evs = process_events!(1, false); + if node1_evs { + had_msg_or_ev = true; + } + let node2_evs = process_events!(2, false); + if node2_evs { + had_msg_or_ev = true; + } + // Sync nodes to chain tip after messages so + // monitors that just received preimages can + // generate claims when they see commitment txs. + sync_with_chain_state(&chain_state, &nodes[0], &monitor_a, &mut node_height_a, None); + sync_with_chain_state(&chain_state, &nodes[1], &monitor_b, &mut node_height_b, None); + sync_with_chain_state(&chain_state, &nodes[2], &monitor_c, &mut node_height_c, None); + // Process chain monitor events (BumpTransaction, + // SpendableOutputs). + { + let monitors = [&monitor_a, &monitor_b, &monitor_c]; + let broadcasters: [&Arc; 3] = [&broadcast_a, &broadcast_b, &broadcast_c]; + let keys_managers = [&keys_manager_a, &keys_manager_b, &keys_manager_c]; + for (idx, monitor) in monitors.iter().enumerate() { + let wallet = WalletSync::new( + &wallets[idx], + Arc::clone(&loggers[idx]), + ); + let handler = BumpTransactionEventHandlerSync::new( + broadcasters[idx].as_ref(), + &wallet, + keys_managers[idx].as_ref(), + Arc::clone(&loggers[idx]), + ); + let broadcaster = broadcasters[idx]; + monitor.chain_monitor.process_pending_events( + &|event: events::Event| { + if let events::Event::BumpTransaction(ref bump) = event { + match bump { + events::bump_transaction::BumpTransactionEvent::ChannelClose { + commitment_tx, + channel_id, + counterparty_node_id, + .. + } => { + broadcaster.broadcast_transactions(&[( + commitment_tx, + lightning::chain::chaininterface::TransactionType::UnilateralClose { + counterparty_node_id: *counterparty_node_id, + channel_id: *channel_id, + }, + )]); + }, + events::bump_transaction::BumpTransactionEvent::HTLCResolution { .. } => { + handler.handle_event(bump); + }, + } + } + Ok(()) + }, + ); + } + } + let mut had_new_txs = false; + for confirm_iter in 0..32 { + let mut found = false; + let mut pending_txs: Vec = Vec::new(); + for tx in broadcast_a.txn_broadcasted.borrow_mut().drain(..) { + pending_txs.push(tx); + } + for tx in broadcast_b.txn_broadcasted.borrow_mut().drain(..) { + pending_txs.push(tx); + } + for tx in broadcast_c.txn_broadcasted.borrow_mut().drain(..) { + pending_txs.push(tx); + } + // Sort by lock_time so preimage claims + // (lock_time 0) confirm before timeout txs + // (lock_time = cltv_expiry) when both spend + // the same HTLC output in the same drain + // round. The lock_time consensus check in + // confirm_tx handles the case where the + // timeout's lock_time hasn't been reached, + // but when the chain height is past both + // lock_times, this sort is the tiebreaker. + pending_txs.sort_by_key(|tx| tx.lock_time.to_consensus_u32()); + let mut deferred_txs = pending_txs; + loop { + let mut next_deferred_txs = Vec::new(); + let mut progressed = false; + for tx in deferred_txs { + if confirm_tx_and_sync_wallets(&mut chain_state, tx.clone()) { + found = true; + progressed = true; + } else { + next_deferred_txs.push(tx); + } + } + if !progressed { + deferred_txs = next_deferred_txs + .into_iter() + .filter(|tx| should_retry_confirm_later(&chain_state, tx)) + .collect(); + break; + } + deferred_txs = next_deferred_txs; + } + if !deferred_txs.is_empty() { + broadcast_a.txn_broadcasted.borrow_mut().extend( + deferred_txs.into_iter() + ); + } + if !found { + break; + } + assert!( + confirm_iter < 31, + "process_all_events tx confirmation loop failed to quiesce at settle iter {i}: {}", + pending_work_summary!() + ); + had_new_txs = true; + sync_with_chain_state(&chain_state, &nodes[0], &monitor_a, &mut node_height_a, None); + sync_with_chain_state(&chain_state, &nodes[1], &monitor_b, &mut node_height_b, None); + sync_with_chain_state(&chain_state, &nodes[2], &monitor_c, &mut node_height_c, None); + } + if completed_monitor_update || had_new_txs || had_msg_or_ev { last_pass_no_updates = false; continue; } @@ -2811,10 +3797,16 @@ pub fn do_test(data: &[u8], out: Out) { // // Thus, we only exit if we manage two iterations with no messages // or events to process. + settled = true; break; } last_pass_no_updates = true; } + assert!( + settled, + "process_all_events exceeded settle budget: {}", + pending_work_summary!() + ); } }; } @@ -2828,13 +3820,71 @@ pub fn do_test(data: &[u8], out: Out) { } process_all_events!(); + let reconcile_pending_payments = || { + for node_idx in 0..nodes.len() { + let active_pending = nodes[node_idx] + .list_recent_payments() + .into_iter() + .filter_map(|payment| match payment { + RecentPaymentDetails::Pending { payment_id, .. } => { + Some(payment_id) + }, + _ => None, + }) + .collect::>(); + // Restarts rebuild outbound-payment state from the live + // ChannelManager. Drop any ids that remain only in the + // harness cache so the final invariant checks reflect the + // node state we are actually exercising. + pending_payments.borrow_mut()[node_idx] + .retain(|payment_id| active_pending.contains(payment_id)); + } + }; + + // If any channels were force-closed, advance chain height until HTLC + // resolution activity quiesces. We keep this bounded to avoid hangs, + // but allow more rounds than the original fixed four-pass cleanup since + // RBF bumps and confirmation delays can legitimately require additional + // chain progress before a sender sees a terminal payment event. + if !closed_channels.borrow().is_empty() { + let open_channels = nodes[0] + .list_channels() + .iter() + .chain(nodes[1].list_channels().iter()) + .chain(nodes[2].list_channels().iter()) + .cloned() + .collect::>(); + let open_refs: Vec<&_> = open_channels.iter().collect(); + for _ in 0..64 { + let requires_timelock_resolution = + [&monitor_a, &monitor_b, &monitor_c].iter().any(|monitor| { + has_timed_balance( + &monitor.chain_monitor.get_claimable_balances(&open_refs), + ) + }); + reconcile_pending_payments(); + let has_pending_payments = + pending_payments.borrow().iter().any(|payments| !payments.is_empty()); + let requires_timelock_resolution = + requires_timelock_resolution || has_pending_payments; + if !requires_timelock_resolution { + break; + } + chain_state.advance_height(250); + process_all_events!(); + } + } + // Verify no payments are stuck - all should have resolved + reconcile_pending_payments(); for (idx, pending) in pending_payments.borrow().iter().enumerate() { assert!( pending.is_empty(), - "Node {} has {} stuck pending payments after settling all state", + "Node {} has {} stuck pending payments after settling all state: ids={:?}; {}", idx, - pending.len() + pending.len(), + pending, + pending_work_summary!(), ); } @@ -2854,18 +3904,61 @@ pub fn do_test(data: &[u8], out: Out) { // Finally, make sure that at least one end of each channel can make a substantial payment for &chan_id in &chan_ab_ids { + if closed_channels.borrow().contains(&chan_id) { + continue; + } assert!( send(0, 1, chan_id, 10_000_000, &mut p_ctr) || send(1, 0, chan_id, 10_000_000, &mut p_ctr) ); } for &chan_id in &chan_bc_ids { + if closed_channels.borrow().contains(&chan_id) { + continue; + } assert!( send(1, 2, chan_id, 10_000_000, &mut p_ctr) || send(2, 1, chan_id, 10_000_000, &mut p_ctr) ); } + // After settlement, verify that closed channels have no + // ClaimableOnChannelClose balances (which would indicate the + // monitor still thinks the channel is open). + if !closed_channels.borrow().is_empty() { + let open_channels = nodes[0] + .list_channels() + .iter() + .chain(nodes[1].list_channels().iter()) + .chain(nodes[2].list_channels().iter()) + .map(|c| c.clone()) + .collect::>(); + let open_refs: Vec<&_> = open_channels.iter().collect(); + for (label, monitor) in + [("A", &monitor_a), ("B", &monitor_b), ("C", &monitor_c)] + { + let balances = monitor.chain_monitor.get_claimable_balances(&open_refs); + for balance in &balances { + if matches!(balance, Balance::ClaimableOnChannelClose { .. }) { + panic!( + "Monitor {} has ClaimableOnChannelClose balance after settlement: {:?}", + label, balance + ); + } + } + if !balances.is_empty() { + out.locked_write( + format!( + "Monitor {} has {} remaining balances after settlement.\n", + label, + balances.len() + ) + .as_bytes(), + ); + } + } + } + last_htlc_clear_fee_a = fee_est_a.ret_val.load(atomic::Ordering::Acquire); last_htlc_clear_fee_b = fee_est_b.ret_val.load(atomic::Ordering::Acquire); last_htlc_clear_fee_c = fee_est_c.ret_val.load(atomic::Ordering::Acquire); diff --git a/fuzz/src/lib.rs b/fuzz/src/lib.rs index 5f429ea2c3b..25c2fffa23e 100644 --- a/fuzz/src/lib.rs +++ b/fuzz/src/lib.rs @@ -15,9 +15,6 @@ extern crate lightning_rapid_gossip_sync; #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); -#[cfg(not(hashes_fuzz))] -compile_error!("Fuzz targets need cfg=hashes_fuzz"); - #[cfg(not(secp256k1_fuzz))] compile_error!("Fuzz targets need cfg=secp256k1_fuzz"); diff --git a/fuzz/test_cases/base32/smoke b/fuzz/test_cases/base32/smoke new file mode 100644 index 00000000000..573541ac970 --- /dev/null +++ b/fuzz/test_cases/base32/smoke @@ -0,0 +1 @@ +0 diff --git a/fuzz/test_cases/bech32_parse/smoke b/fuzz/test_cases/bech32_parse/smoke new file mode 100644 index 00000000000..573541ac970 --- /dev/null +++ b/fuzz/test_cases/bech32_parse/smoke @@ -0,0 +1 @@ +0 diff --git a/fuzz/test_cases/chanmon_consistency/crash-02830a6ff7757f3570924b0c0fd9118a7cdd9770 b/fuzz/test_cases/chanmon_consistency/crash-02830a6ff7757f3570924b0c0fd9118a7cdd9770 new file mode 100644 index 00000000000..57c626b8597 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-02830a6ff7757f3570924b0c0fd9118a7cdd9770 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-0473b0e767d9a98de62538ce5afcbbc2e6ec5af2 b/fuzz/test_cases/chanmon_consistency/crash-0473b0e767d9a98de62538ce5afcbbc2e6ec5af2 new file mode 100644 index 00000000000..ba413134fbb --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-0473b0e767d9a98de62538ce5afcbbc2e6ec5af2 @@ -0,0 +1 @@ +pppppp0ppp0ÀÞÚÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-05e175d40f60b823f730fa874d98dc10dd2bb6ad b/fuzz/test_cases/chanmon_consistency/crash-05e175d40f60b823f730fa874d98dc10dd2bb6ad new file mode 100644 index 00000000000..cabed892750 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-05e175d40f60b823f730fa874d98dc10dd2bb6ad @@ -0,0 +1 @@ +lls²ÿÿÿÿÝÝÝÝÝÿÿÿÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-07bdc4e56ee67bd2ffa409f76529199d748ab2d8 b/fuzz/test_cases/chanmon_consistency/crash-07bdc4e56ee67bd2ffa409f76529199d748ab2d8 new file mode 100644 index 00000000000..eb3ac3716d2 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-07bdc4e56ee67bd2ffa409f76529199d748ab2d8 @@ -0,0 +1 @@ +pppppp0ÀÐ%ÞÞÏØÙÚÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-096cc3008264dccaefb945f5a4b7a2d3c9f8e90c b/fuzz/test_cases/chanmon_consistency/crash-096cc3008264dccaefb945f5a4b7a2d3c9f8e90c new file mode 100644 index 00000000000..f00662619a1 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-096cc3008264dccaefb945f5a4b7a2d3c9f8e90c @@ -0,0 +1 @@ +<!''ÐØ¥!ÙÚÞºÿ³ÑºÓÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-09a17e06913dea74dba796940cec86cb4e2dd597 b/fuzz/test_cases/chanmon_consistency/crash-09a17e06913dea74dba796940cec86cb4e2dd597 new file mode 100644 index 00000000000..30543451915 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-09a17e06913dea74dba796940cec86cb4e2dd597 @@ -0,0 +1 @@ +<!ÑØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-09f5a41270b07f70a031884cbdfd081e8600923e b/fuzz/test_cases/chanmon_consistency/crash-09f5a41270b07f70a031884cbdfd081e8600923e new file mode 100644 index 00000000000..e0ff1832a4f Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-09f5a41270b07f70a031884cbdfd081e8600923e differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-0b87d8b430697fe9d1781a38f41a68ebcf7b18c1 b/fuzz/test_cases/chanmon_consistency/crash-0b87d8b430697fe9d1781a38f41a68ebcf7b18c1 new file mode 100644 index 00000000000..6fa6375a31f --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-0b87d8b430697fe9d1781a38f41a68ebcf7b18c1 @@ -0,0 +1 @@ +p0pÀÞÞÏbÿ`ÙÚÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-0c3334736f5c55e44088d6140580354827026732 b/fuzz/test_cases/chanmon_consistency/crash-0c3334736f5c55e44088d6140580354827026732 new file mode 100644 index 00000000000..13cce60bcd9 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-0c3334736f5c55e44088d6140580354827026732 @@ -0,0 +1 @@ +<!ÒÑØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-0f0ca42c8b4c815495919663652db18483d5e846 b/fuzz/test_cases/chanmon_consistency/crash-0f0ca42c8b4c815495919663652db18483d5e846 new file mode 100644 index 00000000000..6ff82459687 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-0f0ca42c8b4c815495919663652db18483d5e846 @@ -0,0 +1 @@ +<ÐØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-15b45517356c182051c2b334e09c00f4f9368e94 b/fuzz/test_cases/chanmon_consistency/crash-15b45517356c182051c2b334e09c00f4f9368e94 new file mode 100644 index 00000000000..117070ce1fa --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-15b45517356c182051c2b334e09c00f4f9368e94 @@ -0,0 +1 @@ +1Ù<ÚÞ1ÿÿÞÙ<ÚÞþÿþÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-18062bd37528e06c4921e7ef7df2b2c3e676823b b/fuzz/test_cases/chanmon_consistency/crash-18062bd37528e06c4921e7ef7df2b2c3e676823b new file mode 100644 index 00000000000..6fc01e9d3e1 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-18062bd37528e06c4921e7ef7df2b2c3e676823b @@ -0,0 +1 @@ +<ˆ0"tst¢tst¢tssÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-22125d8a200205d52723ec232f5aab710856f4b0 b/fuzz/test_cases/chanmon_consistency/crash-22125d8a200205d52723ec232f5aab710856f4b0 new file mode 100644 index 00000000000..fbecffa507b Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-22125d8a200205d52723ec232f5aab710856f4b0 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-228ea00412a2fab1e866fc6df32ffd00bbfe81ad b/fuzz/test_cases/chanmon_consistency/crash-228ea00412a2fab1e866fc6df32ffd00bbfe81ad new file mode 100644 index 00000000000..4a6a76ade6c Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-228ea00412a2fab1e866fc6df32ffd00bbfe81ad differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-242de208110143401fcf4e1ebaa7d9d38fb93611 b/fuzz/test_cases/chanmon_consistency/crash-242de208110143401fcf4e1ebaa7d9d38fb93611 new file mode 100644 index 00000000000..76da0f6debb --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-242de208110143401fcf4e1ebaa7d9d38fb93611 @@ -0,0 +1 @@ +*ÿ¹¹¹þÿÿÒ¸ÿÞÞÞÞÿ¹¹¹¹¹¹¹ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-24f1373b1cf51f95af854d6d8730336b77728007 b/fuzz/test_cases/chanmon_consistency/crash-24f1373b1cf51f95af854d6d8730336b77728007 new file mode 100644 index 00000000000..0064fa17f19 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-24f1373b1cf51f95af854d6d8730336b77728007 @@ -0,0 +1 @@ +*ÿ¹tÿA2¹¹¹¹ÑØÙÚÞÿÿ¹¹ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-2923c14608fb259c21862cd71ffeb6ac74b0ba32 b/fuzz/test_cases/chanmon_consistency/crash-2923c14608fb259c21862cd71ffeb6ac74b0ba32 new file mode 100644 index 00000000000..ff1549ef79f --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-2923c14608fb259c21862cd71ffeb6ac74b0ba32 @@ -0,0 +1 @@ +p0p0ÀÞÞÏØ°Zÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-2a0852bec1d75334538dacec26831db6995b6e33 b/fuzz/test_cases/chanmon_consistency/crash-2a0852bec1d75334538dacec26831db6995b6e33 new file mode 100644 index 00000000000..f5e273ff51f --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-2a0852bec1d75334538dacec26831db6995b6e33 @@ -0,0 +1 @@ +p0ÀÞÞÏbÿÙÚÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-2d93541536e19c030d95d236e6be545352d98b80 b/fuzz/test_cases/chanmon_consistency/crash-2d93541536e19c030d95d236e6be545352d98b80 new file mode 100644 index 00000000000..0c7432d7c20 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-2d93541536e19c030d95d236e6be545352d98b80 @@ -0,0 +1 @@ +*ÿ¹tÿA¹¹¹¹ÑØÙÚÞÿÿ¹¹ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-2e002fcfdc76c5981f5f93c0f842b548fb56c7a7 b/fuzz/test_cases/chanmon_consistency/crash-2e002fcfdc76c5981f5f93c0f842b548fb56c7a7 new file mode 100644 index 00000000000..bd5c0aab70a --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-2e002fcfdc76c5981f5f93c0f842b548fb56c7a7 @@ -0,0 +1 @@ +p0t0ÀÞÞÏØÙZÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-2fad50c7fd20b250f0349887445af198124900df b/fuzz/test_cases/chanmon_consistency/crash-2fad50c7fd20b250f0349887445af198124900df new file mode 100644 index 00000000000..44d0be6fc50 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-2fad50c7fd20b250f0349887445af198124900df differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-2fcd63b2ed709dfcd9c6a08dc673d1f896b6cdad b/fuzz/test_cases/chanmon_consistency/crash-2fcd63b2ed709dfcd9c6a08dc673d1f896b6cdad new file mode 100644 index 00000000000..13845ae46ec Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-2fcd63b2ed709dfcd9c6a08dc673d1f896b6cdad differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-315119ea09b9febec156d212fe57020def4b5af4 b/fuzz/test_cases/chanmon_consistency/crash-315119ea09b9febec156d212fe57020def4b5af4 new file mode 100644 index 00000000000..7475486ac05 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-315119ea09b9febec156d212fe57020def4b5af4 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-32a013d8bd38f3ba39d4a214ba0780edd41ccb85 b/fuzz/test_cases/chanmon_consistency/crash-32a013d8bd38f3ba39d4a214ba0780edd41ccb85 new file mode 100644 index 00000000000..3d3b1f24fa4 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-32a013d8bd38f3ba39d4a214ba0780edd41ccb85 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-33c08a8f15f1c842df5da4fc92228d00606573f9 b/fuzz/test_cases/chanmon_consistency/crash-33c08a8f15f1c842df5da4fc92228d00606573f9 new file mode 100644 index 00000000000..391b9204000 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-33c08a8f15f1c842df5da4fc92228d00606573f9 @@ -0,0 +1 @@ +<ˆ0sslqlqqÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-33e77c2f720493e306bbfea79f151388ca7a04ea b/fuzz/test_cases/chanmon_consistency/crash-33e77c2f720493e306bbfea79f151388ca7a04ea new file mode 100644 index 00000000000..2c4a1c6cac6 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-33e77c2f720493e306bbfea79f151388ca7a04ea differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-37a18356d608c97415c0a1bef6a0f13fe04c8b97 b/fuzz/test_cases/chanmon_consistency/crash-37a18356d608c97415c0a1bef6a0f13fe04c8b97 new file mode 100644 index 00000000000..877a41dd6ae Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-37a18356d608c97415c0a1bef6a0f13fe04c8b97 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-380ee6f8c1030828f4d80582154b0418fca58c90 b/fuzz/test_cases/chanmon_consistency/crash-380ee6f8c1030828f4d80582154b0418fca58c90 new file mode 100644 index 00000000000..7c68f220ac4 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-380ee6f8c1030828f4d80582154b0418fca58c90 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-38192a6cb0500969f301c7a6742949ecd213bfae b/fuzz/test_cases/chanmon_consistency/crash-38192a6cb0500969f301c7a6742949ecd213bfae new file mode 100644 index 00000000000..6a518fb21f9 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-38192a6cb0500969f301c7a6742949ecd213bfae @@ -0,0 +1 @@ +ÀÐqÌÞØðqqqpqqq2ùÿÿÿÊÿÿÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-387c18b4c7235aa1960400de5b0d5798202ec3b1 b/fuzz/test_cases/chanmon_consistency/crash-387c18b4c7235aa1960400de5b0d5798202ec3b1 new file mode 100644 index 00000000000..b8bb741383a --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-387c18b4c7235aa1960400de5b0d5798202ec3b1 @@ -0,0 +1 @@ +<!pÒÑØÙSÚÞÞ¬±¹Aÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-3bb94b7b4397397caa5eb0e9ba6abb9a18028270 b/fuzz/test_cases/chanmon_consistency/crash-3bb94b7b4397397caa5eb0e9ba6abb9a18028270 new file mode 100644 index 00000000000..cfc3d2f8b9c Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-3bb94b7b4397397caa5eb0e9ba6abb9a18028270 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-3be4d9d7a75c8459b3ec349474c7fc206b00fe9c b/fuzz/test_cases/chanmon_consistency/crash-3be4d9d7a75c8459b3ec349474c7fc206b00fe9c new file mode 100644 index 00000000000..1704e96b3e9 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-3be4d9d7a75c8459b3ec349474c7fc206b00fe9c differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-3cda5b606ce05f4207207e8fd1480fe530a51b13 b/fuzz/test_cases/chanmon_consistency/crash-3cda5b606ce05f4207207e8fd1480fe530a51b13 new file mode 100644 index 00000000000..f8199bc4193 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-3cda5b606ce05f4207207e8fd1480fe530a51b13 @@ -0,0 +1 @@ +LÐ'»ÿ¡MÿÿÞÞÞÞ¥ÿÿMºÿ£¥ÿ4 \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-3f8a6e5b806235b795ebea3d6998943a3ab6ff9d b/fuzz/test_cases/chanmon_consistency/crash-3f8a6e5b806235b795ebea3d6998943a3ab6ff9d new file mode 100644 index 00000000000..f87c02c637f Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-3f8a6e5b806235b795ebea3d6998943a3ab6ff9d differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-41ffe016736ddfef0eb1d877b35a0c85bd5cfd5f b/fuzz/test_cases/chanmon_consistency/crash-41ffe016736ddfef0eb1d877b35a0c85bd5cfd5f new file mode 100644 index 00000000000..fc0bba34218 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-41ffe016736ddfef0eb1d877b35a0c85bd5cfd5f @@ -0,0 +1 @@ +©ÿÿÿ4„¦ÞÞÿý¸¸ÙÚÞÞÿýÿÿÿ# \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-45240f379a3a24948c4b091fd658a9f0ef4d4963 b/fuzz/test_cases/chanmon_consistency/crash-45240f379a3a24948c4b091fd658a9f0ef4d4963 new file mode 100644 index 00000000000..d7082c3b943 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-45240f379a3a24948c4b091fd658a9f0ef4d4963 @@ -0,0 +1 @@ +0ÿÿÀÐ%ÞÞÏØÙÚÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-49e1240588c1b4507b24c4f07dae75faef02a639 b/fuzz/test_cases/chanmon_consistency/crash-49e1240588c1b4507b24c4f07dae75faef02a639 new file mode 100644 index 00000000000..3526b2a5c33 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-49e1240588c1b4507b24c4f07dae75faef02a639 @@ -0,0 +1 @@ +1Ù<ÚÞ1Ù<ÚÞ1Þþÿþÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-4da789d875488d8f244bccefaff4295ae801c745 b/fuzz/test_cases/chanmon_consistency/crash-4da789d875488d8f244bccefaff4295ae801c745 new file mode 100644 index 00000000000..e7546a2fde9 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-4da789d875488d8f244bccefaff4295ae801c745 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-4e4b47b5a0f4c4689868a3003ae7d62e5ac78484 b/fuzz/test_cases/chanmon_consistency/crash-4e4b47b5a0f4c4689868a3003ae7d62e5ac78484 new file mode 100644 index 00000000000..44c320f63c0 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-4e4b47b5a0f4c4689868a3003ae7d62e5ac78484 @@ -0,0 +1 @@ +©³±ÿ£„¦ÞÞÿý¸¸ÙÚÞÞÿýÿÿÿ# \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-53d6404dc8dee21adf112f3c909459f67e176301 b/fuzz/test_cases/chanmon_consistency/crash-53d6404dc8dee21adf112f3c909459f67e176301 new file mode 100644 index 00000000000..5338141114c Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-53d6404dc8dee21adf112f3c909459f67e176301 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-544eff2c026e0464aff1a9afaa4acd2912e93267 b/fuzz/test_cases/chanmon_consistency/crash-544eff2c026e0464aff1a9afaa4acd2912e93267 new file mode 100644 index 00000000000..d9d649dcd7f --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-544eff2c026e0464aff1a9afaa4acd2912e93267 @@ -0,0 +1 @@ +<!pÒÑØÙÚÞAÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-54a3422e8e1c578813d5cfce1f8b732040fc668e b/fuzz/test_cases/chanmon_consistency/crash-54a3422e8e1c578813d5cfce1f8b732040fc668e new file mode 100644 index 00000000000..2c800b20503 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-54a3422e8e1c578813d5cfce1f8b732040fc668e @@ -0,0 +1 @@ +p0p0ÀÞÞÏØÙZÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-55fd3e4e7c2506a9ce067b0e0a468161db22dec0 b/fuzz/test_cases/chanmon_consistency/crash-55fd3e4e7c2506a9ce067b0e0a468161db22dec0 new file mode 100644 index 00000000000..d8ab917ffc9 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-55fd3e4e7c2506a9ce067b0e0a468161db22dec0 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-56271abf5206dd39ac1a1035d49d41f61ee0606e b/fuzz/test_cases/chanmon_consistency/crash-56271abf5206dd39ac1a1035d49d41f61ee0606e new file mode 100644 index 00000000000..8b270f512b8 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-56271abf5206dd39ac1a1035d49d41f61ee0606e @@ -0,0 +1 @@ +pppppp0ÀÞÞÏØÙÚÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-5be7542ec7a98b835a2c3dca63e3d89a76050fe6 b/fuzz/test_cases/chanmon_consistency/crash-5be7542ec7a98b835a2c3dca63e3d89a76050fe6 new file mode 100644 index 00000000000..5e7297f2464 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-5be7542ec7a98b835a2c3dca63e3d89a76050fe6 @@ -0,0 +1,3 @@ +<   + ! + ''õÞõÿÐÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-5d2ca379ca5dabcbfae13c3eca104e48a4bf94c9 b/fuzz/test_cases/chanmon_consistency/crash-5d2ca379ca5dabcbfae13c3eca104e48a4bf94c9 new file mode 100644 index 00000000000..84c52f85935 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-5d2ca379ca5dabcbfae13c3eca104e48a4bf94c9 @@ -0,0 +1 @@ +0ÐØÜÝÞØÙÚÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-63164e99d1a0561c352ea11be619b8505a83ceb4 b/fuzz/test_cases/chanmon_consistency/crash-63164e99d1a0561c352ea11be619b8505a83ceb4 new file mode 100644 index 00000000000..39e32a2a992 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-63164e99d1a0561c352ea11be619b8505a83ceb4 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-6aec66d5104839013b44f977a01915c29f2e6795 b/fuzz/test_cases/chanmon_consistency/crash-6aec66d5104839013b44f977a01915c29f2e6795 new file mode 100644 index 00000000000..f638552b6c0 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-6aec66d5104839013b44f977a01915c29f2e6795 @@ -0,0 +1 @@ +1Ù<ÚÞ1Ù<ÚÞÙ<ÚÞþÿþÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-6af2409d5c331f44f76e165e735cd2e9104aed9e b/fuzz/test_cases/chanmon_consistency/crash-6af2409d5c331f44f76e165e735cd2e9104aed9e new file mode 100644 index 00000000000..f76b32f1f81 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-6af2409d5c331f44f76e165e735cd2e9104aed9e @@ -0,0 +1 @@ +<: !''<8 !''ÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-6b5c5549ee7ed6e7fcf9613d62c295fd65d100ce b/fuzz/test_cases/chanmon_consistency/crash-6b5c5549ee7ed6e7fcf9613d62c295fd65d100ce new file mode 100644 index 00000000000..a3fb940a20a --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-6b5c5549ee7ed6e7fcf9613d62c295fd65d100ce @@ -0,0 +1 @@ +0ÐØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-6bd8c4ea12175b25bb1d239699622ba5485248cf b/fuzz/test_cases/chanmon_consistency/crash-6bd8c4ea12175b25bb1d239699622ba5485248cf new file mode 100644 index 00000000000..8e9ad17c554 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-6bd8c4ea12175b25bb1d239699622ba5485248cf @@ -0,0 +1 @@ +0ÀÐØÞÞÏØÙÚÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-6bda1f46384cf85ae2d9ca8048619963a9416ddc b/fuzz/test_cases/chanmon_consistency/crash-6bda1f46384cf85ae2d9ca8048619963a9416ddc new file mode 100644 index 00000000000..b821013dfc9 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-6bda1f46384cf85ae2d9ca8048619963a9416ddc @@ -0,0 +1 @@ +<:!''ÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-767cf8ac05cf878f93f55fe21f96a9e76b28c5f9 b/fuzz/test_cases/chanmon_consistency/crash-767cf8ac05cf878f93f55fe21f96a9e76b28c5f9 new file mode 100644 index 00000000000..94a4149ae75 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-767cf8ac05cf878f93f55fe21f96a9e76b28c5f9 @@ -0,0 +1 @@ +pppppp0p0ÀÞÞÏØÚÿ¹ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-7776698efb54442fa8170cb39b7c7bf72e515335 b/fuzz/test_cases/chanmon_consistency/crash-7776698efb54442fa8170cb39b7c7bf72e515335 new file mode 100644 index 00000000000..2e3ac113613 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-7776698efb54442fa8170cb39b7c7bf72e515335 @@ -0,0 +1 @@ +<!RÑØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-79790f24a47ad8f39398df48800b946cd85fc3fe b/fuzz/test_cases/chanmon_consistency/crash-79790f24a47ad8f39398df48800b946cd85fc3fe new file mode 100644 index 00000000000..53489553b7a --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-79790f24a47ad8f39398df48800b946cd85fc3fe @@ -0,0 +1 @@ +08@HÐØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-7ab7fa1fb4303a91c57ec241fefdf5826d2b52aa b/fuzz/test_cases/chanmon_consistency/crash-7ab7fa1fb4303a91c57ec241fefdf5826d2b52aa new file mode 100644 index 00000000000..25a42eb822b Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-7ab7fa1fb4303a91c57ec241fefdf5826d2b52aa differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-7b7826cea32794a2ab2c245cd3dc024355b07c78 b/fuzz/test_cases/chanmon_consistency/crash-7b7826cea32794a2ab2c245cd3dc024355b07c78 new file mode 100644 index 00000000000..1c8b2ed020a Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-7b7826cea32794a2ab2c245cd3dc024355b07c78 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-7c72226eeba2eb5192d9b7adfead405d3b93fdf9 b/fuzz/test_cases/chanmon_consistency/crash-7c72226eeba2eb5192d9b7adfead405d3b93fdf9 new file mode 100644 index 00000000000..eec265dbd2e Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-7c72226eeba2eb5192d9b7adfead405d3b93fdf9 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-7cb0cf9df154821deb68a78001ce9c0e27f97b0a b/fuzz/test_cases/chanmon_consistency/crash-7cb0cf9df154821deb68a78001ce9c0e27f97b0a new file mode 100644 index 00000000000..306efa39b4f --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-7cb0cf9df154821deb68a78001ce9c0e27f97b0a @@ -0,0 +1 @@ +<2!Ø`!'Ð'ÙÚÞÓÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-815718bf6e59d981220f037f7509c9cfe5401485 b/fuzz/test_cases/chanmon_consistency/crash-815718bf6e59d981220f037f7509c9cfe5401485 new file mode 100644 index 00000000000..2014a91992e --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-815718bf6e59d981220f037f7509c9cfe5401485 @@ -0,0 +1 @@ +<: !''ÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-8453a4a3cf9dd9f60e5aa40fdce440b69f62869d b/fuzz/test_cases/chanmon_consistency/crash-8453a4a3cf9dd9f60e5aa40fdce440b69f62869d new file mode 100644 index 00000000000..ef2df9fb32c --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-8453a4a3cf9dd9f60e5aa40fdce440b69f62869d @@ -0,0 +1 @@ +pÞÁÀÏÅÿ8ÿÿÿÿÿÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-86ee8ae4c13784d3d750f6d4b970ec0852ea2bc3 b/fuzz/test_cases/chanmon_consistency/crash-86ee8ae4c13784d3d750f6d4b970ec0852ea2bc3 new file mode 100644 index 00000000000..50558c7a57e --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-86ee8ae4c13784d3d750f6d4b970ec0852ea2bc3 @@ -0,0 +1 @@ +Pppp0ÀÞÞÏØÙÚÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-87093ec5446a84482f5a728fc65a51a15b6de843 b/fuzz/test_cases/chanmon_consistency/crash-87093ec5446a84482f5a728fc65a51a15b6de843 new file mode 100644 index 00000000000..ae01ca7a1ce Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-87093ec5446a84482f5a728fc65a51a15b6de843 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-87f98b753291bd37f92795d32e2df4c3597dd6dd b/fuzz/test_cases/chanmon_consistency/crash-87f98b753291bd37f92795d32e2df4c3597dd6dd new file mode 100644 index 00000000000..c7851baa1e9 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-87f98b753291bd37f92795d32e2df4c3597dd6dd differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-8ab54f3642a60a239a7bb787838f3e5a6b6f4f41 b/fuzz/test_cases/chanmon_consistency/crash-8ab54f3642a60a239a7bb787838f3e5a6b6f4f41 new file mode 100644 index 00000000000..50f706994ac --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-8ab54f3642a60a239a7bb787838f3e5a6b6f4f41 @@ -0,0 +1 @@ +ÐÿÞ ØÙÚÌÜÜÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-8ec6798103af6cedfdec68373991c0c0a73e3770 b/fuzz/test_cases/chanmon_consistency/crash-8ec6798103af6cedfdec68373991c0c0a73e3770 new file mode 100644 index 00000000000..877960d1655 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-8ec6798103af6cedfdec68373991c0c0a73e3770 @@ -0,0 +1 @@ +<:!''ÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-8f5cc4f6de42f52dcb571b6c0f21df957eb25462 b/fuzz/test_cases/chanmon_consistency/crash-8f5cc4f6de42f52dcb571b6c0f21df957eb25462 new file mode 100644 index 00000000000..e64b0b71a13 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-8f5cc4f6de42f52dcb571b6c0f21df957eb25462 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-8fb6d213ac7d14f6c62c09e7baf392f01e8688d0 b/fuzz/test_cases/chanmon_consistency/crash-8fb6d213ac7d14f6c62c09e7baf392f01e8688d0 new file mode 100644 index 00000000000..1cfe803f166 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-8fb6d213ac7d14f6c62c09e7baf392f01e8688d0 @@ -0,0 +1 @@ +0ÐØÞØÞØÙÚÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-90c560825e852e3dfb64e09d6764b85cf9f7689d b/fuzz/test_cases/chanmon_consistency/crash-90c560825e852e3dfb64e09d6764b85cf9f7689d new file mode 100644 index 00000000000..9b42ec41387 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-90c560825e852e3dfb64e09d6764b85cf9f7689d @@ -0,0 +1 @@ +*ÿ¹¹¹Ò¸ÿþÿÿÞÞÞÞÿ¹¹¹¹¹¹¹ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-91d8898837e425d607ef36ed73fa364b0fa58121 b/fuzz/test_cases/chanmon_consistency/crash-91d8898837e425d607ef36ed73fa364b0fa58121 new file mode 100644 index 00000000000..b54c9f94956 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-91d8898837e425d607ef36ed73fa364b0fa58121 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-91ebb8583ed7705e2601334e52428ea5eb80a681 b/fuzz/test_cases/chanmon_consistency/crash-91ebb8583ed7705e2601334e52428ea5eb80a681 new file mode 100644 index 00000000000..ba9c42d7059 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-91ebb8583ed7705e2601334e52428ea5eb80a681 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-93c44c96a5c5e1d4532370b2c77bb372170bd59b b/fuzz/test_cases/chanmon_consistency/crash-93c44c96a5c5e1d4532370b2c77bb372170bd59b new file mode 100644 index 00000000000..ee8a1ca0fda --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-93c44c96a5c5e1d4532370b2c77bb372170bd59b @@ -0,0 +1 @@ +<: !'ÙÄ:Ý !''ÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-9c69d63a708c0a83d2d1fa60577a1a9270924ff2 b/fuzz/test_cases/chanmon_consistency/crash-9c69d63a708c0a83d2d1fa60577a1a9270924ff2 new file mode 100644 index 00000000000..817a8c0fae7 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-9c69d63a708c0a83d2d1fa60577a1a9270924ff2 @@ -0,0 +1 @@ +ÿÿÿ;±;;!'' ÞÐÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-9c84f405725b7c171338f776b7ac7f3a3b010f34 b/fuzz/test_cases/chanmon_consistency/crash-9c84f405725b7c171338f776b7ac7f3a3b010f34 new file mode 100644 index 00000000000..1327780da7b Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-9c84f405725b7c171338f776b7ac7f3a3b010f34 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-a235e98ab95f66315cef361c49eea5483ce2d91a b/fuzz/test_cases/chanmon_consistency/crash-a235e98ab95f66315cef361c49eea5483ce2d91a new file mode 100644 index 00000000000..50a06ead7be --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-a235e98ab95f66315cef361c49eea5483ce2d91a @@ -0,0 +1 @@ +©³ÿ£„¦ÞÞÿý¸¸ÙÚÞÞÿýÿÿÿ# \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-a6628891c34498ca2cb4122c2ee66fe4ba6cd01d b/fuzz/test_cases/chanmon_consistency/crash-a6628891c34498ca2cb4122c2ee66fe4ba6cd01d new file mode 100644 index 00000000000..e118d59953d Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-a6628891c34498ca2cb4122c2ee66fe4ba6cd01d differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-a8f59ca92bcc53e042fd759493c67a35f308721a b/fuzz/test_cases/chanmon_consistency/crash-a8f59ca92bcc53e042fd759493c67a35f308721a new file mode 100644 index 00000000000..d355f750cdf --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-a8f59ca92bcc53e042fd759493c67a35f308721a @@ -0,0 +1 @@ +lls@2pp=Pp=ÿ²ÿÿÿÿÝÝÝÝÝÿÿÿÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-ace48b23767637be15eb3763e88170f7aab17cd4 b/fuzz/test_cases/chanmon_consistency/crash-ace48b23767637be15eb3763e88170f7aab17cd4 new file mode 100644 index 00000000000..398618ee6e1 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-ace48b23767637be15eb3763e88170f7aab17cd4 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-adf5f907d4bc584e6348b7188532f6fc08cda464 b/fuzz/test_cases/chanmon_consistency/crash-adf5f907d4bc584e6348b7188532f6fc08cda464 new file mode 100644 index 00000000000..30cd3547b40 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-adf5f907d4bc584e6348b7188532f6fc08cda464 @@ -0,0 +1 @@ +1Ù<ÚÞ1Ù<ÚÞþÿþÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-af7499de68300f3346be7b69ff913c8da2394d23 b/fuzz/test_cases/chanmon_consistency/crash-af7499de68300f3346be7b69ff913c8da2394d23 new file mode 100644 index 00000000000..bb734d0634c --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-af7499de68300f3346be7b69ff913c8da2394d23 @@ -0,0 +1 @@ +1Ù<ÚÞ1ÿÿÿúÞÙ<ÚÞþÿþÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-b2e70396bda55d716c022a683df49d72e28b5cae b/fuzz/test_cases/chanmon_consistency/crash-b2e70396bda55d716c022a683df49d72e28b5cae new file mode 100644 index 00000000000..1f4fc7ff612 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-b2e70396bda55d716c022a683df49d72e28b5cae differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-ba5dd0ee55c764b2ae71543e95fd63c496d924bd b/fuzz/test_cases/chanmon_consistency/crash-ba5dd0ee55c764b2ae71543e95fd63c496d924bd new file mode 100644 index 00000000000..cd546ddda6f --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-ba5dd0ee55c764b2ae71543e95fd63c496d924bd @@ -0,0 +1 @@ +<!''ÐØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-baa2cd71d1e22c966f3c2ddc44cf5b297da5d671 b/fuzz/test_cases/chanmon_consistency/crash-baa2cd71d1e22c966f3c2ddc44cf5b297da5d671 new file mode 100644 index 00000000000..9eba9c2ea97 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-baa2cd71d1e22c966f3c2ddc44cf5b297da5d671 @@ -0,0 +1 @@ +0ÞÁÀÏÅÿ8ÿÿÿÿÿÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-c1fe932fa21c4382ba71ec745790386f010b939c b/fuzz/test_cases/chanmon_consistency/crash-c1fe932fa21c4382ba71ec745790386f010b939c new file mode 100644 index 00000000000..cde747a622b --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-c1fe932fa21c4382ba71ec745790386f010b939c @@ -0,0 +1 @@ +º<ÿÿÿÿÿ!!ØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-c29e58a510e698fc8205e4896a938adb92424105 b/fuzz/test_cases/chanmon_consistency/crash-c29e58a510e698fc8205e4896a938adb92424105 new file mode 100644 index 00000000000..197089daa96 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-c29e58a510e698fc8205e4896a938adb92424105 @@ -0,0 +1 @@ +<<ÿÞÞ<ÿÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-c7b166535d5d3591604aeb239b01592f24fff27b b/fuzz/test_cases/chanmon_consistency/crash-c7b166535d5d3591604aeb239b01592f24fff27b new file mode 100644 index 00000000000..d9aff66d38c --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-c7b166535d5d3591604aeb239b01592f24fff27b @@ -0,0 +1 @@ +08@HÿÿÐØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-cb39e58d20b35ceb4ecd9fc8dd91272e308f11a1 b/fuzz/test_cases/chanmon_consistency/crash-cb39e58d20b35ceb4ecd9fc8dd91272e308f11a1 new file mode 100644 index 00000000000..2b5f05bc2c6 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-cb39e58d20b35ceb4ecd9fc8dd91272e308f11a1 @@ -0,0 +1 @@ +11Ù<ÚÞ2Ù<ÚÞþÿþÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-cc144c9fa2f889e3c3665b1e7c870ddd41cb3e15 b/fuzz/test_cases/chanmon_consistency/crash-cc144c9fa2f889e3c3665b1e7c870ddd41cb3e15 new file mode 100644 index 00000000000..0151e0666cf --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-cc144c9fa2f889e3c3665b1e7c870ddd41cb3e15 @@ -0,0 +1 @@ +X````ÿй¹¸ÑØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-cec678efd9c2c03dccf92f62c20e9520566d130f b/fuzz/test_cases/chanmon_consistency/crash-cec678efd9c2c03dccf92f62c20e9520566d130f new file mode 100644 index 00000000000..2fce5ce66ab Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-cec678efd9c2c03dccf92f62c20e9520566d130f differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-cedac69cfff63a360470d6f051164b149f74bc18 b/fuzz/test_cases/chanmon_consistency/crash-cedac69cfff63a360470d6f051164b149f74bc18 new file mode 100644 index 00000000000..2d9943a57c8 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-cedac69cfff63a360470d6f051164b149f74bc18 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-cf44c3acf507cae6fd00e0bf331d18536c551ce1 b/fuzz/test_cases/chanmon_consistency/crash-cf44c3acf507cae6fd00e0bf331d18536c551ce1 new file mode 100644 index 00000000000..e17d8f2b3d6 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-cf44c3acf507cae6fd00e0bf331d18536c551ce1 @@ -0,0 +1 @@ +pppppp0ÀÞÞÏÅÿ3ÿÿÿÿÿÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-d09e9319d459f21b180f1c730fbf4e89840bd6c5 b/fuzz/test_cases/chanmon_consistency/crash-d09e9319d459f21b180f1c730fbf4e89840bd6c5 new file mode 100644 index 00000000000..2997e078806 Binary files /dev/null and b/fuzz/test_cases/chanmon_consistency/crash-d09e9319d459f21b180f1c730fbf4e89840bd6c5 differ diff --git a/fuzz/test_cases/chanmon_consistency/crash-d11e5e5259e57e32f120f0d005bc52aead73d099 b/fuzz/test_cases/chanmon_consistency/crash-d11e5e5259e57e32f120f0d005bc52aead73d099 new file mode 100644 index 00000000000..30780adc949 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-d11e5e5259e57e32f120f0d005bc52aead73d099 @@ -0,0 +1 @@ +Xÿÿÿú!ÐÑØÙÚÞÞÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-d3ee0bad80fbd14f1f62903fc6d23f26ed5eb405 b/fuzz/test_cases/chanmon_consistency/crash-d3ee0bad80fbd14f1f62903fc6d23f26ed5eb405 new file mode 100644 index 00000000000..d89dd3db529 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-d3ee0bad80fbd14f1f62903fc6d23f26ed5eb405 @@ -0,0 +1 @@ +lls²ÿÿÿÿÞÝ ÿ³ ÝÝÝÿÿÿÿ \ No newline at end of file diff --git a/fuzz/test_cases/chanmon_consistency/crash-d5124444b5e39d9a67c395e6325d340fff97a159 b/fuzz/test_cases/chanmon_consistency/crash-d5124444b5e39d9a67c395e6325d340fff97a159 new file mode 100644 index 00000000000..2c349eb8342 --- /dev/null +++ b/fuzz/test_cases/chanmon_consistency/crash-d5124444b5e39d9a67c395e6325d340fff97a159 @@ -0,0 +1 @@ +<ˆ0"ts(ctx: &Secp256k1, msg: &Message, sk: &SecretKey) -> Signature { #[cfg(feature = "grind_signatures")] - let sig = ctx.sign_ecdsa_low_r(msg, sk); + let sig = if cfg!(fuzzing) { ctx.sign_ecdsa(msg, sk) } else { ctx.sign_ecdsa_low_r(msg, sk) }; #[cfg(not(feature = "grind_signatures"))] let sig = ctx.sign_ecdsa(msg, sk); sig @@ -79,10 +79,16 @@ pub fn sign_with_aux_rand( ctx: &Secp256k1, msg: &Message, sk: &SecretKey, entropy_source: &ES, ) -> Signature { #[cfg(feature = "grind_signatures")] - let sig = loop { - let sig = ctx.sign_ecdsa_with_noncedata(msg, sk, &entropy_source.get_secure_random_bytes()); - if sig.serialize_compact()[0] < 0x80 { - break sig; + let sig = { + if cfg!(fuzzing) { + return sign(ctx, msg, sk); + } + loop { + let sig = + ctx.sign_ecdsa_with_noncedata(msg, sk, &entropy_source.get_secure_random_bytes()); + if sig.serialize_compact()[0] < 0x80 { + break sig; + } } }; #[cfg(all(not(feature = "grind_signatures"), not(ldk_test_vectors)))] diff --git a/lightning/src/events/bump_transaction/mod.rs b/lightning/src/events/bump_transaction/mod.rs index 6a5e9948653..ed383ba4f50 100644 --- a/lightning/src/events/bump_transaction/mod.rs +++ b/lightning/src/events/bump_transaction/mod.rs @@ -484,7 +484,11 @@ impl= signed_tx_weight); + // When fuzzing, signatures are trivially small so the actual weight can be + // significantly less than estimated. Skip the lower-bound check. + #[cfg(not(fuzzing))] assert!(expected_signed_tx_weight * 99 / 100 <= signed_tx_weight); let expected_package_fee = Amount::from_sat(fee_for_weight( @@ -732,7 +736,11 @@ impl= signed_tx_weight); + // When fuzzing, signatures are trivially small so the actual weight can be + // significantly less than estimated. Skip the lower-bound check. + #[cfg(not(fuzzing))] assert!(expected_signed_tx_weight * 98 / 100 <= signed_tx_weight); let expected_signed_tx_fee = diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index af4d1569d0c..6960df66b47 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -58,7 +58,7 @@ fn test_monitor_and_persister_update_fail() { 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 nodes = create_network(2, &node_cfgs, &node_chanmgrs); let node_a_id = nodes[0].node.get_our_node_id(); let node_b_id = nodes[1].node.get_our_node_id(); @@ -4609,7 +4609,7 @@ fn test_claim_to_closed_channel_blocks_claimed_event() { let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let legacy_cfg = test_legacy_channel_config(); let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(legacy_cfg), None]); - let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); let node_a_id = nodes[0].node.get_our_node_id(); let node_b_id = nodes[1].node.get_our_node_id(); @@ -4653,6 +4653,92 @@ fn test_claim_to_closed_channel_blocks_claimed_event() { expect_payment_claimed!(nodes[1], payment_hash, 1_000_000); } +#[test] +fn test_reload_handles_new_force_close_below_pending_closed_channel_update() { + let chanmon_cfgs = create_chanmon_cfgs(2); + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); + + let persister; + let chain_mon; + let node_b_reload; + + let legacy_cfg = test_legacy_channel_config(); + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(legacy_cfg), None]); + let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); + + let node_a_id = nodes[0].node.get_our_node_id(); + let node_b_id = nodes[1].node.get_our_node_id(); + + let chan_a = + create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000); + let (payment_preimage, ..) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000); + + // Save monitor bytes from before the close. On reload we'll pair these stale bytes with a + // newer ChannelManager state, forcing startup to regenerate the close update from the monitor's + // current update_id instead of replaying a still-pending close from serialized manager state. + let monitor_before_close = get_monitor!(nodes[1], chan_a.2).encode(); + + let message = "Channel force-closed".to_owned(); + nodes[0] + .node + .force_close_broadcasting_latest_txn(&chan_a.2, &node_b_id, message.clone()) + .unwrap(); + check_added_monitors(&nodes[0], 1); + let a_reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message }; + check_closed_event(&nodes[0], 1, a_reason, &[node_b_id], 1_000_000); + check_closed_broadcast(&nodes[0], 1, true); + + let as_commit_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0); + assert_eq!(as_commit_tx.len(), 1); + + // Let B see A's commitment confirmation normally. This generates and completes the + // CommitmentTxConfirmed force-close monitor update, after which the ChannelManager drops the + // channel from memory and only remembers the latest closed-channel update_id. + mine_transaction(&nodes[1], &as_commit_tx[0]); + check_closed_broadcast(&nodes[1], 1, true); + check_added_monitors(&nodes[1], 1); + let b_reason = ClosureReason::CommitmentTxConfirmed; + check_closed_event(&nodes[1], 1, b_reason, &[node_a_id], 1_000_000); + assert!(nodes[1].node.list_channels().is_empty()); + + // Now create a later closed-channel update and keep it in flight. This is the replayed + // `pending_update` that startup will see first. Because the channel is already closed in the + // ChannelManager, this claim lands on the closed-channel bookkeeping path and gets update_id 4. + chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress); + nodes[1].node.claim_funds(payment_preimage); + check_added_monitors(&nodes[1], 1); + assert!(nodes[1].node.get_and_clear_pending_events().is_empty()); + + // Serialize the newer ChannelManager state, but reload it against the stale pre-close monitor + // bytes captured above. Startup then reconstructs two updates for the same closed channel: + // 1. a regenerated force-close update at id 3, derived from the stale monitor bytes and the + // remembered closed-channel update_id in the ChannelManager, + // 2. the still-in-flight preimage update at id 4, replayed from serialized closed-channel + // in-flight updates. + // + // With the fix in place, startup keeps the regenerated close update ahead of the replayed + // preimage update for this channel, so the stale monitor is brought from 2 -> 3 -> 4. + // The test framework also checks that the chain source watchlist matches the monitor set after + // reload. Because we intentionally go back to stale monitor bytes here, we have to drop the + // old watch registrations before constructing the new ChainMonitor. + nodes[1].chain_source.watched_txn.lock().unwrap().clear(); + nodes[1].chain_source.watched_outputs.lock().unwrap().clear(); + let manager_b = nodes[1].node.encode(); + reload_node!( + nodes[1], + &manager_b, + &[&monitor_before_close], + persister, + chain_mon, + node_b_reload + ); + assert!(nodes[1].node.list_channels().is_empty()); + let events = nodes[1].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1, "{events:?}"); + assert!(matches!(events[0], Event::PaymentClaimed { .. })); + check_added_monitors(&nodes[1], 2); +} + #[test] #[cfg(all(feature = "std", not(target_os = "windows")))] fn test_single_channel_multiple_mpp() { diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index a3c33b8320f..8ab18d3a0fa 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -19489,8 +19489,8 @@ impl< } } - // The newly generated `close_background_events` have to be added after any updates that - // were already in-flight on shutdown, so we append them here. + // Merge the newly generated close updates with any replayed in-flight updates while keeping + // same-channel updates ordered by `update_id`. pending_background_events.reserve(close_background_events.len()); 'each_bg_event: for mut new_event in close_background_events { if let BackgroundEvent::MonitorUpdateRegeneratedOnStartup { @@ -19506,7 +19506,8 @@ impl< ChannelMonitorUpdateStep::ChannelForceClosed { .. } )); let mut updated_id = false; - for pending_event in pending_background_events.iter() { + let mut insert_idx = pending_background_events.len(); + for (idx, pending_event) in pending_background_events.iter().enumerate() { if let BackgroundEvent::MonitorUpdateRegeneratedOnStartup { counterparty_node_id: pending_cp, funding_txo: pending_funding, @@ -19518,7 +19519,6 @@ impl< && funding_txo == pending_funding && channel_id == pending_chan_id; if for_same_channel { - debug_assert!(update.update_id >= pending_update.update_id); if pending_update.updates.iter().any(|upd| { matches!(upd, ChannelMonitorUpdateStep::ChannelForceClosed { .. }) }) { @@ -19527,8 +19527,19 @@ impl< // force-close update, no need to duplicate it. continue 'each_bg_event; } - update.update_id = pending_update.update_id.saturating_add(1); - updated_id = true; + if update.update_id < pending_update.update_id { + // If we reloaded from stale monitor bytes, the regenerated + // close update may need to run before a later replayed + // post-close update for the same channel. + insert_idx = cmp::min(insert_idx, idx); + } else { + let next_update_id = cmp::max( + update.update_id, + pending_update.update_id.saturating_add(1), + ); + updated_id |= next_update_id != update.update_id; + update.update_id = next_update_id; + } } } } @@ -19551,6 +19562,11 @@ impl< .1; debug_assert!(!in_flight_updates.iter().any(|upd| upd == update)); in_flight_updates.push(update.clone()); + in_flight_updates.sort_by_key(|upd| upd.update_id); + if insert_idx < pending_background_events.len() { + pending_background_events.insert(insert_idx, new_event); + continue; + } } pending_background_events.push(new_event); }