Skip to content

Conversation

@tnull
Copy link
Contributor

@tnull tnull commented Jan 6, 2026

Closes #189.

I asked Claude Code to implement the changes necessary to update to the recently released Electrum Protocol v1.6.

Putting in draft for now until I got initial feedback (cc oleonardolima ValuedMammal). We also still need to change the test setup to a v1.6-compatible server to actually run the new tests against.

@tnull tnull marked this pull request as draft January 6, 2026 11:09
@tnull tnull force-pushed the 2026-01-protocol-v1.6 branch from 9c09893 to 93c20f9 Compare January 6, 2026 11:12
@tnull
Copy link
Contributor Author

tnull commented Jan 6, 2026

Hmm, test_local_timeout is currently failing, likely because we now need to successfully negotiate the version before returning the client. Though I have to say I don't fully understand what the test is for in the first place. Could someone explain what we try to assert there exactly?

@oleonardolima oleonardolima added the new feature New feature or request label Jan 6, 2026
@oleonardolima oleonardolima moved this to In Progress in BDK Chain Jan 6, 2026
@ValuedMammal
Copy link
Contributor

Concept ACK

@tnull tnull force-pushed the 2026-01-protocol-v1.6 branch from 93c20f9 to 114a3c1 Compare January 23, 2026 09:57
@tnull tnull marked this pull request as ready for review January 23, 2026 09:57
@tnull tnull force-pushed the 2026-01-protocol-v1.6 branch 4 times, most recently from 17f66bc to faeef85 Compare January 23, 2026 10:31
@tnull
Copy link
Contributor Author

tnull commented Jan 23, 2026

Alright, now updated the CI to use a v1.6 server for tests, fixed some minor things that came up, and opted to simply drop the test_local_timeouts test case as its dummy server implementation is incompatible with the v1.6 flow (that requires version negotiation). Let me know if you think that's acceptable @oleonardolima @ValuedMammal.

Undrafted, as this should be ready-to-go.

@tnull tnull force-pushed the 2026-01-protocol-v1.6 branch 3 times, most recently from e16260d to f689698 Compare January 23, 2026 11:27
Copy link
Contributor

@ValuedMammal ValuedMammal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a first pass, overall it looks reasonable. I left some nits and a few questions. I'm curious if you've had a chance to test this in the wild.

In 38386fe: "feat: Automatically negotiate protocol version on connect"

The commit message refers to a server_version() method that "updates the stored version", but that seems to be hallucinated.

tnull added 2 commits January 27, 2026 09:51
.. we just picked a random tcp-based server running Electrum X 1.19 with
decent uptime from https://1209k.com/bitcoin-eye/ele.php.
The local timeout test was introduce in
f30be3b as a wait to check that
connection timeouts work. However, it uses a pretty flaky setup to begin
with, requiring manual `iptables` rules in CI, and it leans on a dummy
server implementation that doesn't actually do anything besides
accepting the connection.

However, as with protocol v1.6 we now only consider the connection
successful (and for now return the `Client`) if the counterparty
responded to our version negotiation, we're now incompatible with the
dummy setup of `test_local_timeout`. Since I'm not sure how solid and
important the specific test coverage is to begin with, I here opted to
just drop the test case.
@tnull
Copy link
Contributor Author

tnull commented Jan 27, 2026

I did a first pass, overall it looks reasonable. I left some nits and a few questions. I'm curious if you've had a chance to test this in the wild.

No, we did not test this in the wild yet, though of course now the tests run against v1.6 mainnet servers, so they are somewhat an 'in the wild' test.

The commit message refers to a server_version() method that "updates the stored version", but that seems to be hallucinated.

Ah, not hallucinated, but this is a stale comment that referred to a previous approach that I ended up amending.

@tnull tnull requested a review from ValuedMammal January 27, 2026 09:07
@tnull tnull force-pushed the 2026-01-protocol-v1.6 branch 2 times, most recently from 485c4b0 to a439485 Compare January 28, 2026 09:15
@tnull
Copy link
Contributor Author

tnull commented Jan 28, 2026

Addressed pending comments and force-pushed the following changes:

> git diff-tree -U2  485c4b0 a439485
diff --git a/src/raw_client.rs b/src/raw_client.rs
index d806a92..3feb754 100644
--- a/src/raw_client.rs
+++ b/src/raw_client.rs
@@ -47,5 +47,5 @@ use crate::types::*;

 /// Client name sent to the server during protocol version negotiation.
-pub const CLIENT_NAME: &str = "rust-electrum-client";
+pub const CLIENT_NAME: &str = "";

 /// Minimum protocol version supported by this client.
@@ -965,4 +965,5 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
                 deserialized.headers.push(deserialize(&header_bytes)?);
             }
+            deserialized.header_hexes.clear();
             Ok(deserialized)
         } else {

@tnull
Copy link
Contributor Author

tnull commented Feb 6, 2026

@ValuedMammal @oleonardolima Any update here? Do you want me to make any further changes or is this good to go?

@oleonardolima
Copy link
Contributor

@ValuedMammal @oleonardolima Any update here? Do you want me to make any further changes or is this good to go?

I'm doing another round of review right now, though I think this one needs to wait on #194 being merged and released first.

@tnull
Copy link
Contributor Author

tnull commented Feb 9, 2026

this one needs to wait on #194 being merged and released first.

How come? Can't they get released together?

Copy link
Contributor

@oleonardolima oleonardolima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good, thanks for working on this one. I left a few nits, that could also be addressed in a follow-up.

Copy link
Contributor

@oleonardolima oleonardolima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

partial tACK a439485

As a matter of getting it ready to merge, some commits could be reworded to conventional commits, and also the changelog could be added to the PR description.

I've currently tested it with old servers, and didn' find any regressions. I didn't test the new methods though, will need to spawn a server on my end to do it.

Copy link
Contributor

@oleonardolima oleonardolima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK a439485

It only needs addressing the previous commments, other than that it looks ready to go. I've tested the new broadcast_package on testnet, through: ssl://testnet.qtornado.com:51002.

@oleonardolima oleonardolima moved this from In Progress to Needs Review in BDK Chain Feb 10, 2026
We now send `server.version` as the first message after establishing a
connection, as required by Electrum protocol v1.6.

This is a breaking change as the constructors now return errors if
protocol negotiation fails.

Co-Authored-By: Claude Code AI
Signed-off-by: Elias Rohrer <dev@tnull.de>
Add the `mempool.get_info` RPC method to the ElectrumApi trait. This
method was added in protocol v1.6 and provides more detailed mempool
fee information than the deprecated `blockchain.relayfee` method.

Co-Authored-By: Claude Code AI
Signed-off-by: Elias Rohrer <dev@tnull.de>
Add support for the optional `mode` argument to `blockchain.estimatefee`
which was added in protocol v1.6. The mode is passed to bitcoind's
`estimatesmartfee` RPC as the `estimate_mode` parameter.

This is a breaking change as the `estimate_fee` signature has changed.

Co-Authored-By: Claude Code AI
…lity

Parse `blockchain.block.headers` response based on negotiated protocol version:
- v1.6+: Headers returned as array of hex strings in `headers` field
- v1.4 (legacy): Headers returned as concatenated hex in `hex` field

Co-Authored-By: Claude Code AI
Add support for the `blockchain.transaction.broadcast_package` RPC method
introduced in protocol v1.6 for package relay (CPFP) support.

Co-Authored-By: Claude Code AI
Signed-off-by: Elias Rohrer <dev@tnull.de>
Add documentation note that `relay_fee` is deprecated in protocol v1.6
and users should use `mempool_get_info` instead.

Co-Authored-By: Claude Code AI
Previously we'd then fail on the deserialization step, which is odd.

Signed-off-by: Elias Rohrer <dev@tnull.de>
@tnull tnull force-pushed the 2026-01-protocol-v1.6 branch from a439485 to 638da77 Compare February 10, 2026 09:22
@tnull
Copy link
Contributor Author

tnull commented Feb 10, 2026

Thanks, amended to address the pending comments:

> git diff-tree -U2 a439485 638da77
diff --git a/src/api.rs b/src/api.rs
index ea59066..b3c0fef 100644
--- a/src/api.rs
+++ b/src/api.rs
@@ -302,6 +302,7 @@ pub trait ElectrumApi {
     /// Returns the minimum accepted fee by the server's node in **Bitcoin, not Satoshi**.
     ///
-    /// **Note:** This method is deprecated in protocol v1.6+. Use [`mempool_get_info`](#method.mempool_get_info)
-    /// instead, which provides `minrelaytxfee` along with additional mempool fee information.
+    /// **Note:** This method was removed in protocol v1.6+. Use
+    /// [`mempool_get_info`](#method.mempool_get_info) instead, which provides `minrelaytxfee`
+    /// along with additional mempool fee information.
     fn relay_fee(&self) -> Result<f64, Error>;

diff --git a/src/types.rs b/src/types.rs
index b83a47a..4a7d075 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -231,5 +231,7 @@ pub struct ServerFeaturesRes {
 ///
 /// This is returned as an array of two strings: `[server_software_version, protocol_version]`.
-#[derive(Clone, Debug)]
+
+#[derive(Clone, Debug, Deserialize)]
+#[serde(from = "(String, String)")]
 pub struct ServerVersionRes {
     /// Server software version string (e.g., "ElectrumX 1.18.0").
@@ -239,21 +241,10 @@ pub struct ServerVersionRes {
 }

-impl<'de> Deserialize<'de> for ServerVersionRes {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: de::Deserializer<'de>,
-    {
-        let arr: Vec<String> = Vec::deserialize(deserializer)?;
-        let mut iter = arr.into_iter();
-        let server_software_version = iter.next().ok_or_else(|| {
-            de::Error::custom("expected server_software_version as first element")
-        })?;
-        let protocol_version = iter
-            .next()
-            .ok_or_else(|| de::Error::custom("expected protocol_version as second element"))?;
-        Ok(ServerVersionRes {
+impl From<(String, String)> for ServerVersionRes {
+    fn from((server_software_version, protocol_version): (String, String)) -> Self {
+        Self {
             server_software_version,
             protocol_version,
-        })
+        }
     }
 }

.. and also cleaned up the commit messages a bit to reduce on the bullet points...

@tnull tnull requested a review from oleonardolima February 10, 2026 09:24
Copy link
Contributor

@oleonardolima oleonardolima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK 638da77

@oleonardolima oleonardolima added the api API breaking change label Feb 10, 2026
Copy link
Member

@luisschwab luisschwab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK 638da77

@ValuedMammal
Copy link
Contributor

ValuedMammal commented Feb 11, 2026

ACK 638da77

I just left a comment #190 (comment) about batch_estimate_fee.

@oleonardolima oleonardolima merged commit 7c716cc into bitcoindevkit:master Feb 11, 2026
4 checks passed
@github-project-automation github-project-automation bot moved this from Needs Review to Done in BDK Chain Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api API breaking change new feature New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Add support for Electrum protocol v1.6

4 participants