Skip to content

Commit 707a699

Browse files
Merge pull request #1 from BitGo/sync-with-upstream-rust-bitcoin
Sync with upstream rust bitcoin
2 parents e91f411 + 15ad78a commit 707a699

926 files changed

Lines changed: 105854 additions & 1 deletion

File tree

Some content is hidden

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

.cargo/mutants.toml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
additional_cargo_args = ["--all-features"]
2+
examine_globs = ["consensus_encoding/src/**/*.rs", "units/src/**/*.rs", "primitives/src/**/*.rs"]
3+
exclude_globs = [
4+
"units/src/amount/verification.rs" # kani tests
5+
]
6+
exclude_re = [
7+
"impl Arbitrary",
8+
"impl Debug",
9+
"impl fmt::Debug",
10+
".*Error",
11+
"deserialize", # Skip serde mutation tests
12+
"serde_details::<impl de::Visitor<'_>", # Skip serde mutation tests
13+
"Iterator", # Mutating operations in an iterator can result in an infinite loop
14+
"<impl .*Decodable for .*>::decoder", # Mutant replacing Default::default() is equivalent to returning new()
15+
"<impl .*Decoder for .*>::read_limit", # Function is for optimization and does not need to be tested.
16+
17+
18+
# ----------------------------------Crate-specific exclusions----------------------------------
19+
# units
20+
# src/amount/mod.rs
21+
"units/.* parse_signed_to_satoshi", # Can't kill all mutants since there is no denomination smaller than Satoshi
22+
"units/.* fmt_satoshi_in", # Related to formatting/display
23+
"units/.* dec_width", # Replacing num /= 10 with num %=10 in a loop causes a timeout due to infinite loop
24+
# src/locktime/relative.rs
25+
"units/.* LockTime::to_consensus_u32", # Mutant from replacing | with ^, this returns the same value since the XOR is taken against the u16 with an all-zero bitmask
26+
"units/.* FeeRate::fee_vb", # Deprecated
27+
"units/.* FeeRate::fee_wu", # Deprecated
28+
"units/.* SignedAmount::checked_abs", # Deprecated
29+
"units/.* NumberOfBlocks::value", # Deprecated
30+
"units/.* NumberOf512Seconds::to_consensus_u32", # Deprecated
31+
"units/.* MedianTimePast::to_consensus_u32", # Deprecated
32+
"units/.* Height::to_consensus_u32", # Deprecated
33+
"units/.* Sequence::to_hex", # Deprecated
34+
"units/.* Sequence::from_512_second_intervals", # Mutant from replacing | with ^, this returns the same value since the XOR is taken against the u16 with an all-zero bitmask
35+
36+
# primitives
37+
"primitives/.* Opcode::classify", # Not possible to kill all mutants without individually checking every opcode classification
38+
"primitives/.* Block<Checked>::cached_witness_root", # Skip getters
39+
"primitives/.* Block<Checked>::transactions", # Skip getters
40+
"primitives/.* Script::to_bytes", # Deprecated
41+
"primitives/.* decode_cursor", # Mutating operations in decode_cursor can result in an infinite loop
42+
"primitives/.* fmt_debug", # Mutants from formatting/display changes
43+
"primitives/.* fmt_debug_pretty", # Mutants from formatting/display changes
44+
"primitives/.* CompactTarget::to_hex", # Deprecated
45+
"primitives/.* Script::to_hex", # Deprecated
46+
"primitives/.* Script<T>::to_hex", # Deprecated
47+
"primitives/.* ScriptBuf::to_hex", # Deprecated
48+
"primitives/.* ScriptBuf<T>::to_hex", # Deprecated
49+
"primitives/.* <impl Encoder for .*Encoder<'_>>::current_chunk", # Replacing the return with Some(vec![]) causes an infinite loop.
50+
"primitives/.* <impl Encoder for .*Encoder<'_>>::advance", # Replacing the return with true causes an infinite loop.
51+
"primitives/.* <impl Decoder for WitnessDecoder>::push_bytes", # Replacing == with != causes an infinite loop
52+
"primitives/.* WitnessDecoder::resize_if_needed", # Replacing *= with += still resizes the buffer making the mutant untestable.
53+
"primitives/.* replace \\+ with \\* in MerkleNode::calculate_root", # Replacing + with * causes an infinite loop
54+
"primitives/.* replace == with != in MerkleNode::calculate_root", # Replacing == with != isn't caught unless alloc is disabled.
55+
56+
# consensus_encoding - most of these are for mutations in the logic used to determine when to stop encoding or decoding.
57+
"consensus_encoding/.* <impl Decoder for ArrayDecoder<N>>::push_bytes", # Mutations cause an infinite loop
58+
"consensus_encoding/.* <impl Decoder for .*>::end", # Mutations cause an infinite loop
59+
"consensus_encoding/.* encode_to_vec", # Mutations cause an infinite loop
60+
"consensus_encoding/.* encode_to_writer", # Mutations cause an infinite loop
61+
"consensus_encoding/.* decode_from_slice", # Mutations cause an infinite loop
62+
"consensus_encoding/.* decode_from_read", # Mutations cause an infinite loop
63+
"consensus_encoding/.* <impl Decoder for .*>::push_bytes", # Mutations cause an infinite loop
64+
]

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.rs diff=rust

.github/dependabot.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Set update schedule for GitHub Actions
2+
version: 2
3+
updates:
4+
- package-ecosystem: "github-actions"
5+
directory: "/"
6+
schedule:
7+
# Check for updates to GitHub Actions every week
8+
interval: "weekly"
9+
# Defines a cooldown period for dependency updates,
10+
# allowing updates to be delayed for a configurable number of days.
11+
cooldown:
12+
default-days: 60

.github/labeler.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ci:
2+
- changed-files:
3+
- any-glob-to-any-file: .github/**
4+
test:
5+
- changed-files:
6+
- any-glob-to-any-file: fuzz/**
7+
- any-glob-to-any-file: '*/tests/**'
8+
- any-glob-to-any-file: 'dep_test'
9+
- any-glob-to-any-file: 'contrib/run_task.sh'
10+
- any-glob-to-any-file: 'contrib/test_vars.sh'
11+
- any-glob-to-any-file: '*/contrib/extra_tests.sh'
12+
- any-glob-to-any-file: '*/contrib/test_vars.sh'
13+
doc:
14+
- changed-files:
15+
- any-glob-to-any-file: '**/*.md'

.github/workflows/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# rust-bitcoin workflow notes
2+
3+
We are attempting to run max 20 parallel jobs using GitHub actions (usage limit for free tier).
4+
5+
ref: https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration
6+
7+
The minimal/recent lock files are handled by CI (`rust.yml`).
8+
9+
## Jobs
10+
11+
Run from rust.yml unless stated otherwise. Unfortunately we are now exceeding the 20 job target.
12+
(Prepare is quick and must be run first anyway.)
13+
14+
0. `Prepare`
15+
1. `Stable - minimal`
16+
2. `Stable - recent`
17+
3. `Nightly - minimal`
18+
4. `Nightly - recent`
19+
5. `MSRV - minimal`
20+
6. `MSRV - recent`
21+
7. `Lint`
22+
8. `Docs`
23+
9. `Docsrs`
24+
10. `Bench`
25+
11. `Arch32bit`
26+
12. `Cross`
27+
13. `Embedded`
28+
14. `ASAN`
29+
15. `WASM`
30+
16. `Kani`
31+
17. `API`
32+
18. `Policy` - enforce repository coding policy.
33+
19. `Re-exports`
34+
20. `DiffMutants`
35+
21. `release` - run by `release.yml`
36+
22. `labeler` - run by `manage-pr.yml`
37+
23. `Shellcheck` - run by `shellcheck.yml`
38+
39+
If any change touches the `.github/` directory then the `zizmor`, run by `zizmor.yml`, will be
40+
triggered for that PR.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.45.0
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Automatically generated by fuzz/generate-files.sh
2+
name: Fuzz
3+
on:
4+
schedule:
5+
# 5am every day UTC, this correlates to:
6+
# - 10pm PDT
7+
# - 6am CET
8+
# - 4pm AEDT
9+
- cron: '00 05 * * *'
10+
permissions: {}
11+
12+
jobs:
13+
fuzz:
14+
if: ${{ !github.event.act }}
15+
runs-on: ubuntu-24.04
16+
permissions:
17+
contents: read
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
# We only get 20 jobs at a time, we probably don't want to go
22+
# over that limit with fuzzing because of the hour run time.
23+
fuzz_target: [
24+
bitcoin_arbitrary_block,
25+
bitcoin_arbitrary_script,
26+
bitcoin_arbitrary_transaction,
27+
bitcoin_arbitrary_witness,
28+
bitcoin_deserialize_block,
29+
bitcoin_deserialize_prefilled_transaction,
30+
bitcoin_deserialize_psbt,
31+
bitcoin_deserialize_script,
32+
bitcoin_deserialize_transaction,
33+
bitcoin_deserialize_witness,
34+
bitcoin_parse_address,
35+
bitcoin_parse_outpoint,
36+
bitcoin_script_bytes_to_asm_fmt,
37+
consensus_encoding_decode_array,
38+
consensus_encoding_decode_byte_vec,
39+
consensus_encoding_decode_compact_size,
40+
consensus_encoding_decode_decoder2,
41+
hashes_json,
42+
hashes_ripemd160,
43+
hashes_sha1,
44+
hashes_sha256,
45+
hashes_sha512,
46+
hashes_sha512_256,
47+
p2p_arbitrary_addrv2,
48+
p2p_deserialize_addrv2,
49+
p2p_deserialize_raw_net_msg,
50+
units_arbitrary_weight,
51+
units_parse_amount,
52+
units_parse_int,
53+
units_standard_checks,
54+
]
55+
steps:
56+
- name: Install test dependencies
57+
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
58+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
59+
with:
60+
persist-credentials: false
61+
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
62+
63+
id: cache-fuzz
64+
with:
65+
path: |
66+
~/.cargo/bin
67+
fuzz/target
68+
target
69+
key: cache-${{ matrix.target }}-${{ hashFiles('**/Cargo.toml','**/Cargo.lock') }}
70+
- uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 # stable
71+
with:
72+
toolchain: '1.74.0'
73+
- name: fuzz
74+
run: |
75+
if [[ "${{ matrix.fuzz_target }}" =~ ^bitcoin ]]; then
76+
export RUSTFLAGS='--cfg=hashes_fuzz --cfg=secp256k1_fuzz'
77+
fi
78+
echo "Using RUSTFLAGS $RUSTFLAGS"
79+
cd fuzz && ./fuzz.sh "${{ matrix.fuzz_target }}"
80+
- run: echo "${{ matrix.fuzz_target }}" >executed_${{ matrix.fuzz_target }}
81+
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
82+
with:
83+
name: executed_${{ matrix.fuzz_target }}
84+
path: executed_${{ matrix.fuzz_target }}
85+
86+
verify-execution:
87+
if: ${{ !github.event.act }}
88+
needs: fuzz
89+
runs-on: ubuntu-24.04
90+
permissions:
91+
contents: read
92+
steps:
93+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
94+
with:
95+
persist-credentials: false
96+
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
97+
- name: Display structure of downloaded files
98+
run: ls -R
99+
- run: find executed_* -type f -exec cat {} + | sort > executed
100+
- run: source ./fuzz/fuzz-util.sh && listTargetNames | sort | diff - executed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# From https://model-checking.github.io/kani/install-github-ci.html
2+
name: Kani CI
3+
on:
4+
schedule:
5+
- cron: '59 23 * * *' # midnight every day.
6+
permissions: {}
7+
jobs:
8+
run-kani:
9+
runs-on: ubuntu-24.04
10+
permissions:
11+
contents: read
12+
steps:
13+
- name: 'Checkout your code.'
14+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
15+
with:
16+
persist-credentials: false
17+
18+
- name: 'Run Kani on your code.'
19+
uses: model-checking/kani-github-action@f838096619a707b0f6b2118cf435eaccfa33e51f # v1.1
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Weekly cargo-mutants
2+
on:
3+
schedule:
4+
- cron: "0 0 * * 0" # runs weekly on Sunday at 00:00
5+
workflow_dispatch: # allows manual triggering
6+
permissions: {}
7+
jobs:
8+
cargo-mutants:
9+
runs-on: ubuntu-24.04
10+
permissions:
11+
contents: read
12+
issues: write
13+
steps:
14+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
15+
with:
16+
persist-credentials: false
17+
- uses: taiki-e/install-action@81ee1d48d9194cdcab880cbdc7d36e87d39874cb # v2.62.45
18+
with:
19+
tool: cargo-mutants
20+
- run: cargo mutants --in-place --no-shuffle
21+
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
22+
if: always()
23+
with:
24+
name: mutants.out
25+
path: mutants.out
26+
- name: Check for new mutants
27+
if: always()
28+
run: |
29+
if [ -s mutants.out/missed.txt ]; then
30+
echo "New missed mutants found"
31+
MUTANTS_VERSION=$(cargo mutants --version)
32+
gh issue create \
33+
--title "New Mutants Found" \
34+
--body "$(cat <<EOF
35+
Displaying up to the first 10 mutants:
36+
\`\`\`
37+
$(head -n 10 mutants.out/missed.txt)
38+
\`\`\`
39+
Running cargo mutants version: ${MUTANTS_VERSION}
40+
For the complete list, please check the [mutants.out artifact](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}).
41+
EOF
42+
)"
43+
echo "create_issue=true" >> $GITHUB_ENV
44+
else
45+
echo "No new mutants found"
46+
echo "create_issue=false" >> $GITHUB_ENV
47+
fi
48+
env:
49+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Nightly rustfmt
2+
on:
3+
schedule:
4+
- cron: "0 0 * * 0" # runs weekly on Sunday at 00:00
5+
workflow_dispatch: # allows manual triggering
6+
permissions: {}
7+
jobs:
8+
format:
9+
name: Nightly rustfmt
10+
runs-on: ubuntu-24.04
11+
permissions:
12+
contents: write
13+
pull-requests: write
14+
steps:
15+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
16+
with:
17+
persist-credentials: false
18+
- uses: dtolnay/rust-toolchain@55d80eb3c5a4228eec5390a083c092095115c6f1 # nightly
19+
with:
20+
components: rustfmt
21+
- name: Run Nightly rustfmt
22+
# Run the formatter and manually remove trailing whitespace.
23+
run: cargo +nightly fmt && git ls-files -- '*.rs' -z | xargs sed -E -i'' -e 's/[[:space:]]+$//'
24+
- name: Get the current date
25+
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
26+
- name: Create Pull Request
27+
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
28+
with:
29+
author: Fmt Bot <bot@example.com>
30+
title: Automated nightly rustfmt (${{ env.date }})
31+
body: |
32+
Automated nightly `rustfmt` changes by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action
33+
commit-message: ${{ env.date }} automated rustfmt nightly
34+
labels: rustfmt
35+

0 commit comments

Comments
 (0)