ci: detach fuzz cron from bin generation
What changed, and why it matters
This commit is a maintenance-only change to the project's automated fuzz testing setup. It switches the daily fuzzing workflow from generating one GitHub Actions job per fuzz target to running targets across a fixed set of 16 shared jobs. It removes the script that generated the workflow file and deletes a verification step that checked every target ran. There is no change to the actual Bitcoin library code, no user-facing behavior change, and no security fix or vulnerability introduced.
No security action needed. Reviewers may want to confirm the new sharding logic covers all fuzz targets and that removing the verify-execution job is acceptable, but this is a CI quality concern, not a security issue.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit modifies .github/workflows/cron-daily-fuzz.yml and fuzz/generate-files.sh. It replaces a dynamically generated matrix of fuzz_target entries with a static shard_id matrix of 0..15. Each shard now runs a subset of targets selected via cargo fuzz list, sort, and awk modulo arithmetic. The workflow no longer uploads per-target artifacts and no longer has a verify-execution job that diffs cargo fuzz list against executed targets. The fuzz/generate-files.sh script loses the code that emitted the workflow YAML. These are CI infrastructure changes only; no Rust source code in the crate is touched.
Changed components
.github/workflows/cron-daily-fuzz.ymlfuzz/generate-files.shInspect captured patch +16 / −209
diff --git a/.github/workflows/cron-daily-fuzz.yml b/.github/workflows/cron-daily-fuzz.yml
index 70d6503d..9e2f2f1a 100644
--- a/.github/workflows/cron-daily-fuzz.yml
+++ b/.github/workflows/cron-daily-fuzz.yml
@@ -1,4 +1,5 @@
-# Automatically generated by fuzz/generate-files.sh
+# Fuzz targets are distributed over a static number of jobs.
+
name: Fuzz
on:
schedule:
@@ -17,116 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- fuzz_target: [
- bitcoin_0_32_compare_consensus_encoding,
- bitcoin_0_32_deser_net_msg,
- bitcoin_0_32_deserialize_address,
- bitcoin_0_32_deserialize_psbt,
- bitcoin_0_32_outpoint_string,
- bitcoin_arbitrary_block,
- bitcoin_arbitrary_script,
- bitcoin_arbitrary_transaction,
- bitcoin_arbitrary_witness,
- bitcoin_compare_consensus_encoding,
- bitcoin_deserialize_block,
- bitcoin_deserialize_prefilled_transaction,
- bitcoin_deserialize_script,
- bitcoin_deserialize_transaction,
- bitcoin_deserialize_witness,
- bitcoin_encoding_roundtrip_absolute_lock_time,
- bitcoin_encoding_roundtrip_amount,
- bitcoin_encoding_roundtrip_block,
- bitcoin_encoding_roundtrip_block_hash,
- bitcoin_encoding_roundtrip_block_header,
- bitcoin_encoding_roundtrip_block_height,
- bitcoin_encoding_roundtrip_block_time,
- bitcoin_encoding_roundtrip_block_version,
- bitcoin_encoding_roundtrip_compact_target,
- bitcoin_encoding_roundtrip_out_point,
- bitcoin_encoding_roundtrip_p2p_address_addr_v1_message,
- bitcoin_encoding_roundtrip_p2p_address_addr_v2,
- bitcoin_encoding_roundtrip_p2p_address_addr_v2_message,
- bitcoin_encoding_roundtrip_p2p_address_address,
- bitcoin_encoding_roundtrip_p2p_bip152_block_transactions,
- bitcoin_encoding_roundtrip_p2p_bip152_block_transactions_request,
- bitcoin_encoding_roundtrip_p2p_bip152_header_and_short_ids,
- bitcoin_encoding_roundtrip_p2p_bip152_prefilled_transaction,
- bitcoin_encoding_roundtrip_p2p_bip152_short_id,
- bitcoin_encoding_roundtrip_p2p_magic,
- bitcoin_encoding_roundtrip_p2p_merkle_tree_merkle_block,
- bitcoin_encoding_roundtrip_p2p_merkle_tree_partial_merkle_tree,
- bitcoin_encoding_roundtrip_p2p_message_addr_payload,
- bitcoin_encoding_roundtrip_p2p_message_addr_v2_payload,
- bitcoin_encoding_roundtrip_p2p_message_blockdata_block_locator,
- bitcoin_encoding_roundtrip_p2p_message_blockdata_get_blocks_message,
- bitcoin_encoding_roundtrip_p2p_message_blockdata_get_headers_message,
- bitcoin_encoding_roundtrip_p2p_message_blockdata_inventory,
- bitcoin_encoding_roundtrip_p2p_message_bloom_bloom_flags,
- bitcoin_encoding_roundtrip_p2p_message_bloom_filter_add,
- bitcoin_encoding_roundtrip_p2p_message_bloom_filter_load,
- bitcoin_encoding_roundtrip_p2p_message_command_string,
- bitcoin_encoding_roundtrip_p2p_message_compact_blocks_send_cmpct,
- bitcoin_encoding_roundtrip_p2p_message_erlay_send_tx_rcn_cl,
- bitcoin_encoding_roundtrip_p2p_message_fee_filter,
- bitcoin_encoding_roundtrip_p2p_message_filter_c_f_checkpt,
- bitcoin_encoding_roundtrip_p2p_message_filter_c_f_headers,
- bitcoin_encoding_roundtrip_p2p_message_filter_c_filter,
- bitcoin_encoding_roundtrip_p2p_message_filter_filter_hash,
- bitcoin_encoding_roundtrip_p2p_message_filter_filter_header,
- bitcoin_encoding_roundtrip_p2p_message_filter_get_c_f_checkpt,
- bitcoin_encoding_roundtrip_p2p_message_filter_get_c_f_headers,
- bitcoin_encoding_roundtrip_p2p_message_filter_get_c_filters,
- bitcoin_encoding_roundtrip_p2p_message_headers_message,
- bitcoin_encoding_roundtrip_p2p_message_inventory_payload,
- bitcoin_encoding_roundtrip_p2p_message_network_alert,
- bitcoin_encoding_roundtrip_p2p_message_network_header,
- bitcoin_encoding_roundtrip_p2p_message_network_reject,
- bitcoin_encoding_roundtrip_p2p_message_network_reject_reason,
- bitcoin_encoding_roundtrip_p2p_message_network_user_agent,
- bitcoin_encoding_roundtrip_p2p_message_network_version_message,
- bitcoin_encoding_roundtrip_p2p_message_ping,
- bitcoin_encoding_roundtrip_p2p_message_pong,
- bitcoin_encoding_roundtrip_p2p_message_v1_message_header,
- bitcoin_encoding_roundtrip_p2p_message_v1_network_message,
- bitcoin_encoding_roundtrip_p2p_protocol_version,
- bitcoin_encoding_roundtrip_p2p_service_flags,
- bitcoin_encoding_roundtrip_redeem_script_buf,
- bitcoin_encoding_roundtrip_script_pub_key_buf,
- bitcoin_encoding_roundtrip_script_sig_buf,
- bitcoin_encoding_roundtrip_sequence,
- bitcoin_encoding_roundtrip_tap_script_buf,
- bitcoin_encoding_roundtrip_transaction,
- bitcoin_encoding_roundtrip_transaction_version,
- bitcoin_encoding_roundtrip_tx_in,
- bitcoin_encoding_roundtrip_tx_merkle_node,
- bitcoin_encoding_roundtrip_tx_out,
- bitcoin_encoding_roundtrip_witness,
- bitcoin_encoding_roundtrip_witness_merkle_node,
- bitcoin_encoding_roundtrip_witness_script_buf,
- bitcoin_parse_address,
- bitcoin_parse_outpoint,
- bitcoin_script_bytes_to_asm_fmt,
- consensus_encoding_decode_array,
- consensus_encoding_decode_byte_vec,
- consensus_encoding_decode_compact_size,
- consensus_encoding_decode_decoder2,
- hashes_0_32_cbor,
- hashes_arbitrary_json,
- hashes_json,
- hashes_ripemd160,
- hashes_sha1,
- hashes_sha256,
- hashes_sha512,
- hashes_sha512_256,
- p2p_arbitrary_addrv2,
- p2p_deserialize_addrv2,
- p2p_deserialize_raw_net_msg,
- units_0_32_deserialize_amount,
- units_arbitrary_weight,
- units_parse_amount,
- units_parse_int,
- units_standard_checks,
- ]
+ shard_id: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
steps:
- name: Install test dependencies
run: sudo apt-get update -y && sudo apt-get install -y binutils-dev libunwind8-dev libcurl4-openssl-dev libelf-dev libdw-dev cmake gcc libiberty-dev
@@ -140,35 +32,21 @@ jobs:
~/.cargo/bin
fuzz/target
target
- key: cache-${{ matrix.fuzz_target }}-${{ hashFiles('**/Cargo.toml','**/Cargo.lock') }}
+ key: cache-fuzz-${{ hashFiles('**/Cargo.toml','**/Cargo.lock') }}
- uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 # stable
with:
toolchain: '1.74.0'
- - name: fuzz
+ - run: cargo install --locked --version 0.12.0 cargo-fuzz
+ - name: Fuzz shard ${{ matrix.shard_id }}
run: |
- if [[ "${{ matrix.fuzz_target }}" =~ ^bitcoin ]]; then
+ shard_targets=($(cargo fuzz list | sort | awk -v shard=${{ matrix.shard_id }} 'BEGIN{i=0} {if (i++ % 16 == shard) print}'))
+ for target in "${shard_targets[@]}"; do
+ if [[ "$target" =~ ^bitcoin ]]; then
export RUSTFLAGS='--cfg=hashes_fuzz --cfg=secp256k1_fuzz'
- fi
- echo "Using RUSTFLAGS $RUSTFLAGS"
- cd fuzz && ./fuzz.sh "${{ matrix.fuzz_target }}"
- - run: echo "${{ matrix.fuzz_target }}" >executed_${{ matrix.fuzz_target }}
- - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
- with:
- name: executed_${{ matrix.fuzz_target }}
- path: executed_${{ matrix.fuzz_target }}
-
- verify-execution:
- needs: fuzz
- runs-on: ubuntu-24.04
- permissions:
- contents: read
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- with:
- persist-credentials: false
- - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
- - run: cargo install --locked --version 0.12.0 cargo-fuzz
- - name: Display structure of downloaded files
- run: ls -R
- - run: find executed_* -type f -exec cat {} + | sort > executed
- - run: cargo fuzz list | sort | diff - executed
+ else
+ unset RUSTFLAGS
+ fi
+ echo "Using RUSTFLAGS: ${RUSTFLAGS:-<empty>}"
+ cd fuzz && ./fuzz.sh "$target"
+ cd ..
+ done
diff --git a/fuzz/generate-files.sh b/fuzz/generate-files.sh
index dd0f87a5..5b9a134c 100755
--- a/fuzz/generate-files.sh
+++ b/fuzz/generate-files.sh
@@ -75,74 +75,3 @@ doc = false
bench = false
EOF
done
-
-# 2. Generate .github/workflows/cron-daily-fuzz.yml
-cat > "$REPO_DIR/.github/workflows/cron-daily-fuzz.yml" <<EOF
-# Automatically generated by fuzz/generate-files.sh
-name: Fuzz
-on:
- schedule:
- # 5am every day UTC, this correlates to:
- # - 10pm PDT
- # - 6am CET
- # - 4pm AEDT
- - cron: '00 05 * * *'
-permissions: {}
-
-jobs:
- fuzz:
- runs-on: ubuntu-24.04
- permissions:
- contents: read
- strategy:
- fail-fast: false
- matrix:
- fuzz_target: [
-$(for name in $(cargo fuzz list); do echo " $name,"; done)
- ]
- steps:
- - name: Install test dependencies
- run: sudo apt-get update -y && sudo apt-get install -y binutils-dev libunwind8-dev libcurl4-openssl-dev libelf-dev libdw-dev cmake gcc libiberty-dev
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- with:
- persist-credentials: false
- - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
- id: cache-fuzz
- with:
- path: |
- ~/.cargo/bin
- fuzz/target
- target
- key: cache-\${{ matrix.fuzz_target }}-\${{ hashFiles('**/Cargo.toml','**/Cargo.lock') }}
- - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 # stable
- with:
- toolchain: '1.74.0'
- - name: fuzz
- run: |
- if [[ "\${{ matrix.fuzz_target }}" =~ ^bitcoin ]]; then
- export RUSTFLAGS='--cfg=hashes_fuzz --cfg=secp256k1_fuzz'
- fi
- echo "Using RUSTFLAGS \$RUSTFLAGS"
- cd fuzz && ./fuzz.sh "\${{ matrix.fuzz_target }}"
- - run: echo "\${{ matrix.fuzz_target }}" >executed_\${{ matrix.fuzz_target }}
- - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- with:
- name: executed_\${{ matrix.fuzz_target }}
- path: executed_\${{ matrix.fuzz_target }}
-
- verify-execution:
- needs: fuzz
- runs-on: ubuntu-24.04
- permissions:
- contents: read
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- with:
- persist-credentials: false
- - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
- - run: cargo install --locked --version 0.12.0 cargo-fuzz
- - name: Display structure of downloaded files
- run: ls -R
- - run: find executed_* -type f -exec cat {} + | sort > executed
- - run: cargo fuzz list | sort | diff - executed
-EOF
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.