Files
rfc.vac.dev/assets/js/02856484.e448364a.js
2025-08-01 18:13:23 +00:00

1 line
47 KiB
JavaScript

"use strict";(self.webpackChunklogos_docs_template=self.webpackChunklogos_docs_template||[]).push([[8920],{35997:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var a=n(87462),i=(n(67294),n(3905));const r={title:"5/WAKU0",name:"Waku v0",status:"deprecated",editor:"Oskar Thor\xe9n &lt;oskarth@titanproxy.com&gt;",contributors:["Adam Babik &lt;adam@status.im&gt;","Andrea Maria Piana &lt;andreap@status.im&gt;","Dean Eigenmann &lt;dean@status.im&gt;","Kim De Mey &lt;kimdemey@status.im&gt;"]},o=void 0,s={unversionedId:"deprecated/5/waku0",id:"deprecated/5/waku0",title:"5/WAKU0",description:"- Status: deprecated",source:"@site/waku/deprecated/5/waku0.md",sourceDirName:"deprecated/5",slug:"/deprecated/5/waku0",permalink:"/waku/deprecated/5/waku0",draft:!1,tags:[],version:"current",frontMatter:{title:"5/WAKU0",name:"Waku v0",status:"deprecated",editor:"Oskar Thor\xe9n &lt;oskarth@titanproxy.com&gt;",contributors:["Adam Babik &lt;adam@status.im&gt;","Andrea Maria Piana &lt;andreap@status.im&gt;","Dean Eigenmann &lt;dean@status.im&gt;","Kim De Mey &lt;kimdemey@status.im&gt;"]},sidebar:"defaultSidebar",previous:{title:"Deprecated RFCs",permalink:"/waku/deprecated/"},next:{title:"16/WAKU2-RPC",permalink:"/waku/deprecated/16/rpc"}},l={},p=[{value:"Motivation",id:"motivation",level:2},{value:"Definitions",id:"definitions",level:2},{value:"Underlying Transports and Prerequisites",id:"underlying-transports-and-prerequisites",level:2},{value:"Use of DevP2P",id:"use-of-devp2p",level:3},{value:"Gossip based routing",id:"gossip-based-routing",level:3},{value:"Wire Specification",id:"wire-specification",level:2},{value:"Use of RLPx transport protocol",id:"use-of-rlpx-transport-protocol",level:3},{value:"ABNF specification",id:"abnf-specification",level:3},{value:"Packet Codes",id:"packet-codes",level:3},{value:"Packet usage",id:"packet-usage",level:3},{value:"Status",id:"status",level:4},{value:"Messages",id:"messages",level:4},{value:"Status Update",id:"status-update",level:4},{value:"PoW Requirement update",id:"pow-requirement-update",level:5},{value:"Bloom filter update",id:"bloom-filter-update",level:5},{value:"Topic Interest update",id:"topic-interest-update",level:5},{value:"Rate Limits update",id:"rate-limits-update",level:5},{value:"Message Confirmations update",id:"message-confirmations-update",level:5},{value:"P2P Request",id:"p2p-request",level:4},{value:"P2P Message",id:"p2p-message",level:4},{value:"Payload Encryption",id:"payload-encryption",level:3},{value:"Packet code Rationale",id:"packet-code-rationale",level:3},{value:"Additional capabilities",id:"additional-capabilities",level:2},{value:"Light node",id:"light-node",level:3},{value:"Accounting for resources (experimental)",id:"accounting-for-resources-experimental",level:3},{value:"Upgradability and Compatibility",id:"upgradability-and-compatibility",level:2},{value:"General principles and policy",id:"general-principles-and-policy",level:3},{value:"Backwards Compatibility",id:"backwards-compatibility",level:3},{value:"Waku-Whisper bridging",id:"waku-whisper-bridging",level:3},{value:"Forward Compatibility",id:"forward-compatibility",level:3},{value:"Appendix A: Security considerations",id:"appendix-a-security-considerations",level:2},{value:"Scalability and UX",id:"scalability-and-ux",level:3},{value:"Privacy",id:"privacy",level:3},{value:"Spam resistance",id:"spam-resistance",level:3},{value:"Censorship resistance",id:"censorship-resistance",level:3},{value:"Appendix B: Implementation Notes",id:"appendix-b-implementation-notes",level:2},{value:"Implementation Matrix",id:"implementation-matrix",level:3},{value:"Recommendations for clients",id:"recommendations-for-clients",level:3},{value:"Node discovery",id:"node-discovery",level:3},{value:"Changelog",id:"changelog",level:2},{value:"Version 0.6",id:"version-06",level:3},{value:"Version 0.5",id:"version-05",level:3},{value:"Version 0.4",id:"version-04",level:3},{value:"Version 0.3",id:"version-03",level:3},{value:"Version 0.2",id:"version-02",level:3},{value:"Version 0.1",id:"version-01",level:3},{value:"Differences between shh/6 and waku/0",id:"differences-between-shh6-and-waku0",level:3},{value:"Copyright",id:"copyright",level:2},{value:"Footnotes",id:"footnotes",level:2}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Status: deprecated"),(0,i.kt)("li",{parentName:"ul"},"Editor: Oskar Thor\xe9n ","<",(0,i.kt)("a",{parentName:"li",href:"mailto:oskarth@titanproxy.com"},"oskarth@titanproxy.com"),">"),(0,i.kt)("li",{parentName:"ul"},"Contributors:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Adam Babik ","<",(0,i.kt)("a",{parentName:"li",href:"mailto:adam@status.im"},"adam@status.im"),">"),(0,i.kt)("li",{parentName:"ul"},"Andrea Maria Piana ","<",(0,i.kt)("a",{parentName:"li",href:"mailto:andreap@status.im"},"andreap@status.im"),">"),(0,i.kt)("li",{parentName:"ul"},"Dean Eigenmann ","<",(0,i.kt)("a",{parentName:"li",href:"mailto:dean@status.im"},"dean@status.im"),">"),(0,i.kt)("li",{parentName:"ul"},"Kim De Mey ","<",(0,i.kt)("a",{parentName:"li",href:"mailto:kimdemey@status.im"},"kimdemey@status.im"),">")))),(0,i.kt)("p",null,"This specification describes the format of Waku messages within the \xd0\u039eVp2p Wire Protocol.\nThis spec substitutes ",(0,i.kt)("a",{parentName:"p",href:"https://eips.ethereum.org/EIPS/eip-627"},"EIP-627"),".\nWaku is a fork of the original Whisper protocol that enables better usability\nfor resource restricted devices,\nsuch as mostly-offline bandwidth-constrained smartphones.\nIt does this through (a) light node support,\n(b) historic messages (with a mailserver)\n(c) expressing topic interest for better bandwidth usage and\n(d) basic rate limiting."),(0,i.kt)("h2",{id:"motivation"},"Motivation"),(0,i.kt)("p",null,"Waku was created to incrementally improve in areas that Whisper is lacking in,\nwith special attention to resource restricted devices.\nWe specify the standard for Waku messages\nin order to ensure forward compatibility of different Waku clients,\nbackwards compatibility with Whisper clients,\nas well as to allow multiple implementations of Waku and its capabilities.\nWe also modify the language to be more unambiguous, concise and consistent."),(0,i.kt)("h2",{id:"definitions"},"Definitions"),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Term"),(0,i.kt)("th",{parentName:"tr",align:null},"Definition"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Light node")),(0,i.kt)("td",{parentName:"tr",align:null},"A Waku node that does not forward any messages.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Envelope")),(0,i.kt)("td",{parentName:"tr",align:null},"Messages sent and received by Waku nodes.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Node")),(0,i.kt)("td",{parentName:"tr",align:null},"Some process that is able to communicate for Waku.")))),(0,i.kt)("h2",{id:"underlying-transports-and-prerequisites"},"Underlying Transports and Prerequisites"),(0,i.kt)("h3",{id:"use-of-devp2p"},"Use of DevP2P"),(0,i.kt)("p",null,"For nodes to communicate, they MUST implement devp2p and run RLPx.\nThey MUST have some way of connecting to other nodes.\nNode discovery is largely out of scope for this spec,\nbut see the appendix for some suggestions on how to do this."),(0,i.kt)("h3",{id:"gossip-based-routing"},"Gossip based routing"),(0,i.kt)("p",null,"In Whisper, messages are gossiped between peers.\nWhisper is a form of rumor-mongering protocol\nthat works by flooding to its connected peers based on some factors.\nMessages are eligible for retransmission until their TTL expires.\nA node SHOULD relay messages to all connected nodes\nif an envelope matches their PoW and bloom filter settings.\nIf a node works in light mode, it MAY choose not to forward envelopes.\nA node MUST NOT send expired envelopes,\nunless the envelopes are sent as a ",(0,i.kt)("a",{parentName:"p",href:"./mailserver"},"mailserver")," response.\nA node SHOULD NOT send a message to a peer that it has already sent before."),(0,i.kt)("h2",{id:"wire-specification"},"Wire Specification"),(0,i.kt)("h3",{id:"use-of-rlpx-transport-protocol"},"Use of RLPx transport protocol"),(0,i.kt)("p",null,"All Waku messages are sent as devp2p RLPx transport protocol,\nversion 5",(0,i.kt)("sup",{parentName:"p",id:"fnref-1"},(0,i.kt)("a",{parentName:"sup",href:"#fn-1",className:"footnote-ref"},"1"))," packets.\nThese packets MUST be RLP-encoded arrays of data containing two objects:\npacket code followed by another object (whose type depends on the packet code).\nSee ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/ethereum/wiki/wiki/RLP"},"informal RLP spec")," and\nthe ",(0,i.kt)("a",{parentName:"p",href:"https://ethereum.github.io/yellowpaper/paper.pdf"},"Ethereum Yellow Paper, appendix B"),"\nfor more details on RLP."),(0,i.kt)("p",null,"Waku is a RLPx subprotocol called ",(0,i.kt)("inlineCode",{parentName:"p"},"waku")," with version ",(0,i.kt)("inlineCode",{parentName:"p"},"0"),".\nThe version number corresponds to the major version in the header spec.\nMinor versions should not break compatibility of ",(0,i.kt)("inlineCode",{parentName:"p"},"waku"),",\nthis would result in a new major.\n(Some exceptions to this apply in the Draft stage\nof where client implementation is rapidly change)."),(0,i.kt)("h3",{id:"abnf-specification"},"ABNF specification"),(0,i.kt)("p",null,"Using ",(0,i.kt)("a",{parentName:"p",href:"https://tools.ietf.org/html/rfc5234"},"Augmented Backus-Naur form (ABNF)"),"\nwe have the following format:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-abnf"},'; Packet codes 0 - 127 are reserved for Waku protocol\npacket-code = 1*3DIGIT\n\n; rate limits\nlimit-ip = 1*DIGIT\nlimit-peerid = 1*DIGIT\nlimit-topic = 1*DIGIT\n\nrate-limits = "[" limit-ip limit-peerid limit-topic "]"\n\npow-requirement-key = 48\nbloom-filter-key = 49\nlight-node-key = 50\nconfirmations-enabled-key = 51\nrate-limits-key = 52\ntopic-interest-key = 53\n\nstatus-options = "["\n [ pow-requirement-key pow-requirement ]\n [ bloom-filter-key bloom-filter ]\n [ light-node-key light-node ]\n [ confirmations-enabled-key confirmations-enabled ]\n [ rate-limits-key rate-limits ]\n [ topic-interest-key topic-interest ]\n"]"\n\nstatus = "[" version status-options "]"\n\nstatus-update = status-options\n\n; version is "an integer (as specified in RLP)"\nversion = DIGIT\n\nconfirmations-enabled = BIT\n\nlight-node = BIT\n\n; pow is "a single floating point value of PoW.\n; This value is the IEEE 754 binary representation\n; of a 64-bit floating point number.\n; Values of qNAN, sNAN, INF and -INF are not allowed.\n; Negative values are also not allowed."\npow = 1*DIGIT "." 1*DIGIT\npow-requirement = pow\n\n; bloom filter is "a byte array"\nbloom-filter = *OCTET\n\nwaku-envelope = "[" expiry ttl topic data nonce "]"\n\n; List of topics interested in\ntopic-interest = "[" *10000topic "]"\n\n; 4 bytes (UNIX time in seconds)\nexpiry = 4OCTET\n\n; 4 bytes (time-to-live in seconds)\nttl = 4OCTET\n\n; 4 bytes of arbitrary data\ntopic = 4OCTET\n\n; byte array of arbitrary size\n; (contains encrypted message)\ndata = OCTET\n\n; 8 bytes of arbitrary data\n; (used for PoW calculation)\nnonce = 8OCTET\n\nmessages = 1*waku-envelope\n\n; mail server / client specific\np2p-request = waku-envelope\np2p-message = 1*waku-envelope\n\n; packet-format needs to be paired with its\n; corresponding packet-format\npacket-format = "[" packet-code packet-format "]"\n\nrequired-packet = 0 status /\n1 messages /\n22 status-update /\n\noptional-packet = 126 p2p-request / 127 p2p-message\n\npacket = "[" required-packet [ optional-packet ] "]"\n')),(0,i.kt)("p",null,"All primitive types are RLP encoded. Note that, per RLP specification,\nintegers are encoded starting from ",(0,i.kt)("inlineCode",{parentName:"p"},"0x00"),"."),(0,i.kt)("h3",{id:"packet-codes"},"Packet Codes"),(0,i.kt)("p",null,"The message codes reserved for Waku protocol: 0 - 127."),(0,i.kt)("p",null,"Messages with unknown codes MUST be ignored without generating any error,\nfor forward compatibility of future versions."),(0,i.kt)("p",null,"The Waku sub-protocol MUST support the following packet codes:"),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Name"),(0,i.kt)("th",{parentName:"tr",align:null},"Int Value"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"Status"),(0,i.kt)("td",{parentName:"tr",align:null},"0")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"Messages"),(0,i.kt)("td",{parentName:"tr",align:null},"1")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"Status Update"),(0,i.kt)("td",{parentName:"tr",align:null},"22")))),(0,i.kt)("p",null,"The following message codes are optional, but they are reserved for specific purpose."),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Name"),(0,i.kt)("th",{parentName:"tr",align:null},"Int Value"),(0,i.kt)("th",{parentName:"tr",align:null},"Comment"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"Batch Ack"),(0,i.kt)("td",{parentName:"tr",align:null},"11"),(0,i.kt)("td",{parentName:"tr",align:null})),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"Message Response"),(0,i.kt)("td",{parentName:"tr",align:null},"12"),(0,i.kt)("td",{parentName:"tr",align:null})),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"P2P Request"),(0,i.kt)("td",{parentName:"tr",align:null},"126"),(0,i.kt)("td",{parentName:"tr",align:null})),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"P2P Message"),(0,i.kt)("td",{parentName:"tr",align:null},"127"),(0,i.kt)("td",{parentName:"tr",align:null})))),(0,i.kt)("h3",{id:"packet-usage"},"Packet usage"),(0,i.kt)("h4",{id:"status"},"Status"),(0,i.kt)("p",null,"The Status message serves as a Waku handshake and peers MUST exchange this\nmessage upon connection. It MUST be sent after the RLPx handshake and prior to\nany other Waku messages."),(0,i.kt)("p",null,"A Waku node MUST await the Status message from a peer\nbefore engaging in other Waku protocol activity with that peer.\nWhen a node does not receive the Status message from a peer,\nbefore a configurable timeout, it SHOULD disconnect from that peer."),(0,i.kt)("p",null,"Upon retrieval of the Status message, the node SHOULD validate the message\nreceived and validated the Status message. Note that its peer might not be in\nthe same state."),(0,i.kt)("p",null,"When a node is receiving other Waku messages from a peer before a Status\nmessage is received,\nthe node MUST ignore these messages and SHOULD disconnect from that peer.\nStatus messages received after the handshake is completed MUST also be ignored."),(0,i.kt)("p",null,"The status message MUST contain an association list containing various options.\nAll options within this association list are OPTIONAL,\nordering of the key-value pairs is not guaranteed and\ntherefore MUST NOT be relied on.\nUnknown keys in the association list SHOULD be ignored."),(0,i.kt)("h4",{id:"messages"},"Messages"),(0,i.kt)("p",null,"This packet is used for sending the standard Waku envelopes."),(0,i.kt)("h4",{id:"status-update"},"Status Update"),(0,i.kt)("p",null,"The Status Update message is used to communicate an update\nof the settings of the node.\nThe format is the same as the Status message, all fields are optional.\nIf none of the options are specified the message MUST be ignored and\nconsidered a noop.\nFields that are omitted are considered unchanged,\nfields that haven't changed SHOULD not be transmitted."),(0,i.kt)("h5",{id:"pow-requirement-update"},"PoW Requirement update"),(0,i.kt)("p",null,"When PoW is updated, peers MUST NOT deliver the sender envelopes\nwith PoW lower than specified in this message."),(0,i.kt)("p",null,"PoW is defined as average number of iterations,\nrequired to find the current BestBit\n(the number of leading zero bits in the hash), divided by message size and TTL:"),(0,i.kt)("p",null,">"," PoW = (2*",(0,i.kt)("em",{parentName:"p"},"BestBit) / (size ")," TTL)"),(0,i.kt)("p",null,"PoW calculation:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"}," fn short_rlp(envelope) = rlp of envelope, excluding env_nonce field.\n fn pow_hash(envelope, env_nonce) = sha3(short_rlp(envelope) ++ env_nonce)\n fn pow(pow_hash, size, ttl) = 2**leading_zeros(pow_hash) / (size * ttl)\n")),(0,i.kt)("p",null,"where size is the size of the RLP-encoded envelope,\nexcluding ",(0,i.kt)("inlineCode",{parentName:"p"},"env_nonce")," field (size of ",(0,i.kt)("inlineCode",{parentName:"p"},"short_rlp(envelope)"),")."),(0,i.kt)("h5",{id:"bloom-filter-update"},"Bloom filter update"),(0,i.kt)("p",null,"The bloom filter is used to identify a number of topics\nto a peer without compromising (too much)\nprivacy over precisely what topics are of interest.\nPrecise control over the information content (and thus efficiency of the filter)\nmay be maintained through the addition of bits."),(0,i.kt)("p",null,"Blooms are formed by the bitwise OR operation on a number of bloomed topics.\nThe bloom function takes the topic and projects them onto a 512-bit slice.\nAt most, three bits are marked for each bloomed topic."),(0,i.kt)("p",null,"The projection function is defined as a mapping from a 4-byte slice S\nto a 512-bit slice D; for ease of explanation, S will dereference to bytes,\nwhereas D will dereference to bits."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-python"}," LET D[*] = 0\n FOREACH i IN { 0, 1, 2 } DO\n LET n = S[i]\n IF S[3] & (2 ** i) THEN n += 256\n D[n] = 1\n END FOR\n")),(0,i.kt)("p",null,"A full bloom filter (all the bits set to 1)\nmeans that the node is to be considered a ",(0,i.kt)("inlineCode",{parentName:"p"},"Full Node")," and it will accept any topic."),(0,i.kt)("p",null,"If both Topic Interest and bloom filter are specified,\nTopic Interest always takes precedence and bloom filter MUST be ignored."),(0,i.kt)("p",null,"If only bloom filter is specified, the current Topic Interest MUST be discarded and\nonly the updated bloom filter MUST be used when forwarding or posting envelopes."),(0,i.kt)("p",null,"A bloom filter with all bits set to 0 signals\nthat the node is not currently interested in receiving any envelope."),(0,i.kt)("h5",{id:"topic-interest-update"},"Topic Interest update"),(0,i.kt)("p",null,"This packet is used by Waku nodes for sharing their interest\nin messages with specific topics.\nIt does this in a more bandwidth considerate way,\nat the expense of some metadata protection.\nPeers MUST only send envelopes with specified topics."),(0,i.kt)("p",null,"It is currently bounded to a maximum of 10000 topics.\nIf you are interested in more topics than that,\nthis is currently underspecified and likely requires updating it.\nThe constant is subject to change."),(0,i.kt)("p",null,"If only Topic Interest is specified,\nthe current bloom filter MUST be discarded and\nonly the updated Topic Interest MUST be used when forwarding or posting envelopes."),(0,i.kt)("p",null,"An empty array signals that the node\nis not currently interested in receiving any envelope."),(0,i.kt)("h5",{id:"rate-limits-update"},"Rate Limits update"),(0,i.kt)("p",null,"This packet is used for informing other nodes of their self defined rate limits."),(0,i.kt)("p",null,"In order to provide basic Denial-of-Service attack protection,\neach node SHOULD define its own rate limits.\nThe rate limits SHOULD be applied on IPs, peer IDs, and envelope topics."),(0,i.kt)("p",null,"Each node MAY decide to whitelist, i.e. do not rate limit, selected IPs or peer IDs."),(0,i.kt)("p",null,"If a peer exceeds node's rate limits, the connection between them MAY be dropped."),(0,i.kt)("p",null,"Each node SHOULD broadcast its rate limits to its peers using the rate limits packet.\nThe rate limits MAY also be sent as an optional parameter in the handshake."),(0,i.kt)("p",null,"Each node SHOULD respect rate limits advertised by its peers.\nThe number of packets SHOULD be throttled in order not to exceed peer's rate limits.\nIf the limit gets exceeded, the connection MAY be dropped by the peer."),(0,i.kt)("h5",{id:"message-confirmations-update"},"Message Confirmations update"),(0,i.kt)("p",null,"Message confirmations tell a node that a message originating\nfrom it has been received by its peers,\nallowing a node to know whether a message has or has not been received."),(0,i.kt)("p",null,"A node MAY send a message confirmation for any batch of messages\nreceived with a packet Messages Code."),(0,i.kt)("p",null,"A message confirmation is sent using Batch Acknowledge packet or\nMessage Response packet.\nThe Batch Acknowledge packet is followed by a keccak256 hash\nof the envelopes batch data."),(0,i.kt)("p",null,"The current ",(0,i.kt)("inlineCode",{parentName:"p"},"version")," of the message response is ",(0,i.kt)("inlineCode",{parentName:"p"},"1"),"."),(0,i.kt)("p",null,"Using ",(0,i.kt)("a",{parentName:"p",href:"https://tools.ietf.org/html/rfc5234"},"Augmented Backus-Naur form (ABNF)"),"\nwe have the following format:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-abnf"},'; a version of the Message Response\nversion = 1*DIGIT\n\n; keccak256 hash of the envelopes batch data (raw bytes) for which the confirmation is sent\nhash = *OCTET\n\nhasherror = *OCTET\n\n; error code\ncode = 1*DIGIT\n\n; a descriptive error message\ndescription = *ALPHA\n\nerror = "[" hasherror code description "]"\nerrors = *error\n\nresponse = "[" hash errors "]"\n\nconfirmation = "[" version response "]"\n')),(0,i.kt)("p",null,"The supported codes:\n",(0,i.kt)("inlineCode",{parentName:"p"},"1"),": means time sync error which happens when an envelope is too old or\ncreated in the future (the root cause is no time sync between nodes)."),(0,i.kt)("p",null,"The drawback of sending message confirmations\nis that it increases the noise in the network because for each sent message,\na corresponding confirmation is broadcast by one or more peers."),(0,i.kt)("h4",{id:"p2p-request"},"P2P Request"),(0,i.kt)("p",null,"This packet is used for sending Dapp-level peer-to-peer requests,\ne.g. Waku Mail Client requesting old messages from the ",(0,i.kt)("a",{parentName:"p",href:"./mailserver"},"Waku Mail Server"),"."),(0,i.kt)("h4",{id:"p2p-message"},"P2P Message"),(0,i.kt)("p",null,"This packet is used for sending the peer-to-peer messages,\nwhich are not supposed to be forwarded any further.\nE.g. it might be used by the Waku Mail Server for delivery of old\n(expired) messages, which is otherwise not allowed."),(0,i.kt)("h3",{id:"payload-encryption"},"Payload Encryption"),(0,i.kt)("p",null,"Asymmetric encryption uses the standard Elliptic Curve Integrated Encryption Scheme\nwith SECP-256k1 public key."),(0,i.kt)("p",null,"Symmetric encryption uses AES GCM algorithm with random 96-bit nonce."),(0,i.kt)("h3",{id:"packet-code-rationale"},"Packet code Rationale"),(0,i.kt)("p",null,"Packet codes ",(0,i.kt)("inlineCode",{parentName:"p"},"0x00")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"0x01")," are already used in all Waku / Whisper versions.\nPacket code ",(0,i.kt)("inlineCode",{parentName:"p"},"0x02")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"0x03")," were previously used in Whisper but\nare deprecated as of Waku v0.4"),(0,i.kt)("p",null,"Packet code ",(0,i.kt)("inlineCode",{parentName:"p"},"0x22")," is used to dynamically change the settings of a node."),(0,i.kt)("p",null,"Packet codes ",(0,i.kt)("inlineCode",{parentName:"p"},"0x7E")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"0x7F")," may be used to implement Waku Mail Server and Client.\nWithout P2P messages it would be impossible to deliver the old messages,\nsince they will be recognized as expired,\nand the peer will be disconnected for violating the Whisper protocol.\nThey might be useful for other purposes\nwhen it is not possible to spend time on PoW,\ne.g. if a stock exchange will want to provide live feed about the latest trades."),(0,i.kt)("h2",{id:"additional-capabilities"},"Additional capabilities"),(0,i.kt)("p",null,"Waku supports multiple capabilities.\nThese include light node, rate limiting and bridging of traffic.\nHere we list these capabilities, how they are identified,\nwhat properties they have and what invariants they must maintain."),(0,i.kt)("p",null,"Additionally there is the capability of a mailserver\nwhich is documented in its on ",(0,i.kt)("a",{parentName:"p",href:"mailserver"},"specification"),"."),(0,i.kt)("h3",{id:"light-node"},"Light node"),(0,i.kt)("p",null,"The rationale for light nodes is to allow for interaction with waku\non resource restricted devices as bandwidth can often be an issue."),(0,i.kt)("p",null,"Light nodes MUST NOT forward any incoming messages,\nthey MUST only send their own messages.\nWhen light nodes happen to connect to each other,\nthey SHOULD disconnect.\nAs this would result in messages being dropped between the two."),(0,i.kt)("p",null,"Light nodes are identified by the ",(0,i.kt)("inlineCode",{parentName:"p"},"light_node")," value in the status message."),(0,i.kt)("h3",{id:"accounting-for-resources-experimental"},"Accounting for resources (experimental)"),(0,i.kt)("p",null,"Nodes MAY implement accounting, keeping track of resource usage.\nIt is heavily inspired by\nSwarm's ",(0,i.kt)("a",{parentName:"p",href:"https://www.bokconsulting.com.au/wp-content/uploads/2016/09/tron-fischer-sw3.pdf"},"SWAP protocol"),",\nand works by doing pairwise accounting for resources."),(0,i.kt)("p",null,"Each node keeps track of resource usage with all other nodes.\nWhenever an envelope is received from a node that is expected\n(fits bloom filter or topic interest, is legal, etc) this is tracked."),(0,i.kt)("p",null,"Every epoch (say, every minute or every time an event happens)\nstatistics SHOULD be aggregated and saved by the client:"),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"peer"),(0,i.kt)("th",{parentName:"tr",align:null},"sent"),(0,i.kt)("th",{parentName:"tr",align:null},"received"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"peer1"),(0,i.kt)("td",{parentName:"tr",align:null},"0"),(0,i.kt)("td",{parentName:"tr",align:null},"123")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"peer2"),(0,i.kt)("td",{parentName:"tr",align:null},"10"),(0,i.kt)("td",{parentName:"tr",align:null},"40")))),(0,i.kt)("p",null,"In later versions this will be amended by nodes communication thresholds,\nsettlements and disconnect logic."),(0,i.kt)("h2",{id:"upgradability-and-compatibility"},"Upgradability and Compatibility"),(0,i.kt)("h3",{id:"general-principles-and-policy"},"General principles and policy"),(0,i.kt)("p",null,"These are policies that guide how we make decisions when it comes to upgradability,\ncompatibility, and extensibility:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Waku aims to be compatible with previous and future versions.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"In cases where we want to break this compatibility, we do so gracefully and\nas a single decision point.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"To achieve this,\nwe employ the following two general strategies:"))),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"a) Accretion (including protocol negotiation) over changing data"),(0,i.kt)("li",{parentName:"ul"},"b) When we want to change things, we give it a new name\n(for example, a version number).")),(0,i.kt)("p",null,"Examples:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"We enable bridging between ",(0,i.kt)("inlineCode",{parentName:"li"},"shh/6")," and\n",(0,i.kt)("inlineCode",{parentName:"li"},"waku/0")," until such a time as when we are ready to gracefully drop support\nfor ",(0,i.kt)("inlineCode",{parentName:"li"},"shh/6")," (1, 2, 3)."),(0,i.kt)("li",{parentName:"ul"},"When we add parameter fields, we (currently) do so by accreting them in a list,\nso old clients can ignore new fields (dynamic list)\nand new clients can use new capabilities (1, 3)."),(0,i.kt)("li",{parentName:"ul"},"To better support (2) and (3) in the future,\nwe will likely release a new version that gives better support for open,\ngrowable maps (association lists or native map type) (3)"),(0,i.kt)("li",{parentName:"ul"},"When we we want to provide a new set of messages that have different requirements,\nwe do so under a new protocol version and employ protocol versioning.\nThis is a form of accretion at a level above -\nit ensures a client can support both protocols at once and\ndrop support for legacy versions gracefully. (1,2,3)")),(0,i.kt)("h3",{id:"backwards-compatibility"},"Backwards Compatibility"),(0,i.kt)("p",null,"Waku is a different subprotocol from Whisper so it isn't directly compatible.\nHowever, the data format is the same,\nso compatibility can be achieved by the use of a bridging mode as described below.\nAny client which does not implement certain packet codes\nshould gracefully ignore the packets with those codes.\nThis will ensure the forward compatibility."),(0,i.kt)("h3",{id:"waku-whisper-bridging"},"Waku-Whisper bridging"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"waku/0")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"shh/6")," are different DevP2P subprotocols,\nhowever they share the same data format making their envelopes compatible.\nThis means we can bridge the protocols naively, this works as follows."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Roles:")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Waku client A, only Waku capability"),(0,i.kt)("li",{parentName:"ul"},"Whisper client B, only Whisper capability"),(0,i.kt)("li",{parentName:"ul"},"WakuWhisper bridge C, both Waku and Whisper capability")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Flow:")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"A posts message; B posts message."),(0,i.kt)("li",{parentName:"ol"},"C picks up message from A and B and relays them both to Waku and Whisper."),(0,i.kt)("li",{parentName:"ol"},"A receives message on Waku; B on Whisper.")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Note"),": This flow means if another bridge C1 is active,\nwe might get duplicate relaying for a message between C1 and C2.\nI.e. Whisper(","<",">","Waku","<",">","Whisper)","<",">","Waku, A-C1-C2-B.\nTheoretically this bridging chain can get as long as TTL permits."),(0,i.kt)("h3",{id:"forward-compatibility"},"Forward Compatibility"),(0,i.kt)("p",null,"It is desirable to have a strategy for maintaining forward compatibility\nbetween ",(0,i.kt)("inlineCode",{parentName:"p"},"waku/0")," and future version of waku.\nHere we outline some concerns and strategy for this."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Connecting to nodes with multiple versions:"),"\nThe way this SHOULD be accomplished in the future\nis by negotiating the versions of subprotocols,\nwithin the ",(0,i.kt)("inlineCode",{parentName:"p"},"hello")," message nodes transmit their capabilities along with a version.\nAs suggested in ",(0,i.kt)("a",{parentName:"p",href:"https://eips.ethereum.org/EIPS/eip-8"},"EIP-8"),",\nif a node connects that has a higher version number for a specific capability,\nthe node with a lower number SHOULD assume backwards compatibility.\nThe node with the higher version\nwill decide if compatibility can be assured between versions,\nif this is not the case it MUST disconnect.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Adding new packet codes:"),"\nNew packet codes can be added easily due to the available packet codes.\nUnknown packet codes SHOULD be ignored.\nUpgrades that add new packet codes SHOULD implement some fallback mechanism\nif no response was received for nodes that do not yet understand this packet.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Adding new options in ",(0,i.kt)("inlineCode",{parentName:"strong"},"status-options"),":"),"\nNew options can be added to the ",(0,i.kt)("inlineCode",{parentName:"p"},"status-options")," association list\nin the ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"status-update")," packet as options are OPTIONAL and\nunknown option keys SHOULD be ignored.\nA node SHOULD NOT disconnect from a peer\nwhen receiving ",(0,i.kt)("inlineCode",{parentName:"p"},"status-options")," with unknown option keys."))),(0,i.kt)("h2",{id:"appendix-a-security-considerations"},"Appendix A: Security considerations"),(0,i.kt)("p",null,"There are several security considerations to take into account when running Waku.\nChief among them are: scalability, DDoS-resistance and privacy.\nThese also vary depending on what capabilities are used.\nThe security considerations for extra capabilities such as ",(0,i.kt)("a",{parentName:"p",href:"./mailserver##security-considerations"},"mailservers"),"\ncan be found in their respective specifications."),(0,i.kt)("h3",{id:"scalability-and-ux"},"Scalability and UX"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Bandwidth usage:")),(0,i.kt)("p",null,"In version 0 of Waku, bandwidth usage is likely to be an issue.\nFor more investigation into this,\nsee the theoretical scaling model described ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vacp2p/research/tree/dcc71f4779be832d3b5ece9c4e11f1f7ec24aac2/whisper_scalability"},"here"),"."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Gossip-based routing:")),(0,i.kt)("p",null,"Use of gossip-based routing doesn't necessarily scale.\nIt means each node can see a message multiple times,\nand having too many light nodes can cause propagation probability that is too low.\nSee ",(0,i.kt)("a",{parentName:"p",href:"https://our.status.im/whisper-pss-comparison/"},"Whisper vs PSS"),"\nfor more and a possible Kademlia based alternative."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Lack of incentives:")),(0,i.kt)("p",null,"Waku currently lacks incentives to run nodes,\nwhich means node operators are more likely to create centralized choke points."),(0,i.kt)("h3",{id:"privacy"},"Privacy"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Light node privacy:")),(0,i.kt)("p",null,"The main privacy concern with light nodes\nis that directly connected peers will know that a message originates from them\n(as it are the only ones it sends).\nThis means nodes can make assumptions about what messages (topics)\ntheir peers are interested in."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Bloom filter privacy:")),(0,i.kt)("p",null,"By having a bloom filter where only the topics you are interested in are set,\nyou reveal which messages you are interested in.\nThis is a fundamental tradeoff between bandwidth usage and privacy,\nthough the tradeoff space is likely suboptimal in terms of the\n",(0,i.kt)("a",{parentName:"p",href:"https://eprint.iacr.org/2017/954.pdf"},"Anonymity")," ",(0,i.kt)("a",{parentName:"p",href:"https://petsymposium.org/2019/files/hotpets/slides/coordination-helps-anonymity-slides.pdf"},"trilemma"),"."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Privacy guarantees not rigorous:")),(0,i.kt)("p",null,"Privacy for Whisper / Waku haven't been studied rigorously for various threat models\nlike global passive adversary, local active attacker, etc.\nThis is unlike e.g. Tor and mixnets."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Topic hygiene:")),(0,i.kt)("p",null,"Similar to bloom filter privacy,\nif you use a very specific topic you reveal more information.\nSee scalability model linked above."),(0,i.kt)("h3",{id:"spam-resistance"},"Spam resistance"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"PoW bad for heterogeneous devices:")),(0,i.kt)("p",null,"Proof of work is a poor spam prevention mechanism.\nA mobile device can only have a very low PoW\nin order not to use too much CPU / burn up its phone battery.\nThis means someone can spin up a powerful node and overwhelm the network."),(0,i.kt)("h3",{id:"censorship-resistance"},"Censorship resistance"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Devp2p TCP port blockable:")),(0,i.kt)("p",null,"By default Devp2p runs on port ",(0,i.kt)("inlineCode",{parentName:"p"},"30303"),",\nwhich is not commonly used for any other service.\nThis means it is easy to censor, e.g. airport WiFi.\nThis can be mitigated somewhat by running on e.g. port ",(0,i.kt)("inlineCode",{parentName:"p"},"80")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"443"),",\nbut there are still outstanding issues.\nSee libp2p and Tor's Pluggable Transport for how this can be improved."),(0,i.kt)("h2",{id:"appendix-b-implementation-notes"},"Appendix B: Implementation Notes"),(0,i.kt)("h3",{id:"implementation-matrix"},"Implementation Matrix"),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Client"),(0,i.kt)("th",{parentName:"tr",align:null},"Spec supported"),(0,i.kt)("th",{parentName:"tr",align:null},"Details"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Status-go")),(0,i.kt)("td",{parentName:"tr",align:null},"0.5"),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("a",{parentName:"td",href:"https://github.com/status-im/status-go/blob/develop/WAKU.md"},"details"))),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Nimbus")),(0,i.kt)("td",{parentName:"tr",align:null},"0.4"),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("a",{parentName:"td",href:"https://github.com/status-im/nimbus/tree/8747fe1ecd36fe778bb92b97634db84d364fede8/waku"},"details"))))),(0,i.kt)("h3",{id:"recommendations-for-clients"},"Recommendations for clients"),(0,i.kt)("p",null,"Notes useful for implementing Waku mode."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Avoid duplicate envelopes:")),(0,i.kt)("p",null,"To avoid duplicate envelopes, only connect to one Waku node.\nBenign duplicate envelopes is an intrinsic property of Whisper\nwhich often leads to a N factor increase in traffic,\nwhere N is the number of peers you are connected to."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Topic specific recommendations -")),(0,i.kt)("p",null,"Consider partition topics based on some usage,\nto avoid too much traffic on a single topic."),(0,i.kt)("h3",{id:"node-discovery"},"Node discovery"),(0,i.kt)("p",null,"Resource restricted devices SHOULD use\n",(0,i.kt)("a",{parentName:"p",href:"https://eips.ethereum.org/EIPS/eip-1459"},"EIP-1459")," to discover nodes."),(0,i.kt)("p",null,"Known static nodes MAY also be used."),(0,i.kt)("h2",{id:"changelog"},"Changelog"),(0,i.kt)("h3",{id:"version-06"},"Version 0.6"),(0,i.kt)("p",null,"Released ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vacp2p/specs/commit/9e650995f24179844857520c68fa3e8f6018b125"},"April 21,2020")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Mark spec as Deprecated mode in terms of its lifecycle.")),(0,i.kt)("h3",{id:"version-05"},"Version 0.5"),(0,i.kt)("p",null,"Released ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vacp2p/specs/commit/7b9dc562bc50c6bb844ac575cb221ec9cda2530a"},"March 17,2020")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Clarify the preferred way of handling unknown keys\nin the ",(0,i.kt)("inlineCode",{parentName:"li"},"status-options")," association list."),(0,i.kt)("li",{parentName:"ul"},"Correct spec/implementation mismatch:\nChange RLP keys to be the their int values in order to reflect production behavior")),(0,i.kt)("h3",{id:"version-04"},"Version 0.4"),(0,i.kt)("p",null,"Released ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vacp2p/specs/commit/17bd066e317bbe33af07146b721d73f24de47e88"},"February 21, 2020"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Simplify implementation matrix with latest state"),(0,i.kt)("li",{parentName:"ul"},"Introduces a new required packet code Status Code (",(0,i.kt)("inlineCode",{parentName:"li"},"0x22"),")\nfor communicating option changes"),(0,i.kt)("li",{parentName:"ul"},"Deprecates the following packet codes:\nPoW Requirement (",(0,i.kt)("inlineCode",{parentName:"li"},"0x02"),"), Bloom Filter (",(0,i.kt)("inlineCode",{parentName:"li"},"0x03"),"), Rate limits (",(0,i.kt)("inlineCode",{parentName:"li"},"0x20"),"),\nTopic interest (",(0,i.kt)("inlineCode",{parentName:"li"},"0x21"),") - all superseded by the new Status Code (",(0,i.kt)("inlineCode",{parentName:"li"},"0x22"),")"),(0,i.kt)("li",{parentName:"ul"},"Increased ",(0,i.kt)("inlineCode",{parentName:"li"},"topic-interest")," capacity from 1000 to 10000")),(0,i.kt)("h3",{id:"version-03"},"Version 0.3"),(0,i.kt)("p",null,"Released ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vacp2p/specs/commit/73138d6ba954ab4c315e1b8d210ac7631b6d1428"},"February 13, 2020"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Recommend DNS based node discovery over other Discovery methods."),(0,i.kt)("li",{parentName:"ul"},"Mark spec as Draft mode in terms of its lifecycle."),(0,i.kt)("li",{parentName:"ul"},"Simplify Changelog and misc formatting."),(0,i.kt)("li",{parentName:"ul"},"Handshake/Status message not compatible with shh/6 nodes;\nspecifying options as association list."),(0,i.kt)("li",{parentName:"ul"},"Include topic-interest in Status handshake."),(0,i.kt)("li",{parentName:"ul"},"Upgradability policy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"topic-interest")," packet code.")),(0,i.kt)("h3",{id:"version-02"},"Version 0.2"),(0,i.kt)("p",null,"Released ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vacp2p/specs/blob/waku-0.2.0/waku.md"},"December 10, 2019"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"General style improvements."),(0,i.kt)("li",{parentName:"ul"},"Fix ABNF grammar."),(0,i.kt)("li",{parentName:"ul"},"Mailserver requesting/receiving."),(0,i.kt)("li",{parentName:"ul"},"New packet codes: topic-interest (experimental), rate limits (experimental)."),(0,i.kt)("li",{parentName:"ul"},"More details on handshake modifications."),(0,i.kt)("li",{parentName:"ul"},"Accounting for resources mode (experimental)"),(0,i.kt)("li",{parentName:"ul"},"Appendix with security considerations: scalability and UX, privacy, and spam resistance."),(0,i.kt)("li",{parentName:"ul"},"Appendix with implementation notes and\nimplementation matrix across various clients with breakdown per capability."),(0,i.kt)("li",{parentName:"ul"},"More details on handshake and parameters."),(0,i.kt)("li",{parentName:"ul"},"Describe rate limits in more detail."),(0,i.kt)("li",{parentName:"ul"},"More details on mailserver and mail client API."),(0,i.kt)("li",{parentName:"ul"},"Accounting for resources mode (very experimental)."),(0,i.kt)("li",{parentName:"ul"},"Clarify differences with Whisper.")),(0,i.kt)("h3",{id:"version-01"},"Version 0.1"),(0,i.kt)("p",null,"Initial version. Released ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vacp2p/specs/blob/b59b9247f2ac1bf45c75bd3227a2e5dd87b6d7b0/waku.md"},"November 21, 2019"),"."),(0,i.kt)("h3",{id:"differences-between-shh6-and-waku0"},"Differences between shh/6 and waku/0"),(0,i.kt)("p",null,"Summary of main differences between this spec and Whisper v6, as described in ",(0,i.kt)("a",{parentName:"p",href:"https://eips.ethereum.org/EIPS/eip-627"},"EIP-627"),":"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"RLPx subprotocol is changed from ",(0,i.kt)("inlineCode",{parentName:"li"},"shh/6")," to ",(0,i.kt)("inlineCode",{parentName:"li"},"waku/0"),"."),(0,i.kt)("li",{parentName:"ul"},"Light node capability is added."),(0,i.kt)("li",{parentName:"ul"},"Optional rate limiting is added."),(0,i.kt)("li",{parentName:"ul"},"Status packet has following additional parameters: light-node,\nconfirmations-enabled and rate-limits"),(0,i.kt)("li",{parentName:"ul"},"Mail Server and Mail Client functionality is now part of the specification."),(0,i.kt)("li",{parentName:"ul"},"P2P Message packet contains a list of envelopes instead of a single envelope.")),(0,i.kt)("h2",{id:"copyright"},"Copyright"),(0,i.kt)("p",null,"Copyright and related rights waived via ",(0,i.kt)("a",{parentName:"p",href:"https://creativecommons.org/publicdomain/zero/1.0/"},"CC0"),"."),(0,i.kt)("h2",{id:"footnotes"},"Footnotes"),(0,i.kt)("div",{className:"footnotes"},(0,i.kt)("hr",{parentName:"div"}),(0,i.kt)("ol",{parentName:"div"},(0,i.kt)("li",{parentName:"ol",id:"fn-1"},"Felix Lange et al. ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/ethereum/devp2p/blob/master/rlpx.md"},"The RLPx Transport Protocol"),". Ethereum.",(0,i.kt)("a",{parentName:"li",href:"#fnref-1",className:"footnote-backref"},"\u21a9")))))}c.isMDXComponent=!0},3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,a,i=function(e,t){if(null==e)return{};var n,a,i={},r=Object.keys(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=p(n),u=i,h=m["".concat(l,".").concat(u)]||m[u]||c[u]||r;return n?a.createElement(h,o(o({ref:t},d),{},{components:n})):a.createElement(h,o({ref:t},d))}));function u(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,o[1]=s;for(var p=2;p<r;p++)o[p]=n[p];return a.createElement.apply(null,o)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"}}]);