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
|