diff --git a/packages/cli/src/networks/ephemery.ts b/packages/cli/src/networks/ephemery.ts new file mode 100644 index 000000000000..f3d2dcacd7f1 --- /dev/null +++ b/packages/cli/src/networks/ephemery.ts @@ -0,0 +1,8 @@ +export {ephemeryChainConfig as chainConfig} from "@lodestar/config/networks"; + +export const depositContractDeployBlock = 0; +export const genesisFileUrl = "https://ephemery.dev/latest/genesis.ssz"; +export const bootnodesFileUrl = "https://ephemery.dev/latest/bootstrap_nodes.txt"; + +// Pick from above file +export const bootEnrs = []; diff --git a/packages/cli/src/networks/index.ts b/packages/cli/src/networks/index.ts index a44575b94351..85846164b473 100644 --- a/packages/cli/src/networks/index.ts +++ b/packages/cli/src/networks/index.ts @@ -18,8 +18,18 @@ import * as ropsten from "./ropsten.js"; import * as sepolia from "./sepolia.js"; import * as holesky from "./holesky.js"; import * as chiado from "./chiado.js"; - -export type NetworkName = "mainnet" | "dev" | "gnosis" | "goerli" | "ropsten" | "sepolia" | "holesky" | "chiado"; +import * as ephemery from "./ephemery.js"; + +export type NetworkName = + | "mainnet" + | "dev" + | "gnosis" + | "goerli" + | "ropsten" + | "sepolia" + | "holesky" + | "chiado" + | "ephemery"; export const networkNames: NetworkName[] = [ "mainnet", "gnosis", @@ -28,6 +38,7 @@ export const networkNames: NetworkName[] = [ "sepolia", "holesky", "chiado", + "ephemery", // Leave always as last network. The order matters for the --help printout "dev", @@ -69,6 +80,8 @@ export function getNetworkData(network: NetworkName): { return holesky; case "chiado": return chiado; + case "ephemery": + return ephemery; default: throw Error(`Network not supported: ${network}`); } diff --git a/packages/config/src/chainConfig/networks/ephemery.ts b/packages/config/src/chainConfig/networks/ephemery.ts new file mode 100644 index 000000000000..c338c26f2cf3 --- /dev/null +++ b/packages/config/src/chainConfig/networks/ephemery.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import {fromHexString as b} from "@chainsafe/ssz"; +import {ChainConfig} from "../types.js"; +import {chainConfig as mainnet} from "../presets/mainnet.js"; + +// Ephemery dynamic beacon chain config: +// https://github.com/ephemery-testnet/ephemery-genesis/blob/master/cl-config.yaml + +// Ephemery specification: +// https://github.com/taxmeifyoucan/EIPs/blob/d298cdd8eaf47a21e7770e5c6efef870587c924d/EIPS/eip-6916.md + +// iteration 0, "base"-genesis +const baseChainConfig: ChainConfig = { + ...mainnet, + + CONFIG_NAME: "ephemery", + + // Genesis + // --------------------------------------------------------------- + MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 64, + // Thu Dec 02 2021 19:00:00 GMT+0000 + MIN_GENESIS_TIME: 1638471600, + GENESIS_FORK_VERSION: b("0x1000101b"), + GENESIS_DELAY: 300, + + // Forking + // --------------------------------------------------------------- + // Altair + ALTAIR_FORK_VERSION: b("0x2000101b"), + ALTAIR_FORK_EPOCH: 0, + // Merge + BELLATRIX_FORK_VERSION: b("0x3000101b"), + BELLATRIX_FORK_EPOCH: 0, + TERMINAL_TOTAL_DIFFICULTY: BigInt("0"), + // Capella + CAPELLA_FORK_VERSION: b("0x4000101b"), + CAPELLA_FORK_EPOCH: 0, + // Deneb + DENEB_FORK_VERSION: b("0x5000101b"), + + // Deposit contract + // --------------------------------------------------------------- + DEPOSIT_CHAIN_ID: 39438000, + DEPOSIT_NETWORK_ID: 39438000, + DEPOSIT_CONTRACT_ADDRESS: b("0x4242424242424242424242424242424242424242"), + + ETH1_FOLLOW_DISTANCE: 12, +}; + +// Reset interval (7 days) in milliseconds, based on ephemery-genesis values.env: +// https://github.com/ephemery-testnet/ephemery-genesis/blob/9a28fbef950c8547d78785f8a0ea49a95ce19a48/values.env#L5 +const RESET_INTERVAL_MS = 604800000; +const iteration = Math.floor(Date.now() - baseChainConfig.MIN_GENESIS_TIME) / RESET_INTERVAL_MS; + +export const ephemeryChainConfig: ChainConfig = { + ...baseChainConfig, + + MIN_GENESIS_TIME: RESET_INTERVAL_MS * iteration + baseChainConfig.MIN_GENESIS_TIME, + DEPOSIT_CHAIN_ID: baseChainConfig.DEPOSIT_CHAIN_ID + iteration, + DEPOSIT_NETWORK_ID: baseChainConfig.DEPOSIT_NETWORK_ID + iteration, +}; diff --git a/packages/config/src/networks.ts b/packages/config/src/networks.ts index e9d549fa1e75..8ff3cdd15256 100644 --- a/packages/config/src/networks.ts +++ b/packages/config/src/networks.ts @@ -6,6 +6,7 @@ import {ropstenChainConfig} from "./chainConfig/networks/ropsten.js"; import {sepoliaChainConfig} from "./chainConfig/networks/sepolia.js"; import {holeskyChainConfig} from "./chainConfig/networks/holesky.js"; import {chiadoChainConfig} from "./chainConfig/networks/chiado.js"; +import {ephemeryChainConfig} from "./chainConfig/networks/ephemery.js"; export { mainnetChainConfig, @@ -15,9 +16,10 @@ export { sepoliaChainConfig, holeskyChainConfig, chiadoChainConfig, + ephemeryChainConfig, }; -export type NetworkName = "mainnet" | "gnosis" | "goerli" | "ropsten" | "sepolia" | "holesky" | "chiado"; +export type NetworkName = "mainnet" | "gnosis" | "goerli" | "ropsten" | "sepolia" | "holesky" | "chiado" | "ephemery"; export const networksChainConfig: Record = { mainnet: mainnetChainConfig, gnosis: gnosisChainConfig, @@ -26,6 +28,7 @@ export const networksChainConfig: Record = { sepolia: sepoliaChainConfig, holesky: holeskyChainConfig, chiado: chiadoChainConfig, + ephemery: ephemeryChainConfig, }; export type GenesisData = { @@ -62,4 +65,8 @@ export const genesisData: Record = { genesisTime: 1665396300, genesisValidatorsRoot: "0x9d642dac73058fbf39c0ae41ab1e34e4d889043cb199851ded7095bc99eb4c1e", }, + ephemery: { + genesisTime: ephemeryChainConfig.MIN_GENESIS_TIME + ephemeryChainConfig.GENESIS_DELAY, + genesisValidatorsRoot: "0x0000000000000000000000000000000000000000000000000000000000000000", + }, }; diff --git a/packages/prover/src/utils/execution.ts b/packages/prover/src/utils/execution.ts index dcab3d7d7fb4..083f15e1e5dd 100644 --- a/packages/prover/src/utils/execution.ts +++ b/packages/prover/src/utils/execution.ts @@ -46,6 +46,7 @@ export function getChainCommon(network: string): Common { case "ropsten": case "sepolia": case "holesky": + case "ephemery": // TODO: Not sure how to detect the fork during runtime return new Common({chain: network, hardfork: Hardfork.Shanghai}); case "minimal":