{"id":16037133,"url":"https://github.com/rcasatta/electrsd","last_synced_at":"2025-04-05T05:03:38.979Z","repository":{"id":40480890,"uuid":"370305450","full_name":"RCasatta/electrsd","owner":"RCasatta","description":"Utility to run a regtest electrsd process connected to a given bitcoind instance, useful in integration testing environment.","archived":false,"fork":false,"pushed_at":"2025-03-18T13:56:24.000Z","size":3401,"stargazers_count":21,"open_issues_count":13,"forks_count":18,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T04:04:17.660Z","etag":null,"topics":["bitcoin","electrs","integration-testing","testing"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RCasatta.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-24T09:58:07.000Z","updated_at":"2025-03-18T13:55:09.000Z","dependencies_parsed_at":"2024-05-29T14:56:38.260Z","dependency_job_id":"5733feb0-c23f-457e-a689-82ca2d2bd1fe","html_url":"https://github.com/RCasatta/electrsd","commit_stats":{"total_commits":104,"total_committers":13,"mean_commits":8.0,"dds":"0.24038461538461542","last_synced_commit":"956aea3a60cec70277069559128862e36dadf9ef"},"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RCasatta%2Felectrsd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RCasatta%2Felectrsd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RCasatta%2Felectrsd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RCasatta%2Felectrsd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RCasatta","download_url":"https://codeload.github.com/RCasatta/electrsd/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247289409,"owners_count":20914464,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitcoin","electrs","integration-testing","testing"],"created_at":"2024-10-08T22:10:41.707Z","updated_at":"2025-04-05T05:03:38.955Z","avatar_url":"https://github.com/RCasatta.png","language":"Rust","readme":"[![MIT license](https://img.shields.io/github/license/RCasatta/electrsd)](https://github.com/RCasatta/electrsd/blob/master/LICENSE)\n[![Crates](https://img.shields.io/crates/v/electrsd.svg)](https://crates.io/crates/electrsd)\n\n# Electrsd\n\nUtility to run a regtest [electrs](https://github.com/romanz/electrs/) process connected to a given [bitcoind](https://github.com/RCasatta/bitcoind) instance, \nuseful in integration testing environment.\n\n```rust\nlet bitcoind = bitcoind::BitcoinD::new(\"/usr/local/bin/bitcoind\").unwrap();\nlet electrsd = electrsd::ElectrsD::new(\"/usr/local/bin/electrs\", bitcoind).unwrap();\nlet header = electrsd.client.block_headers_subscribe().unwrap();\nassert_eq!(header.height, 0);\n```\n\n## Automatic binaries download\n\nIn your project Cargo.toml, activate the following features\n\n```yml\nelectrsd = { version= \"0.23\", features = [\"corepc-node_23_1\", \"electrs_0_9_1\"] }\n```\n\nThen use it:\n\n```rust\nlet bitcoind_exe = bitcoind::downloaded_exe_path().expect(\"bitcoind version feature must be enabled\");\nlet bitcoind = bitcoind::BitcoinD::new(bitcoind_exe).unwrap();\nlet electrs_exe = electrsd::downloaded_exe_path().expect(\"electrs version feature must be enabled\");\nlet electrsd = electrsd::ElectrsD::new(electrs_exe, bitcoind).unwrap();\n```\n\nWhen the `ELECTRSD_DOWNLOAD_ENDPOINT`/`BITCOIND_DOWNLOAD_ENDPOINT` environment variables are set,\n`electrsd`/`bitcoind` will try to download the binaries from the given endpoints.\n\nWhen you don't use the auto-download feature you have the following options:\n\n- have `electrs` executable in the `PATH`\n- provide the `electrs` executable via the `ELECTRS_EXEC` env var\n\n```rust\nif let Ok(exe_path) = electrsd::exe_path() {\n  let electrsd = electrsd::electrsD::new(exe_path).unwrap();\n}\n```\n\nStartup options could be configured via the `Conf` struct using `electrsD::with_conf` or `electrsD::from_downloaded_with_conf`.\n\n## Nix\n\nFor determinisim, in nix you cannot hit the internet within the `build.rs`. Moreover, some downstream crates cannot remove the auto-download feature from their dev-deps. In this case you can set the `ELECTRSD_SKIP_DOWNLOAD` env var and provide the electrs executable in the `PATH` (or skip the test execution).\n\n## Issues with traditional approach\n\nI used integration testing based on external bash script launching needed external processes, there are many issues with this approach like:\n\n* External script may interfere with local development environment https://github.com/rust-bitcoin/rust-bitcoincore-rpc/blob/200fc8247c1896709a673b82a89ca0da5e7aa2ce/integration_test/run.sh#L9\n* Use of a single huge test to test everything https://github.com/rust-bitcoin/rust-bitcoincore-rpc/blob/200fc8247c1896709a673b82a89ca0da5e7aa2ce/integration_test/src/main.rs#L122-L203\n* 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)\n* bash script are hard, especially support different OS and versions\n\n## Features\n\n  * electrsd use a temporary directory as db dir\n  * A free port is asked to the OS (a very low probability race condition is still possible) \n  * The process is killed when the struct goes out of scope no matter how the test finishes\n  * Automatically download `electrs` executable with enabled features. Since there are no official binaries, they are built using the [manual workflow](.github/workflows/build_electrs.yml) under this project. Supported version are:\n    * [electrs 0.10.6](https://github.com/romanz/electrs/releases/tag/v0.10.6) (feature=electrs_0_10_6)\n    * [electrs 0.9.11](https://github.com/romanz/electrs/releases/tag/v0.9.11) (feature=electrs_0_9_11)\n    * [electrs 0.9.1](https://github.com/romanz/electrs/releases/tag/v0.9.1) (feature=electrs_0_9_1)\n    * [electrs 0.8.10](https://github.com/romanz/electrs/releases/tag/v0.8.10) (feature=electrs_0_8_10)\n    * [electrs esplora](https://github.com/Blockstream/electrs/tree/a33e97e1a1fc63fa9c20a116bb92579bbf43b254) (feature=esplora_a33e97e1)\n\nThanks to these features every `#[test]` could easily run isolated with its own environment\n\n## Deprecations\n\n- Starting from version `0.26` the env var `ELECTRS_EXE` is deprecated in favor of `ELECTRS_EXEC`.\n\n\n## Used by\n\n  * [bdk](https://github.com/bitcoindevkit/bdk)\n  * [BEWallet](https://github.com/LeoComandini/BEWallet)\n  * [gdk rust](https://github.com/Blockstream/gdk/blob/master/subprojects/gdk_rust/)\n  * [lwk](https://github.com/Blockstream/lwk)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frcasatta%2Felectrsd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frcasatta%2Felectrsd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frcasatta%2Felectrsd/lists"}