Commit graph

5 commits

Author SHA1 Message Date
undercover-cactus
406a0dc59e
test: storagehub e2e (#394)
## Summary

Add Storage Hub basic end to end test. This PR also include some fixes
to allow Storage Hub node and datahaven node to run on the same network
(local chain). Before that one was running on dev and the other one on
the local chain.

## What changed

* Added `storagehub.test.ts` e2e test. In this file we explicitly start
the storagehub node using the launch function already used in the CI
* Added Storage Hub backend the flow so it can be used in the e2e test
* Fix the `--chain local` vs `--chain dev` issue. The storagehub nodes
were started on the dev network and therefore they were never syncing
with the datahaven node
* Fix  the folder permission issue in the CI by fixing the folder name
* Added StorageHub javascript lib

---------

Co-authored-by: Gonza Montiel <gonzamontiel@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
Co-authored-by: Gonza Montiel <gon.montiel@gmail.com>
2026-03-11 12:39:47 +01:00
Ahmad Kaouk
f5067ea842
fix(e2e): stabilize submitter CI and local relayer startup (#470)
## Summary
- fixes the untrusted CI failure in `e2e-tests / E2E Tests with Kurtosis
Ethereum Network`
- keeps validator-set-submitter startup actionable by avoiding test-only
contract config imports during container startup
- improves submitter readiness diagnostics by capturing both stdout and
stderr from container logs and making streamed log matching robust to
chunked UTF-8 output
- reduces validator-set-submitter Docker build time in CI by building
from `test/` and adding a tight `test/.dockerignore`
- makes local arm64 E2E runs use a native local Snowbridge relayer image
instead of forcing `linux/amd64` emulation
- auto-builds the local relayer image when needed for `:local` tags

## Why
The original failing untrusted test started as a submitter container
startup problem, but the branch now also addresses a second timeout path
that showed up while debugging:
- the submitter image was being built from the repository root with a
large Docker context, which made the `validator-set-update` suite spend
most of its hook timeout budget inside `docker build`
- on Apple Silicon, forcing `datahavenxyz/snowbridge-relay:latest`
through `linux/amd64` caused `generate-beacon-checkpoint` to segfault
during local runs

These changes make the submitter failure actionable, cut the CI Docker
build context down substantially, and keep local E2E runs reliable on
arm64.

## Validation
- `cd test && bun fmt`
- `cd test && bun x tsc --noEmit`
- `bun test e2e/suites/validator-set-update.test.ts --timeout 900000`
- `cd test && docker build -f tools/validator-set-submitter/Dockerfile
-t datahavenxyz/validator-set-submitter:local .`
2026-03-06 13:08:13 +01:00
Ahmad Kaouk
39aea69e36
test: integrate validator-set-submitter Docker container into E2E test (#453)
## Summary

- Replace the manual `sendNewValidatorSetForEra` contract call in the
`validator-set-update` E2E test with the **validator-set-submitter
daemon** running as a Docker container
- Add `test/e2e/framework/submitter.ts` with helpers to build the image,
launch the container on the shared Docker network, and clean up after
the test
- Remove unused imports (`getOwnerAccount`, `decodeEventLog`,
`parseEther`, `gatewayAbi`) that were only needed for manual submission

The submitter automatically detects the last session of an era and
submits the validator set via Snowbridge, matching production behavior
more closely than the previous manual call.

## Test plan

- [x] `bun test e2e/suites/validator-set-update.test.ts --timeout
900000` passes (4/4 tests, 15 assertions)
- [x] Verify submitter container starts and connects to both Ethereum
and DataHaven
- [x] Verify `ExternalValidatorsSet` event is observed on DataHaven
- [x] Verify submitter container is cleaned up after the test
- [x] Verify Charlie and Dave appear in the final validator set
2026-02-24 18:31:49 +02:00
Ahmad Kaouk
eaf55fb414
feat: implement weighted top-32 validator selection (#443)
## Overview

Implements deterministic weighted-stake-based validator selection in
`DataHavenServiceManager`, building on the era-targeting submitter model
from PR #433. Previously, `buildNewValidatorSetMessage()` forwarded all
registered operators in arbitrary membership order with no stake-based
ranking, meaning high-stake operators could be displaced by lower-stake
ones when downstream caps applied. This PR fixes that by computing a
weighted stake score per operator and selecting the top-32 candidates
before bridging the set to DataHaven.

Spec: `specs/validator-set-selection/validator-set-selection.md`

## Contract Changes (`DataHavenServiceManager.sol`)

**New state:**
- `MAX_ACTIVE_VALIDATORS = 32` — cap on the outbound validator set
- `mapping(IStrategy => uint96) public strategiesAndMultipliers` —
per-strategy weight used in the selection formula

**Updated `buildNewValidatorSetMessage()`:**
1. Fetches allocated stake for all operators × strategies from
`AllocationManager`
2. Computes `weightedStake(op) = Σ(allocatedStake[op][j] ×
multiplier[j])` across all strategies
3. Filters operators with no solochain address mapping or zero weighted
stake
4. Runs a partial selection sort to pick the top `min(candidateCount,
32)` by descending weighted stake; ties broken by lower operator address
(deterministic)
5. Reverts with `EmptyValidatorSet()` if no eligible candidates remain

**Admin API changes:**
- `addStrategiesToValidatorsSupportedStrategies()` signature changed
from `IStrategy[]` to `IRewardsCoordinatorTypes.StrategyAndMultiplier[]`
— strategy and multiplier are stored atomically in one call, eliminating
the risk of a strategy being registered without a multiplier
- New `setStrategiesAndMultipliers(StrategyAndMultiplier[])` — updates
multiplier weights for existing strategies without touching the
EigenLayer strategy set
- New `getStrategiesAndMultipliers()` — returns all strategies with
their current multipliers
- `removeStrategiesFromValidatorsSupportedStrategies()` now cleans up
multiplier entries on removal

**New error / event:**
- `EmptyValidatorSet()` — reverts when no eligible candidates exist
- `StrategiesAndMultipliersSet(StrategyAndMultiplier[])` — emitted on
add or update of multipliers

## Tests (`ValidatorSetSelection.t.sol`)

New 552-line Foundry test suite covering all cases from the spec:

| Case |
|------|
| `addStrategies` stores multiplier atomically |
| `removeStrategies` deletes multiplier |
| `setStrategiesAndMultipliers` updates without touching the strategy
set |
| `getStrategiesAndMultipliers` returns correct pairs |
| Weighted stake computed correctly across multiple strategies |
| Operators with zero weighted stake are excluded |
| Unset multiplier treated as 0 |
| Top-32 selection when candidate count > 32 |
| All candidates included when count < 32 |
| Tie-breaking by lower operator address |
| `EmptyValidatorSet` revert when no eligible operators |

## Deploy Scripts

- **`DeployBase.s.sol`**: Sets a default multiplier of `1` for all
configured validator strategies after AVS registration via
`setStrategiesAndMultipliers`
- **New `AllocateOperatorStake.s.sol`**: Forge script that allocates
full magnitude (`1e18`) to the validator operator set for a given
operator. Must be run at least one block after `SignUpValidator` to
respect EigenLayer's allocation configuration delay.

## E2E Framework

- **`validators.ts` — `registerOperator()`**: Extended to deposit tokens
into each deployed strategy and allocate full magnitude to the DataHaven
operator set after registration. Previously operators registered without
staking, producing zero weighted stake and getting filtered out by the
new selection logic.
- **`setup-validators.ts`**: Added a stake allocation pass after the
registration loop, invoking `AllocateOperatorStake.s.sol` per validator.
- **`validator-set-update.test.ts`**: Added debug logging for
transaction receipts and the `OutboundMessageAccepted` /
`ExternalValidatorsSet` events.
- **`generated.ts`**: Regenerated contract bindings to include new
functions, events, and the `EmptyValidatorSet` error.

## ⚠️ Breaking Changes ⚠️

- `addStrategiesToValidatorsSupportedStrategies(IStrategy[])` →
`addStrategiesToValidatorsSupportedStrategies(StrategyAndMultiplier[])`:
callers must supply multipliers alongside strategies.
- Operators with zero weighted stake are no longer included in the
bridged validator set.

## Rollout Notes

1. PR #433 (era-targeting + submitter role) must be deployed first
2. Deploy this `ServiceManager` upgrade
3. Confirm `strategiesAndMultipliers` is set for all active strategies
(default multiplier `1` applied automatically by `DeployBase`)
4. Deploy the runtime cap-enforcement changes (spec section 10.2)
5. Submitter daemon requires no changes — continues submitting
`targetEra = ActiveEra + 1`
2026-02-24 09:23:57 +01:00
Steve Degosserie
17c215d047
refactor(test): reorganize e2e test suites (#373)
## Summary

Reorganizes the test directory structure for better clarity and
maintainability:

- **Rename `test/datahaven/` → `test/moonwall/`**: Clearly identifies
these as Moonwall single-node tests
- **Move `test/framework/` → `test/e2e/framework/`**: Groups e2e test
utilities under a dedicated folder
- **Move `test/suites/` → `test/e2e/suites/`**: Groups e2e test suites
with the framework
- **Add `test/e2e/framework/validators.ts`**: Extracts validator test
helpers from utils into the e2e framework
- **Update documentation**: README.md and E2E_FRAMEWORK_OVERVIEW.md
reflect the new structure

### New Directory Structure

```
test/
├── e2e/
│   ├── suites/          # E2E test suites (Kurtosis-based)
│   └── framework/       # E2E test utilities & helpers
├── moonwall/            # Moonwall single-node tests
├── launcher/            # Network deployment tools
└── ...
```

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 15:52:33 +02:00