Expand description
freshet — a resumable, permissionless, shardable MapReduce over Solana accounts.
A Solana transaction can only lock ~128 accounts and spend 1.4M CU, so a single event cannot atomically modify an unbounded set of accounts. freshet is the on-chain pattern that lifts that ceiling: one logical effect is partitioned into permissionless, resumable, idempotent crank batches, optionally in two phases —
- REDUCE — scan N member accounts into a commutative-monoid accumulator (e.g. tally a histogram, find a winner), then
- MAP — apply the result to every member, including members whose owner never shows up (push-mode), which a pull-based “claim it yourself” design cannot express.
Exactly-once is guaranteed by a monotonic cursor within an epoch plus a per-member
epoch stamp across re-runs; liveness by a keeper bounty. See the SPEC for the full
contract.
§What this crate is
This is the framework-agnostic core — pure, no_std, alloc-free logic with no
Solana dependency:
partition— the deterministic member→shard partition (§2.8), computed never stored.state— the verified state-machine guards (advance_stepet al.) that drive every phase transition, plus a host-only executable model (Machine, behind thestdfeature) that the property tests model-check.monoid— theMonoidtrait for the REDUCE accumulator, withSumandMaxWinner.
freshet is a library linked into the consumer program, not a standalone program — only the program that owns an account may write it. The consumer owns its account layout and delegates control-flow to these guards, so its handlers run the verified logic rather than a re-implementation. Reference settlers in Pinocchio, Anchor, and Quasar (with a cross-framework CU benchmark) live in the repository.
§Example
use freshet::partition::{partition_len, partition_start};
use freshet::monoid::{Monoid, Sum};
// 10 members over 3 shards tile [0,10) as 4 + 3 + 3, contiguous and gap-free.
assert_eq!(partition_len(10, 3, 0), 4);
assert_eq!(partition_len(10, 3, 1), 3);
assert_eq!(partition_start(10, 3, 1), 4);
// A REDUCE accumulator merges associatively, so shards combine in any order/count.
assert_eq!(Sum(3).combine(Sum(4)).combine(Sum(0)), Sum(7));§Features
std(default) — enables the host-onlyMachinemodel used by the property tests. Disable it (default-features = false) for theno_std, alloc-free surface that on-chain programs link.
Modules§
- monoid
- §1 — the REDUCE accumulator. A
MonoidMUST be associative + commutative so shards merge in any order/count deterministically (the §7 sharding contract);IDENTITYseedsacc_global/acc_partial(explicit init — zeroed bytes are NOT assumed equal to IDENTITY for non-zero monoids). Concrete monoids the demos use live here. - partition
- §2.8 — deterministic member→shard partition (computed, never stored).
- state
- Executable model of the freshet state machine: the pure transition guards plus a
host-only
Machinethat exercises them. The on-chain Pinocchio handlers delegate their control flow to the same guards, so both run identical logic. The property tests cover every guard, cursor-derived completion, the reset clear-set, lazy-reset, and the safety/liveness invariants. SeeSPEC.mdfor the contract.