Conversation
GalRogozinski
left a comment
There was a problem hiding this comment.
Need to talk about the algorithm tomorrow
|
It seems that simply increasing the number of topics by 4x (to 512) also gives us some benefits CC @liorrutenberg @GalRogozinski @moshe-blox @alan-ssvlabs @y0sher |
|
Hey all, thought I'd throw my thoughts on this also. I like the cost function, seems like a good thing to optimize. As has been discussed (but just wanted to make it a bit more explicit), we can minimize the cost function to always be 0 if we have an infinite number of topics. I.e each committee has its own topic. The trade-off as has been mentioned is network stability. What I think might be useful to mention that I've seen on real networks is why and how bad this network instability is. Imo it comes from a few main sources:
Anyway, I'd imagine simulations would show larger number of subnets would give better trade-offs in performance, but we want to be weary of the above, which are problems that typically simulations won't show. Erring on the side of caution would imply not going too hard on number of subnets. The other thing that drew my attention was each client managing state. This is a distributed consensus problem. If our nodes disagree on the state, we're going to be subscribed to different subnets. It wasn't obvious to me what happens in cases of forks. There is a time window, but we could fork beyond that window. Maybe we can rollback the state. If there is an error in our state, will it be easy to diagnose? Like will each client know it needs to re-sync or rollback, or will we just be on the wrong subnets and fail silently? Can we leverage the Ethereum state, and just have a mapping on a smart contract which resolves all of these problems? This is just some thoughts I had looking over this proposal. I think its a good idea to be smarter about subnet allocation. |
I can imagine a hash stored in the smart contract could work. Every event emitted changes the hash, and by checking against the hash in the Ethereum state, a node could ensure that it has the correct SSV state. If that check fails, the node could try to resync from the latest finalized state, and if that fails, fully resync. While I feel like this could allow us to safeguard against weird re-org related issues, changing sync to only consider finalized blocks (instead of a delay of 8 blocks) is preferable in my opinion. While this slows all Validator and Operator management actions (and even prevents them in times of long non-finality), it prevents the whole SSV network from failing if Ethereum is unstable. |
|
TODOs:
Conclusion on possible ways forward:
|
|
Hey @AgeManning and @dknopik Indeed, a large number of topics may be problematic for the discovery layer. Regarding syncing on the state:
|
Goals (what we're trying to achieve)
How Ethereum handles itFrom the consensus specs:
What's different in SSV
The key SSV challengeIn Ethereum, if one validator is slow to upgrade, only that validator is affected. In SSV, if one operator in a 4-operator committee is slow, the entire committee could fail to reach consensus because:
This is why SSV needs a more robust transition strategy than Ethereum's "upgrade your client before the fork" approach. What I think we're trying to solveThe core problem: How do we ensure all operators in every committee can participate in consensus across the fork boundary, given that some operators may be slightly ahead or behind? |
Suggested Improvements to achieve the goals (proposed wording, RFC-style)1. Slot-derived validation is the source of truthRule: Nodes MUST derive the fork from Why: Topic is transport-level and sender-controlled; slot is protocol-level and deterministic. If two operators are slightly ahead/behind, slot-based validation ensures they still apply the same rules and avoid split-brain consensus. 2. Explicit handling of early messages on new topicsRule: During Why: This removes ambiguity ("accept but don't process"), keeps the new mesh healthy, and prevents starving new topics before activation. 3. Publisher rule is slot-based and single-topicRule: Each message MUST be published to exactly one topic derived from its slot-implied fork (never to both old and new). Why: Prevents duplicate propagation, avoids cross-fork rebroadcast, and makes sender/receiver behavior deterministic. 4. SUBSEQUENT_WINDOW aligned with message validity windowRule: Why: Otherwise we may unsubscribe from old topics while some last-slot pre-fork messages are still valid, causing avoidable duty loss. If kept at 1 slot: The SIP SHOULD explicitly state that valid late pre-fork messages may be dropped. 5. Unambiguous timeline at the fork boundaryRule: "At the fork" MUST be defined as slot 0 of Why: Removes ambiguity about first-slot behavior, prevents operators from diverging in handling during the activation slot, and improves duty continuity. 6. Keep fork transition encapsulatedRule: Subscription timing + topic derivation belong in a dedicated fork module; other components only consume "fork from slot" decisions. Why: Avoids scattering fork-transition logic across validators/QBFT, reduces implementation risk, and makes the transition consistent across the codebase. |
|
What do you think about a clean separation:
But the key nuance is: validation only applies to messages you actually receive. If we unsubscribe too early, valid pre‑fork messages on old topics won’t arrive at all, so validation can’t save them. So the intended model should be:
That gives you a crisp division of responsibility:
If we want this in RFC wording, something like: During SUBSEQUENT_WINDOW, nodes MUST remain subscribed to old topics. For all received messages, nodes MUST derive the fork from message.slot and validate against that fork’s rules; the received topic is only a consistency check. After SUBSEQUENT_WINDOW, nodes MAY drop old topics, and any remaining messages on old topics MAY be dropped even if they would otherwise be slot‑valid. If the goal is “no message loss,” then SUBSEQUENT_WINDOW must cover the valid‑late window (≈ one epoch today). If we keep it at 1 slot, we should explicitly accept that some still‑valid pre‑fork messages can be dropped, even though slot‑based validation would have accepted them. |
|
@nkryuchkov @diegomrsantos @iurii-ssv DM me if something is still not clear or unresolved. |
Clarify window values + justify the trade-offTwo points still feel underspecified: 1. Constants table is ambiguousRight now the table says Please make units explicit and state whether these are RECOMMENDED defaults or fixed values. Suggested text:
2. Trade-off vs existing message TTL isn't explainedCurrent validation accepts late messages for committee/aggregator roles up to If At the same time, the resource overhead of extending Ask: please either
|
Resource impact of keeping
|
| Percentile | Extra topics | Extra mesh slots (topics×D) | Mesh ops/sec (≈ slots×1.43) | IHAVE IDs/sec (upper bound) | IHAVE KB/sec | Mem @128–256B/slot |
|---|---|---|---|---|---|---|
| Avg | 2.31 | 18.5 | 26 | 845 | 9.9 | 2–5 KB |
| p95 | 5 | 40 | 57 | 1,829 | 21.4 | 5–10 KB |
| p99 | 35 | 280 | 400 | 12,800 | 150 | 36–72 KB |
| Max | 69 | 552 | 789 | 25,234 | 296 | 70–141 KB |
Interpretation
- These are per-operator, 1-epoch only.
- "Mesh slots" are per-topic mesh entries, not necessarily new TCP connections (peer overlap reduces connections).
- IHAVE figures are upper bounds; real rates are often lower.
- Data-plane bandwidth does not double if we enforce one-topic publishing; the extra load is inbound old-topic gossip for ~1 epoch.
|
Co-authored-by: diegomrsantos <diegomrsantos@gmail.com>
Co-authored-by: diegomrsantos <diegomrsantos@gmail.com>
Co-authored-by: diegomrsantos <diegomrsantos@gmail.com>
Co-authored-by: diegomrsantos <diegomrsantos@gmail.com>
diegomrsantos
left a comment
There was a problem hiding this comment.
Amazing work, thanks everyone for the discussion and iterations here!


Network topology SIP with the proposal of changing the network structure, namely how validators are assigned to topics, to reduce the number of non-committee messages an operator needs to handle.