Skip to content

Comments

Remove Node from public interface#534

Draft
rustaceanrob wants to merge 4 commits into2140-dev:masterfrom
rustaceanrob:26-2-18-encapsulate-node
Draft

Remove Node from public interface#534
rustaceanrob wants to merge 4 commits into2140-dev:masterfrom
rustaceanrob:26-2-18-encapsulate-node

Conversation

@rustaceanrob
Copy link
Collaborator

@rustaceanrob rustaceanrob commented Feb 18, 2026

Closes #527

This addresses the long standing architecture question of why there was a Node and Client separation. Before I learned about using this sealed trait technique (not sure if it has a name), I didn't know how to limit the user to call run a single time. This PR introduces guided state-transitions for the client, with each impl body having different methods available. When Idle, the user can call one of run, run_detached, run_with_runtime, which covers all the ways I know of in terms of how to spawn a node process with tokio. The client then has all of the available methods the user might expect, i.e broadcast a transaction or shutdown the node. I decided to also remove the Requester type, since this design allows Client to implement that functionality. The only downside I am seeing is the Client must be returned for each state transition. Using &mut self and changing the state is invalid AFICT.

Tried to make the commits somewhat atomic here, but just a high level review is cool, a.k.a just looking at the API updates in the examples and getting a gut-feel. @thunderbiscuit

cc @nyonson if you wanna poke around the changes

@rustaceanrob rustaceanrob force-pushed the 26-2-18-encapsulate-node branch 2 times, most recently from 24fe41e to 606976a Compare February 18, 2026 17:15
@nyonson
Copy link
Collaborator

nyonson commented Feb 18, 2026

Before I learned about using this sealed trait technique (not sure if it has a name), I didn't know how to limit the user to call run a single time.

Is this the typestate pattern?

@rustaceanrob
Copy link
Collaborator Author

Ah yup that's the one

First step in cleaning up the `Node`/`Client` relationship. This
abstracts running a `task`, which will require some new methods to run
with more flexibility (bring your own runtime or use an OS thread). The
panic introduced will be impossible to hit in a later commit where I
will introduce sealed traits.
@rustaceanrob rustaceanrob force-pushed the 26-2-18-encapsulate-node branch from 606976a to dfe64ef Compare February 23, 2026 16:37
Uses the sealed trait hack to only allow for compiler enforced state
transactions. There is first a `run` step, followed by the typical
methods a client would expect. I decided to scrap the `Requester` and
instead encapsulate the event receivers with a newtype. Running a client
gives access to the event receivers as well as the handle to the task.

The only downside I see with this is `&mut self` doesn't seem to be
possible, as each impl block is defined for it's `State` type. I need to
fiddle with that to see if we can't remove the need to return the client
each state transition.
@rustaceanrob rustaceanrob force-pushed the 26-2-18-encapsulate-node branch from dfe64ef to 373ecc5 Compare February 23, 2026 16:50
@rustaceanrob
Copy link
Collaborator Author

After poking around potential dependent crates I think this needs a bit more work, particularly to work with LDK node

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.

Architecture Questions (Node/Client)

2 participants