gasWantedReap
int64gasWantedReap is the gas ceiling a reaping transaction is assumed to ask for, used only to price the advertised bounty. It is the measured cost of a ten-note reap rounded up; a caller reaping more notes should re-price with storagecost.EvaluateAtFloor directly rather than trust this.
Value
5000000
maxBody
untyped bigintmaxBody caps a note so one poster cannot lock an unbounded deposit in a single call, which would also make the gas cost of reaping it unpredictable.
Value
(4096 <untyped> bigint)
Note
typeNote is one posting. Body is what costs storage; the rest is bookkeeping that makes the incentive visible in Render.
Value
v0.Note
notes
*v1.Listnotes is append-addressed: an index is stable for the life of the realm, which is what lets Compact reclaim dead nodes without renumbering.
- OID
- 0df328…a16a:4
notes details
Post
func(body string, ttl int64) intPost adds a note that becomes reapable ttl blocks from now, and locks the storage deposit for it against the caller. A ttl of zero is allowed and makes the note reapable immediately, which is the cheapest way to demonstrate the mechanism.
- OID
- 0df328…a16a:6
Post details
Reap
func(limit int) intReap deletes up to limit expired notes and returns how many it deleted. Permissionless by design. The storage deposit freed goes to whoever signed this transaction, so a stranger keeping the board tidy is paid for it out of the deposits the posters locked. A note that has not expired is skipped, not refused, so a reaper never has to guess which indices are ripe. It walks from the highest index down, which is not cosmetic. In the backing list the oldest indices are the ancestors of the newest, so a node can only be freed once everything below it is dead. Reaping oldest-first with a binding limit therefore never creates a dead tail and leaves Compactable at zero, stranding the tree structure, which measures at roughly two thirds of what an entry costs. Reaping newest-first makes each batch immediately compactable. Every candidate is expired either way, so the order changes only who gets paid how much, and it is measured: see the ulist package doc.
- OID
- 0df328…a16a:8
Reap details
Compact
func() intCompact frees the tree nodes that reaping left behind and returns how many. Also permissionless, and also paid the same way. It is a separate call because it is a separate economic decision, and a surprisingly large one: on chain, compacting a drained board returned about three times what deleting the notes themselves did, because a list node costs more than the note it carries. But it returns nothing at all while any live note sits below the dead ones, so the two calls are worth batching in that order: reap, then compact. Compactable says how much is actually there, for free.
- OID
- 0df328…a16a:9
Compact details
Reapable
func() intReapable counts the notes that have expired and not yet been reaped.
- OID
- 0df328…a16a:10
Reapable details
Compactable
func() intCompactable reports how many dead tree nodes a Compact would free.
- OID
- 0df328…a16a:11
Compactable details
Live
func() intLive counts the notes still holding storage.
- OID
- 0df328…a16a:12
Live details
Bounty
func() v0.QuoteBounty prices what is currently on the table for a reaper, at the default storage price and the floor gas price. The byte figure is an estimate from payload length, never the chain's own accounting. Treat it as an advertisement, not a settlement.
- OID
- 0df328…a16a:13
Bounty details
noteAt
func(i int) (*v0.Note, bool)noteAt reads index i, reporting whether a live note is there. A reaped or compacted index reads as absent.
- OID
- 0df328…a16a:14
noteAt details
Render
func(path string) string- OID
- 0df328…a16a:15
Render details
verdictWord
func(q v0.Quote) string- OID
- 0df328…a16a:16
verdictWord details
summarize
func(body string) stringsummarize keeps the board readable when a note is long, and keeps a note from breaking out of the bullet item it is rendered into. A body is whatever bytes a poster paid to store, so on the board it is attacker-controlled input landing in an INLINE markdown slot. Neutralizing it is sanitize.InlineText's job rather than this realm's: it strips bidi and zero-width characters, folds every line separator to a space, and escapes the CommonMark punctuation that would otherwise let a note inject a link, an image, a heading or an HTML block into a page every reader loads. A hand rolled ReplaceAll of "\\n" and "|" stops none of that. Truncate first, sanitize second, and never the other way round. InlineText escapes by inserting backslashes and is not idempotent, so cutting its output at an offset can strand a trailing lone backslash that then escapes the chrome this realm appends after it.
- OID
- 0df328…a16a:17
summarize details
headRunes
func(s string, width int) (string, bool)headRunes returns the first width runes of s and whether it cut anything. It counts runes, not bytes: slicing a body at a byte offset splits a multi-byte character in half and puts invalid UTF-8 on the page, which one emoji in a note is enough to trigger.
- OID
- 0df328…a16a:18