2020-02-27 17:52:12 +00:00
|
|
|
# multiprotocol: multiformat inspired self-describing protocol identifiers
|
2020-02-27 17:43:10 +00:00
|
|
|
|
2020-02-27 21:09:51 +00:00
|
|
|
@TODO MOVE TABLE TO VAC SPECIFIC REPO
|
|
|
|
|
2020-02-27 23:24:16 +00:00
|
|
|
This specification describes a simple method for nodes to describe the set of their capabilities.
|
|
|
|
The protocol is inspired by other [multiformats](https://multiformats.io/), it provides both human and machine-readable
|
|
|
|
representations.
|
2020-02-27 17:43:10 +00:00
|
|
|
|
2020-02-27 23:24:16 +00:00
|
|
|
The goal is to provide more granular identification for nodes beyond their connection information as provided by
|
2020-02-27 23:30:08 +00:00
|
|
|
[multiaddr](https://github.com/multiformats/multiaddr).
|
2020-02-27 17:43:10 +00:00
|
|
|
|
2020-02-27 23:30:08 +00:00
|
|
|
Multiprotocol is generic in that any protocol can adapt the `code`s used for their own protocol.
|
|
|
|
**A namespace is used to differentiate between protocols, this number should be arbitrary enough to not cause overlap**.
|
2020-02-27 17:43:10 +00:00
|
|
|
|
2020-02-27 23:24:16 +00:00
|
|
|
<!--
|
2020-02-27 17:43:10 +00:00
|
|
|
This repository contains the [multiprotocol definition](./multiprotocol.csv) used by [vac](https://vac.dev),
|
|
|
|
the [go implementation](https://github.com/vacp2p/go-multiprotocol) however is generic and therefore anyone can implement their own table.
|
2020-02-27 23:24:16 +00:00
|
|
|
-->
|
2020-02-27 17:43:10 +00:00
|
|
|
|
2020-02-27 23:24:16 +00:00
|
|
|
## Protocol Definitions
|
2020-02-27 17:43:10 +00:00
|
|
|
|
2020-02-27 23:24:16 +00:00
|
|
|
Protocol values are defined using a csv table, current implementations support this standard.
|
|
|
|
The CSV file MUST contain a header of the fields defined, these are `code`, `size`, `name` and `comment`.
|
|
|
|
Their values should be as follows:
|
2020-02-27 17:43:10 +00:00
|
|
|
|
|
|
|
| field | description |
|
2020-02-27 17:55:59 +00:00
|
|
|
| :---------: | :------------------------------------------------------------------------------------------------------------------------------ |
|
2020-02-27 17:43:10 +00:00
|
|
|
| **code** | This field contains the code identifying the key. |
|
|
|
|
| **size** | This field identifies the expected keys size, it can be any number or `V`, indicating that the value itself is length prefixed. |
|
|
|
|
| **name** | The human readable name of the field. |
|
|
|
|
| **comment** | Any developer related comments for the field. |
|
|
|
|
|
2020-02-27 23:24:16 +00:00
|
|
|
Below is an example valid csv table, the values in it will be used further in the examples within this document.
|
2020-02-27 17:43:10 +00:00
|
|
|
|
2020-02-27 23:24:16 +00:00
|
|
|
```csv
|
|
|
|
code, size, name, comment
|
|
|
|
42, 0, vac, namespace
|
|
|
|
2, V, waku,
|
|
|
|
3, V, store,
|
|
|
|
4, V, relay,
|
2020-02-27 17:43:10 +00:00
|
|
|
```
|
2020-02-27 23:24:16 +00:00
|
|
|
|
|
|
|
## Specification
|
|
|
|
|
2020-02-27 23:26:32 +00:00
|
|
|
A multiprotocol, like a multiaddr is a recursive (TLV)+ (type-length-value repeating) encoding,
|
|
|
|
except we add the addition of prefixes such as the `namespace`, `protocol` and `version`. It has two forms:
|
2020-02-27 23:24:16 +00:00
|
|
|
- a human-readable version to be used when printing to the user (UTF-8)
|
|
|
|
- a binary-packed version to be used in storage, transmissions on the wire, and as a primitive in other formats.
|
|
|
|
|
|
|
|
### Human-readable
|
|
|
|
|
|
|
|
Below is a psuedo regex of the encoding itself.
|
|
|
|
|
|
|
|
```regexp
|
2020-02-27 17:43:10 +00:00
|
|
|
/<namespace>/<protocol>/<version>(/<capability>/<version>|<capability>)+
|
|
|
|
```
|
|
|
|
|
2020-02-27 23:24:16 +00:00
|
|
|
- `namespace` - the namespace represents the protocol namespace. In our case this would be `vac`.
|
|
|
|
- `protocol` - the protocol represents the specific protocol we are identifying, in our case `waku`.
|
|
|
|
- `version` - the version represents the global protocol version, this can be any integer.
|
|
|
|
|
|
|
|
Next we have our repeating fields:
|
2020-02-27 23:29:03 +00:00
|
|
|
|
2020-02-27 23:24:16 +00:00
|
|
|
- `capability` - this represents a specific supported capability, for example `store` or `relay`.
|
|
|
|
- `version` - this field is not required, if the `size` for a specific capability is `0`, it represents the supported version,
|
|
|
|
this can either be latest or earliest, we leave this to implementers to decide.
|
|
|
|
|
|
|
|
Now, let's look at some human-readable examples:
|
2020-02-27 17:43:10 +00:00
|
|
|
|
|
|
|
```
|
|
|
|
/vac/waku/2
|
|
|
|
/vac/waku/2/relay/2
|
|
|
|
/vac/waku/2/store/1
|
|
|
|
```
|
|
|
|
|
2020-02-27 23:24:16 +00:00
|
|
|
### Machine-readable
|
|
|
|
|
|
|
|
@TODO
|
2020-02-27 17:43:10 +00:00
|
|
|
|
|
|
|
```
|
|
|
|
<namespace uvarint><protocol uvarint><version uvarint>(<protoCode uvarint><value []byte>)+
|
|
|
|
```
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
2020-02-27 17:48:36 +00:00
|
|
|
```python
|
|
|
|
0x2a 0x2 0x1 0x32 # /vac/waku/2
|
|
|
|
0x2a 0x2 0x1 0x32 0x4 0x1 0x32 # /vac/waku/2/relay/2
|
|
|
|
0x2a 0x2 0x1 0x32 0x3 0x1 0x32 # /vac/waku/2/store/1
|
2020-02-27 17:43:10 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
With multiaddr:
|
|
|
|
|
|
|
|
```
|
|
|
|
/ip4/127.0.0.1/tcp/9000/vac/waku/0.2/relay/0.2
|
2020-02-27 17:48:36 +00:00
|
|
|
```
|
2020-02-27 23:24:16 +00:00
|
|
|
## Implementations
|
|
|
|
- [go-multiprotocol](https://github.com/vacp2p/go-multiprotocol)
|