tiny.machine.fault
Defined in tiny.machine.
Testing how a system survives failure means choosing, at a named place, whether the failure happens, and a replay has to make the same choices the recorded run made.
API (11)
Actions
Public operations.
advance: Extends the running fault-chain digest by one decision it has verified.decide: Pairs a point it has verified with one choice, the outcome recorded at a fault point, then hashes that pair into the decision digest.prepare: Assembles a fault point, one place a fault may occur, from its material and computes the id that authenticates it, so that the same place in two runs comes out as the same value.verifyDecision: Verifies both halves of a stored decision to prove the record unchanged, checking from the bottom up with the point id first and then the decision digest over it.verifyPoint: Recomputes a point's id from its fields and rejects any drift, proving the stored record unchanged.
Types and contracts
Public types and contracts.
Choice: The outcome recorded at one fault point, its choice.Decision: A point together with the choice made at it, a fault decision.Dialect: The version number a fault record is written under, its encoding version.Error: Rejections of fault material.Kind: The eleven fault families a point can name, its fault kind: a machine crash, a process crash, an I/O error, packet loss, packet delay, packet reorder, a partition, a clock jump, an entropy choice, capacity exhaustion, and a host service failure.Point: The named place where a fault can be injected, a fault point.
Source
Source: lib/machine/src/fault/canon.zig:14
zig
/// Rejections of fault material./// A caller matches on these to tell which piece failed, because every variant names/// the digest or the encoding version that failed recomputation: the basis, the/// chain, the decision, the point, or the subject.pub const Error = error{ InvalidFaultBasis, InvalidFaultChain, InvalidFaultDecision, InvalidFaultPoint, InvalidFaultSubject,};Source: lib/machine/src/fault/types.zig:6
zig
/// The version number a fault record is written under, its encoding version. A reader/// checks this before trusting a stored fault record. The reader rejects a record/// written under a version it does not speak. One version exists today: `deterministic_fault_v1`.pub const Dialect = enum(u16) { deterministic_fault_v1 = 1,};Source: lib/machine/src/fault/canon.zig:91
zig
/// Extends the running fault-chain digest by one decision it has verified./// Equal chain digests prove equal fault histories./// An all-zero previous digest is rejected, and the decision is verified before/// it folds in.pub fn advance( previous: os.abi.Digest, decision: types.Decision,) Error!os.abi.Digest { try validateDigest(previous, error.InvalidFaultChain); try verifyDecision(decision); var hasher = Sha256.init(.{}); hasher.update(chain_domain); hasher.update(&previous); hasher.update(&decision.digest); var digest: os.abi.Digest = undefined; hasher.final(&digest); return digest;}Source: lib/machine/src/fault/canon.zig:66
zig
/// Pairs a point it has verified with one choice, the outcome recorded at a fault/// point, then hashes that pair into the decision digest./// The point is verified before the choice is bound to it.pub fn decide(point: types.Point, choice: types.Choice) Error!types.Decision { try verifyPoint(point); var decision: types.Decision = .{ .point = point, .choice = choice, .digest = undefined, }; decision.digest = decisionDigest(decision); return decision;}Source: lib/machine/src/fault/canon.zig:31
zig
/// Assembles a fault point, one place a fault may occur, from its material and computes/// the id that authenticates it, so that the same place in two runs comes out as/// the same value./// An all-zero basis digest and an all-zero subject digest are both rejected before/// the id is computed./// The id is a SHA-256 digest over the encoding version, the basis, the kind, and/// the subject, under the point domain tag./// A domain tag is a distinct constant string hashed before a value, so digests/// of different kinds never collide.pub fn prepare( basis: os.abi.Digest, kind: types.Kind, subject: os.abi.Digest,) Error!types.Point { try validateDigest(basis, error.InvalidFaultBasis); try validateDigest(subject, error.InvalidFaultSubject); var point: types.Point = .{ .id = undefined, .dialect = .deterministic_fault_v1, .basis = basis, .kind = kind, .subject = subject, }; point.id = pointDigest(point); return point;}Source: lib/machine/src/fault/canon.zig:80
zig
/// Verifies both halves of a stored decision to prove the record unchanged, checking/// from the bottom up with the point id first and then the decision digest over/// it.pub fn verifyDecision(decision: types.Decision) Error!void { try verifyPoint(decision.point); if (!std.mem.eql(u8, &decision.digest, &decisionDigest(decision))) { return error.InvalidFaultDecision; }}Source: lib/machine/src/fault/canon.zig:52
zig
/// Recomputes a point's id from its fields and rejects any drift, proving the stored/// record unchanged./// A point carrying an unknown encoding version is rejected first.pub fn verifyPoint(point: types.Point) Error!void { if (point.dialect != .deterministic_fault_v1) { return error.InvalidFaultPoint; } try validateDigest(point.basis, error.InvalidFaultBasis); try validateDigest(point.subject, error.InvalidFaultSubject); if (!std.mem.eql(u8, &point.id, &pointDigest(point))) { return error.InvalidFaultPoint; }}Source: lib/machine/src/fault/root.zig
zig
//! Testing how a system survives failure means choosing, at a named place, whether//! the failure happens, and a replay has to make the same choices the recorded run//! made. The place has to be named by the state it was derived from, so that the//! same place in two runs is the same value. A run makes many such choices, and//! comparing two runs means comparing their whole histories of choices. The choices//! have to fall into one order together with the inputs the machines receive. Digests//! of different kinds must never collide, and a stored record can be altered after//! the fact.//!//! The namespace names each place where a fault may occur (a *fault point*) by the//! digest of the state it grew from, its kind, and a digest for whatever it targets,//! plus an id that commits the other three. The outcome recorded at such a place//! (a *choice*) is either bypass, which leaves execution untouched, or inject, which//! applies the fault effect. The namespace binds one verified point to the choice//! taken there and carries a digest over the pair (a *fault decision*).//!//! `advance` folds each decision into one running digest (the *fault chain digest*),//! so a single digest stands for an entire fault history and two histories agree//! exactly when their digests agree. Each decision also enters the ordered record//! of every admitted input, settlement, and fault decision across a world's nodes//! (the *ledger*, `Fabric` in the code). There it takes one entry, which advances//! the entry frontier and counts against the same admission budget as an admitted//! input.//!//! Digests are SHA-256, taken under three distinct constant strings hashed before//! the value (each a *domain tag*): one tag each for points, decisions, and the//! chain. Every check hashes the material again and refuses a record whose stored//! digest disagrees with the rebuilt one.//!//! - *fault kind*: one of the eleven fault families a point can name, from a machine//! crash through a host service failure.const canon = @import("canon.zig");const types = @import("types.zig");pub const Choice = types.Choice;pub const Decision = types.Decision;pub const Dialect = types.Dialect;pub const Error = canon.Error;pub const Kind = types.Kind;pub const Point = types.Point;pub const advance = canon.advance;pub const decide = canon.decide;pub const prepare = canon.prepare;pub const verifyDecision = canon.verifyDecision;pub const verifyPoint = canon.verifyPoint;Source: lib/machine/src/root.zig:69
zig
pub const fault = @import("fault/root.zig");Audit
| Definitions | 8 |
|---|---|
| Public names | 8 |
| Members | 6 |
| Version | 26.7.0 |
| Revision | daab053ee433 |