Problem
Any method without a dispatch arm in handle_command — a typo, an unimplemented
Electrum method (blockchain.scripthash.get_mempool,
blockchain.transaction.get_tsc_merkle), or blockchain.scripthash.get_balance on
Liquid builds (where the arm is compiled out via #[cfg(not(feature = "liquid"))]) —
causes the server to close the TCP connection without writing any JSON-RPC response.
Clients cannot distinguish an intentionally unsupported method from an outage, and
retrying clients turn one cheap error reply into repeated TCP+TLS reconnects.
Inside a batch request, a single unknown method kills the whole batch and the
connection; the remaining requests are never answered.
Cause
The catch-all arm in handle_command:
&_ => bail!("unknown method {} {:?}", method, params),
bail! returns Err from the whole function, bypassing the error-to-JSON conversion
a few lines below — that conversion only sees errors that dispatched handlers assign
into result. The unknown-method error instead propagates through the ? in
handle_value and handle_replies, and run() logs "connection handling failed"
and shuts the socket down.
Fix
Produce the error as a value inside result, so it flows through the existing
conversion and is returned as a normal JSON-RPC error reply:
&_ => Err(format!("unknown method {}", method).into()),
- The connection stays open, matching other handler errors in electrs and other
Electrum server implementations (ElectrumX, Fulcrum).
params are deliberately omitted from the message so client-controlled input is
not echoed back; only the method name is included.
- Batches now answer their remaining requests when one entry has an unknown method.
Out of scope
Malformed input still drops the connection, unchanged: invalid JSON, requests
without a string method / array params / id, oversized batches, invalid UTF-8,
and TLS bytes on the plaintext port. The first two arguably deserve error replies as
well (with "id": null per JSON-RPC), but that is a larger change than this fix.
Testing
Against a local instance:
echo '{"jsonrpc":"2.0","id":1,"method":"blockchain.scripthash.get_mempool","params":["e573ed3c89a107e4c5b67cebc6a6cadb2faa40fb02a7c5092d9b4d4f118a3efe"]}' | nc localhost 50001
Before fix we see: connection closes with no payload.
After fix we should see: {"error":"unknown method blockchain.scripthash.get_mempool","id":1,"jsonrpc":"2.0"}
and the connection remains open.
A batch mixing server.ping with an unknown method should return results for both entries instead of dropping the connection.
Problem
Any method without a dispatch arm in
handle_command— a typo, an unimplementedElectrum method (
blockchain.scripthash.get_mempool,blockchain.transaction.get_tsc_merkle), orblockchain.scripthash.get_balanceonLiquid builds (where the arm is compiled out via
#[cfg(not(feature = "liquid"))]) —causes the server to close the TCP connection without writing any JSON-RPC response.
Clients cannot distinguish an intentionally unsupported method from an outage, and
retrying clients turn one cheap error reply into repeated TCP+TLS reconnects.
Inside a batch request, a single unknown method kills the whole batch and the
connection; the remaining requests are never answered.
Cause
The catch-all arm in
handle_command:bail!returnsErrfrom the whole function, bypassing the error-to-JSON conversiona few lines below — that conversion only sees errors that dispatched handlers assign
into
result. The unknown-method error instead propagates through the?inhandle_valueandhandle_replies, andrun()logs "connection handling failed"and shuts the socket down.
Fix
Produce the error as a value inside
result, so it flows through the existingconversion and is returned as a normal JSON-RPC error reply:
Electrum server implementations (ElectrumX, Fulcrum).
paramsare deliberately omitted from the message so client-controlled input isnot echoed back; only the method name is included.
Out of scope
Malformed input still drops the connection, unchanged: invalid JSON, requests
without a string
method/ arrayparams/id, oversized batches, invalid UTF-8,and TLS bytes on the plaintext port. The first two arguably deserve error replies as
well (with
"id": nullper JSON-RPC), but that is a larger change than this fix.Testing
Against a local instance:
Before fix we see: connection closes with no payload.
After fix we should see:
{"error":"unknown method blockchain.scripthash.get_mempool","id":1,"jsonrpc":"2.0"}and the connection remains open.
A batch mixing
server.pingwith an unknown method should return results for both entries instead of dropping the connection.