fix: 🐛 Use lodestar instead of lighthouse CL client (#91)

Lighthouse consensus layer client has a bug when building the next sync
committee merkle proof, that is preventing the Snowbridge relayer from
updating the next sync committee in the Ethereum Beacon Client pallet,
on the DataHaven Substrate chain. See issue
[here](https://github.com/sigp/lighthouse/issues/7552).

As a consequence, we're moving to the lodestar implementation.
This commit is contained in:
Facundo Farall 2025-06-09 12:29:31 -03:00 committed by GitHub
parent f07afda0b0
commit 001487e50f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 114 additions and 117 deletions

View file

@ -4,15 +4,15 @@ on:
workflow_dispatch:
inputs:
label:
description: 'Label for the Docker image'
description: "Label for the Docker image"
required: true
type: string
branch:
description: 'Branch to checkout and build'
description: "Branch to checkout and build"
required: true
type: string
fast_runtime:
description: 'Enable fast runtime features'
description: "Enable fast runtime features"
required: false
type: boolean
default: false
@ -116,6 +116,7 @@ jobs:
- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
timeout-minutes: 240 # 4 hours
with:
context: ./operator
file: ./operator/Dockerfile

View file

@ -20,7 +20,7 @@ This repo comes with a CLI for launching a local DataHaven network, packaged wit
1. A full Ethereum network with:
- 2 x Execution Layer clients (e.g., reth)
- 2 x Consensus Layer clients (e.g., lighthouse)
- 2 x Consensus Layer clients (e.g., lodestar)
- Blockscout Explorer services for EL (if enabled with --blockscout)
- Dora Explorer service for CL
- Contracts deployed and configured for the DataHaven network.

View file

@ -1,29 +1,29 @@
{
"source": {
"beacon": {
"endpoint": "http://cl-1-lighthouse-reth:4000",
"stateEndpoint": "http://cl-1-lighthouse-reth:4000",
"spec": {
"syncCommitteeSize": 512,
"slotsInEpoch": 32,
"epochsPerSyncCommitteePeriod": 256,
"forkVersions": {
"deneb": 0,
"electra": 0
}
},
"datastore": {
"location": "tmp/datastore",
"maxEntries": 100
}
"source": {
"beacon": {
"endpoint": "http://cl-1-lodestar-reth:4000",
"stateEndpoint": "http://cl-1-lodestar-reth:4000",
"spec": {
"syncCommitteeSize": 512,
"slotsInEpoch": 32,
"epochsPerSyncCommitteePeriod": 256,
"forkVersions": {
"deneb": 0,
"electra": 0
}
},
"sink": {
"parachain": {
"endpoint": "ws://dh-validator-0:9944",
"maxWatchedExtrinsics": 8,
"headerRedundancy": 20
},
"updateSlotInterval": 30
},
"datastore": {
"location": "tmp/datastore",
"maxEntries": 100
}
}
}
},
"sink": {
"parachain": {
"endpoint": "ws://dh-validator-0:9944",
"maxWatchedExtrinsics": 8,
"headerRedundancy": 20
},
"updateSlotInterval": 30
}
}

View file

@ -1,23 +1,23 @@
{
"source": {
"polkadot": {
"endpoint": "ws://dh-validator-0:9944"
}
},
"sink": {
"ethereum": {
"endpoint": "ws://el-1-reth-lighthouse:8546",
"gas-limit": ""
},
"descendants-until-final": 3,
"contracts": {
"BeefyClient": "0x4826533B4897376654Bb4d4AD88B7faFD0C98528",
"Gateway": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf"
}
},
"on-demand-sync": {
"max-tokens": 5,
"refill-amount": 1,
"refill-period": 3600
"source": {
"polkadot": {
"endpoint": "ws://dh-validator-0:9944"
}
}
},
"sink": {
"ethereum": {
"endpoint": "ws://el-1-reth-lodestar:8546",
"gas-limit": ""
},
"descendants-until-final": 3,
"contracts": {
"BeefyClient": "0x4826533B4897376654Bb4d4AD88B7faFD0C98528",
"Gateway": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf"
}
},
"on-demand-sync": {
"max-tokens": 5,
"refill-amount": 1,
"refill-period": 3600
}
}

View file

@ -1,41 +1,41 @@
{
"source": {
"ethereum": {
"endpoint": "ws://el-1-reth-lighthouse:8546"
},
"contracts": {
"Gateway": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf"
},
"channel-id": "",
"beacon": {
"endpoint": "http://cl-1-lighthouse-reth:4000",
"stateEndpoint": "http://cl-1-lighthouse-reth:4000",
"spec": {
"syncCommitteeSize": 512,
"slotsInEpoch": 32,
"epochsPerSyncCommitteePeriod": 256,
"forkVersions": {
"deneb": 0,
"electra": 0
}
},
"datastore": {
"location": "",
"maxEntries": 100
}
}
"source": {
"ethereum": {
"endpoint": "ws://el-1-reth-lodestar:8546"
},
"sink": {
"parachain": {
"endpoint": "ws://dh-validator-0:9944",
"maxWatchedExtrinsics": 8,
"headerRedundancy": 20
}
"contracts": {
"Gateway": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf"
},
"instantVerification": false,
"schedule": {
"id": 1,
"totalRelayerCount": 1,
"sleepInterval": 1
"channel-id": "",
"beacon": {
"endpoint": "http://cl-1-lodestar-reth:4000",
"stateEndpoint": "http://cl-1-lodestar-reth:4000",
"spec": {
"syncCommitteeSize": 512,
"slotsInEpoch": 32,
"epochsPerSyncCommitteePeriod": 256,
"forkVersions": {
"deneb": 0,
"electra": 0
}
},
"datastore": {
"location": "",
"maxEntries": 100
}
}
}
},
"sink": {
"parachain": {
"endpoint": "ws://dh-validator-0:9944",
"maxWatchedExtrinsics": 8,
"headerRedundancy": 20
}
},
"instantVerification": false,
"schedule": {
"id": 1,
"totalRelayerCount": 1,
"sleepInterval": 1
}
}

View file

@ -45,7 +45,7 @@ Follow these steps to set up and interact with your test environment:
2. Launch a DataHaven solochain.
3. Start a Kurtosis network which includes:
- 2 Ethereum Execution Layer clients (reth)
- 2 Ethereum Consensus Layer clients (lighthouse)
- 2 Ethereum Consensus Layer clients (lodestar)
- Blockscout Explorer services for EL (if enabled with --blockscout)
- Dora Explorer service for CL
4. Deploy DataHaven smart contracts to the Ethereum network. This can optionally include verification on Blockscout if the `--verified` flag is used (requires Blockscout to be enabled).

View file

@ -34,10 +34,10 @@ export interface LaunchOptions {
}
export const BASE_SERVICES = [
"cl-1-lighthouse-reth",
"cl-2-lighthouse-reth",
"el-1-reth-lighthouse",
"el-2-reth-lighthouse",
"cl-1-lodestar-reth",
"cl-2-lodestar-reth",
"el-1-reth-lodestar",
"el-2-reth-lodestar",
"dora"
];

View file

@ -158,22 +158,18 @@ const registerServices = async (launchedNetwork: LaunchedNetwork, enclaveName: s
// Configure EL RPC URL
try {
const rethPublicPort = await getPortFromKurtosis("el-1-reth-lighthouse", "rpc", enclaveName);
const rethPublicPort = await getPortFromKurtosis("el-1-reth-lodestar", "rpc", enclaveName);
invariant(rethPublicPort && rethPublicPort > 0, "❌ Could not find EL RPC port");
const elRpcUrl = `http://127.0.0.1:${rethPublicPort}`;
launchedNetwork.elRpcUrl = elRpcUrl;
logger.info(`📝 Execution Layer RPC URL configured: ${elRpcUrl}`);
// Configure CL Endpoint
const lighthousePublicPort = await getPortFromKurtosis(
"cl-1-lighthouse-reth",
"http",
enclaveName
);
const clEndpoint = `http://127.0.0.1:${lighthousePublicPort}`;
const lodestarPublicPort = await getPortFromKurtosis("cl-1-lodestar-reth", "http", enclaveName);
const clEndpoint = `http://127.0.0.1:${lodestarPublicPort}`;
invariant(
clEndpoint,
"❌ CL Endpoint could not be determined from Kurtosis service cl-1-lighthouse-reth"
"❌ CL Endpoint could not be determined from Kurtosis service cl-1-lodestar-reth"
);
launchedNetwork.clEndpoint = clEndpoint;
logger.info(`📝 Consensus Layer Endpoint configured: ${clEndpoint}`);

View file

@ -175,12 +175,12 @@ export const launchRelayers = async (options: LaunchOptions, launchedNetwork: La
const json = await file.json();
const ethWsPort = await getPortFromKurtosis(
"el-1-reth-lighthouse",
"el-1-reth-lodestar",
"ws",
options.kurtosisEnclaveName
);
const ethHttpPort = await getPortFromKurtosis(
"cl-1-lighthouse-reth",
"cl-1-lodestar-reth",
"http",
options.kurtosisEnclaveName
);
@ -394,8 +394,8 @@ export const initEthClientPallet = async (
datastorePath: string
) => {
logger.debug("Initialising eth client pallet");
// Poll the beacon chain until it's ready every 10 seconds for 5 minutes
await waitBeaconChainReady(launchedNetwork, 10000, 300000);
// Poll the beacon chain until it's ready every 10 seconds for 10 minutes
await waitBeaconChainReady(launchedNetwork, 10000, 600000);
const beaconConfigHostPath = path.resolve(RELAYER_CONFIG_PATHS.BEACON);
const beaconConfigContainerPath = `/app/${RELAYER_CONFIG_PATHS.BEACON}`;

View file

@ -1,6 +1,6 @@
participants:
- el_type: reth
cl_type: lighthouse
cl_type: lodestar
count: 2
additional_services:

View file

@ -13,9 +13,9 @@
"generate:snowbridge-cfgs": "bun -e \"import {generateSnowbridgeConfigs} from './scripts/gen-snowbridge-cfgs.ts'; await generateSnowbridgeConfigs()\"",
"generate:types": "(cd ../operator && cargo build --release) && bun x papi add --wasm \"../operator/target/release/wbuild/datahaven-stagenet-runtime/datahaven_stagenet_runtime.wasm\" datahaven",
"start:e2e:verified": "bun cli launch --verified --blockscout --deploy-contracts --setup-validators --update-validator-set --fund-validators",
"start:e2e:verified:relayers": "bun cli launch --verified --blockscout --deploy-contracts --setup-validators --update-validator-set --fund-validators --slot-time 1 --relayer --datahaven",
"start:e2e:verified:relayers": "bun cli launch --verified --blockscout --deploy-contracts --setup-validators --update-validator-set --fund-validators --relayer --datahaven",
"start:e2e:local": "LOG_LEVEL=debug bun start:e2e:ci --bd",
"start:e2e:ci": "bun cli launch --datahaven --no-build-datahaven --launch-kurtosis --deploy-contracts --fund-validators --setup-validators --update-validator-set --relayer --clean-network",
"start:e2e:ci": "bun cli launch --datahaven --no-build-datahaven --launch-kurtosis --deploy-contracts --fund-validators --setup-validators --update-validator-set --relayer --clean-network --slot-time 2",
"start:e2e:minrelayer": "bun cli launch --relayer --deploy-contracts --no-setup-validators --no-update-validator-set --no-fund-validators --datahaven",
"start:all": "bun cli launch --datahaven --build-datahaven --launch-kurtosis --deploy-contracts --fund-validators --setup-validators --update-validator-set --relayer --blockscout --verified --clean-network --set-parameters",
"stop:docker:datahaven": "docker rm -f $(docker ps -aq --filter name='^datahaven-') 2>/dev/null || true; docker network rm datahaven-net || true",

View file

@ -19,7 +19,7 @@ The first step involves setting up the testing infrastructure using Kurtosis, a
- **Ethereum Network**
- Execution Layer (EL) clients: reth nodes
- Consensus Layer (CL) clients: lighthouse nodes
- Consensus Layer (CL) clients: lodestar nodes
- Block explorer (Blockscout) for monitoring
- **DataHaven Solochain**
- Multiple validator nodes to form a test network

View file

@ -46,8 +46,8 @@ export const ANVIL_FUNDED_ACCOUNTS = {
export const CHAIN_ID = 3151908;
export const CONTAINER_NAMES = {
EL1: "el-1-reth-lighthouse",
EL2: "el-2-reth-lighthouse",
EL1: "el-1-reth-lodestar",
EL2: "el-2-reth-lodestar",
"blockscout-be": "blockscout--",
"blockscout-fe": "blockscout-frontend--"
} as const;

View file

@ -22,23 +22,23 @@ export type KurtosisServiceInfo = {
};
export const standardKurtosisServices = [
"el-1-reth-lighthouse",
"el-2-reth-lighthouse",
"vc-1-reth-lighthouse",
"vc-2-reth-lighthouse",
"el-1-reth-lodestar",
"el-2-reth-lodestar",
"vc-1-reth-lodestar",
"vc-2-reth-lodestar",
"dora"
];
export const StandardServiceMappings: ServiceMapping[] = [
{
service: "reth-1-rpc",
containerPattern: "el-1-reth-lighthouse",
containerPattern: "el-1-reth-lodestar",
internalPort: 8545,
protocol: "tcp"
},
{
service: "reth-2-rpc",
containerPattern: "el-2-reth-lighthouse",
containerPattern: "el-2-reth-lodestar",
internalPort: 8545,
protocol: "tcp"
},