Files
i2p.www/i2p2www/spec/proposals/150-garlic-farm-protocol.rst

297 lines
6.6 KiB
ReStructuredText
Raw Normal View History

2019-05-02 16:19:00 +00:00
====================
Garlic Farm Protocol
====================
.. meta::
:author: zzz
:created: 2019-05-03
:thread: http://zzz.i2p/topics/2234
:lastupdated: 2019-05-03
:status: Open
.. contents::
Overview
========
This is the spec for the Garlic Farm wire protocol,
2019-05-02 20:25:42 +00:00
based on JRaft, its "exts" code for implementation over TCP,
and its "dmprinter" sample application [JRAFT]_.
2019-05-02 16:19:00 +00:00
This will be the backend for coordination of routers publishing
entries in a Meta LeaseSet. See proposal 123.
Goals
=====
Design
======
Specification
=============
The wire protocol is over SSL sockets or non-SSL I2P sockets.
There is no support for clearnet non-SSL sockets.
TODO authentication. Perhaps new messages, or perhaps something before
the request/response phase happens.
There are two types of messages, requests and responses.
Message Types
-------------
2019-05-02 18:58:45 +00:00
======================== ====== =========== =========== =====================================
Message Number Sent By Sent To Notes
======================== ====== =========== =========== =====================================
RequestVoteRequest 1 Candidate Follower Standard Raft RPC
RequestVoteResponse 2 Follower Candidate Standard Raft RPC
AppendEntriesRequest 3 Leader Follower Standard Raft RPC
AppendEntriesResponse 4 Follower Leader Standard Raft RPC
ClientRequest 5 Follower Leader Response is AppendEntriesResponse
2019-05-02 20:25:42 +00:00
AddServerRequest 6 new server Leader Must contain only a single ClusterServer log entry
AddServerResponse 7 Leader new server
RemoveServerRequest 8 Follower Leader Must contain only a single ClusterServer log entry
2019-05-02 18:58:45 +00:00
RemoveServerResponse 9 Leader Follower
SyncLogRequest 10 Leader Follower
SyncLogResponse 11 Follower Leader
JoinClusterRequest 12 Leader new server Invitation to join
JoinClusterResponse 13 new server Leader
2019-05-02 20:25:42 +00:00
LeaveClusterRequest 14 Leader Follower Command to leave
2019-05-02 18:58:45 +00:00
LeaveClusterResponse 15 Follower Leader
2019-05-02 20:25:42 +00:00
InstallSnapshotRequest 16 Leader Follower Must contain only a single SnapshotSyncRequest log entry
2019-05-02 18:58:45 +00:00
InstallSnapshotResponse 17 Follower Leader Raft Section 7
======================== ====== =========== =========== =====================================
2019-05-02 16:19:00 +00:00
Definitions
-----------
- Source: Identifies the originator of the message
- Destination: Identifies the recipient of the message
2019-05-02 17:15:09 +00:00
- Terms: See Raft. Initialized to 0, increases monotonically
- Indexes: See Raft. Initialized to 0, increases monotonically
2019-05-02 16:19:00 +00:00
Requests
--------
Requests contain a header and zero or more log entries.
Request Header
``````````````
The request header is 45 bytes, as follows.
2019-05-02 18:58:45 +00:00
All values are unsigned big-endian.
2019-05-02 16:19:00 +00:00
.. raw:: html
{% highlight lang='dataspec' %}
Message type: 1 byte
Source: 4 byte integer
Destination: 4 byte integer
Term: 8 byte integer
Last Log Term: 8 byte integer
Last Log Index: 8 byte integer
Commit Index: 8 byte integer
2019-05-02 17:15:09 +00:00
Log size: In bytes, 4 byte integer
2019-05-02 20:25:42 +00:00
Log entries: see below
2019-05-02 16:19:00 +00:00
{% endhighlight %}
Log Entries
```````````
The log contains zero or more log entries.
Each log entry is as follows.
2019-05-02 18:58:45 +00:00
All values are unsigned big-endian.
2019-05-02 16:19:00 +00:00
.. raw:: html
{% highlight lang='dataspec' %}
Term: 8 byte integer
Value type: 1 byte
2019-05-02 18:58:45 +00:00
Entry size: In bytes, 4 byte integer
2019-05-02 16:19:00 +00:00
Entry: length as specified
{% endhighlight %}
2019-05-02 18:58:45 +00:00
Log Contents
````````````
All values are unsigned big-endian.
2019-05-02 17:15:09 +00:00
======================== ======
Log Value Type Number
======================== ======
Application 1
Configuration 2
ClusterServer 3
LogPack 4
SnapshotSyncRequest 5
======================== ======
2019-05-02 16:19:00 +00:00
2019-05-02 17:15:09 +00:00
Application
~~~~~~~~~~~
2019-05-02 16:19:00 +00:00
TBD, probably JSON.
2019-05-02 17:15:09 +00:00
Configuration
~~~~~~~~~~~~~
2019-05-02 17:33:44 +00:00
This is used for the leader to serialize a new cluster configuration and replicate to peers.
2019-05-02 20:25:42 +00:00
It contains zero or more ClusterServer configurations.
2019-05-02 17:33:44 +00:00
.. raw:: html
{% highlight lang='dataspec' %}
Log Index: 8 byte integer
Last Log Index: 8 byte integer
2019-05-02 20:25:42 +00:00
ClusterServer Data for each server:
2019-05-02 17:33:44 +00:00
ID: 4 byte integer
Endpoint data len: In bytes, 4 byte integer
2019-05-02 20:25:42 +00:00
Endpoint data: ASCII string of the form "tcp://localhost:9001", length as specified
2019-05-02 17:33:44 +00:00
{% endhighlight %}
2019-05-02 17:15:09 +00:00
2019-05-02 18:58:45 +00:00
2019-05-02 17:15:09 +00:00
ClusterServer
~~~~~~~~~~~~~
2019-05-02 17:33:44 +00:00
The configuration information for a server in a cluster.
2019-05-02 20:25:42 +00:00
When used in a AddServerRequest Message:
2019-05-02 17:33:44 +00:00
.. raw:: html
{% highlight lang='dataspec' %}
ID: 4 byte integer
Endpoint data len: In bytes, 4 byte integer
2019-05-02 20:25:42 +00:00
Endpoint data: ASCII string of the form "tcp://localhost:9001", length as specified
{% endhighlight %}
When used in a RemoveServerRequest Message:
.. raw:: html
{% highlight lang='dataspec' %}
ID: 4 byte integer
2019-05-02 17:33:44 +00:00
{% endhighlight %}
2019-05-02 17:15:09 +00:00
LogPack
~~~~~~~
2019-05-02 17:44:01 +00:00
The following is gzipped before transmission:
.. raw:: html
{% highlight lang='dataspec' %}
Index data len: In bytes, 4 byte integer
Log data len: In bytes, 4 byte integer
2019-05-02 20:25:42 +00:00
Index data: 8 bytes for each index, length as specified
Log data: length as specified
2019-05-02 17:44:01 +00:00
{% endhighlight %}
2019-05-02 17:15:09 +00:00
SnapshotSyncRequest
2019-05-02 17:44:01 +00:00
~~~~~~~~~~~~~~~~~~~
2019-05-02 17:15:09 +00:00
2019-05-02 17:33:44 +00:00
.. raw:: html
{% highlight lang='dataspec' %}
Message type: 1 byte
Last Log Index: 8 byte integer
Last Log Term: 8 byte integer
Config data len: In bytes, 4 byte integer
Config data: length as specified
2019-05-02 20:25:42 +00:00
Offset: The offset of the data in the database, in bytes, 8 byte integer
2019-05-02 17:33:44 +00:00
Data len: In bytes, 4 byte integer
Data: length as specified
Is Done: 1 if done, 0 if not done (1 byte)
{% endhighlight %}
2019-05-02 17:15:09 +00:00
2019-05-02 16:19:00 +00:00
Responses
---------
The response is 26 bytes, as follows.
2019-05-02 17:15:09 +00:00
All values are unsigned big-endian.
2019-05-02 16:19:00 +00:00
.. raw:: html
{% highlight lang='dataspec' %}
Message type: 1 byte
Source: 4 byte integer
Destination: 4 byte integer
Term: 8 byte integer
2019-05-02 17:15:09 +00:00
Next Index: Initialized to leader last log index + 1, 8 byte integer
Is Accepted: 1 if accepted, 0 if not accepted (1 byte)
2019-05-02 16:19:00 +00:00
{% endhighlight %}
Justification
=============
Atomix is too large and won't allow customization for us to route
the protocol over I2P. Also, its wire format is undocumented, and depends
on Java serialization.
Notes
=====
Issues
======
Migration
=========
No backward compatibility issues.
References
==========
.. [JRAFT]
https://github.com/datatechnology/jraft