Skip to content

Tenderseed v2.2.0

Choose a tag to compare

@github-actions github-actions released this 01 Sep 09:59
· 25 commits to master since this release

This release closes the audit of v2.1.1. Every point was checked against the
code before anything was changed, and the two that carried the most weight were
confirmed in their conclusion but wrong in their cause, which changed what was
written. None of them was a crash, a data loss or a deadlock.

Changed

  • Verification remembers its verdicts. A failing address is now re-tried on
    an exponential schedule, 2^n seconds capped at 4 hours, the same formula the
    upstream crawler uses, instead of being re-dialled at every sweep for the 35
    hours upstream takes to evict it. On a full book that was on the order of a
    thousand futile connections an hour. An address just verified is no longer
    dialled again immediately when another peer mentions it. The window during
    which a successful verdict is trusted is derived from peer_check_period and
    stays strictly below it, so the periodic re-verification the seed exists for
    is never what gets skipped. No new configuration key. See FORK.md section 3.6.
  • A dial collision is no longer counted against the address. A peer that
    connects to us while we are dialling it is reported as a duplicate rejection
    by the transport and by the switch. That was marked as a failed attempt on a
    live address, on a counter shared with the upstream crawler. Every other
    rejection remains a verdict and is still marked.

Added

  • Counters for the verification itself, exported on the existing metrics
    endpoint under <namespace>_seed_verify_dials_total, with one label carrying
    six outcomes that sum to the number of decisions taken. Nothing upstream
    counts connection attempts. They are only registered when
    metrics_listen_addr is set, and registration failures are reported as
    configuration errors rather than raised.
  • A verification sweep line at info level, once per period, carrying the
    same outcomes, for operators without Prometheus.
  • golangci-lint runs in CI, pinned to a fixed version so an upgrade of
    the tool cannot turn the build red on untouched code. The lint target was
    declared in the Makefile and executed nowhere.
  • The three integer limits are validated. A negative
    max_num_inbound_peers or max_num_outbound_peers, or a
    max_packet_msg_payload_size of zero or less, is now refused at startup with
    the name of the key instead of being passed to CometBFT as is.

Fixed

  • The listening socket is released when the switch fails to start. That
    path stopped the metrics server but left the transport listening, unlike both
    paths of Stop.
  • The shutdown signal is trapped after the switch is running. A signal
    arriving during Switch.Start found IsRunning false and would have closed
    the transport under a switch that was still starting.
  • The metrics server compares its sentinel error with errors.Is.
  • The close error of the configuration file is checked.
  • make no longer misses a source file added in a deeper directory:
    $(wildcard internal/**/*.go) is not recursive in GNU make, it means *.

Documentation

  • The worst case cost of a dial was wrong, and three places quoted it. A
    dial costs at most 7 seconds, not 4: one second to connect, then two
    consecutive three second handshake deadlines. A sequential sweep of a full
    selection takes about 29 minutes, not 17, and about 3m40 with 8 workers, not
    2. peer_check_period is about 2.7 times the duration of one sweep, not five
    times. Corrected in config.go, FORK.md section 4 and the README.
  • FORK.md gains section 3.6, which documents the interaction between the sweep
    and the Attempts counter of the address book, and why the sweep never made
    an address evictable meaningfully sooner than upstream would have.

Updating

Only the binary is replaced. Node identity, configuration and address book are
untouched. No configuration key was added, removed or renamed. See the update
procedure in the README.