From 414dc90e21ff834acdd81cc104253a638a9e186d Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Sun, 12 Apr 2026 14:40:36 +0200 Subject: [PATCH] Fix `server.features` response format The current `server.features` implementation returns an invalid `hosts` structure: ```json "hosts": {"tcp_port": 50001} ``` According to the Electrum protocol, `hosts` must be a dictionary keyed by hostname, where each value is a dictionary containing optional keys such as `tcp_port` and/or `ssl_port`. This change updates the response to the correct format, i.e.: ```json { "genesis_hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", "hosts": { "127.0.0.1": { "tcp_port": 50001 }, } "protocol_max": "1.4", "protocol_min": "1.4", "pruning": null, "server_version": "electrs/0.10.0", "hash_function": "sha256" } ``` See: https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-features Signed-off-by: Yuki Kishimoto --- src/electrum.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/electrum.rs b/src/electrum.rs index fa67b1d..e6ef9c6 100644 --- a/src/electrum.rs +++ b/src/electrum.rs @@ -13,6 +13,7 @@ use serde_json::{self, json, Value}; use std::collections::{hash_map::Entry, HashMap}; use std::fmt; use std::iter::FromIterator; +use std::net::SocketAddr; use std::str::FromStr; use crate::{ @@ -150,7 +151,7 @@ pub struct Rpc { daemon: Daemon, signal: Signal, banner: String, - port: u16, + addr: SocketAddr, } impl Rpc { @@ -174,7 +175,7 @@ impl Rpc { daemon, signal, banner: config.server_banner.clone(), - port: config.electrum_rpc_addr.port(), + addr: config.electrum_rpc_addr, }) } @@ -507,7 +508,11 @@ impl Rpc { fn features(&self) -> Result { Ok(json!({ "genesis_hash": self.tracker.chain().get_block_hash(0), - "hosts": { "tcp_port": self.port }, + "hosts": { + self.addr.ip().to_string(): { + "tcp_port": self.addr.port() + } + }, "protocol_max": PROTOCOL_VERSION, "protocol_min": PROTOCOL_VERSION, "pruning": null,