reckon_db_chain_watermark (reckon_db v2.3.5)

View Source

Per-stream chain-start watermark for the tamper-resistance migration story.

Each stream that has ever held integrity-bearing events records the version at which integrity began. Events with version below the watermark are pre-integrity legacy; events at or above must carry prev_event_hash + mac.

Storage

Watermark lives in Khepri under [metadata, integrity, chain_start, StreamId] (the macro ?INTEGRITY_CHAIN_START_PATH from reckon_db.hrl, plus the stream ID). Value is a single non_neg_integer().

Lazy enablement

The watermark is created on the first integrity-bearing append to a stream. There is no explicit "enable integrity on this stream" operation - the act of appending under a store with integrity enabled implicitly sets the watermark if it does not already exist.

For a fresh stream (never had any events) this means the watermark is set to 0 when the first event is written.

For an existing legacy stream (events 0..N-1 already stored) being appended to for the first time AFTER integrity was enabled on the store, the watermark is set to N - the version that the new event is about to take. The first N legacy events stay legacy.

Read-side use

The read path consults the watermark to decide whether to verify integrity on an event. This module's responsibility ends at read/write of the watermark itself; verification logic lives in reckon_gater_integrity.

Summary

Functions

Delete a stream's watermark.

Read the chain-start version for a stream.

Set the chain-start watermark for a stream if not already set.

Functions

delete(StoreId, StreamId)

-spec delete(StoreId :: atom(), StreamId :: binary()) -> ok.

Delete a stream's watermark.

Used only when deleting the entire stream - the watermark is part of the stream's metadata and should not outlive it. Best-effort: any error is swallowed since this should never block stream deletion itself.

lookup(StoreId, StreamId)

-spec lookup(StoreId :: atom(), StreamId :: binary()) -> {ok, non_neg_integer() | undefined}.

Read the chain-start version for a stream.

Returns the version at which integrity began for the stream, or 'undefined' if no watermark has been recorded (i.e., the stream has never had an integrity-bearing append).

set_if_absent(StoreId, StreamId, Version)

-spec set_if_absent(StoreId :: atom(), StreamId :: binary(), Version :: non_neg_integer()) ->
                       {ok, RecordedVersion :: non_neg_integer()}.

Set the chain-start watermark for a stream if not already set.

Returns the version that ended up recorded - either the value passed in (this call set it), or the value that was already present (a concurrent call set it first).

This function intentionally tolerates write-write races: multiple writers attempting to set the same watermark all converge on the same outcome, because the writer's "next version about to write" is itself serialized by reckon-db's per-stream append ordering. If two concurrent writers somehow both reach this code path with the same NextVersion, the watermark ends up equal to NextVersion regardless of who won.