From 7366be9d82589de36c9d0a8566cd122583c361c1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 00:12:59 +0000 Subject: [PATCH 1/4] Initial plan From 2b5ee88e03641732bfa8ca0c05c32bb7dbe2babd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 00:24:37 +0000 Subject: [PATCH 2/4] Pin Bitcoin Core v31.0rc1 in CI: download pre-built binaries instead of building from source - Download pre-built binaries from bitcoincore.org instead of cloning and building Bitcoin Core from source (~7 min savings) - Mine first 17 blocks via RPC generatetoaddress to avoid the IPC extranonce issue at low heights (no patch needed for pre-built binaries) - Update find_bitcoin() to support both downloaded and built-from-source binary layouts - Remove stale coinbase cache (regenerated on first test run) - Update DEVELOP.md with download instructions Co-authored-by: Sjors <10217+Sjors@users.noreply.github.com> Agent-Logs-Url: https://github.com/Sjors/btc-accounting/sessions/99daa589-26a0-48a0-ba58-214f360fd00f --- .github/workflows/ci.yml | 28 +++---- DEVELOP.md | 60 +++++++++----- tests/fixtures/coinbase_cache.json | 128 ----------------------------- tests/regtest/main.rs | 8 +- tests/regtest/node.rs | 43 +++++++--- 5 files changed, 90 insertions(+), 177 deletions(-) delete mode 100644 tests/fixtures/coinbase_cache.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cce0396..52d3dd9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 - 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 diff --git a/DEVELOP.md b/DEVELOP.md index 0548d00..0c5ba61 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -6,28 +6,44 @@ - [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 .. @@ -35,7 +51,7 @@ support enabled. 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 @@ -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. @@ -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: @@ -101,7 +119,7 @@ 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. @@ -109,4 +127,6 @@ 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. diff --git a/tests/fixtures/coinbase_cache.json b/tests/fixtures/coinbase_cache.json deleted file mode 100644 index b581142..0000000 --- a/tests/fixtures/coinbase_cache.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "maturity-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025100feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000","version":536870912,"timestamp":1735516800,"nonce":3}, - "maturity-1": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025200feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000001000000","version":536870912,"timestamp":1735516801,"nonce":2}, - "maturity-2": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025300feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000002000000","version":536870912,"timestamp":1735516801,"nonce":0}, - "maturity-3": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025400feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000003000000","version":536870912,"timestamp":1735516802,"nonce":0}, - "maturity-4": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025500feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000004000000","version":536870912,"timestamp":1735516802,"nonce":0}, - "maturity-5": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025600feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000005000000","version":536870912,"timestamp":1735516802,"nonce":0}, - "maturity-6": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025700feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000006000000","version":536870912,"timestamp":1735516802,"nonce":0}, - "maturity-7": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025800feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000007000000","version":536870912,"timestamp":1735516803,"nonce":2}, - "maturity-8": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025900feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000008000000","version":536870912,"timestamp":1735516803,"nonce":2}, - "maturity-9": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025a00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000009000000","version":536870912,"timestamp":1735516803,"nonce":1}, - "maturity-10": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025b00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000a000000","version":536870912,"timestamp":1735516803,"nonce":1}, - "maturity-11": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025c00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000b000000","version":536870912,"timestamp":1735516803,"nonce":2}, - "maturity-12": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025d00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000c000000","version":536870912,"timestamp":1735516803,"nonce":1}, - "maturity-13": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025e00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000d000000","version":536870912,"timestamp":1735516804,"nonce":0}, - "maturity-14": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025f00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000e000000","version":536870912,"timestamp":1735516804,"nonce":1}, - "maturity-15": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff026000feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000f000000","version":536870912,"timestamp":1735516804,"nonce":1}, - "maturity-16": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020111feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000010000000","version":536870912,"timestamp":1735516804,"nonce":0}, - "maturity-17": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020112feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000011000000","version":536870912,"timestamp":1735516804,"nonce":0}, - "maturity-18": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020113feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000012000000","version":536870912,"timestamp":1735516804,"nonce":1}, - "maturity-19": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020114feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000013000000","version":536870912,"timestamp":1735516805,"nonce":0}, - "maturity-20": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020115feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000014000000","version":536870912,"timestamp":1735516805,"nonce":1}, - "maturity-21": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020116feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000015000000","version":536870912,"timestamp":1735516805,"nonce":0}, - "maturity-22": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020117feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000016000000","version":536870912,"timestamp":1735516805,"nonce":0}, - "maturity-23": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020118feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000017000000","version":536870912,"timestamp":1735516805,"nonce":1}, - "maturity-24": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020119feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000018000000","version":536870912,"timestamp":1735516805,"nonce":1}, - "maturity-25": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011afeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000019000000","version":536870912,"timestamp":1735516806,"nonce":0}, - "maturity-26": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011bfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001a000000","version":536870912,"timestamp":1735516806,"nonce":0}, - "maturity-27": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011cfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001b000000","version":536870912,"timestamp":1735516806,"nonce":1}, - "maturity-28": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011dfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001c000000","version":536870912,"timestamp":1735516806,"nonce":2}, - "maturity-29": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011efeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001d000000","version":536870912,"timestamp":1735516806,"nonce":2}, - "maturity-30": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011ffeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001e000000","version":536870912,"timestamp":1735516806,"nonce":3}, - "maturity-31": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020120feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001f000000","version":536870912,"timestamp":1735516807,"nonce":0}, - "maturity-32": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020121feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000020000000","version":536870912,"timestamp":1735516807,"nonce":0}, - "maturity-33": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020122feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000021000000","version":536870912,"timestamp":1735516807,"nonce":2}, - "maturity-34": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020123feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000022000000","version":536870912,"timestamp":1735516807,"nonce":0}, - "maturity-35": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020124feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000023000000","version":536870912,"timestamp":1735516807,"nonce":2}, - "maturity-36": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020125feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000024000000","version":536870912,"timestamp":1735516807,"nonce":0}, - "maturity-37": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020126feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000025000000","version":536870912,"timestamp":1735516808,"nonce":1}, - "maturity-38": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020127feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000026000000","version":536870912,"timestamp":1735516808,"nonce":0}, - "maturity-39": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020128feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000027000000","version":536870912,"timestamp":1735516808,"nonce":0}, - "maturity-40": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020129feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000028000000","version":536870912,"timestamp":1735516808,"nonce":2}, - "maturity-41": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012afeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000029000000","version":536870912,"timestamp":1735516808,"nonce":0}, - "maturity-42": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012bfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002a000000","version":536870912,"timestamp":1735516808,"nonce":0}, - "maturity-43": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012cfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002b000000","version":536870912,"timestamp":1735516809,"nonce":2}, - "maturity-44": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012dfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002c000000","version":536870912,"timestamp":1735516809,"nonce":2}, - "maturity-45": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012efeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002d000000","version":536870912,"timestamp":1735516809,"nonce":0}, - "maturity-46": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012ffeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002e000000","version":536870912,"timestamp":1735516809,"nonce":0}, - "maturity-47": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020130feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002f000000","version":536870912,"timestamp":1735516809,"nonce":0}, - "maturity-48": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020131feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000030000000","version":536870912,"timestamp":1735516809,"nonce":2}, - "maturity-49": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020132feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000031000000","version":536870912,"timestamp":1735516810,"nonce":2}, - "maturity-50": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020133feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000032000000","version":536870912,"timestamp":1735516810,"nonce":0}, - "maturity-51": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020134feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000033000000","version":536870912,"timestamp":1735516810,"nonce":1}, - "maturity-52": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020135feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000034000000","version":536870912,"timestamp":1735516810,"nonce":0}, - "maturity-53": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020136feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000035000000","version":536870912,"timestamp":1735516810,"nonce":0}, - "maturity-54": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020137feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000036000000","version":536870912,"timestamp":1735516810,"nonce":0}, - "maturity-55": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020138feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000037000000","version":536870912,"timestamp":1735516811,"nonce":0}, - "maturity-56": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020139feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000038000000","version":536870912,"timestamp":1735516811,"nonce":0}, - "maturity-57": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013afeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000039000000","version":536870912,"timestamp":1735516811,"nonce":0}, - "maturity-58": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013bfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003a000000","version":536870912,"timestamp":1735516811,"nonce":2}, - "maturity-59": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013cfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003b000000","version":536870912,"timestamp":1735516811,"nonce":0}, - "maturity-60": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013dfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003c000000","version":536870912,"timestamp":1735516811,"nonce":0}, - "maturity-61": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013efeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003d000000","version":536870912,"timestamp":1735516812,"nonce":1}, - "maturity-62": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013ffeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003e000000","version":536870912,"timestamp":1735516812,"nonce":0}, - "maturity-63": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020140feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003f000000","version":536870912,"timestamp":1735516812,"nonce":0}, - "maturity-64": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020141feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000040000000","version":536870912,"timestamp":1735516812,"nonce":3}, - "maturity-65": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020142feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000041000000","version":536870912,"timestamp":1735516812,"nonce":0}, - "maturity-66": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020143feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000042000000","version":536870912,"timestamp":1735516812,"nonce":1}, - "maturity-67": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020144feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000043000000","version":536870912,"timestamp":1735516813,"nonce":1}, - "maturity-68": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020145feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000044000000","version":536870912,"timestamp":1735516813,"nonce":0}, - "maturity-69": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020146feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000045000000","version":536870912,"timestamp":1735516813,"nonce":1}, - "maturity-70": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020147feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000046000000","version":536870912,"timestamp":1735516813,"nonce":0}, - "maturity-71": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020148feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000047000000","version":536870912,"timestamp":1735516813,"nonce":2}, - "maturity-72": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020149feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000048000000","version":536870912,"timestamp":1735516813,"nonce":1}, - "maturity-73": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014afeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000049000000","version":536870912,"timestamp":1735516814,"nonce":0}, - "maturity-74": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014bfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004a000000","version":536870912,"timestamp":1735516814,"nonce":0}, - "maturity-75": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014cfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004b000000","version":536870912,"timestamp":1735516814,"nonce":2}, - "maturity-76": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014dfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004c000000","version":536870912,"timestamp":1735516814,"nonce":0}, - "maturity-77": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014efeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004d000000","version":536870912,"timestamp":1735516814,"nonce":0}, - "maturity-78": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014ffeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004e000000","version":536870912,"timestamp":1735516814,"nonce":1}, - "maturity-79": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020150feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004f000000","version":536870912,"timestamp":1735516815,"nonce":0}, - "maturity-80": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020151feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000050000000","version":536870912,"timestamp":1735516815,"nonce":0}, - "maturity-81": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020152feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000051000000","version":536870912,"timestamp":1735516815,"nonce":0}, - "maturity-82": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020153feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000052000000","version":536870912,"timestamp":1735516815,"nonce":5}, - "maturity-83": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020154feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000053000000","version":536870912,"timestamp":1735516815,"nonce":1}, - "maturity-84": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020155feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000054000000","version":536870912,"timestamp":1735516815,"nonce":0}, - "maturity-85": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020156feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000055000000","version":536870912,"timestamp":1735516816,"nonce":1}, - "maturity-86": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020157feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000056000000","version":536870912,"timestamp":1735516816,"nonce":3}, - "maturity-87": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020158feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000057000000","version":536870912,"timestamp":1735516816,"nonce":1}, - "maturity-88": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020159feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000058000000","version":536870912,"timestamp":1735516816,"nonce":0}, - "maturity-89": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015afeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000059000000","version":536870912,"timestamp":1735516816,"nonce":2}, - "maturity-90": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015bfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005a000000","version":536870912,"timestamp":1735516816,"nonce":1}, - "maturity-91": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015cfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005b000000","version":536870912,"timestamp":1735516817,"nonce":2}, - "maturity-92": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015dfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005c000000","version":536870912,"timestamp":1735516817,"nonce":3}, - "maturity-93": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015efeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005d000000","version":536870912,"timestamp":1735516817,"nonce":6}, - "maturity-94": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015ffeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005e000000","version":536870912,"timestamp":1735516817,"nonce":0}, - "maturity-95": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020160feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005f000000","version":536870912,"timestamp":1735516817,"nonce":4}, - "maturity-96": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020161feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000060000000","version":536870912,"timestamp":1735516817,"nonce":1}, - "maturity-97": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020162feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000061000000","version":536870912,"timestamp":1735516818,"nonce":0}, - "maturity-98": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020163feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000062000000","version":536870912,"timestamp":1735516818,"nonce":2}, - "maturity-99": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020164feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000063000000","version":536870912,"timestamp":1735516818,"nonce":1}, - "maturity-100": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020165feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000064000000","version":536870912,"timestamp":1735516818,"nonce":0}, - "salary-1-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020167feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed02d8159b414ff2c35035f7dd5eb167fd20b3df0a24adfa9bce2ec4ce2f43572c0120000000000000000000000000000000000000000000000000000000000000000066000000","version":536870912,"timestamp":1735815600,"nonce":0}, - "salary-2-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020169feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed43b1425c98e6aa671dd4acc753a5233f200415a22fd15b707f2209f956a7a5580120000000000000000000000000000000000000000000000000000000000000000068000000","version":536870912,"timestamp":1738580400,"nonce":0}, - "salary-3-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016bfeffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9edde8f47a059ba4cf8e6885b9b1b00d772bc1227beedd360e0e16232bbc5699c9a012000000000000000000000000000000000000000000000000000000000000000006a000000","version":536870912,"timestamp":1740999600,"nonce":2}, - "salary-4-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016dfeffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed49f93f1159f5b9279d2fb8d5e2245396a93f2c76ce834b4040a827f502fa9421012000000000000000000000000000000000000000000000000000000000000000006c000000","version":536870912,"timestamp":1743505200,"nonce":0}, - "salary-5-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016ffeffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed3d080b26c6d09f8af91226ec022baf02b0ee6758d4d814ffd781a446dd804630012000000000000000000000000000000000000000000000000000000000000000006e000000","version":536870912,"timestamp":1746097200,"nonce":0}, - "salary-6-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020171feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed2b3ab7d964543b6d88ba30a2373bddabae05589c0003e9de8e5b4d92865cd98e0120000000000000000000000000000000000000000000000000000000000000000070000000","version":536870912,"timestamp":1748862000,"nonce":1}, - "salary-7-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020173feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed73cfd14563a97a8fd3e604ff02a964899e3ee8f1c056abe756abda8823fee7a00120000000000000000000000000000000000000000000000000000000000000000072000000","version":536870912,"timestamp":1751367600,"nonce":0}, - "salary-8-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020175feffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed19578663a7ecd00db0bbb6e158f6a9d0e4557f38cc9851a072843bf79e1242480120000000000000000000000000000000000000000000000000000000000000000074000000","version":536870912,"timestamp":1754046000,"nonce":1}, - "salary-9-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020177feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed69be90ac5a087bb22770fef73b0ef3d59f8b6fd8d3fb21b4d3d3fa4efd9a5c3c0120000000000000000000000000000000000000000000000000000000000000000076000000","version":536870912,"timestamp":1756724400,"nonce":2}, - "salary-10-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020179feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed41555b0cb4b144d79d4a1dcc52146a9035d1579298890af31bf0b3d37d2307820120000000000000000000000000000000000000000000000000000000000000000078000000","version":536870912,"timestamp":1759316400,"nonce":0}, - "salary-11-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02017bfeffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed44baf169d6dffe20b4996c5698f59eb02dcc8a2ff61d1f9e86a849f8c0ea3e70012000000000000000000000000000000000000000000000000000000000000000007a000000","version":536870912,"timestamp":1762167600,"nonce":1}, - "salary-12-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02017dfeffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed4dd2b951861e4e8913f4d8809976f41c93704355334d0336bb23d8a9939dc5ff012000000000000000000000000000000000000000000000000000000000000000007c000000","version":536870912,"timestamp":1764586800,"nonce":2}, - "seed-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020166feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed783e9a8f387bf573046da7256c40ce33e46b45cecfaf33369437fcc5f6504d8e0120000000000000000000000000000000000000000000000000000000000000000065000000","version":536870912,"timestamp":1735516818,"nonce":2}, - "spend-1-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020168feffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9edbafa6398361f6b63bea2b98a5c688477ce2baa536e342d590f9557aa8c0e439e0120000000000000000000000000000000000000000000000000000000000000000067000000","version":536870912,"timestamp":1736258400,"nonce":0}, - "spend-2-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016afeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed592aaefcfcf4c6848c7ea153c0e4a235072d19930b2cb29ac8acd633c45fd9cc0120000000000000000000000000000000000000000000000000000000000000000069000000","version":536870912,"timestamp":1739034000,"nonce":2}, - "spend-3-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016cfeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed5c0e8ed50e524a9fe05c9543f3be345912afcaab4099219c35c76cb2c63a9c0e012000000000000000000000000000000000000000000000000000000000000000006b000000","version":536870912,"timestamp":1741010400,"nonce":0}, - "spend-4-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016efeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9edf3d2e945a1d9ee3d7d9c5723c346512e3b4089ebf0012876040c40b181a86099012000000000000000000000000000000000000000000000000000000000000000006d000000","version":536870912,"timestamp":1743868800,"nonce":0}, - "spend-5-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020170feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed20758f3ec6314a69dccdcd3fd192a213274015657e6e226ff835b3c30af09bd1012000000000000000000000000000000000000000000000000000000000000000006f000000","version":536870912,"timestamp":1746288000,"nonce":0}, - "spend-6-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020172feffffff0214f3052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9edf1542a9caa931ba406d549fa481830b345853df7647535f13369a997e7711ccd0120000000000000000000000000000000000000000000000000000000000000000071000000","version":536870912,"timestamp":1749146400,"nonce":1}, - "spend-7-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020174feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede27bbd54748eb13174343fb87754736c28ccaf97a2c0b199d7e35f2f8f3c1fd70120000000000000000000000000000000000000000000000000000000000000000073000000","version":536870912,"timestamp":1751378400,"nonce":1}, - "spend-8-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020176feffffff0214f3052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed4bb0fc31816468f3eb9226466856577336a23ebaaab333fbad5fbfd3a7b06abd0120000000000000000000000000000000000000000000000000000000000000000075000000","version":536870912,"timestamp":1754496000,"nonce":2}, - "spend-9-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020178feffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed0dc51679a7815ff60241b10f0014b95acadfc558f1f0ff3f1d4119a154ab49bd0120000000000000000000000000000000000000000000000000000000000000000077000000","version":536870912,"timestamp":1756832400,"nonce":0}, - "spend-10-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02017afeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed8a1ef7930169bddeb167c626671c39f40bae5f9ae2dc84de7a8ada763a6a5d6e0120000000000000000000000000000000000000000000000000000000000000000079000000","version":536870912,"timestamp":1759431600,"nonce":0}, - "spend-11-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02017cfeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9eda03aed3e234c9acbfa28abbb5e512e8aeb45191f0d82621ffc66cb6a0092553c012000000000000000000000000000000000000000000000000000000000000000007b000000","version":536870912,"timestamp":1762455600,"nonce":0}, - "spend-12-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02017efeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed589d0f56daa965e136ab3c4938c91460755ab3eeecf1078721329e87ba92c460012000000000000000000000000000000000000000000000000000000000000000007d000000","version":536870912,"timestamp":1764774000,"nonce":0} -} diff --git a/tests/regtest/main.rs b/tests/regtest/main.rs index c07b2b7..6dd4c51 100644 --- a/tests/regtest/main.rs +++ b/tests/regtest/main.rs @@ -71,11 +71,15 @@ fn run_salary_scenario() -> Result<()> { // Generate initial blocks for maturity (100-block coinbase maturity + 1) let mining_addr = mining.get_new_address()?; - let all_cached = mining.mine_blocks_ipc(101, &mining_addr, "maturity-", &mut coinbase_cache, &rt)?; + // Mine first 17 blocks via RPC (IPC createNewBlock fails at heights ≤ 16 + // without the extranonce patch; the pre-built binary doesn't include it). + node.generate_to_address(17, &mining_addr)?; + // Mine remaining 84 blocks via IPC + let all_cached = mining.mine_blocks_ipc(84, &mining_addr, "ipc-maturity-", &mut coinbase_cache, &rt)?; if !all_cached { eprintln!("⚠️ Cache miss during maturity blocks — output may not be deterministic"); } - eprintln!("Mined 101 blocks to mining wallet"); + eprintln!("Mined 101 blocks to mining wallet (17 via RPC, 84 via IPC)"); // Send initial 0.001 BTC to accounting wallet as seed let accounting_addr = accounting.get_new_address()?; diff --git a/tests/regtest/node.rs b/tests/regtest/node.rs index 43dc3ea..7bec683 100644 --- a/tests/regtest/node.rs +++ b/tests/regtest/node.rs @@ -115,6 +115,15 @@ impl RegtestNode { self.datadir.path().join("regtest").join("node.sock") } + /// Mine blocks via RPC `generatetoaddress` (used for early heights where + /// IPC `createNewBlock` would fail without the extranonce patch). + pub fn generate_to_address(&self, nblocks: u32, address: &str) -> Result> { + self.rpc_call("generatetoaddress", &[ + serde_json::json!(nblocks), + serde_json::json!(address), + ]) + } + pub fn set_mocktime(&self, timestamp: i64) -> Result<()> { self.rpc_call::("setmocktime", &[serde_json::json!(timestamp)])?; Ok(()) @@ -190,24 +199,34 @@ fn find_available_port() -> Result { /// Find a pre-built `bitcoin` wrapper binary. /// -/// Checks bitcoin-core/build/bin/bitcoin (cmake output layout). -/// Build the `bitcoin` and `bitcoin-node` targets first — see CI or README. +/// Checks two layouts: +/// 1. bitcoin-core/bin/bitcoin — downloaded release tarball +/// 2. bitcoin-core/build/bin/bitcoin — cmake build from source +/// +/// See DEVELOP.md for setup instructions. pub fn find_bitcoin() -> Result { let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); let source_dir = manifest_dir.join("bitcoin-core"); - let build_dir = source_dir.join("build"); - let bitcoin = build_dir.join("bin").join("bitcoin"); - if bitcoin.exists() { - return Ok(bitcoin); + // Downloaded binary layout: bitcoin-core/bin/bitcoin + let downloaded = source_dir.join("bin").join("bitcoin"); + if downloaded.exists() { + return Ok(downloaded); + } + + // Built-from-source layout: bitcoin-core/build/bin/bitcoin + let built = source_dir.join("build").join("bin").join("bitcoin"); + if built.exists() { + return Ok(built); } bail!( - "bitcoin not found at {}.\n\ - Build it first:\n \ - cd bitcoin-core\n \ - cmake -B build -DENABLE_WALLET=ON -DBUILD_TESTS=OFF -DBUILD_BENCH=OFF\n \ - cmake --build build -j$(nproc) --target bitcoin bitcoin-node", - bitcoin.display() + "bitcoin not found.\n\ + Download binaries or build from source — see DEVELOP.md.\n\ + Checked:\n \ + {}\n \ + {}", + downloaded.display(), + built.display() ); } From af0d77fd637629b3e1b412cd0f410c4e7b8a317f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 00:28:37 +0000 Subject: [PATCH 3/4] Address review comments: improve doc comments and add cache label clarification Co-authored-by: Sjors <10217+Sjors@users.noreply.github.com> Agent-Logs-Url: https://github.com/Sjors/btc-accounting/sessions/99daa589-26a0-48a0-ba58-214f360fd00f --- tests/regtest/main.rs | 3 ++- tests/regtest/node.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/regtest/main.rs b/tests/regtest/main.rs index 6dd4c51..248967b 100644 --- a/tests/regtest/main.rs +++ b/tests/regtest/main.rs @@ -74,7 +74,8 @@ fn run_salary_scenario() -> Result<()> { // Mine first 17 blocks via RPC (IPC createNewBlock fails at heights ≤ 16 // without the extranonce patch; the pre-built binary doesn't include it). node.generate_to_address(17, &mining_addr)?; - // Mine remaining 84 blocks via IPC + // Mine remaining 84 blocks via IPC (prefix "ipc-maturity-" to distinguish + // from RPC-mined blocks which don't need caching) let all_cached = mining.mine_blocks_ipc(84, &mining_addr, "ipc-maturity-", &mut coinbase_cache, &rt)?; if !all_cached { eprintln!("⚠️ Cache miss during maturity blocks — output may not be deterministic"); diff --git a/tests/regtest/node.rs b/tests/regtest/node.rs index 7bec683..f8114d0 100644 --- a/tests/regtest/node.rs +++ b/tests/regtest/node.rs @@ -117,6 +117,8 @@ impl RegtestNode { /// Mine blocks via RPC `generatetoaddress` (used for early heights where /// IPC `createNewBlock` would fail without the extranonce patch). + /// + /// Returns the block hashes of the generated blocks. pub fn generate_to_address(&self, nblocks: u32, address: &str) -> Result> { self.rpc_call("generatetoaddress", &[ serde_json::json!(nblocks), From b405f0d3d04256455ae334309feeecbefac149d1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 18:08:04 +0000 Subject: [PATCH 4/4] Pin Bitcoin Core to v31.0rc1 tag instead of master Keep the clone + patch + build approach but pin to v31.0rc1 tag so ccache stays valid across CI runs. Co-authored-by: Sjors <10217+Sjors@users.noreply.github.com> Agent-Logs-Url: https://github.com/Sjors/btc-accounting/sessions/a7d32120-0bac-41b8-b5af-2a97bb644d86 --- .github/workflows/ci.yml | 28 ++++--- DEVELOP.md | 60 +++++--------- tests/fixtures/coinbase_cache.json | 128 +++++++++++++++++++++++++++++ tests/regtest/main.rs | 9 +- tests/regtest/node.rs | 45 +++------- 5 files changed, 177 insertions(+), 93 deletions(-) create mode 100644 tests/fixtures/coinbase_cache.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52d3dd9..eede5e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,28 +6,30 @@ 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 dependencies + - name: Install Bitcoin Dependencies run: | sudo apt-get update - sudo apt-get install -y capnproto libcapnp-dev libxml2-utils - - name: Download Bitcoin Core + 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 v31.0rc1 https://github.com/bitcoin/bitcoin.git bitcoin-core + - name: Build Bitcoin Core run: | - 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 + cd bitcoin-core + git apply ../bitcoin-core-ipc-extranonce.patch + 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 - name: Run Test Suite run: cargo test - name: Validate CAMT.053 Fixture diff --git a/DEVELOP.md b/DEVELOP.md index 0c5ba61..0548d00 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -6,44 +6,28 @@ - [Cap'n Proto](https://capnproto.org/install.html) compiler (`capnp`) - macOS: `brew install capnp` - Debian/Ubuntu: `apt install capnproto` -- Bitcoin Core binary (for the integration test) +- Bitcoin Core source tree (for the integration test) -## Getting Bitcoin Core +## Building Bitcoin Core The integration test uses Bitcoin Core's IPC interface (multiprocess mode). You -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 +need to build the `bitcoin` and `bitcoin-node` targets from source, with wallet +support enabled. 1. Clone Bitcoin Core into the project directory: ```bash git clone https://github.com/bitcoin/bitcoin.git bitcoin-core ``` -2. Configure and build: +2. Apply the required patch (pads the coinbase scriptSig for low block heights + so that `createNewBlock` via IPC succeeds at height ≤ 16): ```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 .. @@ -51,7 +35,7 @@ The test looks for the binary at `bitcoin-core/bin/bitcoin`. On macOS, replace `$(nproc)` with `$(sysctl -n hw.logicalcpu)`. -The test also looks for the binary at `bitcoin-core/build/bin/bitcoin`. +The test expects the binary at `bitcoin-core/build/bin/bitcoin`. ## Running tests @@ -70,9 +54,8 @@ 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 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). +3. Mines 101 blocks via IPC (`createNewBlock` + `submitSolution`) for 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. @@ -93,12 +76,11 @@ xmllint --schema tests/fixtures/camt.053.001.02.xsd \ ### Deterministic blocks -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 +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 `tests/fixtures/coinbase_cache.json`. On subsequent runs, cached solutions are -replayed, producing identical block hashes and transaction IDs. The first 17 -blocks are mined via RPC and are not cached. +replayed, producing identical block hashes and transaction IDs. If the cache is missing or stale (e.g. after changing wallet keys or transaction amounts), the test regenerates it automatically and emits warnings: @@ -119,7 +101,7 @@ 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 extranonce patch +### Bitcoin Core 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. @@ -127,6 +109,4 @@ 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. -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. +This patch will be upstreamed to Bitcoin Core. diff --git a/tests/fixtures/coinbase_cache.json b/tests/fixtures/coinbase_cache.json new file mode 100644 index 0000000..b581142 --- /dev/null +++ b/tests/fixtures/coinbase_cache.json @@ -0,0 +1,128 @@ +{ + "maturity-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025100feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000","version":536870912,"timestamp":1735516800,"nonce":3}, + "maturity-1": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025200feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000001000000","version":536870912,"timestamp":1735516801,"nonce":2}, + "maturity-2": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025300feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000002000000","version":536870912,"timestamp":1735516801,"nonce":0}, + "maturity-3": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025400feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000003000000","version":536870912,"timestamp":1735516802,"nonce":0}, + "maturity-4": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025500feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000004000000","version":536870912,"timestamp":1735516802,"nonce":0}, + "maturity-5": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025600feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000005000000","version":536870912,"timestamp":1735516802,"nonce":0}, + "maturity-6": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025700feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000006000000","version":536870912,"timestamp":1735516802,"nonce":0}, + "maturity-7": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025800feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000007000000","version":536870912,"timestamp":1735516803,"nonce":2}, + "maturity-8": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025900feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000008000000","version":536870912,"timestamp":1735516803,"nonce":2}, + "maturity-9": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025a00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000009000000","version":536870912,"timestamp":1735516803,"nonce":1}, + "maturity-10": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025b00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000a000000","version":536870912,"timestamp":1735516803,"nonce":1}, + "maturity-11": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025c00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000b000000","version":536870912,"timestamp":1735516803,"nonce":2}, + "maturity-12": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025d00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000c000000","version":536870912,"timestamp":1735516803,"nonce":1}, + "maturity-13": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025e00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000d000000","version":536870912,"timestamp":1735516804,"nonce":0}, + "maturity-14": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025f00feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000e000000","version":536870912,"timestamp":1735516804,"nonce":1}, + "maturity-15": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff026000feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000f000000","version":536870912,"timestamp":1735516804,"nonce":1}, + "maturity-16": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020111feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000010000000","version":536870912,"timestamp":1735516804,"nonce":0}, + "maturity-17": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020112feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000011000000","version":536870912,"timestamp":1735516804,"nonce":0}, + "maturity-18": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020113feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000012000000","version":536870912,"timestamp":1735516804,"nonce":1}, + "maturity-19": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020114feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000013000000","version":536870912,"timestamp":1735516805,"nonce":0}, + "maturity-20": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020115feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000014000000","version":536870912,"timestamp":1735516805,"nonce":1}, + "maturity-21": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020116feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000015000000","version":536870912,"timestamp":1735516805,"nonce":0}, + "maturity-22": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020117feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000016000000","version":536870912,"timestamp":1735516805,"nonce":0}, + "maturity-23": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020118feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000017000000","version":536870912,"timestamp":1735516805,"nonce":1}, + "maturity-24": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020119feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000018000000","version":536870912,"timestamp":1735516805,"nonce":1}, + "maturity-25": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011afeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000019000000","version":536870912,"timestamp":1735516806,"nonce":0}, + "maturity-26": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011bfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001a000000","version":536870912,"timestamp":1735516806,"nonce":0}, + "maturity-27": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011cfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001b000000","version":536870912,"timestamp":1735516806,"nonce":1}, + "maturity-28": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011dfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001c000000","version":536870912,"timestamp":1735516806,"nonce":2}, + "maturity-29": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011efeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001d000000","version":536870912,"timestamp":1735516806,"nonce":2}, + "maturity-30": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02011ffeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001e000000","version":536870912,"timestamp":1735516806,"nonce":3}, + "maturity-31": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020120feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000001f000000","version":536870912,"timestamp":1735516807,"nonce":0}, + "maturity-32": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020121feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000020000000","version":536870912,"timestamp":1735516807,"nonce":0}, + "maturity-33": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020122feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000021000000","version":536870912,"timestamp":1735516807,"nonce":2}, + "maturity-34": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020123feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000022000000","version":536870912,"timestamp":1735516807,"nonce":0}, + "maturity-35": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020124feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000023000000","version":536870912,"timestamp":1735516807,"nonce":2}, + "maturity-36": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020125feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000024000000","version":536870912,"timestamp":1735516807,"nonce":0}, + "maturity-37": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020126feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000025000000","version":536870912,"timestamp":1735516808,"nonce":1}, + "maturity-38": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020127feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000026000000","version":536870912,"timestamp":1735516808,"nonce":0}, + "maturity-39": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020128feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000027000000","version":536870912,"timestamp":1735516808,"nonce":0}, + "maturity-40": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020129feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000028000000","version":536870912,"timestamp":1735516808,"nonce":2}, + "maturity-41": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012afeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000029000000","version":536870912,"timestamp":1735516808,"nonce":0}, + "maturity-42": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012bfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002a000000","version":536870912,"timestamp":1735516808,"nonce":0}, + "maturity-43": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012cfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002b000000","version":536870912,"timestamp":1735516809,"nonce":2}, + "maturity-44": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012dfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002c000000","version":536870912,"timestamp":1735516809,"nonce":2}, + "maturity-45": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012efeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002d000000","version":536870912,"timestamp":1735516809,"nonce":0}, + "maturity-46": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02012ffeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002e000000","version":536870912,"timestamp":1735516809,"nonce":0}, + "maturity-47": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020130feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000002f000000","version":536870912,"timestamp":1735516809,"nonce":0}, + "maturity-48": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020131feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000030000000","version":536870912,"timestamp":1735516809,"nonce":2}, + "maturity-49": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020132feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000031000000","version":536870912,"timestamp":1735516810,"nonce":2}, + "maturity-50": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020133feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000032000000","version":536870912,"timestamp":1735516810,"nonce":0}, + "maturity-51": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020134feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000033000000","version":536870912,"timestamp":1735516810,"nonce":1}, + "maturity-52": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020135feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000034000000","version":536870912,"timestamp":1735516810,"nonce":0}, + "maturity-53": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020136feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000035000000","version":536870912,"timestamp":1735516810,"nonce":0}, + "maturity-54": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020137feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000036000000","version":536870912,"timestamp":1735516810,"nonce":0}, + "maturity-55": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020138feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000037000000","version":536870912,"timestamp":1735516811,"nonce":0}, + "maturity-56": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020139feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000038000000","version":536870912,"timestamp":1735516811,"nonce":0}, + "maturity-57": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013afeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000039000000","version":536870912,"timestamp":1735516811,"nonce":0}, + "maturity-58": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013bfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003a000000","version":536870912,"timestamp":1735516811,"nonce":2}, + "maturity-59": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013cfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003b000000","version":536870912,"timestamp":1735516811,"nonce":0}, + "maturity-60": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013dfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003c000000","version":536870912,"timestamp":1735516811,"nonce":0}, + "maturity-61": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013efeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003d000000","version":536870912,"timestamp":1735516812,"nonce":1}, + "maturity-62": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02013ffeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003e000000","version":536870912,"timestamp":1735516812,"nonce":0}, + "maturity-63": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020140feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000003f000000","version":536870912,"timestamp":1735516812,"nonce":0}, + "maturity-64": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020141feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000040000000","version":536870912,"timestamp":1735516812,"nonce":3}, + "maturity-65": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020142feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000041000000","version":536870912,"timestamp":1735516812,"nonce":0}, + "maturity-66": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020143feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000042000000","version":536870912,"timestamp":1735516812,"nonce":1}, + "maturity-67": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020144feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000043000000","version":536870912,"timestamp":1735516813,"nonce":1}, + "maturity-68": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020145feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000044000000","version":536870912,"timestamp":1735516813,"nonce":0}, + "maturity-69": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020146feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000045000000","version":536870912,"timestamp":1735516813,"nonce":1}, + "maturity-70": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020147feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000046000000","version":536870912,"timestamp":1735516813,"nonce":0}, + "maturity-71": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020148feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000047000000","version":536870912,"timestamp":1735516813,"nonce":2}, + "maturity-72": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020149feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000048000000","version":536870912,"timestamp":1735516813,"nonce":1}, + "maturity-73": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014afeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000049000000","version":536870912,"timestamp":1735516814,"nonce":0}, + "maturity-74": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014bfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004a000000","version":536870912,"timestamp":1735516814,"nonce":0}, + "maturity-75": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014cfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004b000000","version":536870912,"timestamp":1735516814,"nonce":2}, + "maturity-76": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014dfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004c000000","version":536870912,"timestamp":1735516814,"nonce":0}, + "maturity-77": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014efeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004d000000","version":536870912,"timestamp":1735516814,"nonce":0}, + "maturity-78": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02014ffeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004e000000","version":536870912,"timestamp":1735516814,"nonce":1}, + "maturity-79": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020150feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000004f000000","version":536870912,"timestamp":1735516815,"nonce":0}, + "maturity-80": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020151feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000050000000","version":536870912,"timestamp":1735516815,"nonce":0}, + "maturity-81": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020152feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000051000000","version":536870912,"timestamp":1735516815,"nonce":0}, + "maturity-82": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020153feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000052000000","version":536870912,"timestamp":1735516815,"nonce":5}, + "maturity-83": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020154feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000053000000","version":536870912,"timestamp":1735516815,"nonce":1}, + "maturity-84": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020155feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000054000000","version":536870912,"timestamp":1735516815,"nonce":0}, + "maturity-85": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020156feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000055000000","version":536870912,"timestamp":1735516816,"nonce":1}, + "maturity-86": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020157feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000056000000","version":536870912,"timestamp":1735516816,"nonce":3}, + "maturity-87": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020158feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000057000000","version":536870912,"timestamp":1735516816,"nonce":1}, + "maturity-88": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020159feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000058000000","version":536870912,"timestamp":1735516816,"nonce":0}, + "maturity-89": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015afeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000059000000","version":536870912,"timestamp":1735516816,"nonce":2}, + "maturity-90": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015bfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005a000000","version":536870912,"timestamp":1735516816,"nonce":1}, + "maturity-91": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015cfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005b000000","version":536870912,"timestamp":1735516817,"nonce":2}, + "maturity-92": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015dfeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005c000000","version":536870912,"timestamp":1735516817,"nonce":3}, + "maturity-93": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015efeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005d000000","version":536870912,"timestamp":1735516817,"nonce":6}, + "maturity-94": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02015ffeffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005e000000","version":536870912,"timestamp":1735516817,"nonce":0}, + "maturity-95": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020160feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000005f000000","version":536870912,"timestamp":1735516817,"nonce":4}, + "maturity-96": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020161feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000060000000","version":536870912,"timestamp":1735516817,"nonce":1}, + "maturity-97": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020162feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000061000000","version":536870912,"timestamp":1735516818,"nonce":0}, + "maturity-98": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020163feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000062000000","version":536870912,"timestamp":1735516818,"nonce":2}, + "maturity-99": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020164feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000063000000","version":536870912,"timestamp":1735516818,"nonce":1}, + "maturity-100": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020165feffffff0200f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000064000000","version":536870912,"timestamp":1735516818,"nonce":0}, + "salary-1-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020167feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed02d8159b414ff2c35035f7dd5eb167fd20b3df0a24adfa9bce2ec4ce2f43572c0120000000000000000000000000000000000000000000000000000000000000000066000000","version":536870912,"timestamp":1735815600,"nonce":0}, + "salary-2-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020169feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed43b1425c98e6aa671dd4acc753a5233f200415a22fd15b707f2209f956a7a5580120000000000000000000000000000000000000000000000000000000000000000068000000","version":536870912,"timestamp":1738580400,"nonce":0}, + "salary-3-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016bfeffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9edde8f47a059ba4cf8e6885b9b1b00d772bc1227beedd360e0e16232bbc5699c9a012000000000000000000000000000000000000000000000000000000000000000006a000000","version":536870912,"timestamp":1740999600,"nonce":2}, + "salary-4-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016dfeffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed49f93f1159f5b9279d2fb8d5e2245396a93f2c76ce834b4040a827f502fa9421012000000000000000000000000000000000000000000000000000000000000000006c000000","version":536870912,"timestamp":1743505200,"nonce":0}, + "salary-5-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016ffeffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed3d080b26c6d09f8af91226ec022baf02b0ee6758d4d814ffd781a446dd804630012000000000000000000000000000000000000000000000000000000000000000006e000000","version":536870912,"timestamp":1746097200,"nonce":0}, + "salary-6-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020171feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed2b3ab7d964543b6d88ba30a2373bddabae05589c0003e9de8e5b4d92865cd98e0120000000000000000000000000000000000000000000000000000000000000000070000000","version":536870912,"timestamp":1748862000,"nonce":1}, + "salary-7-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020173feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed73cfd14563a97a8fd3e604ff02a964899e3ee8f1c056abe756abda8823fee7a00120000000000000000000000000000000000000000000000000000000000000000072000000","version":536870912,"timestamp":1751367600,"nonce":0}, + "salary-8-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020175feffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed19578663a7ecd00db0bbb6e158f6a9d0e4557f38cc9851a072843bf79e1242480120000000000000000000000000000000000000000000000000000000000000000074000000","version":536870912,"timestamp":1754046000,"nonce":1}, + "salary-9-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020177feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed69be90ac5a087bb22770fef73b0ef3d59f8b6fd8d3fb21b4d3d3fa4efd9a5c3c0120000000000000000000000000000000000000000000000000000000000000000076000000","version":536870912,"timestamp":1756724400,"nonce":2}, + "salary-10-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020179feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed41555b0cb4b144d79d4a1dcc52146a9035d1579298890af31bf0b3d37d2307820120000000000000000000000000000000000000000000000000000000000000000078000000","version":536870912,"timestamp":1759316400,"nonce":0}, + "salary-11-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02017bfeffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed44baf169d6dffe20b4996c5698f59eb02dcc8a2ff61d1f9e86a849f8c0ea3e70012000000000000000000000000000000000000000000000000000000000000000007a000000","version":536870912,"timestamp":1762167600,"nonce":1}, + "salary-12-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02017dfeffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed4dd2b951861e4e8913f4d8809976f41c93704355334d0336bb23d8a9939dc5ff012000000000000000000000000000000000000000000000000000000000000000007c000000","version":536870912,"timestamp":1764586800,"nonce":2}, + "seed-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020166feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed783e9a8f387bf573046da7256c40ce33e46b45cecfaf33369437fcc5f6504d8e0120000000000000000000000000000000000000000000000000000000000000000065000000","version":536870912,"timestamp":1735516818,"nonce":2}, + "spend-1-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020168feffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9edbafa6398361f6b63bea2b98a5c688477ce2baa536e342d590f9557aa8c0e439e0120000000000000000000000000000000000000000000000000000000000000000067000000","version":536870912,"timestamp":1736258400,"nonce":0}, + "spend-2-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016afeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed592aaefcfcf4c6848c7ea153c0e4a235072d19930b2cb29ac8acd633c45fd9cc0120000000000000000000000000000000000000000000000000000000000000000069000000","version":536870912,"timestamp":1739034000,"nonce":2}, + "spend-3-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016cfeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed5c0e8ed50e524a9fe05c9543f3be345912afcaab4099219c35c76cb2c63a9c0e012000000000000000000000000000000000000000000000000000000000000000006b000000","version":536870912,"timestamp":1741010400,"nonce":0}, + "spend-4-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02016efeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9edf3d2e945a1d9ee3d7d9c5723c346512e3b4089ebf0012876040c40b181a86099012000000000000000000000000000000000000000000000000000000000000000006d000000","version":536870912,"timestamp":1743868800,"nonce":0}, + "spend-5-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020170feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed20758f3ec6314a69dccdcd3fd192a213274015657e6e226ff835b3c30af09bd1012000000000000000000000000000000000000000000000000000000000000000006f000000","version":536870912,"timestamp":1746288000,"nonce":0}, + "spend-6-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020172feffffff0214f3052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9edf1542a9caa931ba406d549fa481830b345853df7647535f13369a997e7711ccd0120000000000000000000000000000000000000000000000000000000000000000071000000","version":536870912,"timestamp":1749146400,"nonce":1}, + "spend-7-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020174feffffff028cf2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ede27bbd54748eb13174343fb87754736c28ccaf97a2c0b199d7e35f2f8f3c1fd70120000000000000000000000000000000000000000000000000000000000000000073000000","version":536870912,"timestamp":1751378400,"nonce":1}, + "spend-8-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020176feffffff0214f3052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed4bb0fc31816468f3eb9226466856577336a23ebaaab333fbad5fbfd3a7b06abd0120000000000000000000000000000000000000000000000000000000000000000075000000","version":536870912,"timestamp":1754496000,"nonce":2}, + "spend-9-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff020178feffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed0dc51679a7815ff60241b10f0014b95acadfc558f1f0ff3f1d4119a154ab49bd0120000000000000000000000000000000000000000000000000000000000000000077000000","version":536870912,"timestamp":1756832400,"nonce":0}, + "spend-10-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02017afeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed8a1ef7930169bddeb167c626671c39f40bae5f9ae2dc84de7a8ada763a6a5d6e0120000000000000000000000000000000000000000000000000000000000000000079000000","version":536870912,"timestamp":1759431600,"nonce":0}, + "spend-11-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02017cfeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9eda03aed3e234c9acbfa28abbb5e512e8aeb45191f0d82621ffc66cb6a0092553c012000000000000000000000000000000000000000000000000000000000000000007b000000","version":536870912,"timestamp":1762455600,"nonce":0}, + "spend-12-0": {"coinbase_hex":"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff02017efeffffff02d0f2052a010000001600149692075e1ed163434057fffa3026376e41aeea980000000000000000266a24aa21a9ed589d0f56daa965e136ab3c4938c91460755ab3eeecf1078721329e87ba92c460012000000000000000000000000000000000000000000000000000000000000000007d000000","version":536870912,"timestamp":1764774000,"nonce":0} +} diff --git a/tests/regtest/main.rs b/tests/regtest/main.rs index 248967b..c07b2b7 100644 --- a/tests/regtest/main.rs +++ b/tests/regtest/main.rs @@ -71,16 +71,11 @@ fn run_salary_scenario() -> Result<()> { // Generate initial blocks for maturity (100-block coinbase maturity + 1) let mining_addr = mining.get_new_address()?; - // Mine first 17 blocks via RPC (IPC createNewBlock fails at heights ≤ 16 - // without the extranonce patch; the pre-built binary doesn't include it). - node.generate_to_address(17, &mining_addr)?; - // Mine remaining 84 blocks via IPC (prefix "ipc-maturity-" to distinguish - // from RPC-mined blocks which don't need caching) - let all_cached = mining.mine_blocks_ipc(84, &mining_addr, "ipc-maturity-", &mut coinbase_cache, &rt)?; + let all_cached = mining.mine_blocks_ipc(101, &mining_addr, "maturity-", &mut coinbase_cache, &rt)?; if !all_cached { eprintln!("⚠️ Cache miss during maturity blocks — output may not be deterministic"); } - eprintln!("Mined 101 blocks to mining wallet (17 via RPC, 84 via IPC)"); + eprintln!("Mined 101 blocks to mining wallet"); // Send initial 0.001 BTC to accounting wallet as seed let accounting_addr = accounting.get_new_address()?; diff --git a/tests/regtest/node.rs b/tests/regtest/node.rs index f8114d0..43dc3ea 100644 --- a/tests/regtest/node.rs +++ b/tests/regtest/node.rs @@ -115,17 +115,6 @@ impl RegtestNode { self.datadir.path().join("regtest").join("node.sock") } - /// Mine blocks via RPC `generatetoaddress` (used for early heights where - /// IPC `createNewBlock` would fail without the extranonce patch). - /// - /// Returns the block hashes of the generated blocks. - pub fn generate_to_address(&self, nblocks: u32, address: &str) -> Result> { - self.rpc_call("generatetoaddress", &[ - serde_json::json!(nblocks), - serde_json::json!(address), - ]) - } - pub fn set_mocktime(&self, timestamp: i64) -> Result<()> { self.rpc_call::("setmocktime", &[serde_json::json!(timestamp)])?; Ok(()) @@ -201,34 +190,24 @@ fn find_available_port() -> Result { /// Find a pre-built `bitcoin` wrapper binary. /// -/// Checks two layouts: -/// 1. bitcoin-core/bin/bitcoin — downloaded release tarball -/// 2. bitcoin-core/build/bin/bitcoin — cmake build from source -/// -/// See DEVELOP.md for setup instructions. +/// Checks bitcoin-core/build/bin/bitcoin (cmake output layout). +/// Build the `bitcoin` and `bitcoin-node` targets first — see CI or README. pub fn find_bitcoin() -> Result { let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); let source_dir = manifest_dir.join("bitcoin-core"); + let build_dir = source_dir.join("build"); + let bitcoin = build_dir.join("bin").join("bitcoin"); - // Downloaded binary layout: bitcoin-core/bin/bitcoin - let downloaded = source_dir.join("bin").join("bitcoin"); - if downloaded.exists() { - return Ok(downloaded); - } - - // Built-from-source layout: bitcoin-core/build/bin/bitcoin - let built = source_dir.join("build").join("bin").join("bitcoin"); - if built.exists() { - return Ok(built); + if bitcoin.exists() { + return Ok(bitcoin); } bail!( - "bitcoin not found.\n\ - Download binaries or build from source — see DEVELOP.md.\n\ - Checked:\n \ - {}\n \ - {}", - downloaded.display(), - built.display() + "bitcoin not found at {}.\n\ + Build it first:\n \ + cd bitcoin-core\n \ + cmake -B build -DENABLE_WALLET=ON -DBUILD_TESTS=OFF -DBUILD_BENCH=OFF\n \ + cmake --build build -j$(nproc) --target bitcoin bitcoin-node", + bitcoin.display() ); }