@lodestar/config 1.35.0-dev.a70bac5bd3 → 1.35.0-dev.ba92bd8a88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/lib/beaconConfig.d.ts.map +1 -0
  2. package/lib/chainConfig/configs/mainnet.d.ts.map +1 -0
  3. package/lib/chainConfig/configs/mainnet.js +10 -0
  4. package/lib/chainConfig/configs/mainnet.js.map +1 -1
  5. package/lib/chainConfig/configs/minimal.d.ts.map +1 -0
  6. package/lib/chainConfig/configs/minimal.js +10 -0
  7. package/lib/chainConfig/configs/minimal.js.map +1 -1
  8. package/lib/chainConfig/default.d.ts.map +1 -0
  9. package/lib/chainConfig/index.d.ts +2 -2
  10. package/lib/chainConfig/index.d.ts.map +1 -0
  11. package/lib/chainConfig/index.js +2 -2
  12. package/lib/chainConfig/index.js.map +1 -1
  13. package/lib/chainConfig/json.d.ts.map +1 -0
  14. package/lib/chainConfig/networks/chiado.d.ts.map +1 -0
  15. package/lib/chainConfig/networks/ephemery.d.ts.map +1 -0
  16. package/lib/chainConfig/networks/gnosis.d.ts.map +1 -0
  17. package/lib/chainConfig/networks/holesky.d.ts.map +1 -0
  18. package/lib/chainConfig/networks/holesky.js +11 -2
  19. package/lib/chainConfig/networks/holesky.js.map +1 -1
  20. package/lib/chainConfig/networks/hoodi.d.ts.map +1 -0
  21. package/lib/chainConfig/networks/hoodi.js +11 -2
  22. package/lib/chainConfig/networks/hoodi.js.map +1 -1
  23. package/lib/chainConfig/networks/mainnet.d.ts.map +1 -0
  24. package/lib/chainConfig/networks/sepolia.d.ts.map +1 -0
  25. package/lib/chainConfig/networks/sepolia.js +11 -2
  26. package/lib/chainConfig/networks/sepolia.js.map +1 -1
  27. package/lib/chainConfig/types.d.ts +5 -0
  28. package/lib/chainConfig/types.d.ts.map +1 -0
  29. package/lib/chainConfig/types.js +5 -0
  30. package/lib/chainConfig/types.js.map +1 -1
  31. package/lib/configs.d.ts.map +1 -0
  32. package/lib/default.d.ts +1 -1
  33. package/lib/default.d.ts.map +1 -0
  34. package/lib/forkConfig/index.d.ts.map +1 -0
  35. package/lib/forkConfig/types.d.ts.map +1 -0
  36. package/lib/genesisConfig/index.d.ts.map +1 -0
  37. package/lib/genesisConfig/index.js.map +1 -1
  38. package/lib/genesisConfig/types.d.ts.map +1 -0
  39. package/lib/index.d.ts +2 -2
  40. package/lib/index.d.ts.map +1 -0
  41. package/lib/index.js +2 -2
  42. package/lib/index.js.map +1 -1
  43. package/lib/networks.d.ts.map +1 -0
  44. package/lib/utils/validateBlobSchedule.d.ts.map +1 -0
  45. package/package.json +12 -10
  46. package/src/beaconConfig.ts +31 -0
  47. package/src/chainConfig/configs/mainnet.ts +158 -0
  48. package/src/chainConfig/configs/minimal.ts +153 -0
  49. package/src/chainConfig/default.ts +19 -0
  50. package/src/chainConfig/index.ts +27 -0
  51. package/src/chainConfig/json.ts +175 -0
  52. package/src/chainConfig/networks/chiado.ts +49 -0
  53. package/src/chainConfig/networks/ephemery.ts +71 -0
  54. package/src/chainConfig/networks/gnosis.ts +74 -0
  55. package/src/chainConfig/networks/holesky.ts +64 -0
  56. package/src/chainConfig/networks/hoodi.ts +64 -0
  57. package/src/chainConfig/networks/mainnet.ts +19 -0
  58. package/src/chainConfig/networks/sepolia.ts +61 -0
  59. package/src/chainConfig/types.ts +252 -0
  60. package/src/configs.ts +4 -0
  61. package/src/default.ts +6 -0
  62. package/src/forkConfig/index.ts +203 -0
  63. package/src/forkConfig/types.ts +59 -0
  64. package/src/genesisConfig/index.ts +180 -0
  65. package/src/genesisConfig/types.ts +29 -0
  66. package/src/index.ts +4 -0
  67. package/src/networks.ts +65 -0
  68. package/src/utils/validateBlobSchedule.ts +32 -0
@@ -0,0 +1,158 @@
1
+ import {PresetName} from "@lodestar/params";
2
+ import {fromHex as b} from "@lodestar/utils";
3
+ import {ChainConfig} from "../types.js";
4
+
5
+ // Mainnet config
6
+ // https://github.com/ethereum/consensus-specs/blob/dev/configs/mainnet.yaml
7
+
8
+ export const chainConfig: ChainConfig = {
9
+ // Extends the mainnet preset
10
+ PRESET_BASE: PresetName.mainnet,
11
+ CONFIG_NAME: "mainnet",
12
+
13
+ // Transition
14
+ // Estimated: Sept 15, 2022
15
+ TERMINAL_TOTAL_DIFFICULTY: BigInt("58750000000000000000000"),
16
+ TERMINAL_BLOCK_HASH: b("0x0000000000000000000000000000000000000000000000000000000000000000"),
17
+ TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: Infinity,
18
+
19
+ // Genesis
20
+ // ---------------------------------------------------------------
21
+ // `2**14` (= 16,384)
22
+ MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16384,
23
+ // Dec 1, 2020, 12pm UTC
24
+ MIN_GENESIS_TIME: 1606824000,
25
+ // Mainnet initial fork version, recommend altering for testnets
26
+ GENESIS_FORK_VERSION: b("0x00000000"),
27
+ // 604800 seconds (7 days)
28
+ GENESIS_DELAY: 604800,
29
+
30
+ // Forking
31
+ // ---------------------------------------------------------------
32
+ // Some forks are disabled for now:
33
+ // - These may be re-assigned to another fork-version later
34
+ // - Temporarily set to max uint64 value: 2**64 - 1
35
+
36
+ // Altair
37
+ ALTAIR_FORK_VERSION: b("0x01000000"),
38
+ ALTAIR_FORK_EPOCH: 74240, // Oct 27, 2021, 10:56:23am UTC
39
+ // Bellatrix
40
+ BELLATRIX_FORK_VERSION: b("0x02000000"),
41
+ BELLATRIX_FORK_EPOCH: 144896, // Sept 6, 2022, 11:34:47am UTC
42
+
43
+ // Capella
44
+ CAPELLA_FORK_VERSION: b("0x03000000"),
45
+ CAPELLA_FORK_EPOCH: 194048, // April 12 (epoch: 194048 slot: 6209536 UTC: 4/12/2023, 10:27:35 PM)
46
+
47
+ // Deneb
48
+ DENEB_FORK_VERSION: b("0x04000000"),
49
+ DENEB_FORK_EPOCH: 269568, // March 13, 2024, 01:55:35pm UTC
50
+
51
+ // ELECTRA
52
+ ELECTRA_FORK_VERSION: b("0x05000000"),
53
+ ELECTRA_FORK_EPOCH: 364032, // May 7, 2025, 10:05:11am UTC
54
+
55
+ // FULU
56
+ FULU_FORK_VERSION: b("0x06000000"),
57
+ FULU_FORK_EPOCH: Infinity,
58
+
59
+ // GLOAS
60
+ GLOAS_FORK_VERSION: b("0x07000000"),
61
+ GLOAS_FORK_EPOCH: Infinity,
62
+
63
+ // Time parameters
64
+ // ---------------------------------------------------------------
65
+ // 12 seconds
66
+ SECONDS_PER_SLOT: 12,
67
+ // 14 (estimate from Eth1 mainnet)
68
+ SECONDS_PER_ETH1_BLOCK: 14,
69
+ // 2**8 (= 256) epochs ~27 hours
70
+ MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256,
71
+ // 2**8 (= 256) epochs ~27 hours
72
+ SHARD_COMMITTEE_PERIOD: 256,
73
+ // 2**11 (= 2,048) Eth1 blocks ~8 hours
74
+ ETH1_FOLLOW_DISTANCE: 2048,
75
+
76
+ // 25% of SLOT_DURATION_MS
77
+ ATTESTATION_DUE_BPS_GLOAS: 2500,
78
+ // 50% of SLOT_DURATION_MS
79
+ AGGREGATE_DUE_BPS_GLOAS: 5000,
80
+ // 25% of SLOT_DURATION_MS
81
+ SYNC_MESSAGE_DUE_BPS_GLOAS: 2500,
82
+ // 50% of SLOT_DURATION_MS
83
+ CONTRIBUTION_DUE_BPS_GLOAS: 5000,
84
+ // 75% of SLOT_DURATION_MS
85
+ PAYLOAD_ATTESTATION_DUE_BPS: 7500,
86
+
87
+ // Validator cycle
88
+ // ---------------------------------------------------------------
89
+ // 2**2 (= 4)
90
+ INACTIVITY_SCORE_BIAS: 4,
91
+ // 2**4 (= 16)
92
+ INACTIVITY_SCORE_RECOVERY_RATE: 16,
93
+ // 2**4 * 10**9 (= 16,000,000,000) Gwei
94
+ EJECTION_BALANCE: 16000000000,
95
+ // 2**2 (= 4)
96
+ MIN_PER_EPOCH_CHURN_LIMIT: 4,
97
+ // 2**3 (= 8)
98
+ MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8,
99
+ // 2**16 (= 65,536)
100
+ CHURN_LIMIT_QUOTIENT: 65536,
101
+
102
+ // Fork choice
103
+ // ---------------------------------------------------------------
104
+ // 40%
105
+ PROPOSER_SCORE_BOOST: 40,
106
+ REORG_HEAD_WEIGHT_THRESHOLD: 20,
107
+ REORG_PARENT_WEIGHT_THRESHOLD: 160,
108
+ REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2,
109
+
110
+ // Deposit contract
111
+ // ---------------------------------------------------------------
112
+ // Ethereum PoW Mainnet
113
+ DEPOSIT_CHAIN_ID: 1,
114
+ DEPOSIT_NETWORK_ID: 1,
115
+ DEPOSIT_CONTRACT_ADDRESS: b("0x00000000219ab540356cBB839Cbe05303d7705Fa"),
116
+
117
+ // Networking
118
+ // ---------------------------------------------------------------
119
+ // 2**10 (= 1024)
120
+ MAX_REQUEST_BLOCKS: 1024,
121
+ // `MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2` (= 33024, ~5 months)
122
+ MIN_EPOCHS_FOR_BLOCK_REQUESTS: 33024,
123
+
124
+ // Deneb
125
+ // 2**7 (= 128)
126
+ MAX_REQUEST_BLOCKS_DENEB: 128,
127
+ // `2**12` (= 4096 epochs, ~18 days)
128
+ MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096,
129
+ BLOB_SIDECAR_SUBNET_COUNT: 6,
130
+ MAX_BLOBS_PER_BLOCK: 6,
131
+ // MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
132
+ MAX_REQUEST_BLOB_SIDECARS: 768,
133
+
134
+ // Electra
135
+ // 2**8 * 10**9 (= 256,000,000,000)
136
+ MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 256000000000,
137
+ // 2**7 * 10**9 (= 128,000,000,000)
138
+ MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 128000000000,
139
+ BLOB_SIDECAR_SUBNET_COUNT_ELECTRA: 9,
140
+ MAX_BLOBS_PER_BLOCK_ELECTRA: 9,
141
+ // MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_ELECTRA
142
+ MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 1152,
143
+
144
+ // Fulu
145
+ NUMBER_OF_CUSTODY_GROUPS: 128,
146
+ DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128,
147
+ MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384,
148
+ SAMPLES_PER_SLOT: 8,
149
+ CUSTODY_REQUIREMENT: 4,
150
+ VALIDATOR_CUSTODY_REQUIREMENT: 8,
151
+ BALANCE_PER_ADDITIONAL_CUSTODY_GROUP: 32000000000,
152
+ // `2**12` (= 4096 epochs, ~18 days)
153
+ MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS: 4096,
154
+
155
+ // Blob Scheduling
156
+ // ---------------------------------------------------------------
157
+ BLOB_SCHEDULE: [],
158
+ };
@@ -0,0 +1,153 @@
1
+ import {PresetName} from "@lodestar/params";
2
+ import {fromHex as b} from "@lodestar/utils";
3
+ import {ChainConfig} from "../types.js";
4
+
5
+ // Minimal config
6
+ // https://github.com/ethereum/consensus-specs/blob/dev/configs/minimal.yaml
7
+
8
+ export const chainConfig: ChainConfig = {
9
+ // Extends the minimal preset
10
+ PRESET_BASE: PresetName.minimal,
11
+ CONFIG_NAME: "minimal",
12
+
13
+ // Transition
14
+ // 2**256-2**10 for testing minimal network
15
+ TERMINAL_TOTAL_DIFFICULTY: BigInt("115792089237316195423570985008687907853269984665640564039457584007913129638912"),
16
+ TERMINAL_BLOCK_HASH: b("0x0000000000000000000000000000000000000000000000000000000000000000"),
17
+ TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: Infinity,
18
+
19
+ // Genesis
20
+ // ---------------------------------------------------------------
21
+ // [customized]
22
+ MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 64,
23
+ // Jan 3, 2020
24
+ MIN_GENESIS_TIME: 1578009600,
25
+ // Highest byte set to 0x01 to avoid collisions with mainnet versioning
26
+ GENESIS_FORK_VERSION: b("0x00000001"),
27
+ // [customized] Faster to spin up testnets, but does not give validator reasonable warning time for genesis
28
+ GENESIS_DELAY: 300,
29
+
30
+ // Forking
31
+ // ---------------------------------------------------------------
32
+ // Values provided for illustrative purposes.
33
+ // Individual tests/testnets may set different values.
34
+
35
+ // Altair
36
+ ALTAIR_FORK_VERSION: b("0x01000001"),
37
+ ALTAIR_FORK_EPOCH: 74240, // Oct 27, 2021, 10:56:23am UTC
38
+ // Bellatrix
39
+ BELLATRIX_FORK_VERSION: b("0x02000001"),
40
+ BELLATRIX_FORK_EPOCH: Infinity,
41
+ // Capella
42
+ CAPELLA_FORK_VERSION: b("0x03000001"),
43
+ CAPELLA_FORK_EPOCH: Infinity,
44
+ // Deneb
45
+ DENEB_FORK_VERSION: b("0x04000001"),
46
+ DENEB_FORK_EPOCH: Infinity,
47
+ // ELECTRA
48
+ ELECTRA_FORK_VERSION: b("0x05000001"),
49
+ ELECTRA_FORK_EPOCH: Infinity,
50
+ // FULU
51
+ FULU_FORK_VERSION: b("0x06000001"),
52
+ FULU_FORK_EPOCH: Infinity,
53
+ // GLOAS
54
+ GLOAS_FORK_VERSION: b("0x07000001"),
55
+ GLOAS_FORK_EPOCH: Infinity,
56
+
57
+ // Time parameters
58
+ // ---------------------------------------------------------------
59
+ // [customized] Faster for testing purposes
60
+ SECONDS_PER_SLOT: 6,
61
+ // 14 (estimate from Eth1 mainnet)
62
+ SECONDS_PER_ETH1_BLOCK: 14,
63
+ // 2**8 (= 256) epochs
64
+ MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256,
65
+ // [customized] higher frequency of committee turnover and faster time to acceptable voluntary exit
66
+ SHARD_COMMITTEE_PERIOD: 64,
67
+ // [customized] process deposits more quickly, but insecure
68
+ ETH1_FOLLOW_DISTANCE: 16,
69
+
70
+ // 25% of SLOT_DURATION_MS
71
+ ATTESTATION_DUE_BPS_GLOAS: 2500,
72
+ // 50% of SLOT_DURATION_MS
73
+ AGGREGATE_DUE_BPS_GLOAS: 5000,
74
+ // 25% of SLOT_DURATION_MS
75
+ SYNC_MESSAGE_DUE_BPS_GLOAS: 2500,
76
+ // 50% of SLOT_DURATION_MS
77
+ CONTRIBUTION_DUE_BPS_GLOAS: 5000,
78
+ // 75% of SLOT_DURATION_MS
79
+ PAYLOAD_ATTESTATION_DUE_BPS: 7500,
80
+
81
+ // Validator cycle
82
+ // ---------------------------------------------------------------
83
+ // 2**2 (= 4)
84
+ INACTIVITY_SCORE_BIAS: 4,
85
+ // 2**4 (= 16)
86
+ INACTIVITY_SCORE_RECOVERY_RATE: 16,
87
+ // 2**4 * 10**9 (= 16,000,000,000) Gwei
88
+ EJECTION_BALANCE: 16000000000,
89
+ // 2**2 (= 4)
90
+ MIN_PER_EPOCH_CHURN_LIMIT: 2,
91
+ // [customized]
92
+ MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 4,
93
+ // [customized] scale queue churn at much lower validator counts for testing
94
+ CHURN_LIMIT_QUOTIENT: 32,
95
+
96
+ // Fork choice
97
+ // ---------------------------------------------------------------
98
+ // 40%
99
+ PROPOSER_SCORE_BOOST: 40,
100
+ REORG_HEAD_WEIGHT_THRESHOLD: 20,
101
+ REORG_PARENT_WEIGHT_THRESHOLD: 160,
102
+ REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2,
103
+
104
+ // Deposit contract
105
+ // ---------------------------------------------------------------
106
+ // Ethereum Goerli testnet
107
+ DEPOSIT_CHAIN_ID: 5,
108
+ DEPOSIT_NETWORK_ID: 5,
109
+ // Configured on a per testnet basis
110
+ DEPOSIT_CONTRACT_ADDRESS: b("0x1234567890123456789012345678901234567890"),
111
+
112
+ // Networking
113
+ // ---------------------------------------------------------------
114
+ // 2**10 (= 1024)
115
+ MAX_REQUEST_BLOCKS: 1024,
116
+ // [customized] `MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2` (= 272)
117
+ MIN_EPOCHS_FOR_BLOCK_REQUESTS: 272,
118
+
119
+ // Deneb
120
+ // 2**7 (= 128)
121
+ MAX_REQUEST_BLOCKS_DENEB: 128,
122
+ // `2**12` (= 4096 epochs, ~18 days)
123
+ MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096,
124
+ BLOB_SIDECAR_SUBNET_COUNT: 6,
125
+ MAX_BLOBS_PER_BLOCK: 6,
126
+ // MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
127
+ MAX_REQUEST_BLOB_SIDECARS: 768,
128
+
129
+ // Electra
130
+ // 2**7 * 10**9 (= 128,000,000,000)
131
+ MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 128000000000,
132
+ // 2**6 * 10**9 (= 64,000,000,000)
133
+ MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 64000000000,
134
+ BLOB_SIDECAR_SUBNET_COUNT_ELECTRA: 9,
135
+ MAX_BLOBS_PER_BLOCK_ELECTRA: 9,
136
+ // MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_ELECTRA
137
+ MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 1152,
138
+
139
+ // Fulu
140
+ NUMBER_OF_CUSTODY_GROUPS: 128,
141
+ DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128,
142
+ MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384,
143
+ SAMPLES_PER_SLOT: 8,
144
+ CUSTODY_REQUIREMENT: 4,
145
+ VALIDATOR_CUSTODY_REQUIREMENT: 8,
146
+ BALANCE_PER_ADDITIONAL_CUSTODY_GROUP: 32000000000,
147
+ // `2**12` (= 4096 epochs, ~18 days)
148
+ MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS: 4096,
149
+
150
+ // Blob Scheduling
151
+ // ---------------------------------------------------------------
152
+ BLOB_SCHEDULE: [],
153
+ };
@@ -0,0 +1,19 @@
1
+ import {ACTIVE_PRESET, PresetName} from "@lodestar/params";
2
+ import {chainConfig as mainnet} from "./configs/mainnet.js";
3
+ import {chainConfig as minimal} from "./configs/minimal.js";
4
+ import {ChainConfig} from "./types.js";
5
+
6
+ let defaultChainConfig: ChainConfig;
7
+
8
+ switch (ACTIVE_PRESET) {
9
+ case PresetName.minimal:
10
+ defaultChainConfig = minimal;
11
+ break;
12
+ case PresetName.mainnet:
13
+ defaultChainConfig = mainnet;
14
+ break;
15
+ default:
16
+ defaultChainConfig = mainnet;
17
+ }
18
+
19
+ export {defaultChainConfig};
@@ -0,0 +1,27 @@
1
+ import {ACTIVE_PRESET} from "@lodestar/params";
2
+ import {defaultChainConfig} from "./default.js";
3
+ import {ChainConfig} from "./types.js";
4
+
5
+ export * from "./default.js";
6
+ export {chainConfigFromJson, chainConfigToJson, deserializeBlobSchedule, specValuesToJson} from "./json.js";
7
+ export * from "./types.js";
8
+
9
+ /**
10
+ * Create an `ChainConfig`, filling in missing values with preset defaults
11
+ */
12
+ export function createChainConfig(input: Partial<ChainConfig>): ChainConfig {
13
+ const config = {
14
+ // Set the config first with default preset values
15
+ ...defaultChainConfig,
16
+ // Override with input
17
+ ...input,
18
+ };
19
+
20
+ // Assert that the preset matches the active preset
21
+ if (config.PRESET_BASE !== ACTIVE_PRESET) {
22
+ throw new Error(
23
+ `Can only create a config for the active preset: ACTIVE_PRESET=${ACTIVE_PRESET} PRESET_BASE=${config.PRESET_BASE}`
24
+ );
25
+ }
26
+ return config;
27
+ }
@@ -0,0 +1,175 @@
1
+ import {fromHex, toHex} from "@lodestar/utils";
2
+ import {validateBlobSchedule} from "../utils/validateBlobSchedule.js";
3
+ import {
4
+ BlobSchedule,
5
+ BlobScheduleEntry,
6
+ ChainConfig,
7
+ SpecJson,
8
+ SpecValue,
9
+ SpecValueTypeName,
10
+ chainConfigTypes,
11
+ isBlobSchedule,
12
+ } from "./types.js";
13
+
14
+ const MAX_UINT64_JSON = "18446744073709551615";
15
+
16
+ export function chainConfigToJson(config: ChainConfig): SpecJson {
17
+ const json: SpecJson = {};
18
+
19
+ for (const key of Object.keys(chainConfigTypes) as (keyof ChainConfig)[]) {
20
+ const value = config[key];
21
+ if (value !== undefined) {
22
+ json[key] = serializeSpecValue(value, chainConfigTypes[key]);
23
+ }
24
+ }
25
+
26
+ return json;
27
+ }
28
+
29
+ export function chainConfigFromJson(json: Record<string, unknown>): ChainConfig {
30
+ const config = {} as ChainConfig;
31
+
32
+ for (const key of Object.keys(chainConfigTypes) as (keyof ChainConfig)[]) {
33
+ const value = json[key];
34
+ if (value !== undefined) {
35
+ config[key] = deserializeSpecValue(json[key], chainConfigTypes[key], key) as never;
36
+ }
37
+ }
38
+
39
+ return config;
40
+ }
41
+
42
+ export function specValuesToJson(spec: Record<string, SpecValue>): SpecJson {
43
+ const json: SpecJson = {};
44
+
45
+ for (const key of Object.keys(spec)) {
46
+ json[key] = serializeSpecValue(spec[key], toSpecValueTypeName(spec[key]));
47
+ }
48
+
49
+ return json;
50
+ }
51
+
52
+ /** Automatic inference of typeName. For critical variables define type names, else infer */
53
+ export function toSpecValueTypeName(value: SpecValue): SpecValueTypeName {
54
+ if (value instanceof Uint8Array) return "bytes";
55
+ if (typeof value === "number") return "number";
56
+ if (typeof value === "bigint") return "bigint";
57
+ if (typeof value === "string") return "string";
58
+ if (isBlobSchedule(value)) return "blob_schedule";
59
+ throw Error(`Unknown value type ${value}`);
60
+ }
61
+
62
+ export function serializeSpecValue(
63
+ value: SpecValue,
64
+ typeName: SpecValueTypeName
65
+ ): string | Record<keyof BlobScheduleEntry, string>[] {
66
+ switch (typeName) {
67
+ case "number":
68
+ if (typeof value !== "number") {
69
+ throw Error(`Invalid value ${value.toString()} expected number`);
70
+ }
71
+ if (value === Infinity) {
72
+ return MAX_UINT64_JSON;
73
+ }
74
+ return value.toString(10);
75
+
76
+ case "bigint":
77
+ if (typeof value !== "bigint") {
78
+ throw Error(`Invalid value ${value.toString()} expected bigint`);
79
+ }
80
+ return value.toString(10);
81
+
82
+ case "bytes":
83
+ if (!(value instanceof Uint8Array)) {
84
+ throw Error(`Invalid value ${value.toString()} expected Uint8Array`);
85
+ }
86
+ return toHex(value);
87
+
88
+ case "string":
89
+ if (typeof value !== "string") {
90
+ throw Error(`Invalid value ${value.toString()} expected string`);
91
+ }
92
+ return value;
93
+
94
+ case "blob_schedule":
95
+ if (!isBlobSchedule(value)) {
96
+ throw Error(`Invalid value ${value.toString()} expected BlobSchedule`);
97
+ }
98
+
99
+ return value.map(({EPOCH, MAX_BLOBS_PER_BLOCK}) => ({
100
+ EPOCH: EPOCH === Infinity ? MAX_UINT64_JSON : EPOCH.toString(10),
101
+ MAX_BLOBS_PER_BLOCK: MAX_BLOBS_PER_BLOCK === Infinity ? MAX_UINT64_JSON : MAX_BLOBS_PER_BLOCK.toString(10),
102
+ }));
103
+ }
104
+ }
105
+
106
+ export function deserializeSpecValue(valueStr: unknown, typeName: SpecValueTypeName, keyName: string): SpecValue {
107
+ if (typeName === "blob_schedule") {
108
+ return deserializeBlobSchedule(valueStr);
109
+ }
110
+
111
+ if (typeof valueStr !== "string") {
112
+ throw Error(`Invalid ${keyName} value ${valueStr} expected string`);
113
+ }
114
+
115
+ switch (typeName) {
116
+ case "number":
117
+ if (valueStr === MAX_UINT64_JSON) {
118
+ return Infinity;
119
+ }
120
+ return parseInt(valueStr, 10);
121
+
122
+ case "bigint":
123
+ return BigInt(valueStr);
124
+
125
+ case "bytes":
126
+ return fromHex(valueStr);
127
+
128
+ case "string":
129
+ return valueStr;
130
+ }
131
+ }
132
+
133
+ export function deserializeBlobSchedule(input: unknown): BlobSchedule {
134
+ if (!Array.isArray(input)) {
135
+ throw Error(`Invalid BLOB_SCHEDULE value ${input} expected array`);
136
+ }
137
+
138
+ const blobSchedule = input.map((entry, i) => {
139
+ if (typeof entry !== "object" || entry === null) {
140
+ throw Error(`Invalid BLOB_SCHEDULE[${i}] entry ${entry} expected object`);
141
+ }
142
+
143
+ const out = {} as BlobScheduleEntry;
144
+
145
+ for (const key of ["EPOCH", "MAX_BLOBS_PER_BLOCK"] as Array<keyof BlobScheduleEntry>) {
146
+ const value = entry[key];
147
+
148
+ if (value === undefined) {
149
+ throw Error(`Invalid BLOB_SCHEDULE[${i}] entry ${JSON.stringify(entry)} missing ${key}`);
150
+ }
151
+
152
+ if (typeof value !== "string") {
153
+ throw Error(`Invalid BLOB_SCHEDULE[${i}].${key} value ${value} expected string`);
154
+ }
155
+
156
+ if (value === MAX_UINT64_JSON) {
157
+ out[key] = Infinity;
158
+ } else {
159
+ const parsed = parseInt(value, 10);
160
+
161
+ if (Number.isNaN(parsed)) {
162
+ throw Error(`Invalid BLOB_SCHEDULE[${i}].${key} value ${value} expected number`);
163
+ }
164
+
165
+ out[key] = parsed;
166
+ }
167
+ }
168
+
169
+ return out;
170
+ });
171
+
172
+ validateBlobSchedule(blobSchedule);
173
+
174
+ return blobSchedule;
175
+ }
@@ -0,0 +1,49 @@
1
+ import {fromHex as b} from "@lodestar/utils";
2
+ import {ChainConfig} from "../types.js";
3
+ import {gnosisChainConfig as gnosis} from "./gnosis.js";
4
+
5
+ // Chiado beacon chain config:
6
+ // https://github.com/gnosischain/configs/blob/main/chiado/config.yaml
7
+
8
+ export const chiadoChainConfig: ChainConfig = {
9
+ ...gnosis,
10
+
11
+ // NOTE: Only add diff values
12
+ CONFIG_NAME: "chiado",
13
+
14
+ // Transition
15
+ TERMINAL_TOTAL_DIFFICULTY: BigInt("231707791542740786049188744689299064356246512"),
16
+
17
+ // Deposit contract
18
+ DEPOSIT_CHAIN_ID: 10200,
19
+ DEPOSIT_NETWORK_ID: 10200,
20
+ DEPOSIT_CONTRACT_ADDRESS: b("0xb97036A26259B7147018913bD58a774cf91acf25"),
21
+
22
+ // 10 October 2022 10:00:00 GMT+0000
23
+ MIN_GENESIS_TIME: 1665396000,
24
+ MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 6000,
25
+ GENESIS_FORK_VERSION: b("0x0000006f"),
26
+ GENESIS_DELAY: 300,
27
+
28
+ // Forking
29
+ ALTAIR_FORK_VERSION: b("0x0100006f"),
30
+ ALTAIR_FORK_EPOCH: 90,
31
+ // Bellatrix
32
+ BELLATRIX_FORK_VERSION: b("0x0200006f"),
33
+ BELLATRIX_FORK_EPOCH: 180,
34
+ // Capella
35
+ CAPELLA_FORK_VERSION: b("0x0300006f"),
36
+ CAPELLA_FORK_EPOCH: 244224, // Wed May 24 2023 13:12:00 GMT+0000
37
+ // Deneb
38
+ DENEB_FORK_VERSION: b("0x0400006f"),
39
+ DENEB_FORK_EPOCH: 516608, // Wed Jan 31 2024 18:15:40 GMT+0000
40
+ // Electra
41
+ ELECTRA_FORK_VERSION: b("0x0500006f"),
42
+ ELECTRA_FORK_EPOCH: 948224, // Thu Mar 06 2025 09:43:40 GMT+0000
43
+ // Fulu
44
+ FULU_FORK_VERSION: b("0x0600006f"),
45
+ FULU_FORK_EPOCH: Infinity,
46
+
47
+ // Blob Scheduling
48
+ BLOB_SCHEDULE: [],
49
+ };
@@ -0,0 +1,71 @@
1
+ import {fromHex as b} from "@lodestar/utils";
2
+ import {chainConfig as mainnet} from "../configs/mainnet.js";
3
+ import {ChainConfig} from "../types.js";
4
+
5
+ // Ephemery dynamic beacon chain config:
6
+ // https://github.com/ephemery-testnet/ephemery-genesis/blob/master/cl-config.yaml
7
+
8
+ // Ephemery specification:
9
+ // https://eips.ethereum.org/EIPS/eip-6916
10
+
11
+ // iteration 0, "base"-genesis
12
+ const baseChainConfig: ChainConfig = {
13
+ ...mainnet,
14
+
15
+ CONFIG_NAME: "ephemery",
16
+
17
+ // Genesis
18
+ // ---------------------------------------------------------------
19
+ MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 64,
20
+ // Thu Dec 02 2021 19:00:00 GMT+0000
21
+ MIN_GENESIS_TIME: 1638471600,
22
+ GENESIS_FORK_VERSION: b("0x1000101b"),
23
+ GENESIS_DELAY: 300,
24
+
25
+ // Forking
26
+ // ---------------------------------------------------------------
27
+ // Altair
28
+ ALTAIR_FORK_VERSION: b("0x2000101b"),
29
+ ALTAIR_FORK_EPOCH: 0,
30
+ // Merge
31
+ BELLATRIX_FORK_VERSION: b("0x3000101b"),
32
+ BELLATRIX_FORK_EPOCH: 0,
33
+ TERMINAL_TOTAL_DIFFICULTY: BigInt("0"),
34
+ // Capella
35
+ CAPELLA_FORK_VERSION: b("0x4000101b"),
36
+ CAPELLA_FORK_EPOCH: 0,
37
+ // Deneb
38
+ DENEB_FORK_VERSION: b("0x5000101b"),
39
+ DENEB_FORK_EPOCH: 0,
40
+ // Electra
41
+ ELECTRA_FORK_VERSION: b("0x6000101b"),
42
+ ELECTRA_FORK_EPOCH: 10,
43
+ // Fulu
44
+ FULU_FORK_VERSION: b("0x7000101b"),
45
+ FULU_FORK_EPOCH: Infinity,
46
+
47
+ // Deposit contract
48
+ // ---------------------------------------------------------------
49
+ DEPOSIT_CHAIN_ID: 39438000,
50
+ DEPOSIT_NETWORK_ID: 39438000,
51
+ DEPOSIT_CONTRACT_ADDRESS: b("0x4242424242424242424242424242424242424242"),
52
+
53
+ ETH1_FOLLOW_DISTANCE: 12,
54
+
55
+ // Blob Scheduling
56
+ // ---------------------------------------------------------------
57
+ BLOB_SCHEDULE: [],
58
+ };
59
+
60
+ // Reset interval (7 days) in milliseconds, based on ephemery-genesis values.env:
61
+ // https://github.com/ephemery-testnet/ephemery-genesis/blob/9a28fbef950c8547d78785f8a0ea49a95ce19a48/values.env#L5
62
+ const RESET_INTERVAL_MS = 604800000;
63
+ const iteration = Math.floor(Date.now() - baseChainConfig.MIN_GENESIS_TIME) / RESET_INTERVAL_MS;
64
+
65
+ export const ephemeryChainConfig: ChainConfig = {
66
+ ...baseChainConfig,
67
+
68
+ MIN_GENESIS_TIME: RESET_INTERVAL_MS * iteration + baseChainConfig.MIN_GENESIS_TIME,
69
+ DEPOSIT_CHAIN_ID: baseChainConfig.DEPOSIT_CHAIN_ID + iteration,
70
+ DEPOSIT_NETWORK_ID: baseChainConfig.DEPOSIT_NETWORK_ID + iteration,
71
+ };