-
Notifications
You must be signed in to change notification settings - Fork 447
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
feat: add support for arbitrary service modules #1563
Conversation
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.
This makes sense to me, but docs should be updated^^
I'm also curious about what @achingbrain thinks about this^^
I like this idea and would ideally extend it to other components that are or should be optional. For example in helia I'm creating disposable dial-only libp2p nodes for use as an RPC client, so they don't need the protocols that are enabled by default - identify, ping etc. Identify in particular causes loads of noise in the logs as the connection tends to get torn down before identify has completed so it'd be great to not have that enabled on the dial-only node at all. Also I think there was interest from lodestar and others to generally have a more minimal libp2p with a smaller surface area. Given that we have things like const libp2p = await createLibp2p({
transports: [
tcp()
],
connectionEncryption: [
noise()
],
streamMuxers: [
yamux()
],
services: [
ping(),
identify(),
fetch(),
nat(),
myCustomService()
]
})
// then later
const value = await libp2p.services.fetch(someKey)
const foo = await libp2p.services.myCustomService.someMethod(bar) We'd then remove .fetch, .ping etc from the libp2p interface as you'd access them via the I'm not sure how this would work with the types though? As in, how to derive the type of the |
With your example, it's probably impossible, but with original proposal where you pass service map it could be done |
I have updated the API to use a const libp2p = await createLibp2p({
transports: [
tcp()
],
connectionEncryption: [
noise()
],
streamMuxers: [
yamux()
],
services: {
ping: ping(),
identify: identify(),
fetch: fetch(),
nat: nat(),
myCustomService: myCustomService()
}
})
const value = await libp2p.services.fetch(someKey)
const foo = await libp2p.services.myCustomService.someMethod(bar) Note that I have expanded the return type of @achingbrain, if it were possible to have services as an array instead of a map and still have types work, how would we reference a service from the node by name? E.g. how would the following array map to the following object: [ ping(), fetch() ] => { ping: (service), fetch: (service) } Would services be required to return an object with a property that identities the name of the service? If this were the case you could also require they have a type property the identifies the type of service (or perhaps just infer it) and it might be possible to move transports, muxers, etc. to the services list. |
This is a good idea and it's something we're going to do, I just shy away from it a little because it's going to be quite disruptive. Maybe after the current round of breaking changes. |
@saul-jb This PR was discussed in today's js-libp2p Triage meeting. In terms of timeline, we are thinking of including this in a js-libp2p release after IPFS Thing (April 15-19). Until then, we want to limit disruptive changes to js-libp2p and keep focus on bugfixes/hardening and general WebRTC related upkeep (new features landing soon in js-libp2p-webrtc). |
@achingbrain, @p-shahi, What is the state of this, is there anything more I can do to help? |
@saul-jb Per this comment #1707 (comment) @achingbrain intends to include this in the upcoming release (0.45.0) |
When libp2p is [configured with arbitrary services](libp2p/js-libp2p#1563) some of those services may be content routers or peer routers or both. An example of this is the `@libp2p/kad-dht` module. In order to communicate to libp2p that they can provide content/peer routing cabapiliy, add well-known symbols that libp2p can use to get references to the routing implementations.
When libp2p is [configured with arbitrary services](libp2p/js-libp2p#1563) some of those services may be content routers or peer routers or both. An example of this is the `@libp2p/kad-dht` module. In order to communicate to libp2p that they can provide content/peer routing cabapiliy, add well-known symbols that libp2p can use to get references to the routing implementations.
The DHT interface is similar to the content/peer routing interfaces but different. In order to detect content/peer routers and peer discovery implementations in [arbitrary libp2p modules](libp2p/js-libp2p#1563) use the exported symbols to create getters for them. The DHTContentRouting and DHTPeerRouting classes have been ported over from libp2p.
The DHT interface is similar to the content/peer routing interfaces but different. In order to detect content/peer routers and peer discovery implementations in [arbitrary libp2p modules](libp2p/js-libp2p#1563) use the exported symbols to create getters for them. The DHTContentRouting and DHTPeerRouting classes have been ported over from libp2p.
803609b
to
c071ddf
Compare
c071ddf
to
db14a27
Compare
Updates the libp2p init args to accept an object of service factory functions that can use internal libp2p components. The returned libp2p object has a `.services` key that corresponds to the service factory keys.
db14a27
to
f65b83b
Compare
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.
This is going to really improve the flexibility, security and size of js-libp2p so thanks a lot for this @saul-jb and @achingbrain . It looks good to me, I only have two comments. I also wonder if we should include #1684 in this PR but it's not a requirement to land this.
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.
LGTM
I didn't check it out and run it, but just looking at the structure it looks good.
Would still love IdentifyService#identify
to return the result but I guess thats a separate discussion.
It would be nice if libp2p support arbitrary modules so that they can automatically be initialized with the libp2p instance so this PR adds this functionality. This is useful because there are many modules one might want to use that do not fit in the predefined categories and it allows them to add those modules alongside the standard ones.
This PR adds a configuration option to the
createLibp2p
method allowing you to add custom modules: