BEP:50
Title:Publish/Subscribe Protocol
Version: 8c4c48d9d89124fef2e28e8d2efb79b0cef83943
Last-Modified:Sun Oct 2 21:25:19 2016 -0700
Author: Steven Siloti <ssiloti@gmail.com>
Status: Draft
Type:Standards Track
Content-Type:text/x-rst
Created:27-Aug-2016
Post-History:

Abstract

This BEP defines a modification of the DHT protocol [1] to provide a topic based publish/subscribe service rather than a key/value store. Each topic is associated with a mutable item [2]. Messages are published as new values for the mutable item. A separate overlay network is maintained for each topic.

Rationale

BEP 46 [3] defines a standard format for publishing a torrent which can later be updated by its publisher using a mutable item. A downside of this method is that it relies on polling the DHT to receive updates. The DHT must be polled at a relatively low rate to avoid putting excessive load on the network. This limitation means there may be a significant delay between an update being published and a client receiving it. This BEP aims to provide a means of propagating updates with minimal delay by using push messages rather than polling.

Protocol

The pub/sub protocol is based on the DHT protocol [1] with the following modifications:

The value of K is set to one.

The routing table's home bucket and its sibling SHOULD have a capacity of at least 8 nodes each. When the home bucket is split the sibling of the previous home bucket (now an uncle of the new home bucket) SHOULD be resized to one node per the setting of K=1.

All messages MUST contain a key c with a 20-byte string value. The value is used to identify which topic the message is intended for. The value MUST be set to the target hash of the mutable item associated with the topic.

The get_peers and announce_peer queries are prohibited.

Mutable get and put queries [2] are only permitted for the mutable item associated with the topic.

If a put query contains a valid update it SHOULD be forwarded to all nodes in the routing table for the topic. An update is valid if the query is valid per BEP 44 [2] and the value has a sequence number greater than the client's currently stored value. The query SHOULD be forwarded by generating new queries as if the client originated the request.

Example Transaction

A get request on a topic network would look like:

{
    "a":
    {
        "id": <20 byte id of sending node (string)>,
        "seq": <optional sequence number (integer)>,
        "target": <20 byte SHA-1 hash of public key and salt (string)>
    },
    "c": <20 byte SHA-1 hash of public key and salt (string)>,
    "t": <transaction-id (string)>,
    "y": "q",
    "q": "get"
}

The seq key SHOULD always be included in get requests unless the node is joining the topic and doesn't have a value for the item yet. The response:

{
    "c": <20 byte SHA-1 hash of public key and salt (string)>,
    "r":
    {
        "id": <20 byte id of sending node (string)>,
        "nodes": <IPv4 nodes close to 'target'>,
        "seq": <monotonically increasing sequence number (integer)>,
        "token": <write-token (string)>
    },
    "t": <transaction-id (string)>,
    "y": "r"
}

Here we're assuming the requester included the seq key and the responder did not have a newer value so it was omitted from the response.

Subscribing to topics

Clients subscribe to a topic by joining that topic's overlay network. Clients bootstrap into a network by sending a get_peers query to the DHT with the info_hash field set to the target hash of the mutable item associated with the topic. Clients SHOULD also announce themselves to this infohash with the port they are listening for DHT messages on. Clients MUST treat each topic as a separate node with its own routing table and transaction state. Nodes for different topics with the same listen address SHOULD use the same node id. Clients SHOULD store the latest value of the mutable item associated with the topic at all times.

Publishing messages

A client which intends to publish messages to a topic SHOULD also subscribe to the topic. When a new message is generated it SHOULD be sent to all peers in the client's routing table for the topic. Clients SHOULD NOT attempt to send a new value to all nodes subscribed to the topic.

References

[1](1, 2) BEP_0005. DHT Protocol. (http://www.bittorrent.org/beps/bep_0005.html)
[2](1, 2, 3) BEP_0044. Storing arbitrary data in the DHT. (http://www.bittorrent.org/beps/bep_0044.html)
[3]BEP_0046. Updating Torrents Via DHT Mutable Items. (http://www.bittorrent.org/beps/bep_0046.html)