# Sync / PostBox
## Problem
Currently, there is no way to receive data between two hosts. In addition, the guild list is currently implemented in a way that is prone to error, as it requires clients to manually invoke `RemoveGuildFromGuildList` after the client leaves a guild. Having a way to send messages between hosts would allow the guild list to be automatically managed between hosts, and for DM invites to work across hosts.
## Solution
Provide an endpoint to post an event to a host, and additionally have a way to 'pull in' events from a target host in case the host was down and unable to receive events. This ensures that there is no loss of events if a host goes down.
## Implementation
When a host wants to send an event to another host, they will first try to call `PostEvent` on the remote host. `PostEvent` notifies a host of an event. If a `PostEvent` fails, the origin host will add the event to a queue of pending events.
When `PostEvent` is called, the host receiving the event needs to know what host it came from. The host sending the event must generate a random UUID of size 16, and sign it with its private key as a JWT. In the `PostEvent`, the `token` value will be set to the signed JWT, and the `host` value will be set to the hostname of the server.
The host receiving the `PostEvent` must send a `auth.v1.GetKey()` request to the `host` specified in the `PostEvent` to obtain the public key. If the public key successfully verifies the `token` specified in the request, then it is a valid request from that host.
When the public key is requested, it is cached and only invalidates if the cached public key does not verify a request correctly.
When a server starts, what it does first is check to see if any hosts it came in contact with has had any events using `Sync`. `Sync` will terminate when all events have been received on the stream.
When a host is receiving a `Sync` request, it has to perform the same authentication method which was described in `PostEvent` to know the correct host is requesting events.
Protobuf definition:
```protobuf
message SyncRequest {
string token = 1;
string host = 2;
}
message PostboxEvent { google.protobuf.Any event = 1; }
message PostEventRequest {
SyncRequest sync_request = 1;
PostBoxEvent event = 2;
}
service PostboxService {
rpc Sync(SyncRequest) returns (stream PostboxEvent) {}
rpc PostEvent(PostEventRequest) returns (google.protobuf.Empty) {}
}
```