@lodestar/config 1.35.0-dev.f80d2d52da → 1.35.0-dev.fcf8d024ea
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.
- package/lib/beaconConfig.d.ts.map +1 -0
- package/lib/chainConfig/configs/mainnet.d.ts.map +1 -0
- package/lib/chainConfig/configs/mainnet.js +24 -1
- package/lib/chainConfig/configs/mainnet.js.map +1 -1
- package/lib/chainConfig/configs/minimal.d.ts.map +1 -0
- package/lib/chainConfig/configs/minimal.js +24 -1
- package/lib/chainConfig/configs/minimal.js.map +1 -1
- package/lib/chainConfig/default.d.ts.map +1 -0
- package/lib/chainConfig/index.d.ts +2 -2
- package/lib/chainConfig/index.d.ts.map +1 -0
- package/lib/chainConfig/index.js +7 -2
- package/lib/chainConfig/index.js.map +1 -1
- package/lib/chainConfig/json.d.ts.map +1 -0
- package/lib/chainConfig/networks/chiado.d.ts.map +1 -0
- package/lib/chainConfig/networks/ephemery.d.ts.map +1 -0
- package/lib/chainConfig/networks/gnosis.d.ts.map +1 -0
- package/lib/chainConfig/networks/holesky.d.ts.map +1 -0
- package/lib/chainConfig/networks/holesky.js +11 -2
- package/lib/chainConfig/networks/holesky.js.map +1 -1
- package/lib/chainConfig/networks/hoodi.d.ts.map +1 -0
- package/lib/chainConfig/networks/hoodi.js +11 -2
- package/lib/chainConfig/networks/hoodi.js.map +1 -1
- package/lib/chainConfig/networks/mainnet.d.ts.map +1 -0
- package/lib/chainConfig/networks/sepolia.d.ts.map +1 -0
- package/lib/chainConfig/networks/sepolia.js +11 -2
- package/lib/chainConfig/networks/sepolia.js.map +1 -1
- package/lib/chainConfig/types.d.ts +12 -0
- package/lib/chainConfig/types.d.ts.map +1 -0
- package/lib/chainConfig/types.js +12 -0
- package/lib/chainConfig/types.js.map +1 -1
- package/lib/configs.d.ts.map +1 -0
- package/lib/default.d.ts +1 -1
- package/lib/default.d.ts.map +1 -0
- package/lib/forkConfig/index.d.ts.map +1 -0
- package/lib/forkConfig/index.js +30 -3
- package/lib/forkConfig/index.js.map +1 -1
- package/lib/forkConfig/types.d.ts +7 -2
- package/lib/forkConfig/types.d.ts.map +1 -0
- package/lib/genesisConfig/index.d.ts.map +1 -0
- package/lib/genesisConfig/index.js.map +1 -1
- package/lib/genesisConfig/types.d.ts.map +1 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/networks.d.ts.map +1 -0
- package/lib/utils/validateBlobSchedule.d.ts.map +1 -0
- package/package.json +12 -10
- package/src/beaconConfig.ts +31 -0
- package/src/chainConfig/configs/mainnet.ts +172 -0
- package/src/chainConfig/configs/minimal.ts +167 -0
- package/src/chainConfig/default.ts +19 -0
- package/src/chainConfig/index.ts +33 -0
- package/src/chainConfig/json.ts +175 -0
- package/src/chainConfig/networks/chiado.ts +49 -0
- package/src/chainConfig/networks/ephemery.ts +71 -0
- package/src/chainConfig/networks/gnosis.ts +74 -0
- package/src/chainConfig/networks/holesky.ts +64 -0
- package/src/chainConfig/networks/hoodi.ts +64 -0
- package/src/chainConfig/networks/mainnet.ts +19 -0
- package/src/chainConfig/networks/sepolia.ts +61 -0
- package/src/chainConfig/types.ts +267 -0
- package/src/configs.ts +4 -0
- package/src/default.ts +6 -0
- package/src/forkConfig/index.ts +236 -0
- package/src/forkConfig/types.ts +68 -0
- package/src/genesisConfig/index.ts +180 -0
- package/src/genesisConfig/types.ts +29 -0
- package/src/index.ts +4 -0
- package/src/networks.ts +65 -0
- package/src/utils/validateBlobSchedule.ts +32 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lodestar/config",
|
|
3
|
-
"version": "1.35.0-dev.
|
|
3
|
+
"version": "1.35.0-dev.fcf8d024ea",
|
|
4
4
|
"description": "Chain configuration required for lodestar",
|
|
5
5
|
"author": "ChainSafe Systems",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -11,15 +11,19 @@
|
|
|
11
11
|
"type": "module",
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
+
"bun": "./src/index.ts",
|
|
14
15
|
"import": "./lib/index.js"
|
|
15
16
|
},
|
|
16
17
|
"./default": {
|
|
18
|
+
"bun": "./src/default.ts",
|
|
17
19
|
"import": "./lib/default.js"
|
|
18
20
|
},
|
|
19
21
|
"./networks": {
|
|
22
|
+
"bun": "./src/networks.ts",
|
|
20
23
|
"import": "./lib/networks.js"
|
|
21
24
|
},
|
|
22
25
|
"./configs": {
|
|
26
|
+
"bun": "./src/configs.ts",
|
|
23
27
|
"import": "./lib/configs.js"
|
|
24
28
|
}
|
|
25
29
|
},
|
|
@@ -34,11 +38,9 @@
|
|
|
34
38
|
},
|
|
35
39
|
"types": "lib/index.d.ts",
|
|
36
40
|
"files": [
|
|
37
|
-
"
|
|
38
|
-
"lib
|
|
39
|
-
"
|
|
40
|
-
"*.d.ts",
|
|
41
|
-
"*.js"
|
|
41
|
+
"src",
|
|
42
|
+
"lib",
|
|
43
|
+
"!**/*.tsbuildinfo"
|
|
42
44
|
],
|
|
43
45
|
"scripts": {
|
|
44
46
|
"clean": "rm -rf lib && rm -f *.tsbuildinfo",
|
|
@@ -65,9 +67,9 @@
|
|
|
65
67
|
],
|
|
66
68
|
"dependencies": {
|
|
67
69
|
"@chainsafe/ssz": "^1.2.2",
|
|
68
|
-
"@lodestar/params": "1.35.0-dev.
|
|
69
|
-
"@lodestar/types": "1.35.0-dev.
|
|
70
|
-
"@lodestar/utils": "1.35.0-dev.
|
|
70
|
+
"@lodestar/params": "1.35.0-dev.fcf8d024ea",
|
|
71
|
+
"@lodestar/types": "1.35.0-dev.fcf8d024ea",
|
|
72
|
+
"@lodestar/utils": "1.35.0-dev.fcf8d024ea"
|
|
71
73
|
},
|
|
72
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "d72abda1a1607ce062febfcfc4528b9e9848c288"
|
|
73
75
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {Root} from "@lodestar/types";
|
|
2
|
+
import {ChainConfig, createChainConfig} from "./chainConfig/index.js";
|
|
3
|
+
import {ForkConfig, createForkConfig} from "./forkConfig/index.js";
|
|
4
|
+
import {createCachedGenesis} from "./genesisConfig/index.js";
|
|
5
|
+
import {CachedGenesis} from "./genesisConfig/types.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Chain run-time configuration with additional fork schedule helpers
|
|
9
|
+
*/
|
|
10
|
+
export type ChainForkConfig = ChainConfig & ForkConfig;
|
|
11
|
+
|
|
12
|
+
export type BeaconConfig = ChainForkConfig & CachedGenesis;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create an `BeaconConfig`, filling in missing values with preset defaults
|
|
16
|
+
*/
|
|
17
|
+
export function createChainForkConfig(chainConfig: Partial<ChainConfig>): ChainForkConfig {
|
|
18
|
+
const fullChainConfig = createChainConfig(chainConfig);
|
|
19
|
+
return {
|
|
20
|
+
...fullChainConfig,
|
|
21
|
+
...createForkConfig(fullChainConfig),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function createBeaconConfig(chainConfig: Partial<ChainConfig>, genesisValidatorsRoot: Root): BeaconConfig {
|
|
26
|
+
const chainForkConfig = createChainForkConfig(chainConfig);
|
|
27
|
+
return {
|
|
28
|
+
...chainForkConfig,
|
|
29
|
+
...createCachedGenesis(chainForkConfig, genesisValidatorsRoot),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
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 (DEPRECATED)
|
|
66
|
+
SECONDS_PER_SLOT: 12,
|
|
67
|
+
// 12000 milliseconds, 12 seconds
|
|
68
|
+
SLOT_DURATION_MS: 12000,
|
|
69
|
+
// 14 (estimate from Eth1 mainnet)
|
|
70
|
+
SECONDS_PER_ETH1_BLOCK: 14,
|
|
71
|
+
// 2**8 (= 256) epochs ~27 hours
|
|
72
|
+
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256,
|
|
73
|
+
// 2**8 (= 256) epochs ~27 hours
|
|
74
|
+
SHARD_COMMITTEE_PERIOD: 256,
|
|
75
|
+
// 2**11 (= 2,048) Eth1 blocks ~8 hours
|
|
76
|
+
ETH1_FOLLOW_DISTANCE: 2048,
|
|
77
|
+
// 1667 basis points, ~17% of SLOT_DURATION_MS
|
|
78
|
+
PROPOSER_REORG_CUTOFF_BPS: 1667,
|
|
79
|
+
// 3333 basis points, ~33% of SLOT_DURATION_MS
|
|
80
|
+
ATTESTATION_DUE_BPS: 3333,
|
|
81
|
+
// 6667 basis points, ~67% of SLOT_DURATION_MS
|
|
82
|
+
AGGREGATE_DUE_BPS: 6667,
|
|
83
|
+
|
|
84
|
+
// Altair
|
|
85
|
+
// 3333 basis points, ~33% of SLOT_DURATION_MS
|
|
86
|
+
SYNC_MESSAGE_DUE_BPS: 3333,
|
|
87
|
+
// 6667 basis points, ~67% of SLOT_DURATION_MS
|
|
88
|
+
CONTRIBUTION_DUE_BPS: 6667,
|
|
89
|
+
|
|
90
|
+
// 25% of SLOT_DURATION_MS
|
|
91
|
+
ATTESTATION_DUE_BPS_GLOAS: 2500,
|
|
92
|
+
// 50% of SLOT_DURATION_MS
|
|
93
|
+
AGGREGATE_DUE_BPS_GLOAS: 5000,
|
|
94
|
+
// 25% of SLOT_DURATION_MS
|
|
95
|
+
SYNC_MESSAGE_DUE_BPS_GLOAS: 2500,
|
|
96
|
+
// 50% of SLOT_DURATION_MS
|
|
97
|
+
CONTRIBUTION_DUE_BPS_GLOAS: 5000,
|
|
98
|
+
// 75% of SLOT_DURATION_MS
|
|
99
|
+
PAYLOAD_ATTESTATION_DUE_BPS: 7500,
|
|
100
|
+
|
|
101
|
+
// Validator cycle
|
|
102
|
+
// ---------------------------------------------------------------
|
|
103
|
+
// 2**2 (= 4)
|
|
104
|
+
INACTIVITY_SCORE_BIAS: 4,
|
|
105
|
+
// 2**4 (= 16)
|
|
106
|
+
INACTIVITY_SCORE_RECOVERY_RATE: 16,
|
|
107
|
+
// 2**4 * 10**9 (= 16,000,000,000) Gwei
|
|
108
|
+
EJECTION_BALANCE: 16000000000,
|
|
109
|
+
// 2**2 (= 4)
|
|
110
|
+
MIN_PER_EPOCH_CHURN_LIMIT: 4,
|
|
111
|
+
// 2**3 (= 8)
|
|
112
|
+
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8,
|
|
113
|
+
// 2**16 (= 65,536)
|
|
114
|
+
CHURN_LIMIT_QUOTIENT: 65536,
|
|
115
|
+
|
|
116
|
+
// Fork choice
|
|
117
|
+
// ---------------------------------------------------------------
|
|
118
|
+
// 40%
|
|
119
|
+
PROPOSER_SCORE_BOOST: 40,
|
|
120
|
+
REORG_HEAD_WEIGHT_THRESHOLD: 20,
|
|
121
|
+
REORG_PARENT_WEIGHT_THRESHOLD: 160,
|
|
122
|
+
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2,
|
|
123
|
+
|
|
124
|
+
// Deposit contract
|
|
125
|
+
// ---------------------------------------------------------------
|
|
126
|
+
// Ethereum PoW Mainnet
|
|
127
|
+
DEPOSIT_CHAIN_ID: 1,
|
|
128
|
+
DEPOSIT_NETWORK_ID: 1,
|
|
129
|
+
DEPOSIT_CONTRACT_ADDRESS: b("0x00000000219ab540356cBB839Cbe05303d7705Fa"),
|
|
130
|
+
|
|
131
|
+
// Networking
|
|
132
|
+
// ---------------------------------------------------------------
|
|
133
|
+
// 2**10 (= 1024)
|
|
134
|
+
MAX_REQUEST_BLOCKS: 1024,
|
|
135
|
+
// `MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2` (= 33024, ~5 months)
|
|
136
|
+
MIN_EPOCHS_FOR_BLOCK_REQUESTS: 33024,
|
|
137
|
+
|
|
138
|
+
// Deneb
|
|
139
|
+
// 2**7 (= 128)
|
|
140
|
+
MAX_REQUEST_BLOCKS_DENEB: 128,
|
|
141
|
+
// `2**12` (= 4096 epochs, ~18 days)
|
|
142
|
+
MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096,
|
|
143
|
+
BLOB_SIDECAR_SUBNET_COUNT: 6,
|
|
144
|
+
MAX_BLOBS_PER_BLOCK: 6,
|
|
145
|
+
// MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
|
|
146
|
+
MAX_REQUEST_BLOB_SIDECARS: 768,
|
|
147
|
+
|
|
148
|
+
// Electra
|
|
149
|
+
// 2**8 * 10**9 (= 256,000,000,000)
|
|
150
|
+
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 256000000000,
|
|
151
|
+
// 2**7 * 10**9 (= 128,000,000,000)
|
|
152
|
+
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 128000000000,
|
|
153
|
+
BLOB_SIDECAR_SUBNET_COUNT_ELECTRA: 9,
|
|
154
|
+
MAX_BLOBS_PER_BLOCK_ELECTRA: 9,
|
|
155
|
+
// MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_ELECTRA
|
|
156
|
+
MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 1152,
|
|
157
|
+
|
|
158
|
+
// Fulu
|
|
159
|
+
NUMBER_OF_CUSTODY_GROUPS: 128,
|
|
160
|
+
DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128,
|
|
161
|
+
MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384,
|
|
162
|
+
SAMPLES_PER_SLOT: 8,
|
|
163
|
+
CUSTODY_REQUIREMENT: 4,
|
|
164
|
+
VALIDATOR_CUSTODY_REQUIREMENT: 8,
|
|
165
|
+
BALANCE_PER_ADDITIONAL_CUSTODY_GROUP: 32000000000,
|
|
166
|
+
// `2**12` (= 4096 epochs, ~18 days)
|
|
167
|
+
MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS: 4096,
|
|
168
|
+
|
|
169
|
+
// Blob Scheduling
|
|
170
|
+
// ---------------------------------------------------------------
|
|
171
|
+
BLOB_SCHEDULE: [],
|
|
172
|
+
};
|
|
@@ -0,0 +1,167 @@
|
|
|
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 (DEPRECATED)
|
|
60
|
+
SECONDS_PER_SLOT: 6,
|
|
61
|
+
// [customized] 6000 milliseconds, 6 seconds
|
|
62
|
+
SLOT_DURATION_MS: 6000,
|
|
63
|
+
// 14 (estimate from Eth1 mainnet)
|
|
64
|
+
SECONDS_PER_ETH1_BLOCK: 14,
|
|
65
|
+
// 2**8 (= 256) epochs
|
|
66
|
+
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256,
|
|
67
|
+
// [customized] higher frequency of committee turnover and faster time to acceptable voluntary exit
|
|
68
|
+
SHARD_COMMITTEE_PERIOD: 64,
|
|
69
|
+
// [customized] process deposits more quickly, but insecure
|
|
70
|
+
ETH1_FOLLOW_DISTANCE: 16,
|
|
71
|
+
// 1667 basis points, ~17% of SLOT_DURATION_MS
|
|
72
|
+
PROPOSER_REORG_CUTOFF_BPS: 1667,
|
|
73
|
+
// 3333 basis points, ~33% of SLOT_DURATION_MS
|
|
74
|
+
ATTESTATION_DUE_BPS: 3333,
|
|
75
|
+
// 6667 basis points, ~67% of SLOT_DURATION_MS
|
|
76
|
+
AGGREGATE_DUE_BPS: 6667,
|
|
77
|
+
|
|
78
|
+
// Altair
|
|
79
|
+
// 3333 basis points, ~33% of SLOT_DURATION_MS
|
|
80
|
+
SYNC_MESSAGE_DUE_BPS: 3333,
|
|
81
|
+
// 6667 basis points, ~67% of SLOT_DURATION_MS
|
|
82
|
+
CONTRIBUTION_DUE_BPS: 6667,
|
|
83
|
+
|
|
84
|
+
// 25% of SLOT_DURATION_MS
|
|
85
|
+
ATTESTATION_DUE_BPS_GLOAS: 2500,
|
|
86
|
+
// 50% of SLOT_DURATION_MS
|
|
87
|
+
AGGREGATE_DUE_BPS_GLOAS: 5000,
|
|
88
|
+
// 25% of SLOT_DURATION_MS
|
|
89
|
+
SYNC_MESSAGE_DUE_BPS_GLOAS: 2500,
|
|
90
|
+
// 50% of SLOT_DURATION_MS
|
|
91
|
+
CONTRIBUTION_DUE_BPS_GLOAS: 5000,
|
|
92
|
+
// 75% of SLOT_DURATION_MS
|
|
93
|
+
PAYLOAD_ATTESTATION_DUE_BPS: 7500,
|
|
94
|
+
|
|
95
|
+
// Validator cycle
|
|
96
|
+
// ---------------------------------------------------------------
|
|
97
|
+
// 2**2 (= 4)
|
|
98
|
+
INACTIVITY_SCORE_BIAS: 4,
|
|
99
|
+
// 2**4 (= 16)
|
|
100
|
+
INACTIVITY_SCORE_RECOVERY_RATE: 16,
|
|
101
|
+
// 2**4 * 10**9 (= 16,000,000,000) Gwei
|
|
102
|
+
EJECTION_BALANCE: 16000000000,
|
|
103
|
+
// 2**2 (= 4)
|
|
104
|
+
MIN_PER_EPOCH_CHURN_LIMIT: 2,
|
|
105
|
+
// [customized]
|
|
106
|
+
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 4,
|
|
107
|
+
// [customized] scale queue churn at much lower validator counts for testing
|
|
108
|
+
CHURN_LIMIT_QUOTIENT: 32,
|
|
109
|
+
|
|
110
|
+
// Fork choice
|
|
111
|
+
// ---------------------------------------------------------------
|
|
112
|
+
// 40%
|
|
113
|
+
PROPOSER_SCORE_BOOST: 40,
|
|
114
|
+
REORG_HEAD_WEIGHT_THRESHOLD: 20,
|
|
115
|
+
REORG_PARENT_WEIGHT_THRESHOLD: 160,
|
|
116
|
+
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2,
|
|
117
|
+
|
|
118
|
+
// Deposit contract
|
|
119
|
+
// ---------------------------------------------------------------
|
|
120
|
+
// Ethereum Goerli testnet
|
|
121
|
+
DEPOSIT_CHAIN_ID: 5,
|
|
122
|
+
DEPOSIT_NETWORK_ID: 5,
|
|
123
|
+
// Configured on a per testnet basis
|
|
124
|
+
DEPOSIT_CONTRACT_ADDRESS: b("0x1234567890123456789012345678901234567890"),
|
|
125
|
+
|
|
126
|
+
// Networking
|
|
127
|
+
// ---------------------------------------------------------------
|
|
128
|
+
// 2**10 (= 1024)
|
|
129
|
+
MAX_REQUEST_BLOCKS: 1024,
|
|
130
|
+
// [customized] `MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2` (= 272)
|
|
131
|
+
MIN_EPOCHS_FOR_BLOCK_REQUESTS: 272,
|
|
132
|
+
|
|
133
|
+
// Deneb
|
|
134
|
+
// 2**7 (= 128)
|
|
135
|
+
MAX_REQUEST_BLOCKS_DENEB: 128,
|
|
136
|
+
// `2**12` (= 4096 epochs, ~18 days)
|
|
137
|
+
MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096,
|
|
138
|
+
BLOB_SIDECAR_SUBNET_COUNT: 6,
|
|
139
|
+
MAX_BLOBS_PER_BLOCK: 6,
|
|
140
|
+
// MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
|
|
141
|
+
MAX_REQUEST_BLOB_SIDECARS: 768,
|
|
142
|
+
|
|
143
|
+
// Electra
|
|
144
|
+
// 2**7 * 10**9 (= 128,000,000,000)
|
|
145
|
+
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 128000000000,
|
|
146
|
+
// 2**6 * 10**9 (= 64,000,000,000)
|
|
147
|
+
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 64000000000,
|
|
148
|
+
BLOB_SIDECAR_SUBNET_COUNT_ELECTRA: 9,
|
|
149
|
+
MAX_BLOBS_PER_BLOCK_ELECTRA: 9,
|
|
150
|
+
// MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_ELECTRA
|
|
151
|
+
MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 1152,
|
|
152
|
+
|
|
153
|
+
// Fulu
|
|
154
|
+
NUMBER_OF_CUSTODY_GROUPS: 128,
|
|
155
|
+
DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128,
|
|
156
|
+
MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384,
|
|
157
|
+
SAMPLES_PER_SLOT: 8,
|
|
158
|
+
CUSTODY_REQUIREMENT: 4,
|
|
159
|
+
VALIDATOR_CUSTODY_REQUIREMENT: 8,
|
|
160
|
+
BALANCE_PER_ADDITIONAL_CUSTODY_GROUP: 32000000000,
|
|
161
|
+
// `2**12` (= 4096 epochs, ~18 days)
|
|
162
|
+
MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS: 4096,
|
|
163
|
+
|
|
164
|
+
// Blob Scheduling
|
|
165
|
+
// ---------------------------------------------------------------
|
|
166
|
+
BLOB_SCHEDULE: [],
|
|
167
|
+
};
|
|
@@ -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,33 @@
|
|
|
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
|
+
// Set SLOT_DURATION_MS if SECONDS_PER_SLOT is provided but SLOT_DURATION_MS is not.
|
|
21
|
+
// This is to provide backward compatibility until Gloas is live
|
|
22
|
+
if (input.SLOT_DURATION_MS === undefined) {
|
|
23
|
+
config.SLOT_DURATION_MS = config.SECONDS_PER_SLOT * 1000;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Assert that the preset matches the active preset
|
|
27
|
+
if (config.PRESET_BASE !== ACTIVE_PRESET) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`Can only create a config for the active preset: ACTIVE_PRESET=${ACTIVE_PRESET} PRESET_BASE=${config.PRESET_BASE}`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
return config;
|
|
33
|
+
}
|
|
@@ -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
|
+
}
|