Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 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
28 changes: 13 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,28 @@ on:
- master
pull_request:

env:
BITCOIN_CORE_VERSION: '31.0rc1'

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Install Bitcoin Dependencies
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential cmake pkgconf python3 libevent-dev libboost-dev ccache capnproto libcapnp-dev libxml2-utils
- name: ccache
uses: actions/cache@v4
with:
path: ~/.cache/ccache
key: ccache-${{ runner.os }}-${{ github.sha }}
restore-keys: ccache-${{ runner.os }}-
- name: Checkout Bitcoin Core
run: git clone --depth 1 --branch master https://github.com/bitcoin/bitcoin.git bitcoin-core
- name: Build Bitcoin Core
sudo apt-get install -y capnproto libcapnp-dev libxml2-utils
- name: Download Bitcoin Core
run: |
cd bitcoin-core
git apply ../bitcoin-core-ipc-extranonce.patch

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, we can't use the binaries, we have to clone the repo and apply this patch.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted to clone + patch + build. Now the only change is --branch master--branch v31.0rc1 in b405f0d.

cmake -B build -DENABLE_WALLET=ON -DENABLE_IPC=ON -DBUILD_TESTS=OFF -DBUILD_BENCH=OFF -DBUILD_TX=OFF -DBUILD_UTIL=OFF -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
cmake --build build -j $(nproc) --target bitcoin bitcoin-node
VERSION="${BITCOIN_CORE_VERSION}"
SERIES="${VERSION%%rc*}"
RC="${VERSION##*rc}"
URL="https://bitcoincore.org/bin/bitcoin-core-${SERIES}/test.rc${RC}/bitcoin-${VERSION}-x86_64-linux-gnu.tar.gz"
curl -fsSLO "${URL}"
tar xzf "bitcoin-${VERSION}-x86_64-linux-gnu.tar.gz"
mv "bitcoin-${VERSION}" bitcoin-core
- name: Run Test Suite
run: cargo test
- name: Validate CAMT.053 Fixture
Expand Down
60 changes: 40 additions & 20 deletions DEVELOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,52 @@
- [Cap'n Proto](https://capnproto.org/install.html) compiler (`capnp`)
- macOS: `brew install capnp`
- Debian/Ubuntu: `apt install capnproto`
- Bitcoin Core source tree (for the integration test)
- Bitcoin Core binary (for the integration test)

## Building Bitcoin Core
## Getting Bitcoin Core

The integration test uses Bitcoin Core's IPC interface (multiprocess mode). You
need to build the `bitcoin` and `bitcoin-node` targets from source, with wallet
support enabled.
need the `bitcoin` and `bitcoin-node` binaries.

### Option A: Download pre-built binaries (recommended)

Download the release tarball and extract it into the project directory:

```bash
VERSION="31.0rc1"
curl -fsSLO "https://bitcoincore.org/bin/bitcoin-core-${VERSION%%rc*}/test.rc${VERSION##*rc}/bitcoin-${VERSION}-x86_64-linux-gnu.tar.gz"
tar xzf "bitcoin-${VERSION}-x86_64-linux-gnu.tar.gz"
mv "bitcoin-${VERSION}" bitcoin-core
```

On macOS (Apple Silicon):
```bash
VERSION="31.0rc1"
curl -fsSLO "https://bitcoincore.org/bin/bitcoin-core-${VERSION%%rc*}/test.rc${VERSION##*rc}/bitcoin-${VERSION}-aarch64-apple-darwin.tar.gz"
tar xzf "bitcoin-${VERSION}-aarch64-apple-darwin.tar.gz"
mv "bitcoin-${VERSION}" bitcoin-core
```

The test looks for the binary at `bitcoin-core/bin/bitcoin`.

### Option B: Build from source

1. Clone Bitcoin Core into the project directory:
```bash
git clone https://github.com/bitcoin/bitcoin.git bitcoin-core
```

2. Apply the required patch (pads the coinbase scriptSig for low block heights
so that `createNewBlock` via IPC succeeds at height ≤ 16):
2. Configure and build:
```bash
cd bitcoin-core
git apply ../bitcoin-core-ipc-extranonce.patch
```

3. Configure and build:
```bash
cmake -B build -DENABLE_WALLET=ON -DENABLE_IPC=ON -DBUILD_TESTS=OFF -DBUILD_BENCH=OFF
cmake --build build -j$(nproc) --target bitcoin bitcoin-node
cd ..
```

On macOS, replace `$(nproc)` with `$(sysctl -n hw.logicalcpu)`.

The test expects the binary at `bitcoin-core/build/bin/bitcoin`.
The test also looks for the binary at `bitcoin-core/build/bin/bitcoin`.

## Running tests

Expand All @@ -54,8 +70,9 @@ The integration test (`cargo test --test regtest`) does the following:
1. Starts a Bitcoin Core node in regtest mode with IPC (`-ipcbind=unix`).
2. Creates two deterministic wallets (`mining` and `accounting`) using fixed
`tprv` keys with `wpkh()` (BIP 84) descriptors.
3. Mines 101 blocks via IPC (`createNewBlock` + `submitSolution`) for coinbase
maturity.
3. Mines 17 blocks via RPC `generatetoaddress` (avoids the IPC extranonce issue
at low heights), then 84 blocks via IPC (`createNewBlock` + `submitSolution`)
for a total of 101 blocks (coinbase maturity).
4. Simulates a 12-month salary scenario: monthly EUR salary → BTC at mock
exchange rates, with random spending.
5. Exports a CAMT.053 XML statement and verifies it via roundtrip reconstruction.
Expand All @@ -76,11 +93,12 @@ xmllint --schema tests/fixtures/camt.053.001.02.xsd \

### Deterministic blocks

All blocks are mined via Bitcoin Core's Cap'n Proto IPC interface. The test
brute-forces a valid nonce for each block and caches the coinbase solution
(coinbase hex, version, timestamp, nonce) in
IPC-mined blocks (heights 17+) are produced via Bitcoin Core's Cap'n Proto IPC
interface. The test brute-forces a valid nonce for each block and caches the
coinbase solution (coinbase hex, version, timestamp, nonce) in
`tests/fixtures/coinbase_cache.json`. On subsequent runs, cached solutions are
replayed, producing identical block hashes and transaction IDs.
replayed, producing identical block hashes and transaction IDs. The first 17
blocks are mined via RPC and are not cached.

If the cache is missing or stale (e.g. after changing wallet keys or transaction
amounts), the test regenerates it automatically and emits warnings:
Expand All @@ -101,12 +119,14 @@ because Schnorr signatures include randomness by default. This would make
transaction IDs non-deterministic even with identical inputs, defeating the
purpose of the coinbase cache.

### Bitcoin Core patch
### Bitcoin Core extranonce patch

The file `bitcoin-core-ipc-extranonce.patch` patches `src/node/interfaces.cpp`
to set `include_dummy_extranonce = true` when the chain height is below 17.
Without this, `createNewBlock` fails with `bad-cb-length` at early heights
because the BIP 34 height push is only 1 byte, but consensus requires coinbase
scriptSig to be at least 2 bytes.

This patch will be upstreamed to Bitcoin Core.
The integration test avoids this issue by mining the first 17 blocks via RPC
`generatetoaddress` instead of IPC. The patch is only needed if you want to use
IPC mining at heights ≤ 16.
Loading