tollgate-core 0.30.2

Zero-I/O, clock-free domain layer for quota admission and accounting: cost tables, account snapshots, fenced local leases, and the reservation state machine.
Documentation

tollgate-core

The zero-I/O domain layer of Tollgate: cost tables, compiled account snapshots, fenced local leases, and the reservation state machine that decides what a request is charged.

Every operation is a function of its arguments. There is no I/O, no clock read (callers pass now), no blocking lock, and cost arithmetic is checked, never wrapping. Unknown, expired, exhausted, or overflowing states deny; there is no slower path to fall back to. That is what lets the layer sit inside a request whose whole budget is a few microseconds.

Where it sits

Tollgate has two planes. The request path is this crate and tollgate-admission; the control plane is tollgate-client, tollgate-server, and a tollgate-store backend. Most services embed Tollgate through tollgate-admission and tollgate-client; this crate is the vocabulary they share.

Charging a request

A snapshot admits the account, a cost table quotes the work, a lease reserves the units, and the reservation either commits at execution start, charging the full quote whatever the outcome, or is cancelled before execution for zero.

use std::sync::Arc;

use jiff::Timestamp;
use tollgate_core::{
    AccountId, AccountSnapshot, AccountStatus, CancelOutcome, CommitFunding, CostTable,
    CostUnits, FencingToken, Generation, LeaseGrant, LeaseId, LocalLease, OpIndex,
    PermissionBits, Reservation, ResolvedLimits,
};

// The embedder's operations, as dense indexes into the cost table.
enum Op {
    Price,
    Greeks,
}

impl OpIndex for Op {
    fn index(&self) -> usize {
        match self {
            Op::Price => 0,
            Op::Greeks => 1,
        }
    }
}

let now = Timestamp::from_second(1_755_600_000).unwrap();
let expires = Timestamp::from_second(1_755_600_060).unwrap();

// One unit fixed per request, plus a per-item weight per operation.
let table = Arc::new(
    CostTable::builder(CostUnits(1), CostUnits(1))
        .weight(&Op::Price, CostUnits(1))
        .weight(&Op::Greeks, CostUnits(5))
        .build(),
);
let snapshot = AccountSnapshot::builder(
    AccountId(1),
    Generation(1),
    AccountStatus::Active,
    expires,
    PermissionBits::bit(0),
    ResolvedLimits::new(1_024),
    Arc::clone(&table),
)
.build();

// A lease the control plane granted: 100 units, spent locally.
let lease = Arc::new(LocalLease::new(
    LeaseGrant {
        lease_id: LeaseId(1),
        account_id: AccountId(1),
        fencing_token: FencingToken(1),
        units: CostUnits(100),
        expires_at: expires,
    },
    CostUnits(10),
));

snapshot.admit(now, PermissionBits::bit(0)).expect("active, fresh, permitted");
let quote = table.quote(&Op::Greeks, 4).expect("known operation");
assert_eq!(quote.total, CostUnits(21)); // 1 fixed + 5 per item × 4

// Admission debits the lease, but the charge is only pending.
let reservation = Reservation::reserve(&lease, quote.total, now).expect("funded");
assert_eq!(lease.remaining(), CostUnits(79));

// Execution start commits the full quote, for success, failure or timeout.
let charged = reservation
    .commit_at_execution_start(now, CommitFunding::LeaseOnly)
    .expect("inside the lease window");
assert_eq!(charged, CostUnits(21));

// A request that ends before execution is released for zero instead.
let early = Reservation::reserve(&lease, CostUnits(5), now).expect("funded");
assert!(matches!(early.cancel(), CancelOutcome::ZeroCharged));
assert_eq!(lease.remaining(), CostUnits(79));

Commit and cancel race on one atomic transition, so exactly one wins.

Features

  • serde: Serialize/Deserialize for the wire-visible types: snapshots and cost tables, lease grants, usage events, deny reasons, budgets, identifiers, and units. Off by default.

Contract

The behaviour above is specified in INVARIANTS.md, where each invariant names the tests that enforce it, and parts are modelled in Lean under formal/lean. Rationale and history are in docs/DESIGN.md.

License

MIT OR Apache-2.0, at your option. Tollgate is a product of MorphIQ Labs, a trade name of Prophetizo LLC.