-
Notifications
You must be signed in to change notification settings - Fork 5
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
propose: fast lane ipns #66
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,336 @@ | ||
# Fast lane IPNS | ||
|
||
Authors: | ||
- @gozala | ||
|
||
Initial PR: TBD <!-- Reference the PR first proposing this document. Oooh, self-reference! --> | ||
Related to: [Reliable Mutability Primitive][] | ||
|
||
[Reliable Mutability Primitive]:https://github.com/protocol/web3-dev-team/pull/19/ | ||
<!-- | ||
This template is for a proposal/brief/pitch for a significant project to be undertaken by a Web3 Dev project team. | ||
The goal of project proposals is to help us decide which work to take on, which things are more valuable than other things. | ||
--> | ||
<!-- | ||
A proposal should contain enough detail for others to understand how this project contributes to our team’s mission of product-market fit | ||
for our unified stack of protocols, what is included in scope of the project, where to get started if a project team were to take this on, | ||
and any other information relevant for prioritizing this project against others. | ||
It does not need to describe the work in much detail. Most technical design and planning would take place after a proposal is adopted. | ||
Good project scope aims for ~3-5 engineers for 1-3 months (though feel free to suggest larger-scoped projects anyway). | ||
Projects do not include regular day-to-day maintenance and improvement work, e.g. on testing, tooling, validation, code clarity, refactors for future capability, etc. | ||
--> | ||
<!-- | ||
For ease of discussion in PRs, consider breaking lines after every sentence or long phrase. | ||
--> | ||
|
||
## Purpose & impact | ||
#### Background & intent | ||
_Describe the desired state of the world after this project? Why does that matter?_ | ||
<!-- | ||
Outline the status quo, including any relevant context on the problem you’re seeing that this project should solve. Wherever possible, include pains or problems that you’ve seen users experience to help motivate why solving this problem works towards top-line objectives. | ||
--> | ||
|
||
##### Problem statement | ||
|
||
Today [IPNS][] fails to provide reliable mutability primitive. There is no implementation that works across go, node and web, which makes it impractical. | ||
|
||
| Routing | web | go | nodejs | | ||
| ------- | ---- | ---- | ------ | | ||
| DHT | ❌ | ✅ | ❌ | | ||
| pubsub | ⚠️ | ⚠️ | ⚠️ | | ||
|
||
> ❌ - Not available | ||
> ✅ - Available | ||
> ⚠️ - Not out of the box | ||
> | ||
> - ❌ DHT in web nodes is impractical as most nodes will be undialable and so will be a web node. | ||
> - ❌ DHT implementation in nodejs is buggy, untersted and unoptimized ([ipfs/js-ipfs#3469][]). | ||
> - ⚠️ PubSub in web nodes only works in swarms formed around central ICE server that are disjoint from go nodes. In practice creating fragmented networks of ephemeral peers. | ||
> - ⚠️ IPNS over pubsub is disabled in go by default (Can be enabled by running daemon with `--enable-namesys-pubsub`). Pubusb itself is also disabled by default ([protocol/web3-dev-team#53][]). | ||
> - ⚠️ IPNS over pubsub in nodejs still requires DHT to bootstrap overlay network of participating peers. Lack of proper DHT implementation prevents it. Which could be overcome via delegated routing but it does not work out of the box. | ||
|
||
Only DHT based implementation in go works out of the box. But it still fails to meet user expectations because: | ||
1. *Slow* publish and resolution. | ||
2. Requires continues republishing. (see [ipfs/go-ipfs#4435]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So does pubsub. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Conversation with @aschmahmann left me with an impression that pubsub is less problematic as peers query network and anyone can respond with a record, which in practice happens to be a lot more effective. @Stebalien Anything I should change about above statements or was that just a side note ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's less problematic as long as someone who resolved the record is still around and still subscribed to the record's pubsub channel. So, for popular records yes. But for unpopular records, no, you'll need to be online and/or republish regardless. |
||
|
||
Teams that have tried using IPNS in their products either switched to using [DNSLink][] or opted-into IPNS over pubsub and still find it *(too slow)* for certain updates *(Textile)*. | ||
|
||
To meet a market fit for products with changing state requirement _(that is anything interactive)_ IPNS needs to work reliably, fast _(comparable to web2 solutions)_ and across all supported enviroments _(go, web, nodejs)_. | ||
|
||
##### Proposition | ||
|
||
At the high level this proposal promises an efficienecy of centralized publishing and resolution while retaining resilience of distributed system. | ||
|
||
Proposed name resolution system is inspired by Domain Name System (DNS) as it introduces athoritative name resolvers _(from now on referred as)_ **name keeper** nodes. But unlike DNS, **name owners** _(private key holders)_ are in charge of choosing a name keepers and retain ability to change a name keeper in the future. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does this actually work? We could add a set of "keepers" to the IPNS record itself, I guess (as long as it's under a signature). I assume that's what you mean, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I go into much greater detail below, but general idea is that instead of having to route on every name resolution, we'd do it very infrequently because there will be specific authoritative node you can ask about current record. That way nodes will be able to resolve "name keeper" address once and cache for future name resolutions. Hypothesis is that while name keeper can change, it will be infrequent enough that we can see huge gains. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, sorry, my question is: how are you specifying these "name keepers"? Where does the list live, how is it published, how is it authenticated, how do I revoke keepers, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you may have meant how name owners choose name keepers. I don't have thought through the specific here, but general idea is that name owner would provide a name keeper with a signed certificate, which it can use to prove to routing nodes that it is indeed the name keeping authority. That said I'm pretty open to discussing / reconsidering many details of this proposal, mostly I'm pitching a bigger picture, that is lets make name publishing fast point to point operation. And make name resolution as close to that as possible. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it. My thinking is that the keepers should be added as additional fields to the IPNS records. That way, there's no way to "roll back". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
"Initial resolution optimization" attempts to describe it at high level. It assumes that infrastructure nodes can keep a list of "name keepers" and respond to queries from the network. If the name is unknown they can fallback to regular resolution DHT/PubSub and then cache the record forever. Note that here they resolve a "name keeper" not an actual record, and because those likely to change rarely no significant load is expected since there multiple layers of long term caching.
Name keepers are in charge of publishing to DHT, and over pubsub (possibly rendezvous) announcing themselves as "name keeper" for a name. Again since name keepers are unlikely to change TTLs could be very high.
Again have not thought through all the details, but broadly speaking "name owner" would issue new certificate overriding old one to a different "name owner", which will than be responsible for updating the network. I expect pubsub would be an effective way to let routing routing nodes about the name keeper change. That said I'm open to alternative here as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I realize I'm pretty vague when I talk about certificates, that is because I intentionally have not spend time thinking through all the details until this gets some traction. That said I think UCANs are providing a pretty good and generalized model. |
||
|
||
> It is assumed that pinning services would be a natural fit for name keeping as they they already are responsible for keeping the content around and mantain list of user pins. | ||
|
||
|
||
This promises to provide efficiency and speed of centralized systems as peers can cache *name keeper* address(es) for name _(on first resolution)_ and use it in all future resolutions, without disturbing rest of the network. | ||
|
||
Name publishing becomes also efficient as name owner can notify *name keeper* directly without disturbing rest of the network. | ||
|
||
> Please note that this enables peers to effectively resolve and/or publish name without having to remain online. | ||
|
||
###### Initial resolution optimization | ||
|
||
To make a very first name resolution nearly as efficient as subsequent ones it is propsoed to develop a new **name routing** service and deploy it on boostrap nodes. Name routing nodes will maintain `IPNS name → multiaddrs[]` mapping enabling peers to resolve an address of a name keeper on a first name resolution. Under assumbiton that reassigment of *name keepers* is going to be rare, overhead on name routing nodes should be insignificant as: | ||
Gozala marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
1. Name routers could cache addresses for a long time. | ||
2. Resolving peers could cache address locally (and require router only first time). | ||
3. Name routers can deny service to peers resolving name too frequently. | ||
4. Name routers are not involved in publishing. | ||
|
||
It is assumed that name routers will be infrastructure nodes, implying that they can be dialed from limited nodes like browsers _*(Have SSL certificates setup, or have a WebRTC address)*_ and can leverage DHT and PubSub so thay they: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wondering if we can reuse rendezvous servers for the exact same purpose? A rendezvous server is a libp2p node with a database that keeps all the multiaddrs registered for a given namespace. It receives registration requests and discovery requests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another possible link here if they would be a different piece of infrastructure would be for the name routers to advertise their role via rendezvous + DHT, so that other peers could easily find such nodes in the network There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think rendezvous nodes could be a perfect fit here, I just did not wanted to tie the proposal to any specific not yet available (as in deployed) solution so it is possible to iterate on this without been blocked on other pieces. |
||
|
||
1. Can resolve new name on demand by raced query of DHT and PubSub. | ||
2. Can become aware of new names through PubSub messages. | ||
3. Can become aware of name keeper changes through PubSub. | ||
|
||
> Note that since name keeper changes are expected to be rare TTL can be really high. | ||
|
||
Name routing service does not has to be limited to infrastructure nodes, peer could provide that service and resolve name keeper address from a local cache. | ||
|
||
|
||
###### DNSLink Optimization | ||
|
||
Name owners could include addresses to chosen name keepers in the [DNSLink][] record, which would enable name resolution without resolving an address through name routers first. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How would this interact with IPNS? IPNS doesn't use DNSLink. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just DNSLink optimization, that would allow you to avoid querying routing nodes described in a previous section. When you resolve IPNS name you'd either already have name keeper address or you query routing nodes to obtain one and cache it forever. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IPNS and DNSLink aren't really related. For DNSLink, you just query your local DNS resolver which is almost always very fast. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I think I know what the misunderstand is here. Today most DNSLink records are Does this makes more sense ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's the first I've heard of that. What's the motivation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
"What does success look like?" section calls out specifically related goals as success metric. That said motivation specifically is:
If I'm not mistaken originally #42 covered a lot of this before it rescoped. |
||
|
||
##### Visual illutrations | ||
|
||
###### Name resolution | ||
|
||
Diagram illustrates a name resolution flow. Note however that it does not show how name router can discover new names and their keepers from pubsub. | ||
|
||
<!-- | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
```flow | ||
pubsub=>start: PubSub | ||
peer=>start: 📱 Peer | ||
router=>start: 🖥 Router Node. | ||
keeper=>start: 🖥 Name Keeper | ||
resolve_keeper=>operation: Resolve QmName keeper | ||
resolve_name=>end: Keeper resolved | ||
cid=>end: QmV8 | ||
localcached=>condition: Is keeper address cached | ||
routercached=>condition: Check the cache | ||
dht_query=>operation: Query DHT | ||
pubsub_query=>operation: Query PubSub | ||
query=>parallel: Query | ||
cache_router=>inputoutput: Save Keeper Address | ||
cache_local=>inputoutput: Save Keeper Addresss | ||
resolve_cid=>operation: Resolve CID for QmName | ||
resolved_cid=>inputoutput: QmName is QmV17 | ||
|
||
peer->localcached | ||
localcached(yes)->resolve_cid | ||
localcached(no, right)->resolve_keeper(right)->router | ||
|
||
router(right)->routercached | ||
routercached(yes)->resolve_cid | ||
routercached(no, right)->query | ||
|
||
query(path1, bottom)->dht_query->cache_router | ||
query(path2, right)->pubsub_query->cache_router | ||
cache_router(left)->resolve_cid | ||
|
||
resolve_cid->keeper->resolved_cid | ||
pubsub->peer | ||
``` | ||
--> | ||
![name resolution](./fast-lane-ipns/resolution.svg) | ||
|
||
|
||
|
||
###### Name update | ||
|
||
Diagram illustrating how name update flow. | ||
|
||
<-- | ||
```flow | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
owner=>start: 📱 Name Owner | ||
ok=>inputoutput: ✅ QmName is QmV2 | ||
error=>inputoutput: ❌ QmV1 is not a head | ||
update=>operation: Update QmName from QmV1 to QmV2 | ||
incremental=>condition: QmName is QmV1 ? | ||
keeper=>end: 🖥 Name Keeper | ||
|
||
|
||
owner->update->keeper->incremental | ||
incremental(yes)->ok | ||
incremental(no)->error | ||
``` | ||
--> | ||
![publish](./fast-lane-ipns/publish.svg) | ||
|
||
|
||
###### Humane readable name resolution | ||
|
||
Diagram illustrates name resolution through DNSLink. | ||
|
||
<-- | ||
|
||
```flow | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure where There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
As per test above this "Diagram illustrates name resolution through DNSLink", so it is an example when peer is trying to resolve There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
peer=>start: Peer | ||
keeper=>start: Name Keeper | ||
router=>start: Name Router | ||
DNS=>end: DNS | ||
dnslink=>operation: a.com -> QmName | ||
lookup=>operation: lookup a.com | ||
has_keeper=>condition: DNSLink has keepr address | ||
resolve_cid=>operation: Reslove QmName | ||
resolve_keeper=>operation: Reslove Keeper | ||
keeper_resolved=>inputoutput: Resolved address | ||
cid=>inputoutput: QmV321 | ||
ttl_name=>condition: a.com in cache? | ||
|
||
peer->ttl_name | ||
ttl_name(no, right)->lookup(right)->has_keeper | ||
ttl_name(yes, bottom)->resolve_cid | ||
|
||
has_keeper(yes, bottom)->resolve_cid | ||
has_keeper(no)->resolve_keeper(bottom)->router->keeper_resolved(left)->resolve_cid | ||
resolve_cid(bottom)->keeper | ||
keeper->cid | ||
``` | ||
--> | ||
![publish](./fast-lane-ipns/dnslink.svg) | ||
|
||
#### Assumptions & hypotheses | ||
|
||
_What must be true for this project to matter?_ | ||
<!--(bullet list)--> | ||
|
||
- Applications need canonical address for a current state. | ||
- Should work across all supported environments out of the box. | ||
- To be practical solution, resolution should be reliable (publish / resolve works at least 99.9%). | ||
- To be practical solution, resolution should be really fast (as fast or faster than DNS resolution). | ||
- To be practical solution publishing should be really fast (To be competitive with web2 should be comparable to sending a HTTP request to the server) | ||
- Overhead should be neglegable. | ||
|
||
#### User workflow example | ||
_How would a developer or user use this new capability?_ | ||
<!--(short paragraph)--> | ||
|
||
#### Impact | ||
_How would this directly contribute to web3 dev stack product-market fit?_ | ||
|
||
<!-- | ||
Explain how this addresses known challenges or opportunities. | ||
What awesome potential impact/outcomes/results will we see if we nail this project? | ||
--> | ||
|
||
🔥🔥🔥 This would provide mutability primitive that is reliable and fast as DNS, but does not require centralized authority or blockchain style concensus. | ||
|
||
Furthermore it would make updating far more convenient than DNS. | ||
|
||
#### Leverage | ||
_How much would nailing this project improve our knowledge and ability to execute future projects?_ | ||
|
||
<!-- | ||
Explain the opportunity or leverage point for our subsequent velocity/impact (e.g. by speeding up development, enabling more contributors, etc) | ||
--> | ||
|
||
🎯🎯 - This would turn IPFS into an essential building block for web3 applications _(that need to do state updates)_ by removing a need for a custom server-side components to address this limitation. | ||
|
||
#### Confidence | ||
_How sure are we that this impact would be realized? Label from [this scale](https://medium.com/@nimay/inside-product-introduction-to-feature-priority-using-ice-impact-confidence-ease-and-gist-5180434e5b15)_. | ||
|
||
<!--Explain why this rating--> | ||
|
||
3 - As high confidence as we can have without doing actual user studies. We know teams that have tried IPNS but found it unrelaible, ultimately rolling out an alternative solution. We also know teams that have evaluated IPFS but chose alternative due to lack of reliable mutability story. | ||
|
||
## Project definition | ||
#### Brief plan of attack | ||
|
||
<!--Briefly describe the milestones/steps/work needed for this project--> | ||
|
||
- Define fast lane name resolution specification. | ||
- Define name keeper serivce specification. | ||
- Define name routing service specification. | ||
- Implement name routing service in go-ipfs. | ||
- Implement name keeper service in go-ipfs. | ||
- Implement fast lane name resolution across web, go, node ipfs. | ||
- Deploy name routing service to PL operated boostrap nodes. | ||
|
||
#### What does done look like? | ||
_What specific deliverables should completed to consider this project done?_ | ||
|
||
- IPNS records can be published and resolved across all supported environments (web, go, node). | ||
- Publishing takes couple of miliseconds. | ||
- Resolution in all but pathological case goes through fast lane. | ||
- Resolution in fast lane takes just couple of miliseconds. | ||
|
||
#### What does success look like? | ||
_Success means impact. How will we know we did the right thing?_ | ||
|
||
<!-- | ||
Provide success criteria. These might include particular metrics, desired changes in the types of bug reports being filed, desired changes in qualitative user feedback (measured via surveys, etc), etc. | ||
--> | ||
|
||
- Teams start using IPNS in [DNSLink][] records as opposet to CIDs. | ||
- We see people storing IPNS addresses in ENS to save on blockchain transactions costs | ||
- We see new projects leveraging IPNS (when human readable name is not a concern) instead of working around it with [DNSLink][]. | ||
- Most lookups go through fast lane. | ||
|
||
#### Counterpoints & pre-mortem | ||
_Why might this project be lower impact than expected? How could this project fail to complete, or fail to be successful?_ | ||
|
||
#### Alternatives | ||
_How might this project’s intent be realized in other ways (other than this project proposal)? What other potential solutions can address the same need?_ | ||
|
||
#### Dependencies/prerequisites | ||
<!--List any other projects that are dependencies/prerequisites for this project that is being pitched.--> | ||
|
||
#### Future opportunities | ||
<!--What future projects/opportunities could this project enable?--> | ||
|
||
## Required resources | ||
|
||
#### Effort estimate | ||
<!--T-shirt size rating of the size of the project. If the project might require external collaborators/teams, please note in the roles/skills section below). | ||
For a team of 3-5 people with the appropriate skills: | ||
- Small, 1-2 weeks | ||
- Medium, 3-5 weeks | ||
- Large, 6-10 weeks | ||
- XLarge, >10 weeks | ||
Describe any choices and uncertainty in this scope estimate. (E.g. Uncertainty in the scope until design work is complete, low uncertainty in execution thereafter.) | ||
--> | ||
|
||
#### Roles / skills needed | ||
<!--Describe the knowledge/skill-sets and team that are needed for this project (e.g. PM, docs, protocol or library expertise, design expertise, etc.). If this project could be externalized to the community or a team outside PL's direct employment, please note that here.--> | ||
|
||
## Appendix | ||
|
||
<!-- ### Fast lane name routing | ||
|
||
Today IPNS supports two name resolution/publishing schemes. They make different tradeoffs, but both disturbing a network when publishing and/or resolving a name. | ||
|
||
- Over DHT | ||
- 💔 Slow to resolve / publish. | ||
- 💔 Has an overhead of needing to republish. | ||
- 💔 Not an option for web peers. | ||
- 💔 Not implemented for node peers. | ||
- 💚 Very resilient | ||
- Over PubSub. | ||
- 💔 Disabled in go peers. | ||
- 💔 Does not work in web (**TODO:** Figure out if we expect it to work). | ||
- 💔 Has a constant overhead (uses resources whether used or not). | ||
- 💔 Initial resolution is slow which makes it slow for non long living peers (mobile devices, web) | ||
- 💚 Super simple and convinient protocol | ||
|
||
--> | ||
|
||
#### F.A.Q | ||
|
||
- Add your question here | ||
|
||
|
||
[Pinata]:https://pinata.cloud/ | ||
[DNSLink]:https://docs.ipfs.io/concepts/dnslink/ | ||
[IPNS]:https://docs.ipfs.io/concepts/ipns/ | ||
[Pinning Services API]:https://ipfs.github.io/pinning-services-api-spec/ | ||
[Petname]:https://en.wikipedia.org/wiki/Petname | ||
|
||
[ipfs/js-ipfs#3469]:https://github.com/ipfs/js-ipfs/issues/3469#issuecomment-775944675 | ||
[protocol/web3-dev-team#53]:https://github.com/protocol/web3-dev-team/pull/53 | ||
[ipfs/go-ipfs#4435]:https://github.com/ipfs/go-ipfs/issues/4435 |
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 can be any router, including the Rendezvous. Ideally what I would like to see was nodes to advertise that they are interested in a given topic in all the means they can DHT/Delegate/Rendezvous/... and then other more limited peers can rely on what suits them better.
I would rephrase the DHT to content/peer routing. I proposed some time ago the Discovery API, which would be a simple abstraction that would forward advertises/findPeers to the available routers. Go also has a discovery API concept similar
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.
That sounds reasonable and possibly worth adding to considered alternatives section. Here I describe current state of things and to my knowledge it does so accurately, isn't it ?