Skip to content

fix(zetaclient): keep signing when the keygen record is reset (backport v38) - #4627

Draft
kingpinXD wants to merge 1 commit into
release/zetaclient/v38from
hotfix/zetaclient-ignore-blanked-keygen-v38
Draft

fix(zetaclient): keep signing when the keygen record is reset (backport v38)#4627
kingpinXD wants to merge 1 commit into
release/zetaclient/v38from
hotfix/zetaclient-ignore-blanked-keygen-v38

Conversation

@kingpinXD

@kingpinXD kingpinXD commented Aug 14, 2026

Copy link
Copy Markdown
Member

Backport of #4618 to release/zetaclient/v38. Do not merge before #4618.

Summary

  • Whitelist p2p peers from TSS.TssParticipantList rather than the keygen record, which zetacore erases on any observer set change.
  • Skip the keygen ceremony when a TSS already exists, instead of waiting on a record scheduled for a block that never arrives.
  • Delete the keygen watcher that restarted every signer at once.
  • Retry every zetacore query on the startup path with a constant backoff, so a contended RPC during a mass restart does not kill startup.

Scope

Production code only, matching the drain backports (#4614 / #4615). Five files: zetaclient/tss/setup.go, service.go, zetaclient/maintenance/tss_listener.go and the two test files. The e2e harness, CI wiring and changelog stay on main — they conflict on this branch and carry no runtime behaviour.

Compatibility with the drain

No shared files, and no drain code reads the keygen record. Setup runs before startDrainIfArmed in cmd/zetaclientd/start.go, so a signer that died in Setup never reached the drain at all — this fix is a prerequisite for the drain rather than a conflict.

Verified on this branch: build clean, zetaclient/tss and zetaclient/maintenance green, and the drain suites still green under -tags drain.

This branch is what testnet signers run, and it already carries the testnet drain anchors, so a build cut from here carries both the drain and this fix.

For operators

While a finalized TSS exists, a keygen scheduled via MsgUpdateKeygen will not run. Rotating requires removing the current TSS first. Tracked in #4623.

Greptile Summary

This backport changes signer startup to derive its p2p whitelist from the finalized TSS, skip unnecessary keygen ceremonies, remove keygen-record restart monitoring, and retry startup RPC queries.

  • Uses finalized TSS participants instead of resettable keygen grantees for peer admission.
  • Avoids restarting all signers when the keygen record is reset.
  • Adds constant-backoff retries and focused startup/listener tests.
  • The GetTSS error fallback can still route an existing signer into a pending or failed keygen ceremony.

Confidence Score: 4/5

The PR should not merge until GetTSS query failures stop being treated as TSS absence, because that can strand an otherwise usable signer in a pending or failed keygen ceremony.

The new fallback loses the distinction between an unavailable TSS query and an absent TSS, allowing a transient RPC failure to override finalized-key detection and select the wrong startup path.

Files Needing Attention: zetaclient/tss/setup.go

Important Files Changed

Filename Overview
zetaclient/tss/setup.go Introduces finalized-TSS whitelist selection and ceremony skipping, but converts GetTSS failures into absence and can re-enter keygen incorrectly.
zetaclient/tss/service.go Adds constant-backoff retrying to the metrics startup keygen query without an identified defect.
zetaclient/maintenance/tss_listener.go Removes keygen-record restart monitoring while retaining TSS address and history watchers.
zetaclient/tss/setup_test.go Covers whitelist source selection and error fallback, but the fallback test asserts only peer selection and does not exercise Setup with a pending or failed keygen.
zetaclient/maintenance/tss_listener_test.go Verifies reset keygen records are ignored while genuine TSS changes still trigger shutdown.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Setup starts] --> B[Fetch keygen record]
    B --> C[Fetch current TSS with retries]
    C -->|Success with pubkey| D[Whitelist TSS participants]
    D --> E[Skip keygen ceremony]
    C -->|Retries exhausted| F[Replace current TSS with empty value]
    F --> G[Whitelist keygen grantees]
    G --> H[Mark key as not finalized]
    H --> I[Enter KeygenCeremony]
    I -->|Pending or failed record| J[Wait, retry, or run unintended keygen]
    I -->|Successful record| K[No-op and continue startup]
Loading
Prompt To Fix All With AI
### Issue 1
zetaclient/tss/setup.go:244-246
**TSS query failure triggers keygen**

When `GetTSS` exhausts its retries while a finalized TSS and a populated pending or failed keygen record exist, this fallback treats the query failure as TSS absence and enters `KeygenCeremony`, causing the signer to wait, retry indefinitely, or perform an unintended keygen instead of starting with the existing key.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(zetaclient): keep signing when the k..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

…rt v38)

Backport of #4618. Production code only, same scope as the drain
backports: the e2e harness, CI wiring and changelog stay on main.

zetacore blanks the keygen record on any observer set change, which took
every mainnet signer down on 2026-08-11 and stopped them restarting.
Three changes: the p2p whitelist now comes from TssParticipantList
instead of the erased grantee list, Setup skips the keygen ceremony when
a TSS already exists, and the keygen watcher that triggered the mass
restart is gone.

Every zetacore query on the startup path is retried with a constant
backoff, so a contended RPC during a mass restart does not kill startup.

Note for operators: while a finalized TSS exists, a keygen scheduled via
MsgUpdateKeygen will not run. Rotating requires removing the current TSS
first. Tracked in #4623.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cd1ZRjpN5br7NRYA9sCp7G
@kingpinXD
kingpinXD requested a review from a team as a code owner August 14, 2026 03:32
@kingpinXD kingpinXD added the no-changelog Skip changelog CI check label Aug 14, 2026
@cursor

cursor Bot commented Aug 14, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

Comment thread zetaclient/tss/setup.go
@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.55102% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
zetaclient/tss/setup.go 80.85% 9 Missing ⚠️
zetaclient/tss/service.go 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@ws4charlie ws4charlie left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — diffed this against #4618 and all five files are byte-identical, and the pre-patch baselines match across main/v37/v38 so the cherry-pick is clean. Built it and ran the tss + maintenance unit tests locally, both green.

@kingpinXD
kingpinXD marked this pull request as draft August 14, 2026 04:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Skip changelog CI check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants