/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */
syntax = "proto2";

package raft;

// This file describes the requirements the consensus algorithm.

// For Raft<Server>, Server::LogEntry must contain these fields.
message RaftConfigPb {
  repeated string node = 1;     // Nodes participating as the consensus.
  repeated string replica = 2;  // Replicas not participating in consensus.
  // Internal fields: set by the consensus algorithm.
  optional int64 term = 3;
  optional int64 index = 4;

  extensions 100 to max;
}

// For Raft<Server>, Server::LogEntry must contain these fields.
//
// PUBLIC
// The only fields which should be set by the user are:
//   'data' which can be used to store any user data.  It is otherwise unused.
//   'config' which can be set to propose a configuration change.
//   'index' should be set in response to GetLogEntry() either because the
//      entry has come from the log (where it was set by Raft) or for
//      summaries, by the user.
//   'extent' can be set for Propose() and summaries from GetLogEntry() to
//      indicate that the log covers a range of indexes.
//
// PRIVATE
//   There are 3 types of consensus log entries:
//      User: when !has_term(), the entry has come from the user:
//         * the initial configuration which was prepended to the log manually.
//         * summaries in a compressed log or from GetLogEntry().
//      Local: when !has_index(), the entry stores only internal state:
//         * the leader, vote and data_committed, config_committed fields.
//      Consensus: replicatable log entries which have been through consesus.
//         * User log entries are converted to Consensus log entries on ingest.
message RaftLogEntryPb {
  // External fields: set by the user.
  optional bytes data = 1;    // Available for user data.
  optional RaftConfigPb config = 2;
  optional int64 index = 3;   // Monotonic log entry index.
  optional int64 extent = 4;  // Indexes covered are [index, index + extent].
  // External/Internal fields: set by consensus, readable by user.
  optional int64 term = 5;    // When !has_term() directly from user.
  // Internal fields: set by the consensus algorithm, purely internal.
  optional int64 previous_log_term = 6;
  optional int64 previous_log_index = 7;
  // Local fields: set by consensus, only persisted on the local node.
  optional string leader = 8;
  optional int64 data_committed = 9;     // Index of committed data.
  optional int64 config_committed = 10;  // Index of committed config.
  optional string vote = 11;             // Vote in the term.

  extensions 100 to max;
}

// For Raft<Server>, Server::Message must contain these fields.
// PRIVATE
message RaftMessagePb {
  optional int64 term = 1;
  optional string from = 2;  // Node this message is from.
  optional string leader = 3;
  optional int64 data_committed = 4;
  optional int64 config_committed = 5;
  optional RaftLogEntryPb entry = 8;
  // Acknowledgement.
  optional bool nack = 9;  // Reset the stream to last_log_term/index.
  // Voting and acknowledgement.
  optional int64 last_log_term = 10;
  optional int64 last_log_index = 11;
  // Voting.
  optional string vote = 12;

  extensions 100 to max;
}
