-
Notifications
You must be signed in to change notification settings - Fork 73
Implement Electrum Protocol v1.6 #190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Electrum Protocol v1.6 #190
Conversation
9c09893 to
93c20f9
Compare
|
Hmm, |
|
Concept ACK |
93c20f9 to
114a3c1
Compare
17f66bc to
faeef85
Compare
|
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 Undrafted, as this should be ready-to-go. |
e16260d to
f689698
Compare
ValuedMammal
left a comment
There was a problem hiding this 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.
.. 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.
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.
Ah, not hallucinated, but this is a stale comment that referred to a previous approach that I ended up amending. |
485c4b0 to
a439485
Compare
|
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 { |
|
@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. |
How come? Can't they get released together? |
oleonardolima
left a comment
There was a problem hiding this 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.
There was a problem hiding this 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.
oleonardolima
left a comment
There was a problem hiding this 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.
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>
a439485 to
638da77
Compare
|
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... |
oleonardolima
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tACK 638da77
luisschwab
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tACK 638da77
|
ACK 638da77 I just left a comment #190 (comment) about |
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
oleonardolimaValuedMammal). We also still need to change the test setup to a v1.6-compatible server to actually run the new tests against.