mirror of
https://github.com/Twigpine/node.git
synced 2026-11-09 05:20:05 -10:00
The cursor was the table-global bigserial, handed to clients verbatim and accepted back as any non-negative integer, then passed straight into a per-repo seq > $1. Two things followed from that, and both were silent. A value issued by a DIFFERENT repository — or by this one before a restore — is an ordinary larger number here, so the query matched nothing, the surface answered 200 with an empty page and echoed the value back, and the subscriber sat permanently past history it had never received with nothing anywhere reading as an error. And because repo_push_events is written by every repository on the node, the gaps between one repository's cursors measured how much the others pushed in between, private ones included. The cursor is now an opaque token carrying a version, a binding to (node DID, repository), and the id of the last event served. The binding is a hash and not a MAC, because there is nothing to forge: the position inside is a row id resolved against this repository's own rows anyway. What it buys is that a foreign cursor is refused by shape, with a message naming which mistake was made, instead of being applied to a repository it was never issued for. An id that resolves to nothing — a token kept across a restore that lost the row — is a 400 that names the recovery, not an empty page the poller reads as being up to date. The global sequence still orders the walk internally, which is what keeps the page cheap, but it no longer leaves the node. The position is the row id, which this surface already publishes in every event, so the token discloses nothing new. The two properties an earlier round established are kept, in their new shape: next_cursor is never null and never moves backwards, and the start of history is an expressible position rather than an absent one, so a first poll of a repository with no events still hands back a token the endpoint accepts back rather than a value a persisting poller would misread.