Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cargo/mutants.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
profile = "mutants"
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Make coverage directory
run: mkdir coverage
- name: Test and report coverage
run: cargo +nightly llvm-cov -q --doctests --branch --all --ignore-filename-regex "example-crates/*" --all-features --lcov --output-path ./coverage/lcov.info
run: cargo +nightly llvm-cov -q --doctests --branch --all --exclude sp_fuzz --ignore-filename-regex "example-crates/*" --all-features --lcov --output-path ./coverage/lcov.info
- name: Generate HTML coverage report
run: genhtml -o coverage-report.html --ignore-errors unmapped ./coverage/lcov.info
- name: Coveralls upload
Expand Down
42 changes: 42 additions & 0 deletions .github/workflows/mutations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Test mutants

permissions:
contents: read

env:
CARGO_TERM_COLOR: always

on:
push:
branches:
- main
pull_request:

jobs:
incremental-mutants:
name: Incremental mutants test
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Relative diff
run: |
git branch -av
git diff origin/${{ github.base_ref }}.. | tee git.diff
- name: Rust Cache
uses: Swatinem/rust-cache@v2
- name: Install Rust toolchain
uses: taiki-e/install-action@v2
with:
tool: cargo-mutants
- name: Mutants
run: |
cargo mutants --no-shuffle -vV --exclude "example-crates/**" --in-diff git.diff -- --all-targets
- name: Archive mutants.out
uses: actions/upload-artifact@v4
if: always()
with:
name: mutants-incremental.out
path: mutants.out
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ Cargo.lock

# Ignore media (should go into media branch)
*.gif

# Ignore cargo-mutants generated output
/mutants.out*
10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
resolver = "2"
members = [
"silentpayments",
"example-crates/example_silentpayments", "dleq", "indexer",
"example-crates/example_silentpayments", "dleq", "indexer", "fuzz",
]
default-members = [
"silentpayments", "dleq", "indexer",
]

[workspace.package]
Expand All @@ -14,3 +17,8 @@ print_stderr = "deny"

[workspace.lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage,coverage_nightly)'] }

[profile.mutants]
inherits = "test"
debug = "none"
opt-level = 3
7 changes: 7 additions & 0 deletions fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
hfuzz_target
hfuzz_workspace
target
corpus
artifacts
# AFL
out
35 changes: 35 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[package]
name = "sp_fuzz"
version = "0.1.0"
edition = "2024"
publish = false
authors.workspace = true

[features]
afl_fuzz = ["afl"]
honggfuzz_fuzz = ["honggfuzz"]
libfuzzer_fuzz = ["libfuzzer-sys"]
stdin_fuzz = []

[dependencies]
bdk_sp = { version = "0.1.0", path = "../silentpayments" }
afl = { version = "0.12", optional = true }
honggfuzz = { version = "0.5", optional = true, default-features = false }
libfuzzer-sys = { version = "0.4", optional = true }

[lib]
name = "sp_fuzz"
path = "src/lib.rs"

[[bin]]
name = "sp_encoding"
path = "src/bin/sp_code_target.rs"

[lints.rust.unexpected_cfgs]
level = "forbid"
check-cfg = [
"cfg(fuzzing)",
"cfg(secp256k1_fuzz)",
"cfg(hashes_fuzz)",
"cfg(taproot)",
]
1 change: 1 addition & 0 deletions fuzz/seeds/seed.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello, AFL!
45 changes: 45 additions & 0 deletions fuzz/src/bin/sp_code_target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#![cfg_attr(feature = "libfuzzer_fuzz", no_main)]

use bdk_sp::encoding::SilentPaymentCode;
use core::convert::TryFrom;

use sp_fuzz::sp_code::sp_code_parse_run;

#[cfg(feature = "afl")]
#[macro_use]
extern crate afl;
#[cfg(feature = "afl")]
fn main() {
fuzz!(|data| {
sp_code_parse_run(data.as_ptr(), data.len());
});
}

#[cfg(feature = "honggfuzz")]
#[macro_use]
extern crate honggfuzz;
#[cfg(feature = "honggfuzz")]
fn main() {
loop {
fuzz!(|data| {
sp_code_parse_run(data.as_ptr(), data.len());
});
}
}

#[cfg(feature = "libfuzzer_fuzz")]
#[macro_use]
extern crate libfuzzer_sys;
#[cfg(feature = "libfuzzer_fuzz")]
fuzz_target!(|data: &[u8]| {
sp_code_parse_run(data.as_ptr(), data.len());
});

#[cfg(feature = "stdin_fuzz")]
fn main() {
use std::io::Read;

let mut data = Vec::with_capacity(1023);
std::io::stdin().read_to_end(&mut data).unwrap();
sp_code_parse_run(data.as_ptr(), data.len());
}
10 changes: 10 additions & 0 deletions fuzz/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#[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");

pub mod sp_code;
20 changes: 20 additions & 0 deletions fuzz/src/sp_code.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use bdk_sp::encoding::SilentPaymentCode;
use core::convert::TryFrom;

#[inline]
pub fn do_test(data: &[u8]) {
if let Ok(received_sp_code) = std::str::from_utf8(data) {
if let Ok(sp_code) = SilentPaymentCode::try_from(received_sp_code) {
let produced_sp_code = sp_code.to_string();
assert_eq!(received_sp_code, produced_sp_code);
}
}
}
pub fn sp_code_parse_test(data: &[u8]) {
do_test(data);
}

#[unsafe(no_mangle)]
pub extern "C" fn sp_code_parse_run(data: *const u8, datalen: usize) {
do_test(unsafe { std::slice::from_raw_parts(data, datalen) });
}
6 changes: 3 additions & 3 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ default:

[doc("Build the project")]
build:
cargo build
cargo build --exclude sp_fuzz

[doc("Check code: formatting, compilation, linting, and commit signature")]
check:
cargo +nightly fmt --all -- --check
cargo check --workspace --exclude 'example_*' --all-features
cargo check --workspace --exclude sp_fuzz --exclude 'example_*' --all-features
cargo clippy --all-features --all-targets -- -D warnings
@[ "$(git log --pretty='format:%G?' -1 HEAD)" = "N" ] && \
echo "\n⚠️ Unsigned commit: BDK requires that commits be signed." || \
Expand All @@ -27,7 +27,7 @@ fmt:

[doc("Run all tests on the workspace with all features")]
test:
cargo test --workspace --exclude 'example_*' --all-features
cargo test --workspace --exclude sp_fuzz --exclude 'example_*' --all-features

[doc("Run pre-push suite: format, check, and test")]
pre-push: fmt check test
Loading