moonbitstack/moonraft/raftpb does not have a README file

    AppendEntriesArgs

    pub(all) struct AppendEntriesArgs {
    term : UInt64
    leader_id : String
    prev_log_index : UInt64
    prev_log_term : UInt64
    entries : Array[Entry]
    leader_commit : UInt64
    } derive(Eq)

    Arguments for the AppendEntries RPC (Raft §5.3), used by the leader both to replicate log entries and, with an empty entries, as a heartbeat.

    AppendEntriesReply

    pub(all) struct AppendEntriesReply {
    term : UInt64
    success : Bool
    match_index : UInt64
    conflict_index : UInt64
    conflict_term : UInt64
    reject_index : UInt64
    } derive(Eq)

    Reply to an AppendEntries RPC. success is true when the follower's log contained a matching entry at prev_log_index and the entries were stored. On success match_index is the highest index the follower now agrees on, so the leader can advance its progress without guessing. On rejection conflict_index is a hint at where the two logs diverge, letting the leader back off in one jump instead of decrementing nextIndex one entry at a time (the optimization sketched in Raft §5.3).

    ConfState

    pub(all) struct ConfState {
    voters : Array[String]
    learners : Array[String]
    voters_outgoing : Array[String]
    learners_next : Array[String]
    auto_leave : Bool
    } derive(Eq)

    A membership snapshot as carried by a Raft snapshot (etcd's ConfState).

    ConfState::empty

    fn ConfState::empty() -> ConfState

    The empty membership state, carried by a snapshot with no recorded configuration (a fresh node, or one written before ConfState existed).

    ConfState::equivalent

    fn ConfState::equivalent(self : ConfState, other : ConfState) -> Bool

    Whether two ConfStates describe the same configuration (etcd's ConfState.Equivalent): the four id lists match as sets (order- and nil/empty-insensitive) and the auto-leave flags agree.

    ConfState::is_empty

    fn ConfState::is_empty(self : ConfState) -> Bool

    Whether this conf state records no membership at all.

    Entry

    pub(all) struct Entry {
    term : UInt64
    index : UInt64
    entry_type : EntryType
    command : Bytes
    } derive(Eq)

    One command entry in the replicated log.

    term is the leader's term — a monotonically increasing logical clock — at the moment the entry was created. index is the entry's 1-based position in the log; index 0 is the empty position before the first entry. entry_type tells the apply loop whether command is an application command or a membership change. command is the opaque payload handed to the state machine (or membership decoder) once the entry is committed.

    Entry::conf

    fn Entry::conf(term : UInt64, index : UInt64, command : Bytes) -> Entry

    Build a configuration-change entry.

    Entry::id

    fn Entry::id(self : Entry) -> EntryId

    The identity (term, index) of this entry.

    Entry::is_conf_change

    fn Entry::is_conf_change(self : Entry) -> Bool

    Whether this entry carries a membership change.

    Entry::normal

    fn Entry::normal(term : UInt64, index : UInt64, command : Bytes) -> Entry

    Build a normal application entry.

    EntryId

    pub(all) struct EntryId {
    term : UInt64
    index : UInt64
    } derive(Eq)

    Uniquely identifies a log entry by the term that first appended it and its index. There is only ever one leader per term and a leader never issues two entries at the same index, so (term, index) pins an entry down. Mirrors etcd's entryID.

    EntryType

    pub(all) enum EntryType {
    Normal
    ConfChange
    } derive(Eq)

    What a log entry carries. A Normal entry holds an opaque state-machine command; a ConfChange entry holds a serialized membership change that the consensus layer applies to the cluster configuration once the entry is committed (Raft §6). Keeping the kind on the entry lets the apply loop route each committed entry to the right place.

    HardState

    pub(all) struct HardState {
    term : UInt64
    vote : String?
    commit : UInt64
    } derive(Eq)

    The small piece of durable state Raft must flush before answering any RPC: the current term, the vote cast in that term, and the commit index. etcd calls this the HardState; persisting it is what lets a node rejoin without violating the election-safety or state-machine-safety properties (§5.3).

    HardState::initial

    fn HardState::initial() -> HardState

    The HardState a fresh node starts from: term 0, no vote, nothing committed.

    HardState::is_empty

    fn HardState::is_empty(self : HardState) -> Bool

    Whether a HardState is the zero value (etcd's IsEmptyHardState): a fresh node that has neither voted nor committed anything has nothing to persist.

    HeartbeatArgs

    pub(all) struct HeartbeatArgs {
    term : UInt64
    leader_id : String
    commit : UInt64
    context : Bytes
    } derive(Eq)

    Arguments for the Heartbeat RPC (Raft §5.2): a leader's periodic liveness beat. It carries no entries — only the leader's commit index (capped at what the follower is known to hold) so a follower can advance its commit index between AppendEntries. Modelling it as a distinct message (rather than an empty AppendEntries) lets the leader treat a heartbeat acknowledgement as pure liveness, separate from log-matching.

    HeartbeatReply

    pub(all) struct HeartbeatReply {
    term : UInt64
    context : Bytes
    } derive(Eq)

    Reply to a Heartbeat RPC: the follower's term and the read-index context it is acknowledging (echoed verbatim).

    InstallSnapshotArgs

    pub(all) struct InstallSnapshotArgs {
    term : UInt64
    leader_id : String
    last_index : UInt64
    last_term : UInt64
    offset : UInt64
    data : Bytes
    done : Bool
    conf_state : ConfState
    } derive(Eq)

    Arguments for the InstallSnapshot RPC (Raft §7). A leader sends this when a follower has fallen so far behind that the entries it needs have already been compacted away. The whole state-machine image up to last_index is shipped in data; real deployments chunk it, which the offset/done pair leaves room for.

    InstallSnapshotArgs::whole

    fn InstallSnapshotArgs::whole(term : UInt64, leader_id : String, snapshot : Snapshot) -> InstallSnapshotArgs

    Build InstallSnapshot arguments that carry a whole snapshot in one message (offset 0, done true), the common case for an in-memory transport.

    InstallSnapshotReply

    pub(all) struct InstallSnapshotReply {
    term : UInt64
    } derive(Eq)

    Reply to an InstallSnapshot RPC. term lets a stale leader discover it has been superseded.

    Message

    pub(all) struct Message {
    from : String
    to : String
    payload : Payload
    force : Bool
    }

    A routed message: a payload with the ids of the sender and intended recipient. The step function consumes these and produces more of them; a transport (real or simulated) is only responsible for delivery.

    Message::is_response

    fn Message::is_response(self : Message) -> Bool

    Whether this message is a response rather than a request. The simulator uses it only for readable traces.

    Message::kind

    fn Message::kind(self : Message) -> String

    A short, stable tag for the payload kind, for logs and scenario traces.

    Message::new

    fn Message::new(from : String, to : String, payload : Payload, force? : Bool) -> Message

    Build a routed message. force is set only for leadership-transfer votes.

    Message::term

    fn Message::term(self : Message) -> UInt64

    The term the message was stamped with. Every payload carries the sender's term; a receiver uses it to decide whether to step down or reject.

    Payload

    pub(all) enum Payload {
    PreVote(RequestVoteArgs)
    PreVoteResp(RequestVoteReply)
    Vote(RequestVoteArgs)
    VoteResp(RequestVoteReply)
    Append(AppendEntriesArgs)
    AppendResp(AppendEntriesReply)
    Heartbeat(HeartbeatArgs)
    HeartbeatResp(HeartbeatReply)
    Snapshot(InstallSnapshotArgs)
    TimeoutNow(UInt64)
    Propose(Array[Entry])
    ReadIndex(Bytes)
    ReadIndexResp(ReadIndexResp)
    TransferLeader(String)
    ForgetLeader
    }

    The body of a message exchanged between nodes. A heartbeat is modelled as an Append with no entries, so the same replication path carries both. Keeping every request paired with its response in one enum lets a transport move Raft traffic without knowing what any particular message means.

    Payload::is_local

    fn Payload::is_local(self : Payload) -> Bool

    etcd classifies a handful of message types as node-local — MsgHup, MsgBeat, MsgSnapStatus, MsgCheckQuorum and the storage-thread messages — which never travel over the transport. This port has no such messages: those triggers are direct method calls (tick / campaign / step), not Payloads. Every transportable Payload is therefore, by construction, a network message.

    ReadIndexResp

    pub(all) struct ReadIndexResp {
    term : UInt64
    index : UInt64
    context : Bytes
    } derive(Eq)

    The leader's answer to a forwarded ReadIndex (etcd's MsgReadIndexResp): the commit index the read is anchored at, echoed back with the caller's context to the server that originated the read. Unlike the request it carries the leader's term, so it is term-checked like any other reply.

    RequestVoteArgs

    pub(all) struct RequestVoteArgs {
    term : UInt64
    candidate_id : String
    last_log_index : UInt64
    last_log_term : UInt64
    } derive(Eq)

    Arguments for the RequestVote RPC (Raft §5.2), sent by a candidate to gather votes for the term it is standing in.

    RequestVoteReply

    pub(all) struct RequestVoteReply {
    term : UInt64
    vote_granted : Bool
    } derive(Eq)

    Reply to a RequestVote RPC. term lets a stale candidate discover it has been superseded; vote_granted is true when the vote was given.

    Snapshot

    pub(all) struct Snapshot {
    last_index : UInt64
    last_term : UInt64
    data : Bytes
    conf_state : ConfState
    } derive(Eq)

    A point-in-time snapshot of the state machine that stands in for the log prefix up to and including last_index. Raft uses snapshots to bound log growth and to bring a badly lagging follower up to date in one shot (§7).

    Snapshot::empty

    fn Snapshot::empty() -> Snapshot

    The empty snapshot: no state captured, baseline at index 0.

    Snapshot::is_empty

    fn Snapshot::is_empty(self : Snapshot) -> Bool

    Whether this snapshot actually captures any state. A baseline index of 0 is the empty snapshot a fresh node starts with.

    entry_encoding_size

    fn entry_encoding_size(e : Entry) -> UInt64

    The protobuf wire size of one entry, following etcd's proto.Size: each non-zero field costs a tag byte plus its varint/length-delimited encoding. Only the byte total matters — it is what limit_size and Storage.Entries budget against.

    ents_size

    fn ents_size(entries : ArrayView[Entry]) -> UInt64

    The total encoding size of a run of entries.

    hard_state_equal

    fn hard_state_equal(a : HardState, b : HardState) -> Bool

    Whether two hard states are equal in all three durable fields — term, vote, and commit (etcd's isHardStateEqual). This is the test that keeps a Ready from carrying a redundant HardState when nothing durable has moved.

    limit_size

    fn limit_size(entries : ArrayView[Entry], max_size : UInt64) -> Array[Entry]

    The longest prefix of entries whose total encoding size does not exceed max_size. Always returns at least one entry when the input is non-empty — so a single oversized entry is still returned — matching etcd's limitSize.

    no_limit

    let no_limit : UInt64

    The sentinel used for an unbounded size cap: no entries/slice request is ever limited by size. Mirrors etcd's noLimit = math.MaxUint64.

    payload_size

    fn payload_size(e : Entry) -> UInt64

    The size of an entry's payload: its command bytes only, independent of term and index. Empty-payload entries (like the no-op a new leader appends) are zero size, so they do not count against the uncommitted-log quota. Mirrors etcd's payloadSize.

    payloads_size

    fn payloads_size(entries : ArrayView[Entry]) -> UInt64

    The total payload size of a run of entries (etcd's payloadsSize).