Tenderseed v2.2.1
This release closes the audit of v2.2.0. Two of its points did not survive a
reading of the pinned upstream source and are recorded below as examined; one it
raised as merely probable turned out to be the most serious of the set. None of
them was a crash, a data loss or a deadlock.
Changed
- The sweep now re-verifies what the seed actually serves. A seed answers a
request for addresses with a selection biased towards the addresses this
reactor promoted. The sweep was drawing an unbiased selection, that is
sampling the whole book uniformly, where promoted addresses are a small
minority. On a book of a thousand entries holding thirty promoted ones, a
promoted address came up in roughly one sweep out of five, and it is precisely
the address served first. Nothing ever demotes a promotion, so that population
is the only one the sweep exists for. The new buckets keep their coverage from
the arrival path, and the bias never shortens the selection: when the old
buckets cannot supply their share, the difference is claimed from the new
ones, so an early book yields a full selection holding all of its promoted
addresses. - The outcome counters gain a stage label, and two outcomes are split. The
stage says whether a decision was taken as an address was offered to the queue
or as it left it, which is what bounds the traffic actually saved: a skip on
the way out is a dial that would certainly have happened, a skip on the way in
only avoided an offer.successno longer covers an address the book refused
to hold, which is nowanswered_unlisted; and a collision observed after a
dial is nowskipped_collisionrather than being folded in with the three
exits that dial nothing, because it is the only one of the four this fork
changed and its value is the count of unfair marks avoided on live addresses.
One series, two labels, ten reachable pairs, still summing to the number of
decisions taken. Anything reading the old outcome names needs updating; this
is the only release in which those series change.
Added
- An unknown configuration key is reported instead of ignored. A misspelled
key was silently dropped and its default applied, which is the likeliest way
an operator loses a setting. It is reported on standard error and never
refused, so an older binary still reads a file written for a newer one. - The queue length at the tick joins the sweep summary line. A queue already
full when the sweep offers its selection means the sweep is the flow being
dropped rather than the arriving one, which is the opposite of what the drop
was meant for. Nothing is changed about the queue until that figure has been
read in production.
Fixed
- The listening socket is released when the metrics counters fail to build.
v2.2.0 fixed the same defect on the path where the switch fails to start and
introduced this one next to it.
Examined, not reproduced
- The duplicate rejection filter was reported as depending on the exact shape
of the upstream error. Searching the pinned source for a pointer to that
type returns nothing outside tests: all three production sites build it by
value, so matching by value covers every existing path. No code change. - Keying the verification state by node identity rather than by full address
was reported as an inconsistency. The documentation was wrong, not the code:
the upstream book is itself keyed by identity throughout, and a verdict
applies to a book entry. Keying on the full address would hold two verdicts
for one entry. FORK.md section 3.6 now says so and says why.
Documentation
- The release notes of v2.2.0 claimed the close error of the configuration file
was checked. It is explicitly discarded, which is the right call for a file
opened to read, but the note said the opposite. - The comment on the outcome counter promised that every path takes exactly one
decision. Shutdown does not: the rest of a batch is abandoned without a
verdict, and nothing should be counted for it. - FORK.md states what earns a counter: one outcome per behaviour whose value can
be interpreted, never one per branch of the code. - The severity gap between an unusable metrics namespace, which refuses to
start, and a metrics port already taken, which is only logged, is stated as
the choice it is: the first value will never become valid, the second can
resolve itself, and shared infrastructure should not stop serving peers over a
metrics port.
Updating
Only the binary is replaced. Node identity, configuration and address book are
untouched. No configuration key was added, removed or renamed. Dashboards and
alerts reading the verification series must be updated, see Changed above. See
the update procedure in the README.