Models
Immutable value types returned across the public API.
Every result object is frozen and slotted: a value handed to an application is owned by that application and never mutates underneath it. This mirrors the core's own discipline, where a host copies a borrowed effect value out of the ledger before the node's next transition invalidates the pointer.
Slot
Slot = int
A one-based position in the global decree log. Zero means "no slot".
NodeId
NodeId = int
A stable, non-zero identity for one member. Zero is reserved as a sentinel.
Message
Message = (
Prepare
| Promise
| PromiseRange
| Accept
| Accepted
| Commit
| Learn
| Nack
| Heartbeat
)
One of the nine protocol messages. Match on the class, not on a tag.
Example
from paxodin import Accept, Commit def describe(message: Message) -> str: ... match message: ... case Accept(slot=slot): ... return f"vote requested for slot {slot}" ... case Commit(slot=slot): ... return f"slot {slot} decided" ... case _: ... return type(message).name
EntryKind
Bases: IntEnum
What a log entry actually is.
The distinction is load bearing. An application that treated all three as opaque bytes would apply a recovery filler as if it were a command, and mistake a reconfiguration for data.
COMMAND
class-attribute
instance-attribute
COMMAND = 1
An application command. Its payload may legitimately be empty.
NOOP
class-attribute
instance-attribute
NOOP = 2
A filler a leader chose into a hole during recovery. Never a command.
STOP_SIGN
class-attribute
instance-attribute
STOP_SIGN = 3
A sealing reconfiguration record, not application data.
WriteKind
Bases: IntEnum
Which durable record the host must journal.
MessageKind
Bases: IntEnum
Which protocol message an envelope carries.
Role
Bases: IntEnum
Proposer status. A follower still acts as acceptor and learner.
CellState
Bases: IntEnum
What an acceptor holds for one decree.
BatchPhase
Bases: IntEnum
Where a pending batch has got to.
A batch with no writes is born CONFIRMED: there is nothing to persist, so
requiring a confirmation would assert a durability fact about no records.
NodeOptions
Bases: TypedDict
Tuning for one participant, at the level of the effect machine.
Timers here are counted in logical ticks, because that is how the engine
counts them and Node does not own a clock. :class:paxodin.Session
takes seconds instead and converts. Zero selects the default for everything.
SessionOptions
Bases: TypedDict
Tuning for a session, in seconds.
These are the same knobs as :class:NodeOptions with the engine's tick unit
converted away: a developer reasons about how long failover takes, not how
many ticks it is.
Profile
dataclass
The capacities the loaded native library was compiled with.
The Odin core is fully parametric, but a shared library fixes its capacities at compile time because values are stored inline in the ledger. A profile therefore describes this build, not a limit of the algorithm.
Attributes:
| Name | Type | Description |
|---|---|---|
max_members |
int
|
Largest voting membership this build accepts. |
window_slots |
int
|
Size of the sliding decree window. Always a power of two. |
chunk_slots |
int
|
Recovery chunk size, and the largest proposal batch. |
max_value_bytes |
int
|
Largest command payload this build accepts. |
max_metadata_bytes |
int
|
Largest reconfiguration metadata blob. |
gate_enforced |
bool
|
True for the test-only library that compiles the core's own durability gate in, where a violation ends the process. |
node_bytes |
int
|
Measured static footprint of one node. |
effects_bytes |
int
|
Measured static footprint of one effects batch. |
max_writes_per_batch |
int
|
Most durable records one transition can produce. |
max_messages_per_batch |
int
|
Most envelopes one transition can produce. |
max_committed_per_batch |
int
|
Most entries one transition can release. |
max_requests_per_batch |
int
|
Most host requests one transition can produce. |
capabilities |
int
|
Bitmask of optional features this build supports. |
fingerprint |
int
|
Identifies this profile in journal headers and handshakes, so a mismatch is caught before a node reads foreign state. |
StopSign
dataclass
A sealing record that ends one configuration and names the next.
LogEntry
dataclass
One decoded log entry.
Attributes:
| Name | Type | Description |
|---|---|---|
kind |
EntryKind
|
Which of the three things this entry is. |
body |
bytes
|
The command payload. Empty for a no-op or a stop sign, and also
legitimately empty for a command that carried no bytes -- read
|
stop_sign |
StopSign | None
|
The sealing record when |
is_command
property
is_command: bool
True when this entry is application data the caller submitted.
Committed
dataclass
One entry released to the application, contiguous with everything before.
Release is not application: receiving this means the participant knows the decision in order, not that the application has acted on it.
WriteRecord
dataclass
One durable record the host must append, in order, before sending.
Attributes:
| Name | Type | Description |
|---|---|---|
requires_barrier |
bool
|
True for a promise or a vote -- the indelible ink whose loss lets a crash choose twice. A decision or trim record is derived state a host may persist behind a cheaper barrier. |
PrepareScope
Bases: IntEnum
What a prepare asks an acceptor to promise.
GLOBAL
class-attribute
instance-attribute
GLOBAL = 0
Every decree from first on: the Multi-Paxos takeover.
BOUNDED
class-attribute
instance-attribute
BOUNDED = 1
Only the decrees in [first, last]: a revocation under ownership.
Prepare
dataclass
Phase one: promise ballot for the decrees in scope and report votes.
Promise
dataclass
One reported vote or decision for one decree, in answer to a prepare.
PromiseRange
dataclass
The manifest that closes a phase-one answer for one chunk.
Accept
dataclass
Phase two: vote for entry in slot under ballot.
Accepted
dataclass
An acceptor's vote, with how far it has decided.
Commit
dataclass
A decision. It carries no ballot because a chosen value is final.
Learn
dataclass
A catch-up request for decided slots starting at from_slot.
Nack
dataclass
A refusal: rejected lost to promised.
Heartbeat
dataclass
A leader's liveness signal, with how far it has decided.
Envelope
dataclass
One protocol message with its addressing and configuration stamp.
The stamp is what lets a receiver refuse traffic from another epoch instead
of relabelling it. Everything else about the message lives in message,
which is one of the nine classes above.
ServeRange
dataclass
History a peer asked for that has fallen below this node's memory floor.
The core no longer holds it; the host serves it from retained history.
NodeState
dataclass
A read-only view of one participant, gathered in a single call.
is_leader
property
is_leader: bool
True when this participant is running phase two for its own slots.
Receipt
dataclass
Where a submitted command ended up.
Attributes:
| Name | Type | Description |
|---|---|---|
configuration_id |
int
|
The configuration that holds the slot. |
slot |
Slot
|
The position the command occupies. |
entry |
LogEntry
|
What was actually decided there. |
Note
A receipt reports agreement and release at this participant. It does not say every peer received the command, and it never says the application applied it.
value
property
value: bytes
The decided payload.