Skip to content

Comments

Add offchain client specification for SSV clusters#2

Open
GalRogozinski wants to merge 24 commits intomainfrom
spec
Open

Add offchain client specification for SSV clusters#2
GalRogozinski wants to merge 24 commits intomainfrom
spec

Conversation

@GalRogozinski
Copy link

This document specifies the offchain oracle client for SSV clusters, detailing its scope, timing configuration, finalization requirements, data sources, Merkle tree construction, and client architecture.

This document specifies the offchain oracle client for SSV clusters, detailing its scope, timing configuration, finalization requirements, data sources, Merkle tree construction, and client architecture.
Updated timing configuration section and adjusted logic for handling epochs and rounds. Modified function signatures and clarified client responsibilities.
Updated configuration format from JSON to YAML in documentation.
SPEC.md Outdated
Comment on lines 139 to 141
### 5.3 Odd-Leaf Handling (Empty Leaf)

Simply duplicate the last leaf. Ensure OpenZepplin compatibility like in [the following library]( https://github.com/cbergoon/merkletree).
Copy link
Contributor

Choose a reason for hiding this comment

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

Internal contradiction: "Empty Leaf" vs "Duplicate Last Leaf"

Section 5.3 title says "Odd-Leaf Handling (Empty Leaf)" but the text says "duplicate the last leaf."

Then Step 7 (L289-L293) says:

If number of leaves is odd, append `emptyLeaf`.

These are different concepts:

  • Duplicate last leaf: leaves.append(leaves[-1])
  • Empty leaf: leaves.append(keccak256(0x00...00)) or similar

This ambiguity would cause different implementations to produce different roots.

Suggested fix: Pick ONE approach and be explicit:

### 5.3 Odd-Leaf Handling
If the number of leaves at any tree level is odd, duplicate the last node.
This is the Bitcoin/standard approach for balanced tree construction.

Example: [A, B, C] → [A, B, C, C] → build tree

SPEC.md Outdated
For each cluster `c`:

- `clusterId` – `bytes32` (canonical cluster identifier).
- `effectiveBalance` – integer (e.g. `uint64` / `uint256`), with agreed units (e.g. Gwei or ETH @marco ?).
Copy link
Contributor

Choose a reason for hiding this comment

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

This question must be resolved before the spec is finalized

Copy link

Choose a reason for hiding this comment

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

@olegshmuelov please use uint64, gwei.

Copy link
Author

Choose a reason for hiding this comment

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

@mtabasco
How do you decode the effective balance?
Aleg will use uint64 (since no uint256 type in go)
Solidity can be fine with this?

* @param clusterOwner Owner address of the cluster
* @param operatorIds Array of operator IDs in the cluster
* @param cluster Current cluster state (provided by oracle)
* @param effectiveBalance Total cluster effective balance in wei (sum of all validators)
Copy link
Contributor

Choose a reason for hiding this comment

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

The UpdateClusterBalance function signature has an inconsistency in units.

The NatSpec comment says:

* @param effectiveBalance Total cluster effective balance in wei (sum of all validators)

But Section 4.1 and 5.1 define effectiveBalance as uint64 in gwei, not wei.

SPEC.md Outdated
- Log permanent failure for this round and wait for manual intervention.

10. **Optional: update cluster balance**
- Listen to the `RootCommitted(merkleRoot, blockNum, block.timestamp)` event and validate the correct `merkleRoot` is constructed for `blockNum`.
Copy link
Contributor

Choose a reason for hiding this comment

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

The RootCommitted event signature in Section 10 differs from Section 6.1.


The `effectiveBalance` of the cluster is the sum of all its SSV validators.
If the `effectiveBalance` of a validator is below or equal to the (EJECTION_BALANCE)(https://eth2book.info/capella/annotated-spec/#validator-cycle) of 16 ETH,
If the `effectiveBalance` of a validator is below or equal to the 32 ETH,
Copy link
Contributor

Choose a reason for hiding this comment

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

just below :)

Comment on lines +120 to +126
##### 5.2 Ordering

- Collect all leaves.
- Sort by `clusterId` ascending (as `bytes32`).
- Construct `leaves[]` in that order.

This ordering guarantees a deterministic Merkle tree.
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorting by leaf hash (instead of clusterID) is equally deterministic and provides compatibility with OpenZeppelin's StandardMerkleTree tooling. This allows external verification using their JavaScript library without custom implementations.

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.

3 participants