diff --git a/discv5/discv5-rationale.md b/discv5/discv5-rationale.md index 95fad20..dcac08e 100644 --- a/discv5/discv5-rationale.md +++ b/discv5/discv5-rationale.md @@ -1,6 +1,6 @@ # Node Discovery Protocol v5 - Rationale -**Draft of August 2019** +**Draft of October 2019** Note that this specification is a work in progress and may change incompatibly without prior notice. @@ -342,24 +342,59 @@ disturb the operation of the protocol. Session keys per node-ID/IP generally pre replay across sessions. The `request-id`, mirrored in response packets, prevents replay of responses within a session. -## Security Considerations for the Topic Index +## The Topic Index -### Spamming with useless registrations +Using FINDNODE queries with appropriately chosen targets, the entire DHT can be sampled by +a random walk to find all other participants. When building a distributed application, it +is often desirable to restrict the search to participants which provide a certain service. +A simple solution to this problem would be to simply split up the network and require +participation in many smaller application-specific networks. However, such networks are +hard to bootstrap and also more vulnerable to attacks which could isolate nodes. + +The topic index provides discovery by provided service in a different way. Nodes maintain +a single node table tracking their neighbors and advertise 'topics' on nodes found by +randomly walking the DHT. While the 'global' topic index can be also spammed, it makes +complete isolation a lot harder. To prevent nodes interested in a certain topic from +finding each other, the entire discovery network would have to be overpowered. + +To make the index useful, searching for nodes by topic must be efficient regardless of the +number of advertisers. This is achieved by estimating the topic 'radius', i.e. the +percentage of all live nodes which are advertising the topic. Advertisement and search +activities are restricted to a region of DHT address space around the topic's 'center'. + +We also want the index to satisfy another property: When a topic advertisement is placed, +it should last for a well-defined amount of time. This ensures nodes may rely on their +advertisements staying placed rather than worrying about keeping them alive. + +Finally, the index should consume limited resources. Just as the node table is limited in +number and size of buckets, the size of the index data structure on each node is limited. + +### Why should advertisers wait? + +Advertisers must wait a certain amount of time before they can be registered. Enforcing +this time limit prevents misuse of the topic index because any topic must be important +enough to outweigh the cost of waiting. Imagine a group phone call: announcing the +participants of the call using topic advertisement isn't a good use of the system because +the topic exists only for a short time and will have very few participants. The waiting +time prevents using the index for this purpose because the call might already be over +before everyone could get registered. + +### Dealing with Topic Spam Our model is based on the following assumptions: -- Anyone can place their own advertisements under any topics and the rate of placing - registrations is not limited globally. The number of active registrations at any time is - roughly proportional to the resources (network bandwidth, mostly) spent on advertising. +- Anyone can place their own advertisements under any topics and the rate of placing ads + is not limited globally. The number of active ads for any node is roughly proportional + to the resources (network bandwidth, mostly) spent on advertising. - Honest actors whose purpose is to connect to other honest actors will spend an adequate - amount of efforts on registering and searching for registrations, depending on the rate - of newly established connections they are targeting. If the given topic is used only by - honest actors, a few registrations per minute will be satisfactory, regardless of the - size of the subnetwork. -- Dishonest actors may want to place an excessive amount of registrations just to disrupt - the discovery service. This will reduce the effectiveness of honest registration efforts - by increasing the topic radius and/or the waiting times. If the attacker(s) can place a - comparable amount or more registrations than all honest actors combined then the rate of + amount of efforts on registering and searching for ads, depending on the rate of newly + established connections they are targeting. If the given topic is used only by honest + actors, a few registrations per minute will be satisfactory, regardless of the size of + the subnetwork. +- Dishonest actors may want to place an excessive amount of ads just to disrupt the + discovery service. This will reduce the effectiveness of honest registration efforts by + increasing the topic radius and/or topic queue waiting times. If the attacker(s) can + place a comparable amount or more ads than all honest actors combined then the rate of new (useful) connections established throughout the network will reduce proportionally to the `honest / (dishonest + honest)` registration rates. @@ -371,33 +406,14 @@ honest actors is proportional to the square root of the attacker's efforts. ### Detecting a useless registration attack -In the case of a symmetrical protocol (where nodes are both searching and advertising -under the same topic) it is easy to detect when most of the queried registrations turn out -to be useless and increase both registration and query frequency. It is a bit harder but -still possible with asymmetrical (client-server) protocols, where only clients can easily -detect useless registrations, while advertisers (servers) do not have a direct way of -detecting when they should increase their advertising efforts. One possible solution is -for servers to also act as clients just to test the server capabilities of other -advertisers. It is also possible to implement a feedback system between trusted clients -and servers. - -### Amplifying network traffic by returning fake registrations - -An attacker might wish to direct discovery traffic to a chosen address by returning -records pointing to that address. - -**TBD: this is not solved.** - -### Not registering/returning valid registrations - -Although the limited registration frequency ensures that the resource requirements of -acting as a proper advertisement medium are sufficiently low, such selfish behavior is -possible, especially if some client implementations choose the easy way and not implement -it at all. This is not a serious problem as long as the majority of nodes are acting -properly, which will hopefully be the case. Advertisers can easily detect if their -registrations are not returned so it is probably possible to implement a mechanism to weed -out selfish nodes if necessary, but the design of such a mechanism is outside the scope of -this document. +In the case of a symmetrical protocol, where nodes are both searching and advertising +under the same topic, it is easy to detect when most of the found ads turn out to be +useless and increase both registration and query frequency. It is a bit harder but still +possible with asymmetrical (client-server) protocols, where only clients can easily detect +useless registrations, while advertisers (servers) do not have a direct way of detecting +when they should increase their advertising efforts. One possible solution is for servers +to also act as clients just to test the server capabilities of other advertisers. It is +also possible to implement a feedback system between trusted clients and servers. # References diff --git a/discv5/discv5-theory.md b/discv5/discv5-theory.md index 8af646f..4dad71f 100644 --- a/discv5/discv5-theory.md +++ b/discv5/discv5-theory.md @@ -1,6 +1,6 @@ # Node Discovery Protocol v5 - Theory -**Draft of August 2019.** +**Draft of October 2019.** Note that this specification is a work in progress and may change incompatibly without prior notice. @@ -26,7 +26,7 @@ used in place of the actual distance. logdistance(n₁, n₂) = log2(distance(n₁, n₂)) -## Maintaining The Local Record +## Maintaining The Local Node Record Participants should update their record, increase the sequence number and sign a new version of the record whenever their information changes. This is especially important for @@ -92,141 +92,199 @@ from the `k` closest nodes it has seen. ## Topic Advertisement -A node's provided services are identified by arbitrary strings called *topics*. Depending -on the needs of the application, a node can advertise multiple topics or no topics at all. -Every node participating in the discovery DHT acts as an advertisement medium, meaning -that it accepts topic registrations from advertising nodes and later returns them to nodes -searching for the same topic. - -The reason topic discovery is proposed in addition to application-specific networks is to -solve bootstrapping issues and improve downward scalability of subnetworks. Scalable -networks that have small subnetworks (and maybe even create new subnetworks automatically) -cannot afford to require a trusted bootnode for each of those subnets. Without a trusted -bootnode, small peer-to-peer networks are very hard to bootstrap and also more vulnerable -to attacks that could isolate nodes, especially the new ones which don't know any trusted -peers. Even though a global registry can also be spammed in order to make it harder to -find useful and honest peers, it makes complete isolation a lot harder because in order to -prevent the nodes of a small subnet from finding each other, the entire discovery network -would have to be overpowered. - -### Advertisement Storage - -Each node participating in the protocol stores ads for any number of topics and a limited -number of ads for each topic. The list of ads for a particular topic is called the *topic -queue* because it functions like a FIFO queue of limited length. There is also a global -limit on the number of ads regardless of the topic queue which contains them. When the -global limit is reached, the last entry of the least recently requested topic queue is -removed. - -For each topic queue, the advertisement medium maintains a *wait period*. This value acts -as a valve controlling the influx of new ads. Registrant nodes communicate interest to -register an ad and receive a *waiting ticket* which they can use to actually register -after the period has passed. Since regular communication among known nodes is required for -other purposes (e.g. node liveness checks), registrants re-learn the wait period values -automatically. - -The wait period for each queue is assigned based on the amount of sucessful registrations. -It is adjusted such that ads will stay in the topic queue for approximately 10 minutes. - -When an ad is added to the queue, the new wait period of the queue is computed as: - - target-ad-lifetime = 600 # how long ads stay queued (10 min) - target-registration-interval = target-ad-lifetime / queue-length - min-wait-period = 60 # (1 min) - control-loop-constant = 600 - - period = time-of-registration - time-of-previous-registration - new-wait-period = wait-period * exp((target-registration-interval - period) / control-loop-constant) - wait-period = max(new-wait-period, min-wait-period) +The topic advertisement subsystem indexes participants by their provided services. A +node's provided services are identified by arbitrary strings called 'topics'. A node +providing a certain service is said to 'place an ad' for itself when it makes itself +discoverable under that topic. Depending on the needs of the application, a node can +advertise multiple topics or no topics at all. Every node participating in the discovery +protocol acts as an advertisement medium, meaning that it accepts topic ads from other +nodes and later returns them to nodes searching for the same topic. + +### Topic Table + +Nodes store ads for any number of topics and a limited number of ads for each topic. The +data structure holding advertisements is called the 'topic table'. The list of ads for a +particular topic is called the 'topic queue' because it functions like a FIFO queue of +limited length. The image below depicts a topic table containing three queues. The queue +for topic `T₁` is at capacity. + +![topic table](./img/topic-queue-diagram.png) + +The queue size limit is implementation-defined. Implementations should place a global +limit on the number of ads in the topic table regardless of the topic queue which contains +them. Reasonable limits are 100 ads per queue and 50000 ads across all queues. Since ENRs +are at most 300 bytes in size, these limits ensure that a full topic table consumes +approximately 15MB of memory. + +Any node may appear at most once in any topic queue, that is, registration of a node which +is already registered for a given topic fails. Implementations may impose other +restrictions on the table, such as restrictions on the number of IP-addresses in a certain +range or number of occurrences of the same node across queues. + +### Tickets + +Ads should remain in the queue for a constant amount of time, the `target-ad-lifetime`. To +maintain this guarantee, new registrations are throttled and registrants must wait for a +certain amount of time before they are admitted. When a node attempts to place an ad, it +receives a 'ticket' which tells them how long they must wait before they will be accepted. +It is up to the registrant node to keep the ticket and present it to the advertisement +medium when the waiting time has elapsed. + +The waiting time constant is: + + target-ad-lifetime = 15min + +The assigned waiting time for any registration attempt is determined according to the +following rules: + +- When the table is full, the waiting time is assigned based on the lifetime of the oldest + ad across the whole table, i.e. the registrant must wait for a table slot to become + available. +- When the topic queue is full, the waiting time depends on the lifetime of the oldest ad + in the queue. The assigned time is `target-ad-lifetime - oldest-ad-lifetime` in this + case. +- Otherwise the ad may be placed immediately. + +Tickets are opaque objects storing arbitrary information determined by the issuing node. +While details of encoding and ticket validation are up to the implementation, tickets must +contain enough information to verify that: + +- The node attempting to use the ticket is the node which requested it. +- The ticket is valid for a single topic only. +- The ticket can only be used within the registration window. +- The ticket can't be used more than once. + +Implementations may choose to include arbitrary other information in the ticket, such as +the cumulative wait time spent by the advertiser. A practical way to handle tickets is to +encrypt and authenticate them with a dedicated secret key: + + ticket = aesgcm_encrypt(ticket-key, ticket-nonce, ticket-pt, '') + ticket-pt = [src-node-id, src-ip, topic, req-time, wait-time, cum-wait-time] + src-node-id = node ID that requested the ticket + src-ip = IP address that requested the ticket + topic = the topic that ticket is valid for + req-time = absolute time of REGTOPIC request + wait-time = waiting time assigned when ticket was created + cum-wait = cumulative waiting time of this node + +### Registration Window + +The image below depicts a single ticket's validity over time. When the ticket is issued, +the node keeping it must wait until the registration window opens. The length of the +registration window is 10 seconds. The ticket becomes invalid after the registration +window has passed. + +![ticket validity over time](./img/ticket-validity.png) + +Since all ticket waiting times are assigned to expire when a slot in the queue opens, the +advertisement medium may receive multiple valid tickets during the registration window and +must choose one of them to be admitted in the topic queue. The winning node is notified +using a [REGCONFIRMATION] response. + +Picking the winner can be achieved by keeping track of a single 'next ticket' per queue +during the registration window. Whenever a new ticket is submitted, first determine its +validity and compare it against the current 'next ticket' to determine which of the two is +better according to an implementation-defined metric such as the cumulative wait time +stored in the ticket. ### Advertisement Protocol -Let us assume that node `A` advertises itself under topic `T`. It selects node `C` as -advertisement medium and wants to register an ad, so that when node `B` (who is searching -for topic `T`) asks `C`, `C` can return the registration entry of `A` to `B`. +This section explains how the topic-related protocol messages are used to place an ad. -Node `A` first tells `C` that it wishes to register by requesting a ticket for topic `T`, -using the [REQTICKET] message. +Let us assume that node `A` provides topic `T`. It selects node `C` as advertisement +medium and wants to register an ad, so that when node `B` (who is searching for topic `T`) +asks `C`, `C` can return the registration entry of `A` to `B`. - A -> C REQTICKET +Node `A` first attempts to register without a ticket by sending [REGTOPIC] to `C`. -`C` replies with a ticket. The ticket contains the node identifier of `A`, the topic, a -serial number and wait period assigned by `C`. + A -> C REGTOPIC [T, ""] - A <- C TICKET +`C` replies with a ticket and waiting time. -Node `A` now waits for the duration of the wait period. When the wait is over, `A` sends a -registration request including the ticket. `C` does not need to remember its issued -tickets, just the serial number of the latest ticket accepted from `A` (after which it -will not accept any tickets issued earlier). + A <- C TICKET [ticket, wait-time] - A -> C REGTOPIC +Node `A` now waits for the duration of the waiting time. When the wait is over, `A` sends +another registration request including the ticket. `C` does not need to remember its +issued tickets since the ticket is authenticated and contains enough information for `C` +to determine its validity. -If the ticket was valid, Node `C` places `A` into the topic queue for `T`. The -[REGCONFIRMATION] response message signals whether `A` is registered. + A -> C REGTOPIC [T, ticket] - A <- C REGCONFIRMATION +Node `C` replies with another ticket. Node `A` must keep this ticket in place of the +earlier one, and must also be prepared to handle a confirmation call in case registration +was successful. -### Ad Placement And Topic Radius Detection + A <- C TICKET [ticket, wait-time] -When the number of nodes advertising a topic (topic size) is at least a certain percentage -of the whole discovery network (rough estimate: at least 1%), it is sufficient to select -random nodes to place ads and also look for ads at randomly selected nodes. In case of a -very high network size/topic size ratio, it helps to have a convention for selecting a -subset of nodes as potential advertisement media. This subset is defined as the nodes -whose Kademlia address is close to `keccak256(T)`, meaning that the binary XOR of the -address and the topic hash interpreted as a fixed point number is smaller than a given -*topic radius*. A radius of 1 means the entire network, in which case advertisements are -distributed uniformly. +Node `C` waits for the registration window to end on the queue and selects `A` as the node +which is registered. Node `C` places `A` into the topic queue for `T` and sends a +[REGCONFIRMATION] response. -Example: + A <- C REGCONFIRMATION [T] -- Nodes in the topic discovery network: 10000 -- Number of advertisers of topic T: 100 -- Registration frequency: 3 per minute -- Average registration lifetime: 10 minutes -- Average number of registrations of topic T at any moment: `3 * 10 * 100 = 3000` -- Expected number of registrations of T found at a randomly selected node (topic density) - assuming a topic radius of 1: 0.3 +### Ad Placement And Topic Radius -When the number of advertisers is smaller than 1% of the entire network, we want to -decrease the topic radius proportionally in order to keep the topic density at a -sufficiently high level. To achieve this, both advertisers and searchers should initially -try selecting nodes with an assumed topic radius of 1 and collect statistical data about -the density of registrations at the selected nodes. If the topic density in the currently -assumed topic radius is under the target level (0.3 in our example), the radius is -decreased. There is no point in decreasing the targeted node subset under the size of -approximately 100 nodes since in this case even a single advertiser can easily be found. -Approximating the density of nodes in a given address space is possible by calculating the -average distance between a randomly selected address and the address of the closest actual -node found. If the approximated number of nodes in our topic radius is under 100, we -increase the radius. +Since every node may act as an advertisement medium for any topic, advertisers and nodes +looking for ads must agree on a scheme by which ads for a topic are distributed. When the +number of nodes advertising a topic is at least a certain percentage of the whole +discovery network (rough estimate: at least 1%), ads may simply be placed on random nodes +because searching for the topic on randomly selected will locate the ads quickly enough. + +However, topic search should be fast even when the number of advertisers for a topic is +much smaller than the number of all live nodes. Advertisers and searchers must agree on a +subset of nodes to serve as advertisement media for the topic. This subset is simply a +region of node ID address space, consisting of nodes whose Kademlia address is within a +certain distance to the topic hash `sha256(T)`. This distance is called the 'topic +radius'. + +Example: for a topic `f3b2529e...` with a radius of 2^240, the subset covers all nodes +whose IDs have prefix `f3b2...`. A radius of 2^256 means the entire network, in which case +advertisements are distributed uniformly among all nodes. The diagram below depicts a +region of address space with the topic hash `t` in the middle and several nodes close to +`t` surrounding it. Dots above the nodes represent entries in the node's queue for the +topic. + +![diagram explaining the topic radius concept](./img/topic-radius-diagram.png) + +To place their ads, participants simply perform a random walk within the currently +estimated radius and run the advertisement protocol by collecting tickets from all nodes +encountered during the walk and using them when their waiting time is over. + +### Topic Radius Estimation + +Advertisers must estimate the topic radius continuously in order to place their ads on +nodes where they will be found. The radius mustn't fall below a certain size because +restricting registration to too few nodes leaves the topic vulnerable to censorship and +leads to long waiting times. If the radius were too large, searching nodes would take too +long to find the ads. + +Estimating the radius uses the waiting time as an indicator of how many other nodes are +attempting to place ads in a certain region. This is achieved by keeping track of the +average time to successful registration within segments of the address space surrounding +the topic hash. Advertisers initially assume the radius is 2^256, i.e. the entire network. +As tickets are collected, the advertiser samples the time it takes to place an ad in each +segment and adjusts the radius such that registration at the chosen distance takes +approximately `target-ad-lifetime / 2` to complete. ## Topic Search Finding nodes that provide a certain topic is a continuous process which reads the content -of topic queues inside the approximated topic radius. Nodes within the radius are -contacted with [TOPICQUERY] packets. Collecting tickets and waiting on them is not -required. The approximated topic radius value can be shared with the registration -algorithm if the the same topic is being registered and searched for. - -To find nodes, the searcher generates random node IDs inside the topic radius and performs -recursive Kademlia lookups on them. All (intermediate) nodes encountered during lookup are -asked for topic queue enties using the [TOPICQUERY] packet. - -Topic search is not meant to be the only mechanism used for selecting peers. A persistent -database of useful peers is also recommended, where the meaning of "useful" is -protocol-specific. Like any DHT algorithm, topic advertisement is based on the law of -large numbers. It is easy to spread junk in it at the cost of wasting some resources. -Creating a more trusted sub-network of peers over time prevents any such attack from -disrupting operation, removing incentives to waste resources on trying to do so. A -protocol-level recommendation-based trust system can be useful, the protocol may even have -its own network topology. +of topic queues inside the approximated topic radius. This is a much simpler process than +topic advertisement because collecting tickets and waiting on them is not required. + +To find nodes for a topic, the searcher generates random node IDs inside the estimated +topic radius and performs Kademlia lookups for these IDs. All (intermediate) nodes +encountered during lookup are asked for topic queue entries using the [TOPICQUERY] packet. + +Radius estimation for topic search is similar to the estimation procedure for +advertisement, but samples the average number of results from TOPICQUERY instead of +average time to registration. The radius estimation value can be shared with the +registration algorithm if the the same topic is being registered and searched for. [EIP-778]: https://eips.ethereum.org/EIPS/eip-778 [PING]: ./discv5-wire.md#ping-request-0x01 [PONG]: ./discv5-wire.md#pong-response-0x02 [FINDNODE]: ./discv5-wire.md#findnode-request-0x03 -[REQTICKET]: ./discv5-wire.md#reqticket-request-0x05 -[REGCONFIRMATION]: ./discv5-wire.md#regconfirmation-response-0x08 -[TOPICQUERY]: ./discv5-wire.md#topicquery-request-0x09 +[REGTOPIC]: ./discv5-wire.md#regtopic-request-0x05 +[REGCONFIRMATION]: ./discv5-wire.md#regconfirmation-response-0x07 +[TOPICQUERY]: ./discv5-wire.md#topicquery-request-0x08 diff --git a/discv5/discv5-wire.md b/discv5/discv5-wire.md index f4b8cd5..8f4eb76 100644 --- a/discv5/discv5-wire.md +++ b/discv5/discv5-wire.md @@ -1,6 +1,6 @@ # Node Discovery Protocol v5 - Wire Protocol -**Draft of August 2019.** +**Draft of October 2019.** This document specifies the wire protocol of Node Discovery v5. Note that this specification is a work in progress and may change incompatibly without prior notice. @@ -273,17 +273,21 @@ current record as the only result. NODES is the response to a FINDNODE or TOPICQUERY message. Multiple NODES messages may be sent as responses to a single query. -### REQTICKET Request (0x05) +### REGTOPIC Request (0x05) - message-data = [request-id, topic] - message-type = 0x05 - topic = a 32-byte topic hash + message-data = [request-id, ENR, ticket] + message-type = 0x07 + node-record = current node record of sender + ticket = byte array containing ticket content -Implementation note: The least requested topics will be evicted from the global space. -This means that an attacker attempting to pollute the global space by requesting creation -of many *new* topic queues will only result in their own topic queues being evicted. -Implementers should be cautious of the attacker attempting to promote their own queues by -requesting their own adverts. +REGTOPIC attempts to register the sender for the given topic. If the requesting node has a +ticket from a previous registration attempt, it must present the ticket. Otherwise +`ticket` is the empty byte array (RLP: `0x80`). The ticket must be valid and its waiting +time must have elapsed before using the ticket. + +REGTOPIC is always answered by a TICKET response. The requesting node may also receive a +REGCONFIRMATION response when registration is successful. It may take up to 10s for the +confirmation to be sent. ### TICKET Response (0x06) @@ -292,49 +296,32 @@ requesting their own adverts. ticket = an opaque byte array representing the ticket wait-time = time to wait before registering, in seconds -TICKET is the response to REQTICKET. It contains a ticket which can be used to register -for the requested topic after `wait-time` has elapsed. - -Note that `ticket` is opaque for the caller and shouldn't be interpreted in any way. -Implementations may choose any internal representation. A practical way to handle tickets -is to encrypt and authenticate them with a separate key. - - ticket = aesgcm_encrypt(ticket-key, ticket-nonce, ticket-pt, '') - ticket-pt = [src-node-id, topic, req-time, wait-time, serial] - src-node-id = node ID that requested the ticket - topic = the topic that ticket is valid for - req-time = absolute time of REQTICKET request - wait-time = waiting time assigned when ticket was created - serial = serial number of ticket +TICKET is the response to REGTOPIC. It contains a ticket which can be used to register for +the requested topic after `wait-time` has elapsed. See the [theory section on tickets] for +more information. -### REGTOPIC Request (0x07) +### REGCONFIRMATION Response (0x07) - message-data = [request-id, ticket, ENR] - message-type = 0x07 - ticket = supplied by TICKET response - node-record = current node record of sender - -REGTOPIC registers the sender for the given topic with a ticket. The ticket must be valid -and its waiting time must have elapsed before using the ticket. - -### REGCONFIRMATION Response (0x08) - - message-data = [request-id, registered] + message-data = [request-id, topic] message-type = 0x07 - registered = boolean, 1 if ticket was valid and node is registered, 0 if not + request-id = request-id of REGTOPIC -REGCONFIRMATION is the response to REGTOPIC. +REGCONFIRMATION notifies the recipient about a successful registration for the given +topic. This call is sent by the advertisement medium after the time window for +registration has elapsed on a topic queue. -### TOPICQUERY Request (0x09) +### TOPICQUERY Request (0x08) message-data = [request-id, topic] message-type = 0x07 topic = 32-byte topic hash -TOPICQUERY requests nodes in the [topic queue] of the given topic. The response is a NODES -message containing node records registered for the topic. +TOPICQUERY requests nodes in the [topic queue] of the given topic. The recipient of this +request must send one or more NODES messages containing node records registered for the +topic. [handshake section]: #handshake [encoding section]: #packet-encoding -[topic queue]: ./discv5-theory.md#advertisement-storage +[topic queue]: ./discv5-theory.md#topic-table +[theory section on tickets]: ./discv5-theory.md#tickets [EIP-778]: https://eips.ethereum.org/EIPS/eip-778 diff --git a/discv5/discv5.md b/discv5/discv5.md index bc53028..619012e 100644 --- a/discv5/discv5.md +++ b/discv5/discv5.md @@ -1,6 +1,6 @@ # Node Discovery Protocol v5 -**Draft of April 2019.** +**Draft of October 2019.** Welcome to the Node Discovery Protocol v5 specification! diff --git a/discv5/img/ticket-validity.png b/discv5/img/ticket-validity.png new file mode 100644 index 0000000..4e32a8f Binary files /dev/null and b/discv5/img/ticket-validity.png differ diff --git a/discv5/img/topic-queue-diagram.png b/discv5/img/topic-queue-diagram.png new file mode 100644 index 0000000..e34a1c5 Binary files /dev/null and b/discv5/img/topic-queue-diagram.png differ diff --git a/discv5/img/topic-radius-diagram.png b/discv5/img/topic-radius-diagram.png new file mode 100644 index 0000000..3a60e24 Binary files /dev/null and b/discv5/img/topic-radius-diagram.png differ