libertaria-stack/core/l2_session/state.zig

133 lines
3.3 KiB
Zig

//! State machine definitions for L2 sessions
//!
//! States represent the lifecycle of a peer relationship.
const std = @import("std");
/// Session states
///
/// See SPEC.md for full state diagram and transition rules.
pub const State = enum {
/// Initial state
idle,
/// Handshake initiated, awaiting response
handshake_initiated,
/// Handshake received, preparing response
handshake_received,
/// Active, healthy session
established,
/// Connectivity issues detected
degraded,
/// Key rotation in progress
rotating,
/// Extended failure, pending cleanup or retry
suspended,
/// Terminal failure state
failed,
/// Check if this state allows sending messages
pub fn canSend(self: State) bool {
return switch (self) {
.established, .degraded, .rotating => true,
else => false,
};
}
/// Check if this state allows receiving messages
pub fn canReceive(self: State) bool {
return switch (self) {
.established, .degraded, .rotating, .handshake_received => true,
else => false,
};
}
/// Check if this is a terminal state
pub fn isTerminal(self: State) bool {
return switch (self) {
.suspended, .failed => true,
else => false,
};
}
};
/// State transition events
pub const Event = enum {
initiate_handshake,
receive_handshake,
receive_response,
send_response,
receive_ack,
heartbeat_ok,
heartbeat_missed,
timeout,
connectivity_restored,
time_to_rotate,
rotation_complete,
rotation_timeout,
invalid_signature,
cleanup,
retry,
};
/// Attempt state transition
/// Returns new state or null if transition is invalid
pub fn transition(current: State, event: Event) ?State {
return switch (current) {
.idle => switch (event) {
.initiate_handshake => .handshake_initiated,
.receive_handshake => .handshake_received,
else => null,
},
.handshake_initiated => switch (event) {
.receive_response => .established,
.timeout => .failed,
.invalid_signature => .failed,
else => null,
},
.handshake_received => switch (event) {
.send_response => .established,
.timeout => .failed,
else => null,
},
.established => switch (event) {
.heartbeat_missed => .degraded,
.time_to_rotate => .rotating,
else => null,
},
.degraded => switch (event) {
.connectivity_restored => .established,
.timeout => .suspended,
else => null,
},
.rotating => switch (event) {
.rotation_complete => .established,
.rotation_timeout => .failed,
else => null,
},
.suspended => switch (event) {
.cleanup => null, // Terminal
.retry => .handshake_initiated,
else => null,
},
.failed => switch (event) {
.cleanup => null, // Terminal
.retry => .handshake_initiated,
else => null,
},
};
}