Skip to content

Conversation

@cdecker
Copy link
Collaborator

@cdecker cdecker commented Nov 5, 2025

The use of the passfd crate meant that we could not upgrade past the tokio==0.3 dependency. Then again the async nature of the whole daemon was not really necessary. Claude went and replaced the async UnixStream + PassFD implementation to sync threads, while still keeping the tokio dependency, but freed from its constraints, for the grpc communication with the plugin.

Replace tokio async I/O with std synchronous I/O in wire.rs:
- Remove tokio::net::UnixStream, use std::os::unix::net::UnixStream
- Remove tokio::sync::Mutex, use std::sync::Mutex
- Convert async read/write methods to blocking
- Replace AsyncReadExt/AsyncWriteExt with std::io Read/Write
- Manually handle 4-byte length prefix with BigEndian read/write

This is Phase 1 of removing old tokio 0.2 dependency and converting
the gl-signerproxy subdaemon to use standard library threading instead
of async/await. The passfd FD passing implementation works naturally
with blocking sockets.
Replace async tokio tasks with standard library threads:
- Convert async fn run() to synchronous fn run()
- Convert async fn process_requests() to synchronous
- Replace tokio::spawn() with std::thread::spawn()
- Create dedicated tokio Runtime for gRPC operations only
- Use runtime.block_on() to execute gRPC calls (ping, request)
- Remove TokioUnixStream, use std::os::unix::net::UnixStream directly
- Pass Arc<Runtime> to all handlers for gRPC operations
- All socket I/O is now blocking (no .await)

The gRPC client still requires tokio internally, so we create a minimal
single-threaded runtime and use it only for gRPC operations via
block_on(). This allows us to remove the tokio async runtime from
everywhere except where strictly necessary for tonic.
…(Phase 3 & 4)

Phase 3 - Upgrade dependencies to modern versions:
- tokio: 0.2 -> 1.x with minimal features (rt, net, io-util only)
- tonic: 0.3 -> 0.8 (matches workspace)
- prost: 0.6 -> 0.11 (matches workspace)
- tonic-build: 0.3 -> 0.8 (matches workspace)
- tower: 0.3 -> 0.4 (matches workspace)

Phase 4 - Remove async from entry points:
- lib.rs: Remove async from Proxy::run()
- signerproxy.rs: Remove #[tokio::main] and async from main()

The subdaemon now uses only std threading with a minimal tokio
runtime exclusively for gRPC operations. No more old tokio 0.2
dependency and no async/await except where required by tonic.
Disable the cln-grpc plugin for standard CLN test nodes created via
node_factory to prevent port conflicts with GL nodes. GL nodes already
have cln-grpc disabled in favor of gl-plugin, but standard test nodes
(e.g., created via node_factory.line_graph()) were still running
cln-grpc, which could cause port collisions during tests.

This ensures consistent behavior across all test nodes.
@cdecker cdecker force-pushed the claude/gl-signerproxy-cln-subdaemon-011CUpYwEFUedqadL8eVo7Rg branch from 8f4601d to b2f95da Compare November 7, 2025 17:07
@cdecker cdecker merged commit 5961c29 into Blockstream:main Nov 11, 2025
11 of 12 checks passed
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.

2 participants