// Copyright 2020 nytopop (Eric Izoita)
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
syntax = "proto2";
package blip;
// The interface that a node running the blip protocol should expose.
service Membership {
rpc PreJoin(PreJoinReq) returns (PreJoinResp);
rpc Join(JoinReq) returns (JoinResp);
rpc BatchedAlert(BatchedAlertReq) returns (Ack);
rpc FastAccepted(FastAcceptedReq) returns (Ack);
rpc Prepare(PrepareReq) returns (Ack);
rpc Promise(PromiseReq) returns (Ack);
rpc Accept(AcceptReq) returns (Ack);
rpc Accepted(AcceptedReq) returns (Ack);
rpc Broadcast(BroadcastReq) returns (Ack);
rpc Probe(Ack) returns (Ack);
}
// A listening address.
message Endpoint {
// An ip address in binary form. Exactly 4 or 16 bytes long.
required bytes host = 1;
// Port number. Is 0xffff or smaller.
required uint32 port = 2;
// Whether tls is enabled.
required bool tls = 3;
}
// A 128 bit unique identifier.
message NodeId {
// The high bits.
required uint64 high = 1;
// The low bits.
required uint64 low = 2;
}
// Metadata exposed by a node during the join protocol.
//
// Should be populated sparingly, as it will be propagated by various messages
// and stored in each node's configuration.
message Metadata {
// Any keys exposed by the node.
map<string, bytes> keys = 1;
}
// A listening address, as well as any metadata associated with the node that
// address refers to.
message NodeMetadata {
// A listening address.
required Endpoint node = 1;
// The node's metadata.
required Metadata meta = 2;
}
// An acknowledgement of receipt, used as a response for rpcs that don't convey
// any information other than that they succeeded.
message Ack {}
// A phase 1 join request, sent by nodes seeking to join a cluster.
message PreJoinReq {
// The address with which the sender expects to be referred to.
required Endpoint sender = 1;
// A unique uuid for the sender.
required NodeId uuid = 2;
}
// A phase 1 join response.
message PreJoinResp {
// The address with which the sender expects to be referred to.
required Endpoint sender = 1;
// The configuration that will be joined.
required uint64 conf_id = 2;
// A list of observers to contact for phase 2 of the join protocol.
repeated Endpoint contact = 3;
}
// A phase 2 join request, sent to each observer in a phase 1 join response.
message JoinReq {
// The address with which the sender expects to be referred to.
required Endpoint sender = 1;
// The ring number sender expects us to observe them at.
required uint64 ring = 2;
// A unique uuid for the sender.
required NodeId uuid = 3;
// The configuration sender is trying to join.
required uint64 conf_id = 4;
// Any metadata that sender wants to expose.
required Metadata meta = 5;
}
// A phase 2 join response.
message JoinResp {
// The address with which the sender expects to be referred to.
required Endpoint sender = 1;
// The updated configuration (which requester is now part of).
required uint64 conf_id = 2;
// All nodes/metadata in the new configuration.
repeated NodeMetadata nodes = 3;
// All uuids in the new configuration.
repeated NodeId uuids = 4;
}
// A batch of edge alerts.
message BatchedAlertReq {
// The address with which the sender expects to be referred to.
required Endpoint sender = 1;
// The configuration this batch refers to (which sender is a part of).
required uint64 conf_id = 2;
// The edge alerts.
repeated Edge edges = 3;
}
// An alert about some edge between an observer and subject changing state.
message Edge {
// The subject node this alert refers to.
required Endpoint node = 1;
// The ring on which sender is the observer of node.
required uint64 ring = 2;
// Additional information about node. If set, this alert indicates that
// node is attempting to join the cluster. Otherwise, somebody is trying
// to eject node from the cluster.
optional Join join = 3;
}
// Additional information about a joining node.
message Join {
// The node's unique identifier.
required NodeId uuid = 1;
// The node's exposed metadata.
required Metadata meta = 2;
}
message FastAcceptedReq {
required Endpoint sender = 1;
required uint64 conf_id = 2;
repeated Endpoint nodes = 3;
}
message Rank {
required uint32 round = 1;
required uint64 node_idx = 2;
}
message PrepareReq {
required Endpoint sender = 1;
required uint64 conf_id = 2;
required Rank rank = 3;
}
message PromiseReq {
required Endpoint sender = 1;
required uint64 conf_id = 2;
required Rank rnd = 3;
required Rank vrnd = 4;
repeated Endpoint vval = 5;
}
message AcceptReq {
required Endpoint sender = 1;
required uint64 conf_id = 2;
required Rank rnd = 3;
repeated Endpoint vval = 4;
}
message AcceptedReq {
required Endpoint sender = 1;
required uint64 conf_id = 2;
required Rank rnd = 3;
repeated Endpoint nodes = 4;
}
// A request to broadcast some message.
message BroadcastReq {
// Unix timestamp generated by the message originator, in seconds since
// the unix epoch.
required uint64 unix = 1;
// A unique identifier for the message. Receivers of broadcast requests
// should ignore any requests if this id has already been seen.
required uint64 uniq = 2;
// The message to be broadcast.
oneof broadcasted {
BatchedAlertReq BatchedAlert = 3;
FastAcceptedReq FastAccepted = 4;
PrepareReq Prepare = 5;
PromiseReq Promise = 6;
AcceptReq Accept = 7;
AcceptedReq Accepted = 8;
}
}