# EPF6 - Week 16 ## Overview - Attended Lodestar Weekly Standups and [shared updates](https://github.com/ChainSafe/lodestar/wiki/Lodestar-Weekly-Standups-2025#epf-contributors-progress) - Continued working on the `NodePair[]` recreation from Kurtosis, with the goal of achieving 1:1 assertion parity with the Docker-based flow. - Continued refining and expanding the creation of **Beacon**, **Execution**, and **Validator** nodes to fully integrate into the new Kurtosis-based `NodePair[]`, ensuring 1:1 parity with Docker-based simulation flow. - Investigated Engine API authentication via `SHARED_JWT_SECRET` and how to manage it in Kurtosis compared to Lodestar’s handling. - Completed the removal of Docker-specific `Job` and `JobOptions` references, with related logic moved to utils/syncing.ts. - Aligned the Kurtosis configuration to correctly manage shared JWT tokens between CL and EL clients. ## Main points - **Node creation functions refinement** - Implemented and reviewed: - `createExecutionNodeFromKurtosis(service, executionType, nodeIndex, elExtraParams)`: ```typescript private async createExecutionNodeFromKurtosis( service: NodeService, executionType: ExecutionClient, nodeIndex: number, elExtraParams: string[] ): Promise<ExecutionNode> { // Ports for public and private URLs for the execution node (Kurtosis services) const httpPort = this.getPort(service, "rpc", "http"); const engPort = this.getPort(service, "engine-rpc", "engine"); const ethRpcPublicUrl = httpPort ? `http://localhost:${httpPort}` : ""; const engineRpcPublicUrl = engPort ? `http://localhost:${engPort}` : ""; const provider = executionType === ExecutionClient.Mock ? null : new (await import("web3")).Web3(ethRpcPublicUrl); if (provider) { const {registerWeb3JsPlugins} = await import("../../web3js/plugins/index.js"); registerWeb3JsPlugins(provider); } if (elExtraParams.length > 0) { this.logger.info(`EL ${service.id} extra params: ${elExtraParams.join(" ")}`); } return { client: executionType, id: `${service.id}-execution-${executionType}`, ttd: BigInt(this.forkConfig.TERMINAL_TOTAL_DIFFICULTY), engineRpcPublicUrl, engineRpcPrivateUrl: engineRpcPublicUrl, ethRpcPublicUrl, ethRpcPrivateUrl: ethRpcPublicUrl, jwtSecretHex: undefined, //Lodestar uses 'SHARED_JWT_SECRET', ethereum-package is hardcoded, provider, serviceContext: service.serviceContext, }; } → Logs **elExtraParams** for traceability; keeps config minimal (URLs, jwt, provider, ttd). - `createValidatorNodeFromKurtosis(service, validatorType, beacon, vcExtraParams)` → Logs **vcExtraParams**; builds KeyManager client using forkConfig. - `createBeaconNodeFromKurtosis(service, beaconType)` → Builds API client from forkConfig :::success :bulb: These functions now aim to generate **assertion-ready node objects**, compatible with Lodestar’s existing test assertions. ::: - **Validator client investigation** - Found that in the current Kurtosis setup, VC services only exposed metrics and not HTTP endpoints. - This conflicted with Lodestar’s KeyManager expectations (which typically live on the beacon REST). - Patched configuration by enabling the **VC HTTP** interface through `keymanager_enabled: true` in the ethereum-package. - After patching, VC services now expose both http-validator and metrics ports as expected. - **Engine API and auth** - Investigated how Lodestar handles the `SHARED_JWT_SECRET` for Engine API authentication. - Aligned the Kurtosis configuration to correctly manage **shared JWT tokens** between CL and EL clients. - Discussed with my mentor to confirm whether the `SHARED_JWT_SECRET` plays any active role in assertion management, since Lodestar and the ethereum-package each define their own hardcoded JWT secrets. I was concerned this mismatch could block a full migration. - The mentor clarified that assertions use **public node APIs**, so the JWT is not involved in assertion logic. The JWT is only required for EL↔CL communication (execution node to beacon node), which Kurtosis handles internally. Therefore, **the difference in JWT handling does not affect the migration.** ## Learnings & Outcomes - The Node creation logic now closely mirrors the Docker-based version and is in a draft state, pending end-to-end validation against `multiFork.test.ts`. Early checks suggest the structure aligns correctly, but full execution and assertion testing are still to come. - `keymanager_enabled: true` was essential for proper validator client exposure. - Kurtosis-based NodePair generation ensures that assertions (e.g., `nodeAssertion`, `accountBalanceAssertion`) can be reused without API modifications. - **Next challenge**: confirm runtime **CL–EL wiring** in Kurtosis matches Docker behavior to ensure assertions reach all endpoints. ## Week 17 TODOs - Commit the draft implementation of `NodePair[]` recreation to receive mentor feedback before proceeding with further testing. - Verify assertion parity with **multiFork.test.ts**. - Start outlining the final presentation for Devconnect on the migration work. ### Useful resources checked [Lodestar JWT ethereum-package](https://github.com/ethpandaops/ethereum-package/blob/ae74385e68086c1984fcd4a4eba995d0cb09afa7/src/cl/lodestar/lodestar_launcher.star#L185) [Lodestar GitHub JWT](https://github.com/ChainSafe/lodestar/blob/793f92c091c563a744a4cc4ec261e142d299853f/packages/cli/test/utils/crucible/constants.ts#L23)