Expand description
Bitcoind
Utility to run a regtest bitcoind process, useful in integration testing environment.
When the auto-download feature is selected by activating one of the version feature, such as 23_0
for bitcoin core 23.0, starting a regtest node is as simple as that:
// the download feature is enabled whenever a specific version is enabled, for example `23_0` or `22_0`
#[cfg(feature = "download")]
{
use bitcoincore_rpc::RpcApi;
let bitcoind = bitcoind::BitcoinD::from_downloaded().unwrap();
assert_eq!(0, bitcoind.client.get_blockchain_info().unwrap().blocks);
}
The build script will automatically download the bitcoin core version 23.0 from bitcoin core,
verify the hashes and place it in the build directory for this crate. If you wish to download from an
alternate location, for example locally for CI, use the BITCOIND_DOWNLOAD_ENDPOINT
env var.
When you don’t use the auto-download feature you have the following options:
- have
bitcoind
executable in thePATH
- provide the
bitcoind
executable via theBITCOIND_EXEC
env var
use bitcoincore_rpc::RpcApi;
if let Ok(exe_path) = bitcoind::exe_path() {
let bitcoind = bitcoind::BitcoinD::new(exe_path).unwrap();
assert_eq!(0, bitcoind.client.get_blockchain_info().unwrap().blocks);
}
Startup options could be configured via the Conf
struct using BitcoinD::with_conf
or
BitcoinD::from_downloaded_with_conf
Issues with traditional approach
I used integration testing based on external bash script launching needed external processes, there are many issues with this approach like:
- External script may interfere with local development environment 1
- Use of a single huge test to test everything 2
- If test are separated, a failing test may fail to leave a clean situation, causing other test to fail (because of the initial situation, not a real failure)
- bash script are hard, especially support different OS and versions
Features
- It waits until bitcoind daemon become ready to accept RPC commands
bitcoind
use a temporary directory as datadir. You can specify the root of your temp directories so that you have node’s datadir in a RAM disk (eg/dev/shm
)- Free ports are asked to the OS. Since you can’t reserve the given portm a low probability race condition is still possible, for this reason the process is tried to be spawn 3 times with different ports.
- The process is killed when the struct goes out of scope no matter how the test finishes
- Allows easy spawning of dependent process like electrs
Thanks to these features every #[test]
could easily run isolated with its own environment.
Doc
To build docs:
RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --features download,doc --open
MSRV
The MSRV is 1.41.1 for version 0.29.* if no feature is used, otherwise is 1.57
Note: to respect 1.41.1 MSRV you need to use and older version of the which and tempfile dependencies, like it’s done in the CI:
cargo update -p which --precise 4.3.0
cargo update -p serde --precise 1.0.152
cargo update -p tempfile --precise 3.3.0
Pinning in Cargo.toml
is avoided because it could cause
compilation issues downstream.
Used by
Via bdk dependency
Via electrsd dependency:
Re-exports
pub use anyhow;
pub use bitcoincore_rpc;
pub use tempfile;
pub use which;
Structs
- Struct representing the bitcoind process with related information
- The node configuration parameters, implements a convenient Default for most common use.
- Contains all the information to connect to this node
Enums
- The DataDir struct defining the kind of data directory the node will contain. Data directory can be either persistent, or temporary.
- All the possible error in this crate
- Enum to specify p2p settings
Functions
- Provide the bitcoind executable path if a version feature has been specified
- Returns the daemon executable path if it’s provided as a feature or as
BITCOIND_EXE
env var. Returns error if none or both are set - Returns a non-used local port if available.
- Validate the specified arg if there is any unavailable or deprecated one