A {regtest} bitcoin node runner 🏃‍♂️
  • Rust 97%
  • Just 1.9%
  • Shell 1.1%
Find a file
merge-script 2426ed3c13
Merge luisschwab/halfin#62: Move cargo-rbmt installation to contrib/install-cargo-rbmt.sh
168b2a4146 chore(ci): move cargo-rbmt installation to `contrib/install-cargo-rbmt.sh` (Luis Schwab)

Pull request description:

Top commit has no ACKs.

Tree-SHA512: 5af1a34b482029cedabe578349a244859b20f9b0f5486318460c86c5dbb2c57139ea379b00427087735c57d962062b222bd36ea0c1985d27846ae17f7d9f341e
2026-05-20 14:14:38 -03:00
.cargo chore(deps): bump bitreq to v0.3.5 2026-04-28 22:40:12 -03:00
.github chore(ci): move cargo-rbmt installation to contrib/install-cargo-rbmt.sh 2026-05-20 14:11:49 -03:00
contrib chore(ci): move cargo-rbmt installation to contrib/install-cargo-rbmt.sh 2026-05-20 14:11:49 -03:00
sha256 chore(utreexod): bump utreexod to v0.5.2 2026-05-20 13:43:19 -03:00
src chore(utreexod): bump utreexod to v0.5.2 2026-05-20 13:43:19 -03:00
static feat(doc): add bitcoin node runner picture 2026-04-18 13:52:53 -03:00
tests chore(utreexod): bump utreexod to v0.5.2 2026-05-20 13:43:19 -03:00
.gitignore chore: update justfile and .gitignore 2026-04-13 20:48:51 -03:00
build.rs chore(utreexod): bump utreexod to v0.5.2 2026-05-20 13:43:19 -03:00
Cargo-minimal.lock chore(cargo): bump version to v0.3.6 2026-05-20 14:01:57 -03:00
Cargo-recent.lock chore(cargo): bump version to v0.3.6 2026-05-20 14:01:57 -03:00
Cargo.toml chore(ci): move cargo-rbmt installation to contrib/install-cargo-rbmt.sh 2026-05-20 14:11:49 -03:00
justfile chore(ci): move cargo-rbmt installation to contrib/install-cargo-rbmt.sh 2026-05-20 14:11:49 -03:00
LICENSE-APACHE chore(doc): relicense MIT/Apache-2.0 2026-04-13 11:11:27 -03:00
LICENSE-MIT chore(doc): relicense MIT/Apache-2.0 2026-04-13 11:11:27 -03:00
LICENSE.md chore(doc): relicense MIT/Apache-2.0 2026-04-13 11:11:27 -03:00
rbmt-version chore(ci): move cargo-rbmt installation to contrib/install-cargo-rbmt.sh 2026-05-20 14:11:49 -03:00
README.md chore(ci): move cargo-rbmt installation to contrib/install-cargo-rbmt.sh 2026-05-20 14:11:49 -03:00

A Bitcoin Node Runner (Hal Finney)

halfin

A {regtest} bitcoin node runner 🏃‍♂️

This crate makes it simple to run regtest bitcoind and utreexod instances from Rust code, useful in integration test contexts.

Heavily inspired by the bitcoind crate.

Supported Implementations

Implementation Version Feature Flag Default Feature
bitcoind v31.0 bitcoind_31_0 Yes
utreexod v0.5.2 utreexod_0_5_2 Yes

By default, the bitcoind_31_0 and utreexod_0_5_2 features are enabled.

Binaries are downloaded automatically at build time: see build.rs.

BitcoinD

use halfin::connect;
use halfin::bitcoind::BitcoinD;

// Use a downloaded binary
let bitcoind_alpha = BitcoinD::new().unwrap();

// Use a local binary
let bin_path = PathBuf::from_str("/usr/local/bin/bitcoind").unwrap();
let bitcoind_beta = BitcoinD::from_bin(&bin_path).unwrap();

// Connect peers
connect(&bitcoind_alpha, &bitcoind_beta).unwrap()

// Mine blocks
bitcoind_alpha.generate(100).unwrap();
assert_eq!(bitcoind_alpha.get_height().unwrap(), 100);

// Wait for a node to catch up with the other
wait_for_height(&bitcoind_beta, 100).unwrap();
assert_eq!(bitcoind_beta.get_height().unwrap(), 100);

UtreexoD

use halfin::utreexod::UtreexoD;

// Use a downloaded binary
let utreexod = UtreexoD::new().unwrap();

// Mine blocks
utreexod.generate(100).unwrap();
assert_eq!(utreexod.get_height().unwrap(), 100);

// Raw call an unimplemented RPC
let res = utreexod.call("uptime", &[]).unwrap();

Running on CI environments

Since utreexod binaries are downloaded directly from its GitHub releases page, we can get 403'ed by GitHub itself. To curb this, you need to export the GITHUB_TOKEN environment variable and give read permissions in your CI workflow, as such:

env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
permissions:
    contents: read

The build.rs script automatically reads this variable from the environment and adds it as an Authorization: Bearer $GITHUB_TOKEN header when making requests to github.com.

if let Ok(token) = env::var("GITHUB_TOKEN") {
    request = request.with_header("Authorization", format!("Bearer {}", token));
}

Developing

This project uses just for command running, and cargo-rbmt to manage everything related to cargo, such as formatting, linting, testing and CI. To install them, run:

~$ cargo install just

~$ cargo install cargo-rbmt

A justfile is provided for convenience. Run just to see available commands:

~$ just
> halfin
> A regtest runner for `bitcoind` and `utreexod`

Available recipes:
    audit      # Run `cargo audit` [alias: a]
    build      # Build `halfin` [alias: b]
    check      # Check code formatting, compilation, and linting [alias: c]
    check-sigs # Checks whether all commits in this branch are signed [alias: cs]
    doc        # Generate documentation [alias: d]
    doc-open   # Generate and open documentation [alias: do]
    fmt        # Format code [alias: f]
    lock       # Regenerate Cargo-recent.lock and Cargo-minimal.lock [alias: l]
    pre-push   # Run pre-push checks [alias: p]
    test       # Run tests across all toolchains and lockfiles [alias: t]
    toolchains # Install and/or Update `cargo-rbmt` and Stable and Nightly toolchains
    zizmor     # Run Zizmor Static Analysis [alias: z]

Minimum Supported Rust Version

This library should compile with any combination of features on Rust 1.85.0.

To build with the MSRV toolchain, copy Cargo-minimal.lock to Cargo.lock.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.