Each time a node publishes an updated IPNS record for a particular key it is propagated by the router into the network where network nodes can choose to accept or reject the new record. When a node attempts to retrieve an IPNS record from the network it uses the router to query for the IPNS record(s) associated with the IPNS key; the node then validates the received records.
In this spec we address building a router based on a PubSub system, particularly focusing on libp2p PubSub.
The protocol has four components:
For a given IPNS local record key described in the IPNS Specification the PubSub topic is:
where base64url-unpadded is an unpadded base64url as specified in [rfc4648].
libp2p PubSub does not have any notion of persistent data built into it. However, we can layer persistence on top of PubSub by utilizing libp2p Fetch.
The protocol has the following steps:
A subscribes to the PubSub topic
t corresponding to the local IPNS record key
A notices that a node
B has connected to it and subscribed to
B a Fetch request for
A's current record then
A updates its record and Publishes it to the network
Note: PubSub does not guarantee that a message sent by a peer
A will be received by a peer
B and it's possible
(e.g. in systems like gossipsub)
that this is true even if
B are already connected. Therefore, whenever
A notices any node that has
connected to it and subscribed to
t it should run the Fetch protocol as described above. However, developers may have routers
with properties that allow the amount of time in step 3 to increase arbitrarily large (including infinite) amounts.
A putting and getting updates to an IPNS key
k, with computed PubSub topic
Note: 5 is optional because it is not necessary. However, receiving duplicate records are already handled efficiently by the above logic and properly running the persistence protocol can be difficult (as in the example below). Periodic republishing can then act as a fall-back plan in the event of errors in the persistence protocol.
Persistence Error Example:
B connects to
A gets the latest record (
B then disconnects from
B reconnects to
A's checking of when
B reconnects has problems it could miss
R2 (e.g. if it polled subscribed peers
every 10 seconds)