Skip to main content

AuditChain

Struct AuditChain 

Source
pub struct AuditChain { /* private fields */ }
Expand description

The chain itself. Open it once and append to it; it is Send + Sync and holds its own lock, because one server writes one chain from many request threads and two appends that interleaved would each claim the same prev.

Implementations§

Source§

impl AuditChain

Source

pub fn open(path: impl Into<PathBuf>) -> Result<AuditChain, AuditError>

Open — or start — the chain at path.

The existing file is read and verified at open, not merely counted. A server that appended to a chain it had not checked would extend somebody’s forgery with genuine entries and make the break look like it happened later than it did.

Source

pub fn open_framed(path: impl Into<PathBuf>) -> Result<AuditChain, AuditError>

Open the chain as the REPLICATED trail — every append is an Append transaction before it is a line in a file, so the twin holds the trail and gunnar control twin replay brings it back.

This is the D6 fix (lane T11, 2026-09-21). Before it, log/ was a per-box path: the twin never held the audit trail and a restore came up with none, reporting success. The restore happens on the worst day, which is the day somebody has to reconstruct what happened.

It refuses rather than falling back. The chain must sit at crate::txlog::AUDIT_REL under a data root the sink knows, or this returns AuditError::Unframed naming why. A chain that quietly wrote unframed lines would reproduce the exact bug — a trail the restore drops without saying so. The caller’s job is to say it out loud and open an ordinary chain with AuditChain::open.

Source

pub fn is_framed(&self) -> bool

Does every append of this chain also become a transaction? See AuditChain::open_framed.

Source

pub fn path(&self) -> &Path

Where the chain lives.

Source

pub fn append( &self, event: AuditEvent<'_>, at_unix_ms: i64, ) -> Result<AuditEntry, AuditError>

Append one decision. Returns the entry that was written (or, while the log is released, queued — Recorded::Queued), whose hash is the new tip an operator can record. A box that follows its primary answers AuditError::NotOriginated.

Source

pub fn record( &self, event: AuditEvent<'_>, at_unix_ms: i64, ) -> Result<Recorded, AuditError>

Record one decision — Recorded says what became of it.

G + G2 (release-3 test2 mock 2026-09-29): a chain opened framed on a box that was then told BecomeTwin at runtime, and a primary whose log was released for its own growth, answered every decision with an error (txlog: this box is a twin …, txlog: released …) that the gate logged at ERROR — 13 and 4 lines per mock — and the grow’s decisions were lost. A follower now originates nothing and says so without an error; a released log holds the trail in memory, in order, and writes it after the remount.

Source

pub fn queued(&self) -> usize

How many entries wait for the log to be taken back (Recorded::Queued).

Source

pub fn flush(&self) -> Result<usize, AuditError>

Write what waits — every held entry, in order, once the log is taken back (the remount after a growth). Answers how many were written; a log still released writes none and keeps them.

Source

pub fn entries(&self) -> Result<Vec<AuditEntry>, AuditError>

Every entry, oldest first.

Source

pub fn verify(&self) -> Result<usize, AuditError>

Check the chain end to end. Ok(n) is “n entries, and they hold”.

This is the function the finding asks for: an operator (or cargo test) can ask the file whether anything in it has been changed or removed, and get an answer that names the entry rather than a shrug.

Source

pub fn tip(&self) -> String

The current tip hash — what a whole history commits to.

Worth writing down somewhere the box cannot reach: with a recorded tip, even a rewrite of the entire file is detected.

Trait Implementations§

Source§

impl Debug for AuditChain

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more