2022-12-01 07:58:41 +00:00
<!DOCTYPE html>
< html lang = "en" dir = "ltr" >
< head >
2022-12-01 08:37:15 +00:00
< meta name = "generator" content = "Hugo 0.106.0" >
2022-12-01 07:58:41 +00:00
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< meta name = "description" content = "25/LIBP2P-DNS-DISCOVERY specifies a scheme to implement libp2p peer discovery via DNS for Waku v2 . The generalised purpose is to retrieve an arbitrarily long , authenticated , updateable list of libp2p peers to bootstrap connection to a libp2p network . Since 10 / WAKU2 currently specifies use of libp2p peer identities , this method is suitable for a new Waku v2 node to discover other Waku v2 nodes to connect to .
This specification is largely based on EIP-1459, with the only deviation being the type of address being encoded (multiaddr vs enr).">
< meta name = "theme-color" content = "#FFFFFF" > < meta property = "og:title" content = "25/LIBP2P-DNS-DISCOVERY" / >
< meta property = "og:description" content = "25/LIBP2P-DNS-DISCOVERY specifies a scheme to implement libp2p peer discovery via DNS for Waku v2 . The generalised purpose is to retrieve an arbitrarily long , authenticated , updateable list of libp2p peers to bootstrap connection to a libp2p network . Since 10 / WAKU2 currently specifies use of libp2p peer identities , this method is suitable for a new Waku v2 node to discover other Waku v2 nodes to connect to .
This specification is largely based on EIP-1459, with the only deviation being the type of address being encoded (multiaddr vs enr)." />
< meta property = "og:type" content = "article" / >
< meta property = "og:url" content = "https://rfc.vac.dev/spec/25/" / > < meta property = "article:section" content = "docs" / >
< title > 25/LIBP2P-DNS-DISCOVERY | Vac RFC< / title >
< link rel = "manifest" href = "/manifest.json" >
< link rel = "icon" href = "/favicon.png" type = "image/x-icon" >
< link rel = "stylesheet" href = "/book.min.e935e20bd0d469378cb482f0958edf258c731a4f895dccd55799c6fbc8043f23.css" integrity = "sha256-6TXiC9DUaTeMtILwlY7fJYxzGk+JXczVV5nG+8gEPyM=" >
2022-12-07 18:15:09 +00:00
< script defer src = "/en.search.min.aa3278d1aeda578ff7108aa1b25e09f72893c3f391dc643c98382c7328f1faed.js" integrity = "sha256-qjJ40a7aV4/3EIqhsl4J9yiTw/OR3GQ8mDgscyjx+u0=" > < / script >
2022-12-01 07:58:41 +00:00
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
< / head >
< body dir = "ltr" >
< input type = "checkbox" class = "hidden toggle" id = "menu-control" / >
< input type = "checkbox" class = "hidden toggle" id = "toc-control" / >
< main class = "container flex" >
< aside class = "book-menu" >
< div class = "book-menu-content" >
< nav >
< h2 class = "book-brand" >
< a href = "/" > < span > Vac RFC< / span >
< / a >
< / h2 >
< div class = "book-search" >
< input type = "text" id = "book-search-input" placeholder = "Search" aria-label = "Search" maxlength = "64" data-hotkeys = "s/" / >
< div class = "book-search-spinner hidden" > < / div >
< ul id = "book-search-results" > < / ul >
< / div >
< ul >
< li > Raw
< ul >
< li > < a href = "/spec/20/" > 20/TOY-ETH-PM< / a > < / li >
< li > < a href = "/spec/24/" > 24/STATUS-CURATION< / a > < / li >
< li > < a href = "/spec/28/" > 28/STATUS-FEATURING< / a > < / li >
< li > < a href = "/spec/31/" > 31/WAKU2-ENR< / a > < / li >
< li > < a href = "/spec/32/" > 32/RLN-SPEC< / a > < / li >
< li > < a href = "/spec/34/" > 34/WAKU2-PEER-EXCHANGE< / a > < / li >
< li > < a href = "/spec/35/" > 35/WAKU2-NOISE< / a > < / li >
< li > < a href = "/spec/37/" > 37/WAKU2-NOISE-SESSIONS< / a > < / li >
2022-12-06 09:59:38 +00:00
< li > < a href = "/spec/38/" > 38/CONSENSUS-CLARO< / a > < / li >
2022-12-01 07:58:41 +00:00
< li > < a href = "/spec/43/" > 43/WAKU2-NOISE-PAIRING< / a > < / li >
< li > < a href = "/spec/44/" > 44/WAKU2-DANDELION< / a > < / li >
< li > < a href = "/spec/45/" > 45/WAKU2-ADVERSARIAL-MODELS< / a > < / li >
2022-12-02 14:32:42 +00:00
< li > < a href = "/spec/46/" > 46/GOSSIPSUB-TOR-PUSH< / a > < / li >
< li > < a href = "/spec/47/" > 47/WAKU2-TOR-PUSH< / a > < / li >
2022-12-01 07:58:41 +00:00
< / ul >
< / li >
< li > Draft
< ul >
< li > < a href = "/spec/1/" > 1/COSS< / a > < / li >
< li > < a href = "/spec/3/" > 3/REMOTE-LOG< / a > < / li >
< li > < a href = "/spec/4/" > 4/MVDS-META< / a > < / li >
< li > < a href = "/spec/10/" > 10/WAKU2< / a > < / li >
< li > < a href = "/spec/12/" > 12/WAKU2-FILTER< / a > < / li >
< li > < a href = "/spec/13/" > 13/WAKU2-STORE< / a > < / li >
< li > < a href = "/spec/14/" > 14/WAKU2-MESSAGE< / a > < / li >
< li > < a href = "/spec/15/" > 15/WAKU2-BRIDGE< / a > < / li >
< li > < a href = "/spec/16/" > 16/WAKU2-RPC< / a > < / li >
< li > < a href = "/spec/17/" > 17/WAKU2-RLN-RELAY< / a > < / li >
< li > < a href = "/spec/18/" > 18/WAKU2-SWAP< / a > < / li >
< li > < a href = "/spec/19/" > 19/WAKU2-LIGHTPUSH< / a > < / li >
< li > < a href = "/spec/21/" > 21/WAKU2-FTSTORE< / a > < / li >
< li > < a href = "/spec/22/" > 22/TOY-CHAT< / a > < / li >
< li > < a href = "/spec/23/" > 23/WAKU2-TOPICS< / a > < / li >
< li > < a href = "/spec/26/" > 26/WAKU2-PAYLOAD< / a > < / li >
< li > < a href = "/spec/27/" > 27/WAKU2-PEERS< / a > < / li >
< li > < a href = "/spec/29/" > 29/WAKU2-CONFIG< / a > < / li >
< li > < a href = "/spec/30/" > 30/ADAPTIVE-NODES< / a > < / li >
< li > < a href = "/spec/33/" > 33/WAKU2-DISCV5< / a > < / li >
< li > < a href = "/spec/36/" > 36/WAKU2-BINDINGS-API< / a > < / li >
< / ul >
< / li >
< li > Stable
< ul >
< li > < a href = "/spec/2/" > 2/MVDS< / a > < / li >
< li > < a href = "/spec/6/" > 6/WAKU1< / a > < / li >
< li > < a href = "/spec/7/" > 7/WAKU-DATA< / a > < / li >
< li > < a href = "/spec/8/" > 8/WAKU-MAIL< / a > < / li >
< li > < a href = "/spec/9/" > 9/WAKU-RPC< / a > < / li >
< li > < a href = "/spec/11/" > 11/WAKU2-RELAY< / a > < / li >
< / ul >
< / li >
< li > Deprecated
< ul >
< li > < a href = "/spec/5/" > 5/WAKU0< / a > < / li >
< / ul >
< / li >
< li > Retired< / li >
< / ul >
< / nav >
2022-12-01 08:37:15 +00:00
< script > ( function ( ) { var e = document . querySelector ( "aside.book-menu nav" ) ; addEventListener ( "beforeunload" , function ( ) { localStorage . setItem ( "menu.scrollTop" , e . scrollTop ) } ) , e . scrollTop = localStorage . getItem ( "menu.scrollTop" ) } ) ( ) < / script >
2022-12-01 07:58:41 +00:00
< / div >
< / aside >
< div class = "book-page" >
< header class = "book-header" >
< div class = "flex align-center justify-between" >
< label for = "menu-control" >
< img src = "/svg/menu.svg" class = "book-icon" alt = "Menu" / >
< / label >
< strong > 25/LIBP2P-DNS-DISCOVERY< / strong >
< label for = "toc-control" >
< img src = "/svg/toc.svg" class = "book-icon" alt = "Table of Contents" / >
< / label >
< / div >
< aside class = "hidden clearfix" >
< nav id = "TableOfContents" >
< ul >
< li > < a href = "#root-entry" > Root entry< / a > < / li >
< li > < a href = "#branch-entry" > Branch entry< / a > < / li >
< li > < a href = "#leaf-entries" > Leaf entries< / a >
< ul >
< li > < a href = "#link-entries" > Link entries< / a > < / li >
< li > < a href = "#multiaddr-entries" > < code > multiaddr< / code > entries< / a > < / li >
< / ul >
< / li >
< / ul >
< / nav >
< / aside >
< / header >
< article class = "markdown" >
2022-12-01 08:37:15 +00:00
< h1 id = "25libp2p-dns-discovery" >
25/LIBP2P-DNS-DISCOVERY
< a class = "anchor" href = "#25libp2p-dns-discovery" > #< / a >
< / h1 >
2022-12-01 07:58:41 +00:00
2022-12-01 08:37:15 +00:00
< h1 id = "libp2p-peer-discovery-via-dns" >
Libp2p Peer Discovery via DNS
< a class = "anchor" href = "#libp2p-peer-discovery-via-dns" > #< / a >
< / h1 >
2022-12-01 07:58:41 +00:00
< ul >
< li > Status: deleted< / li >
< li > Editor: Hanno Cornelius < a href = "mailto:hanno@status.im" > hanno@status.im< / a > < / li >
< / ul > < p > < code > 25/LIBP2P-DNS-DISCOVERY< / code > specifies a scheme to implement < a href = "https://libp2p.io/" > < code > libp2p< / code > < / a > peer discovery via DNS for Waku v2.
The generalised purpose is to retrieve an arbitrarily long, authenticated, updateable list of < a href = "https://docs.libp2p.io/concepts/peer-id/" > < code > libp2p< / code > peers< / a > to bootstrap connection to a < code > libp2p< / code > network.
Since < a href = "https://rfc.vac.dev/spec/10/" > < code > 10/WAKU2< / code > < / a > currently specifies use of < a href = "https://docs.libp2p.io/concepts/peer-id/" > < code > libp2p< / code > peer identities< / a > ,
this method is suitable for a new Waku v2 node to discover other Waku v2 nodes to connect to.< / p >
< p > This specification is largely based on < a href = "https://eips.ethereum.org/EIPS/eip-1459" > EIP-1459< / a > ,
with the only deviation being the type of address being encoded (< code > multiaddr< / code > vs < code > enr< / code > ).
Also see < a href = "https://vac.dev/dns-based-discovery" > this earlier explainer< / a > for more background on the suitability of DNS based discovery for Waku v2.< / p >
< h1 id = "list-encoding" >
List encoding
< a class = "anchor" href = "#list-encoding" > #< / a >
< / h1 >
< p > The peer list MUST be encoded as a < a href = "https://www.wikiwand.com/en/Merkle_tree" > Merkle tree< / a > .
EIP-1459 specifies < a href = "https://eips.ethereum.org/EIPS/eip-1459#specification" > the URL scheme< / a > to refer to such a DNS node list.
This specification uses the same approach, but with a < code > matree< / code > scheme:< / p >
< pre tabindex = "0" > < code > matree://< key> @< fqdn>
< / code > < / pre > < p > where< / p >
< ul >
< li > < code > matree< / code > is the selected < code > multiaddr< / code > Merkle tree scheme< / li >
< li > < code > < fqdn> < / code > is the fully qualified domain name on which the list can be found< / li >
< li > < code > < key> < / code > is the base32 encoding of the compressed 32-byte binary public key that signed the list.< / li >
< / ul >
< p > The example URL from EIP-1459, adapted to the above scheme becomes:< / p >
< pre tabindex = "0" > < code > matree://AM5FCQLWIZX2QFPNJAP7VUERCCRNGRHWZG3YYHIUV7BVDQ5FDPRT2@peers.example.org
< / code > < / pre > < p > Each entry within the Merkle tree MUST be contained within a < a href = "https://www.rfc-editor.org/rfc/rfc1035.txt" > DNS TXT record< / a >
and stored in a subdomain (except for the base URL < code > matree< / code > entry).
The content of any TXT record MUST be small enough to fit into the 512-byte limit imposed on UDP DNS packets,
which limits the number of hashes that can be contained within a branch entry.
The subdomain name for each entry is the base32 encoding of the abbreviated keccak256 hash of its text content.
See < a href = "https://eips.ethereum.org/EIPS/eip-1459#dns-record-structure" > this example< / a > of a fully populated tree for more information.< / p >
< h1 id = "entry-types" >
Entry types
< a class = "anchor" href = "#entry-types" > #< / a >
< / h1 >
< p > The following entry types are derived from < a href = "https://eips.ethereum.org/EIPS/eip-1459" > EIP-1459< / a >
and adapted for use with < code > multiaddrs< / code > :< / p >
< h2 id = "root-entry" >
Root entry
< a class = "anchor" href = "#root-entry" > #< / a >
< / h2 >
< p > The tree root entry MUST use the following format:< / p >
< pre tabindex = "0" > < code > matree-root:v1 m=< ma-root> l=< link-root> seq=< sequence number> sig=< signature>
< / code > < / pre > < p > where< / p >
< ul >
< li > < code > ma-root< / code > and < code > link-root< / code > refer to the root hashes of subtrees
containing < code > multiaddrs< / code > and links to other subtrees, respectively< / li >
< li > < code > sequence-number< / code > is the tree’ s update sequence number.
This number SHOULD increase with each update to the tree.< / li >
< li > < code > signature< / code > is a 65-byte secp256k1 EC signature
over the keccak256 hash of the root record content,
excluding the < code > sig=< / code > part,
encoded as URL-safe base64< / li >
< / ul >
< h2 id = "branch-entry" >
Branch entry
< a class = "anchor" href = "#branch-entry" > #< / a >
< / h2 >
< p > Branch entries MUST take the format:< / p >
< pre tabindex = "0" > < code > matree-branch:< h₁> ,< h₂> ,...,< hₙ>
< / code > < / pre > < p > where< / p >
< ul >
< li > < code > < h₁> ,< h₂> ,...,< hₙ> < / code > are the hashes of other subtree entries< / li >
< / ul >
< h2 id = "leaf-entries" >
Leaf entries
< a class = "anchor" href = "#leaf-entries" > #< / a >
< / h2 >
< p > There are two types of leaf entries:< / p >
< h3 id = "link-entries" >
Link entries
< a class = "anchor" href = "#link-entries" > #< / a >
< / h3 >
< p > For the subtree pointed to by < code > link-root< / code > ,
leaf entries MUST take the format:< / p >
< pre tabindex = "0" > < code > matree://< key> @< fqdn>
< / code > < / pre > < p > which links to a different list located in another domain.< / p >
< h3 id = "multiaddr-entries" >
< code > multiaddr< / code > entries
< a class = "anchor" href = "#multiaddr-entries" > #< / a >
< / h3 >
< p > For the subtree pointed to by < code > ma-root< / code > ,
leaf entries MUST take the format:< / p >
< pre tabindex = "0" > < code > ma:< multiaddr>
< / code > < / pre > < p > which contains the < code > multiaddr< / code > of a < code > libp2p< / code > peer.< / p >
< h1 id = "client-protocol" >
Client protocol
< a class = "anchor" href = "#client-protocol" > #< / a >
< / h1 >
< p > A client MUST adhere to the < a href = "https://eips.ethereum.org/EIPS/eip-1459#client-protocol" > client protocol< / a > as specified in EIP-1459,
and adapted for usage with < code > multiaddr< / code > entry types below:< / p >
< p > To find nodes at a given DNS name a client MUST perform the following steps:< / p >
< ol >
< li > Resolve the TXT record of the DNS name and check whether it contains a valid < code > matree-root:v1< / code > entry.< / li >
< li > Verify the signature on the root against the known public key
and check whether the sequence number is larger than or equal to any previous number seen for that name.< / li >
< li > Resolve the TXT record of a hash subdomain indicated in the record
and verify that the content matches the hash.< / li >
< li > If the resolved entry is of type:
< ul >
< li > < code > matree-branch< / code > : parse the list of hashes and continue resolving them (step 3).< / li >
< li > < code > ma< / code > : import the < code > multiaddr< / code > and add it to a local list of discovered nodes.< / li >
< / ul >
< / li >
< / ol >
< h1 id = "copyright" >
Copyright
< a class = "anchor" href = "#copyright" > #< / a >
< / h1 >
< p > Copyright and related rights waived via
< a href = "https://creativecommons.org/publicdomain/zero/1.0/" > CC0< / a > .< / p >
< h1 id = "references" >
References
< a class = "anchor" href = "#references" > #< / a >
< / h1 >
< ol >
< li > < a href = "https://rfc.vac.dev/spec/10/" > < code > 10/WAKU2< / code > < / a > < / li >
< li > < a href = "https://eips.ethereum.org/EIPS/eip-1459#client-protocol" > EIP-1459: Client Protocol< / a > < / li >
< li > < a href = "https://eips.ethereum.org/EIPS/eip-1459" > EIP-1459: Node Discovery via DNS < / a > < / li >
< li > < a href = "https://libp2p.io/" > < code > libp2p< / code > < / a > < / li >
< li > < a href = "https://docs.libp2p.io/concepts/peer-id/" > < code > libp2p< / code > peer identity< / a > < / li >
< li > < a href = "https://www.wikiwand.com/en/Merkle_tree" > Merkle trees< / a > < / li >
< / ol >
< / article >
< footer class = "book-footer" >
< div class = "flex flex-wrap justify-between" >
< / div >
< / footer >
< div class = "book-comments" >
< / div >
< label for = "menu-control" class = "hidden book-menu-overlay" > < / label >
< / div >
< aside class = "book-toc" >
< div class = "book-toc-content" >
< nav id = "TableOfContents" >
< ul >
< li > < a href = "#root-entry" > Root entry< / a > < / li >
< li > < a href = "#branch-entry" > Branch entry< / a > < / li >
< li > < a href = "#leaf-entries" > Leaf entries< / a >
< ul >
< li > < a href = "#link-entries" > Link entries< / a > < / li >
< li > < a href = "#multiaddr-entries" > < code > multiaddr< / code > entries< / a > < / li >
< / ul >
< / li >
< / ul >
< / nav >
< / div >
< / aside >
< / main >
< / body >
< / html >