Running a keeper
A keeper does two things, and anyone can do them.
During each batch
Call poke(market) for every market a few times, in different L1 blocks. Each call records one price sample. Settlement needs at least 2 samples and voids the batch otherwise. Reveals also sample, so an active market needs fewer pokes.
After each reveal window
For every market with a non-empty book, call settle(batch, market). Then call collectForfeits(batch) once.
A loop
const [batch, phase] = await bp.read.currentBatch();
for (const m of markets) await bp.write.poke([m]);
if (phase === 0 && batch > 0n) {
for (const m of markets) {
const t = await bp.read.tape([batch - 1n, m]);
const book = await bp.read.orders([batch - 1n, m]);
if (t[3] === 0 && book.length) await bp.write.settle([batch - 1n, m]);
}
}
Settlement pays the keeper nothing in version 1. The protocol runs one; the calls are open so that nobody depends on it.