Skip to content

Drop archived bitcoincore-rpc dependency#1288

Open
PeterXMR wants to merge 1 commit into
romanz:masterfrom
PeterXMR:drop-bitcoincore-rpc
Open

Drop archived bitcoincore-rpc dependency#1288
PeterXMR wants to merge 1 commit into
romanz:masterfrom
PeterXMR:drop-bitcoincore-rpc

Conversation

@PeterXMR
Copy link
Copy Markdown

Closes #1254.

The upstream rust-bitcoincore-rpc crate was archived on 2025-11-25. This PR removes it from electrs in favor of a small in-tree rpc module that calls bitcoind directly via the still-maintained jsonrpc crate (which electrs was already pulling in transitively and using directly in batch_request).

Approach

I noticed bitcoincore-rpc was mostly a thin typed wrapper over jsonrpc::Client, and electrs uses only ~10 of its methods — so the replacement is narrow:

  • Auth — local enum mirroring the three variants config.rs constructs.
  • Client — wraps jsonrpc::Client and exposes the eight typed methods Daemon calls (get_network_info, get_blockchain_info, estimate_smart_fee, send_raw_transaction, get_raw_transaction, get_block_info, get_mempool_info, get_raw_mempool) plus the generic call() and get_jsonrpc_client() used for batch requests.
  • Response types#[derive(Deserialize)] structs containing only the fields electrs actually reads, matching the JSON-field renames bitcoind uses (networkactive, initialblockdownload, relayfee, feerate).
  • Error — two-variant enum (JsonRpc | Decode) mirroring the nested shape callers already pattern-match against, so the changes in daemon.rs and electrum.rs are nearly mechanical.

Diff

Cargo.lock      |  38 +-------- (bitcoincore-rpc + -rpc-json removed; no new deps)
Cargo.toml      |   2 +-        (drop bitcoincore-rpc, promote jsonrpc to direct)
src/config.rs   |   2 +-        (import swap)
src/daemon.rs   |  19 +++-----
src/electrum.rs |   2 +-        (downcast_ref target)
src/lib.rs      |   1 +         (mod rpc;)
src/rpc.rs      | 201 +++++++++ (new)

Testing

  • cargo build --all-targets — clean
  • cargo clippy --all-targets -- -D warnings — zero warnings
  • cargo test --lib — 21/21 pass (including config::tests::test_auth_debug, which exercises the local Auth enum's Debug formatting)
  • Integration smoke test against Bitcoin Core 31 on regtest: drove every replaced RPC method end-to-end via the Electrum protocol:
    • blockchain.relayfeeget_network_info::relay_fee (BTC↔Amount serde)
    • blockchain.estimatefeeestimate_smart_fee (correctly maps missing feerate to Option<Amount>::None on regtest)
    • blockchain.transaction.get (hex) → get_raw_transaction (hex + consensus decode)
    • blockchain.transaction.get (verbose) → generic Client::call
    • mempool.get_fee_histogram → mempool sync exercising get_mempool_info + get_raw_mempool + batch getmempoolentry (incl. fees.base, vsize, depends) + batch getrawtransaction
    • blockchain.transaction.broadcast (fresh signed tx) → send_raw_transaction
    • error path: a deliberately-rejected rebroadcast returned through electrs as {"code": 2, ...}, confirming extract_bitcoind_error and the downcast_ref::<crate::rpc::Error>() in electrum.rs work as before.
  • Implicitly exercised at startup: get_blockchain_info (rpc_poll), get_block_info (indexing 111 blocks), get_mempool_info.

Notes

  • I left Auth::None in place (marked #[allow(dead_code)]) for API completeness — daemon.rs matches it but no current code path constructs it. Easy to remove if you'd prefer.
  • I deliberately did not add an EstimateMode enum (the old bitcoincore_rpc_json::EstimateMode) since electrs always passes None for it. The new estimate_smart_fee takes Option<&str> instead, which avoids dead variants. Happy to add the enum back if you'd rather keep the API surface.
  • I'm aware of Switch to bindex #1252 (bindex) — if that's expected to land soon and will rewrite most of daemon.rs anyway, this PR could be deferred or closed. It's a tidy interim cleanup either way.

The `rust-bitcoincore-rpc` crate was archived upstream on 2025-11-25
(see rust-bitcoin/rust-bitcoincore-rpc@92cad27). Replace it with a
small local `rpc` module that implements only the subset electrs
actually uses, layered directly on top of the still-maintained
`jsonrpc` crate — already pulled in transitively and used directly
for `batch_request`.

The new module covers:
- `Auth` (None, UserPass, CookieFile) and a thin `Client` wrapper.
- The eight RPC methods `Daemon` invokes: `get_network_info`,
  `get_blockchain_info`, `estimate_smart_fee`, `send_raw_transaction`,
  `get_raw_transaction`, `get_block_info`, `get_mempool_info`,
  `get_raw_mempool`, plus the generic `call` and a `get_jsonrpc_client`
  accessor used for batch requests.
- Local `Deserialize` response types holding only the fields electrs
  reads from the corresponding bitcoind responses (subset of
  `bitcoincore_rpc::json::*`).
- An `Error` enum mirroring the two-layer `JsonRpc | Decode` shape
  callers already pattern-match against.

Verified against Bitcoin Core 31 on regtest: every replaced RPC path
round-trips successfully (relayfee, estimatefee, transaction.get
hex+verbose, fee_histogram covering mempool sync, broadcast of a fresh
signed tx), and the error-extraction path returns structured
`DaemonError`s through the Electrum protocol.

Closes romanz#1254

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Drop bitcoincore-rpc dependency

1 participant