Skip to content

feat(qbft_manager): shorten proposer QBFT round timeout to 1.5s (SIP-102) - #1325

Merged
shane-moore merged 1 commit into
sigp:epbsfrom
shane-moore:feat/sip102-proposer-round-timeout
Sep 28, 2026
Merged

shane-moore merged 1 commit into
sigp:epbsfrom
shane-moore:feat/sip102-proposer-round-timeout

Conversation

@shane-moore

Copy link
Copy Markdown
Member

Problem, Evidence, and Context

Change Overview

  • Each proposer round now gets 1.5s, measured from when that round starts. After round 2 the instance gives up at the existing cap of 2.
  • The round length is carried in TimeoutMode::Relative, which only the proposer uses. --legacy-proposer-round-timeout restores 2s, and startup logs at info when it is set.
  • Not changed: timers for other duties, message validation (the proposer's allowed round range already reaches past the cap of 2), and the round cap.

Risks, Trade-offs, and Mitigations

  • A round 1 that would have decided between 1.5s and 2.0s is now cut off. go-ssv's slowest observed mainnet round 1 in 30 days was 1148ms. Anchor's Gloas round-1 times are not measured yet; Sepolia will provide them.
  • During a mixed-version rollout, one operator on 1.5s with another operator offline can lose a round-1 quorum that 2s timers would reach. This is rare given the latency data.
  • The rollback flag is committee-wide. Like go-ssv's, it only takes effect once at most f operators in a committee still run 1.5s. The help text says so.

Validation

  • Paused-time timer tests:
    • A two-round proposer instance times out after 3s at 1.5s, and after 4s at the legacy 2s.
    • A proposer instance starting 4s late times out after 8.5s, where other duties' timers would give 10s.
  • A sign_block test checks that the proposer path passes the configured timeout to QBFT, for both values.
  • make cargo-fmt-check, make lint and make cli-reference-check pass.
  • make test (release) passes, with one exception. spec_tests first failed because the ssv-spec fixture submodule was not initialized in the fresh worktree. After initializing it, cargo test --release -p spec_tests passes.

Rollback

Run with --legacy-proposer-round-timeout on every operator in the committee, or revert the commit. There is no storage or wire-format impact.

Additional Info / Next Steps

🤖 Generated with Claude Code

…102)

Gloas moves the attestation deadline to 3s. A proposer instance starts
about 1.1-1.5s into the slot, so with 2s rounds a round change starts
round 2 after the deadline. Give proposer rounds 1.5s each, measured
from each round's start, matching go-ssv #3044.

Add --legacy-proposer-round-timeout to restore 2s, mirroring go-ssv's
LegacyProposerRoundTimeout rollback switch. The value is carried in
TimeoutMode::Relative, which only the proposer uses. SlotTime duties,
message validation, and the proposer round cap are unchanged.

Closes sigp#1324

@shane-moore shane-moore left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

review from opus 5.5 at 64032a6: no findings

checked:

  • round 1 gets the full 1.5s: initialize resets current_round_start_time to now after the sleep_until, so the slot-start value passed by decide_abstract_block doesn't shorten round 1
  • the round 2 cap holds via Role::Proposer.max_round() -> with_max_rounds -> end_round
  • message validation needs no change: the spread upper bound is always >= 4, above the proposer cap of 2
  • matches go-ssv #3044 (1.5s default, legacy bool back to 2s, proposer only, not fork gated, timed from instance start)
  • the startup log fires since enable_logging runs before from_cli

not verified: anchor's round 1 latency under gloas, as the description already says

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 6 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (epbs@9f9b183). Learn more about missing BASE report.

Files with missing lines Patch % Lines
anchor/client/src/config.rs 0.00% 5 Missing ⚠️
anchor/client/src/lib.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             epbs    #1325   +/-   ##
=======================================
  Coverage        ?   80.80%           
=======================================
  Files           ?      179           
  Lines           ?    41275           
  Branches        ?        0           
=======================================
  Hits            ?    33352           
  Misses          ?     7923           
  Partials        ?        0           
Flag Coverage Δ
rust 80.80% <88.88%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@shane-moore
shane-moore merged commit d59a329 into sigp:epbs Sep 28, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants