@lodestar/config 1.35.0-dev.fcf8d024ea → 1.35.0-dev.feed916580
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/chainConfig/configs/mainnet.js +1 -24
- package/lib/chainConfig/configs/mainnet.js.map +1 -1
- package/lib/chainConfig/configs/minimal.js +1 -24
- package/lib/chainConfig/configs/minimal.js.map +1 -1
- package/lib/chainConfig/index.js +0 -5
- package/lib/chainConfig/index.js.map +1 -1
- package/lib/chainConfig/types.d.ts +0 -12
- package/lib/chainConfig/types.js +0 -12
- package/lib/chainConfig/types.js.map +1 -1
- package/lib/default.d.ts +1 -1
- package/lib/forkConfig/index.js +1 -31
- package/lib/forkConfig/index.js.map +1 -1
- package/lib/forkConfig/types.d.ts +0 -7
- package/package.json +10 -12
- package/lib/beaconConfig.d.ts.map +0 -1
- package/lib/chainConfig/configs/mainnet.d.ts.map +0 -1
- package/lib/chainConfig/configs/minimal.d.ts.map +0 -1
- package/lib/chainConfig/default.d.ts.map +0 -1
- package/lib/chainConfig/index.d.ts.map +0 -1
- package/lib/chainConfig/json.d.ts.map +0 -1
- package/lib/chainConfig/networks/chiado.d.ts.map +0 -1
- package/lib/chainConfig/networks/ephemery.d.ts.map +0 -1
- package/lib/chainConfig/networks/gnosis.d.ts.map +0 -1
- package/lib/chainConfig/networks/holesky.d.ts.map +0 -1
- package/lib/chainConfig/networks/hoodi.d.ts.map +0 -1
- package/lib/chainConfig/networks/mainnet.d.ts.map +0 -1
- package/lib/chainConfig/networks/sepolia.d.ts.map +0 -1
- package/lib/chainConfig/types.d.ts.map +0 -1
- package/lib/configs.d.ts.map +0 -1
- package/lib/default.d.ts.map +0 -1
- package/lib/forkConfig/index.d.ts.map +0 -1
- package/lib/forkConfig/types.d.ts.map +0 -1
- package/lib/genesisConfig/index.d.ts.map +0 -1
- package/lib/genesisConfig/types.d.ts.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/networks.d.ts.map +0 -1
- package/lib/utils/validateBlobSchedule.d.ts.map +0 -1
- package/src/beaconConfig.ts +0 -31
- package/src/chainConfig/configs/mainnet.ts +0 -172
- package/src/chainConfig/configs/minimal.ts +0 -167
- package/src/chainConfig/default.ts +0 -19
- package/src/chainConfig/index.ts +0 -33
- package/src/chainConfig/json.ts +0 -175
- package/src/chainConfig/networks/chiado.ts +0 -49
- package/src/chainConfig/networks/ephemery.ts +0 -71
- package/src/chainConfig/networks/gnosis.ts +0 -74
- package/src/chainConfig/networks/holesky.ts +0 -64
- package/src/chainConfig/networks/hoodi.ts +0 -64
- package/src/chainConfig/networks/mainnet.ts +0 -19
- package/src/chainConfig/networks/sepolia.ts +0 -61
- package/src/chainConfig/types.ts +0 -267
- package/src/configs.ts +0 -4
- package/src/default.ts +0 -6
- package/src/forkConfig/index.ts +0 -236
- package/src/forkConfig/types.ts +0 -68
- package/src/genesisConfig/index.ts +0 -180
- package/src/genesisConfig/types.ts +0 -29
- package/src/index.ts +0 -4
- package/src/networks.ts +0 -65
- package/src/utils/validateBlobSchedule.ts +0 -32
package/src/forkConfig/index.ts
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BASIS_POINTS,
|
|
3
|
-
ForkAll,
|
|
4
|
-
ForkName,
|
|
5
|
-
ForkPostAltair,
|
|
6
|
-
ForkPostBellatrix,
|
|
7
|
-
ForkPostDeneb,
|
|
8
|
-
ForkSeq,
|
|
9
|
-
GENESIS_EPOCH,
|
|
10
|
-
SLOTS_PER_EPOCH,
|
|
11
|
-
isForkPostAltair,
|
|
12
|
-
isForkPostBellatrix,
|
|
13
|
-
isForkPostDeneb,
|
|
14
|
-
isForkPostGloas,
|
|
15
|
-
} from "@lodestar/params";
|
|
16
|
-
import {Epoch, SSZTypesFor, Slot, Version, sszTypesFor} from "@lodestar/types";
|
|
17
|
-
import {ChainConfig} from "../chainConfig/index.js";
|
|
18
|
-
import {BlobParameters, ForkBoundary, ForkConfig, ForkInfo} from "./types.js";
|
|
19
|
-
|
|
20
|
-
export * from "./types.js";
|
|
21
|
-
|
|
22
|
-
export function createForkConfig(config: ChainConfig): ForkConfig {
|
|
23
|
-
const phase0: ForkInfo = {
|
|
24
|
-
name: ForkName.phase0,
|
|
25
|
-
seq: ForkSeq.phase0,
|
|
26
|
-
epoch: GENESIS_EPOCH,
|
|
27
|
-
version: config.GENESIS_FORK_VERSION,
|
|
28
|
-
// Will never be used
|
|
29
|
-
prevVersion: config.GENESIS_FORK_VERSION,
|
|
30
|
-
prevForkName: ForkName.phase0,
|
|
31
|
-
};
|
|
32
|
-
const altair: ForkInfo = {
|
|
33
|
-
name: ForkName.altair,
|
|
34
|
-
seq: ForkSeq.altair,
|
|
35
|
-
epoch: config.ALTAIR_FORK_EPOCH,
|
|
36
|
-
version: config.ALTAIR_FORK_VERSION,
|
|
37
|
-
prevVersion: config.GENESIS_FORK_VERSION,
|
|
38
|
-
prevForkName: ForkName.phase0,
|
|
39
|
-
};
|
|
40
|
-
const bellatrix: ForkInfo = {
|
|
41
|
-
name: ForkName.bellatrix,
|
|
42
|
-
seq: ForkSeq.bellatrix,
|
|
43
|
-
epoch: config.BELLATRIX_FORK_EPOCH,
|
|
44
|
-
version: config.BELLATRIX_FORK_VERSION,
|
|
45
|
-
prevVersion: config.ALTAIR_FORK_VERSION,
|
|
46
|
-
prevForkName: ForkName.altair,
|
|
47
|
-
};
|
|
48
|
-
const capella: ForkInfo = {
|
|
49
|
-
name: ForkName.capella,
|
|
50
|
-
seq: ForkSeq.capella,
|
|
51
|
-
epoch: config.CAPELLA_FORK_EPOCH,
|
|
52
|
-
version: config.CAPELLA_FORK_VERSION,
|
|
53
|
-
prevVersion: config.BELLATRIX_FORK_VERSION,
|
|
54
|
-
prevForkName: ForkName.bellatrix,
|
|
55
|
-
};
|
|
56
|
-
const deneb: ForkInfo = {
|
|
57
|
-
name: ForkName.deneb,
|
|
58
|
-
seq: ForkSeq.deneb,
|
|
59
|
-
epoch: config.DENEB_FORK_EPOCH,
|
|
60
|
-
version: config.DENEB_FORK_VERSION,
|
|
61
|
-
prevVersion: config.CAPELLA_FORK_VERSION,
|
|
62
|
-
prevForkName: ForkName.capella,
|
|
63
|
-
};
|
|
64
|
-
const electra: ForkInfo = {
|
|
65
|
-
name: ForkName.electra,
|
|
66
|
-
seq: ForkSeq.electra,
|
|
67
|
-
epoch: config.ELECTRA_FORK_EPOCH,
|
|
68
|
-
version: config.ELECTRA_FORK_VERSION,
|
|
69
|
-
prevVersion: config.DENEB_FORK_VERSION,
|
|
70
|
-
prevForkName: ForkName.deneb,
|
|
71
|
-
};
|
|
72
|
-
const fulu: ForkInfo = {
|
|
73
|
-
name: ForkName.fulu,
|
|
74
|
-
seq: ForkSeq.fulu,
|
|
75
|
-
epoch: config.FULU_FORK_EPOCH,
|
|
76
|
-
version: config.FULU_FORK_VERSION,
|
|
77
|
-
prevVersion: config.ELECTRA_FORK_VERSION,
|
|
78
|
-
prevForkName: ForkName.electra,
|
|
79
|
-
};
|
|
80
|
-
const gloas: ForkInfo = {
|
|
81
|
-
name: ForkName.gloas,
|
|
82
|
-
seq: ForkSeq.gloas,
|
|
83
|
-
epoch: config.GLOAS_FORK_EPOCH,
|
|
84
|
-
version: config.GLOAS_FORK_VERSION,
|
|
85
|
-
prevVersion: config.FULU_FORK_VERSION,
|
|
86
|
-
prevForkName: ForkName.fulu,
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
/** Forks in order order of occurence, `phase0` first */
|
|
90
|
-
// Note: Downstream code relies on proper ordering.
|
|
91
|
-
const forks = {phase0, altair, bellatrix, capella, deneb, electra, fulu, gloas};
|
|
92
|
-
|
|
93
|
-
// Prevents allocating an array on every getForkInfo() call
|
|
94
|
-
const forksAscendingEpochOrder = Object.values(forks);
|
|
95
|
-
const forksDescendingEpochOrder = Object.values(forks).reverse();
|
|
96
|
-
|
|
97
|
-
const blobScheduleDescendingEpochOrder = [...config.BLOB_SCHEDULE].sort((a, b) => b.EPOCH - a.EPOCH);
|
|
98
|
-
|
|
99
|
-
const forkBoundariesAscendingEpochOrder: ForkBoundary[] = [
|
|
100
|
-
// Normal hard-forks (phase0, altair, etc.)
|
|
101
|
-
...forksAscendingEpochOrder.map((fork) => ({
|
|
102
|
-
fork: fork.name,
|
|
103
|
-
epoch: fork.epoch,
|
|
104
|
-
})),
|
|
105
|
-
// Blob Parameter Only (BPO) forks
|
|
106
|
-
// Note: Must be appended after normal hard-forks to have precedence if scheduled at the same epoch
|
|
107
|
-
...config.BLOB_SCHEDULE.map((entry) => ({
|
|
108
|
-
fork: forksDescendingEpochOrder.find((f) => entry.EPOCH >= f.epoch)?.name ?? phase0.name,
|
|
109
|
-
epoch: entry.EPOCH,
|
|
110
|
-
})),
|
|
111
|
-
]
|
|
112
|
-
// Remove unscheduled fork boundaries
|
|
113
|
-
.filter(({epoch}) => epoch !== Infinity)
|
|
114
|
-
// Sort by epoch in ascending order
|
|
115
|
-
.sort((a, b) => a.epoch - b.epoch);
|
|
116
|
-
|
|
117
|
-
const forkBoundariesDescendingEpochOrder = [...forkBoundariesAscendingEpochOrder].reverse();
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
forks,
|
|
121
|
-
forksAscendingEpochOrder,
|
|
122
|
-
forksDescendingEpochOrder,
|
|
123
|
-
forkBoundariesAscendingEpochOrder,
|
|
124
|
-
forkBoundariesDescendingEpochOrder,
|
|
125
|
-
|
|
126
|
-
// Fork convenience methods
|
|
127
|
-
getForkInfo(slot: Slot): ForkInfo {
|
|
128
|
-
const epoch = Math.floor(Math.max(slot, 0) / SLOTS_PER_EPOCH);
|
|
129
|
-
return this.getForkInfoAtEpoch(epoch);
|
|
130
|
-
},
|
|
131
|
-
getForkInfoAtEpoch(epoch: Epoch): ForkInfo {
|
|
132
|
-
return forks[this.getForkBoundaryAtEpoch(epoch).fork];
|
|
133
|
-
},
|
|
134
|
-
getForkBoundaryAtEpoch(epoch: Epoch): ForkBoundary {
|
|
135
|
-
if (epoch < 0) epoch = 0;
|
|
136
|
-
// NOTE: fork boundaries must be sorted by descending epoch, latest first
|
|
137
|
-
for (const boundary of forkBoundariesDescendingEpochOrder) {
|
|
138
|
-
if (epoch >= boundary.epoch) return boundary;
|
|
139
|
-
}
|
|
140
|
-
throw Error("Unreachable as phase0 is scheduled at epoch 0");
|
|
141
|
-
},
|
|
142
|
-
getForkName(slot: Slot): ForkName {
|
|
143
|
-
return this.getForkInfo(slot).name;
|
|
144
|
-
},
|
|
145
|
-
getForkSeq(slot: Slot): ForkSeq {
|
|
146
|
-
return this.getForkInfo(slot).seq;
|
|
147
|
-
},
|
|
148
|
-
getForkSeqAtEpoch(epoch: Epoch): ForkSeq {
|
|
149
|
-
return this.getForkInfoAtEpoch(epoch).seq;
|
|
150
|
-
},
|
|
151
|
-
getForkVersion(slot: Slot): Version {
|
|
152
|
-
return this.getForkInfo(slot).version;
|
|
153
|
-
},
|
|
154
|
-
getForkTypes<F extends ForkName = ForkAll>(slot: Slot): SSZTypesFor<F> {
|
|
155
|
-
return sszTypesFor(this.getForkName(slot)) as SSZTypesFor<F>;
|
|
156
|
-
},
|
|
157
|
-
getPostBellatrixForkTypes(slot: Slot): SSZTypesFor<ForkPostBellatrix> {
|
|
158
|
-
const forkName = this.getForkName(slot);
|
|
159
|
-
if (!isForkPostBellatrix(forkName)) {
|
|
160
|
-
throw Error(`Invalid slot=${slot} fork=${forkName} for post-bellatrix fork types`);
|
|
161
|
-
}
|
|
162
|
-
return sszTypesFor(forkName);
|
|
163
|
-
},
|
|
164
|
-
getPostAltairForkTypes(slot: Slot): SSZTypesFor<ForkPostAltair> {
|
|
165
|
-
const forkName = this.getForkName(slot);
|
|
166
|
-
if (!isForkPostAltair(forkName)) {
|
|
167
|
-
throw Error(`Invalid slot=${slot} fork=${forkName} for post-altair fork types`);
|
|
168
|
-
}
|
|
169
|
-
return sszTypesFor(forkName);
|
|
170
|
-
},
|
|
171
|
-
getPostDenebForkTypes(slot: Slot): SSZTypesFor<ForkPostDeneb> {
|
|
172
|
-
const forkName = this.getForkName(slot);
|
|
173
|
-
if (!isForkPostDeneb(forkName)) {
|
|
174
|
-
throw Error(`Invalid slot=${slot} fork=${forkName} for post-deneb fork types`);
|
|
175
|
-
}
|
|
176
|
-
return sszTypesFor(forkName);
|
|
177
|
-
},
|
|
178
|
-
getMaxBlobsPerBlock(epoch: Epoch): number {
|
|
179
|
-
const fork = this.getForkInfoAtEpoch(epoch).name;
|
|
180
|
-
|
|
181
|
-
switch (fork) {
|
|
182
|
-
case ForkName.electra:
|
|
183
|
-
return config.MAX_BLOBS_PER_BLOCK_ELECTRA;
|
|
184
|
-
case ForkName.deneb:
|
|
185
|
-
return config.MAX_BLOBS_PER_BLOCK;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return this.getBlobParameters(epoch).maxBlobsPerBlock;
|
|
189
|
-
},
|
|
190
|
-
getBlobParameters(epoch: Epoch): BlobParameters {
|
|
191
|
-
if (epoch < config.FULU_FORK_EPOCH) {
|
|
192
|
-
throw Error(`getBlobParameters is not available pre-fulu epoch=${epoch}`);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Find the latest applicable value from blob schedule
|
|
196
|
-
for (const entry of blobScheduleDescendingEpochOrder) {
|
|
197
|
-
if (epoch >= entry.EPOCH) {
|
|
198
|
-
return {epoch: entry.EPOCH, maxBlobsPerBlock: entry.MAX_BLOBS_PER_BLOCK};
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return {epoch: config.ELECTRA_FORK_EPOCH, maxBlobsPerBlock: config.MAX_BLOBS_PER_BLOCK_ELECTRA};
|
|
203
|
-
},
|
|
204
|
-
getAttestationDueMs(fork: ForkName): number {
|
|
205
|
-
if (isForkPostGloas(fork)) {
|
|
206
|
-
return this.getSlotComponentDurationMs(config.ATTESTATION_DUE_BPS_GLOAS);
|
|
207
|
-
}
|
|
208
|
-
return this.getSlotComponentDurationMs(config.ATTESTATION_DUE_BPS);
|
|
209
|
-
},
|
|
210
|
-
getAggregateDueMs(fork: ForkName): number {
|
|
211
|
-
if (isForkPostGloas(fork)) {
|
|
212
|
-
return this.getSlotComponentDurationMs(config.AGGREGATE_DUE_BPS_GLOAS);
|
|
213
|
-
}
|
|
214
|
-
return this.getSlotComponentDurationMs(config.AGGREGATE_DUE_BPS);
|
|
215
|
-
},
|
|
216
|
-
getSyncMessageDueMs(fork: ForkName): number {
|
|
217
|
-
if (isForkPostGloas(fork)) {
|
|
218
|
-
return this.getSlotComponentDurationMs(config.SYNC_MESSAGE_DUE_BPS_GLOAS);
|
|
219
|
-
}
|
|
220
|
-
return this.getSlotComponentDurationMs(config.SYNC_MESSAGE_DUE_BPS);
|
|
221
|
-
},
|
|
222
|
-
getSyncContributionDueMs(fork: ForkName): number {
|
|
223
|
-
if (isForkPostGloas(fork)) {
|
|
224
|
-
return this.getSlotComponentDurationMs(config.CONTRIBUTION_DUE_BPS_GLOAS);
|
|
225
|
-
}
|
|
226
|
-
return this.getSlotComponentDurationMs(config.CONTRIBUTION_DUE_BPS);
|
|
227
|
-
},
|
|
228
|
-
getProposerReorgCutoffMs(_fork: ForkName): number {
|
|
229
|
-
return this.getSlotComponentDurationMs(config.PROPOSER_REORG_CUTOFF_BPS);
|
|
230
|
-
},
|
|
231
|
-
|
|
232
|
-
getSlotComponentDurationMs(basisPoints: number): number {
|
|
233
|
-
return Math.round((basisPoints * config.SLOT_DURATION_MS) / BASIS_POINTS);
|
|
234
|
-
},
|
|
235
|
-
};
|
|
236
|
-
}
|
package/src/forkConfig/types.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import {ForkAll, ForkName, ForkPostAltair, ForkPostBellatrix, ForkPostDeneb, ForkSeq} from "@lodestar/params";
|
|
2
|
-
import {Epoch, SSZTypesFor, Slot, UintNum64, Version} from "@lodestar/types";
|
|
3
|
-
|
|
4
|
-
export type ForkInfo = {
|
|
5
|
-
name: ForkName;
|
|
6
|
-
seq: ForkSeq;
|
|
7
|
-
epoch: Epoch;
|
|
8
|
-
version: Version;
|
|
9
|
-
prevVersion: Version;
|
|
10
|
-
prevForkName: ForkName;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Fork boundaries include both normal hard-forks (phase0, altair, etc.)
|
|
15
|
-
* and Blob Parameter Only (BPO) forks and are used to un-/subscribe to gossip topics
|
|
16
|
-
* and compute the fork digest primarily for domain separation on the p2p layer.
|
|
17
|
-
*/
|
|
18
|
-
export type ForkBoundary = {fork: ForkName; epoch: Epoch};
|
|
19
|
-
|
|
20
|
-
export type BlobParameters = {epoch: Epoch; maxBlobsPerBlock: UintNum64};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Fork schedule and helper methods
|
|
24
|
-
*/
|
|
25
|
-
export type ForkConfig = {
|
|
26
|
-
/** Forks in order order of occurence, `phase0` first */
|
|
27
|
-
forks: {[K in ForkName]: ForkInfo};
|
|
28
|
-
forksAscendingEpochOrder: ForkInfo[];
|
|
29
|
-
forksDescendingEpochOrder: ForkInfo[];
|
|
30
|
-
forkBoundariesAscendingEpochOrder: ForkBoundary[];
|
|
31
|
-
forkBoundariesDescendingEpochOrder: ForkBoundary[];
|
|
32
|
-
|
|
33
|
-
/** Get the hard-fork info for the active fork at `slot` */
|
|
34
|
-
getForkInfo(slot: Slot): ForkInfo;
|
|
35
|
-
/** Get the hard-fork info for the active fork at `epoch` */
|
|
36
|
-
getForkInfoAtEpoch(epoch: Epoch): ForkInfo;
|
|
37
|
-
/** Get the active fork boundary at a given `epoch` */
|
|
38
|
-
getForkBoundaryAtEpoch(epoch: Epoch): ForkBoundary;
|
|
39
|
-
/** Get the hard-fork name at a given slot */
|
|
40
|
-
getForkName(slot: Slot): ForkName;
|
|
41
|
-
/** Get the hard-fork sequence number at a given slot */
|
|
42
|
-
getForkSeq(slot: Slot): ForkSeq;
|
|
43
|
-
/** Get the hard-fork sequence number at a given epoch */
|
|
44
|
-
getForkSeqAtEpoch(epoch: Epoch): ForkSeq;
|
|
45
|
-
/** Get the hard-fork version at a given slot */
|
|
46
|
-
getForkVersion(slot: Slot): Version;
|
|
47
|
-
/** Get SSZ types by hard-fork */
|
|
48
|
-
getForkTypes<F extends ForkName = ForkAll>(slot: Slot): SSZTypesFor<F>;
|
|
49
|
-
/** Get post-altair SSZ types by hard-fork*/
|
|
50
|
-
getPostAltairForkTypes(slot: Slot): SSZTypesFor<ForkPostAltair>;
|
|
51
|
-
/** Get post-bellatrix SSZ types by hard-fork*/
|
|
52
|
-
getPostBellatrixForkTypes(slot: Slot): SSZTypesFor<ForkPostBellatrix>;
|
|
53
|
-
/** Get post-deneb SSZ types by hard-fork*/
|
|
54
|
-
getPostDenebForkTypes(slot: Slot): SSZTypesFor<ForkPostDeneb>;
|
|
55
|
-
/** Get max blobs per block at a given epoch */
|
|
56
|
-
getMaxBlobsPerBlock(epoch: Epoch): number;
|
|
57
|
-
/** Get blob parameters at a given epoch */
|
|
58
|
-
getBlobParameters(epoch: Epoch): BlobParameters;
|
|
59
|
-
|
|
60
|
-
getAttestationDueMs(fork: ForkName): number;
|
|
61
|
-
getAggregateDueMs(fork: ForkName): number;
|
|
62
|
-
getSyncMessageDueMs(fork: ForkName): number;
|
|
63
|
-
getSyncContributionDueMs(fork: ForkName): number;
|
|
64
|
-
getProposerReorgCutoffMs(fork: ForkName): number;
|
|
65
|
-
|
|
66
|
-
/** Convert basis points to milliseconds into the slot */
|
|
67
|
-
getSlotComponentDurationMs(basisPoints: number): number;
|
|
68
|
-
};
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import {digest} from "@chainsafe/as-sha256";
|
|
2
|
-
import {DOMAIN_VOLUNTARY_EXIT, ForkName, ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
3
|
-
import {DomainType, Epoch, ForkDigest, Root, Slot, Version, phase0, ssz} from "@lodestar/types";
|
|
4
|
-
import {intToBytes, strip0xPrefix, toHex, xor} from "@lodestar/utils";
|
|
5
|
-
import {ChainForkConfig} from "../beaconConfig.js";
|
|
6
|
-
import {ForkBoundary} from "../forkConfig/types.js";
|
|
7
|
-
import {CachedGenesis, ForkDigestHex} from "./types.js";
|
|
8
|
-
|
|
9
|
-
export type {ForkDigestContext} from "./types.js";
|
|
10
|
-
|
|
11
|
-
export function createCachedGenesis(chainForkConfig: ChainForkConfig, genesisValidatorsRoot: Root): CachedGenesis {
|
|
12
|
-
const domainCache = new Map<ForkName, Map<DomainType, Uint8Array>>();
|
|
13
|
-
|
|
14
|
-
const forkDigestByEpoch = new Map<Epoch, ForkDigest>();
|
|
15
|
-
const forkDigestHexByEpoch = new Map<Epoch, ForkDigestHex>();
|
|
16
|
-
/** Map of ForkDigest in hex format without prefix: `0011aabb` */
|
|
17
|
-
const epochByForkDigest = new Map<ForkDigestHex, Epoch>();
|
|
18
|
-
|
|
19
|
-
const {forkBoundariesAscendingEpochOrder} = chainForkConfig;
|
|
20
|
-
|
|
21
|
-
for (let i = 0; i < forkBoundariesAscendingEpochOrder.length; i++) {
|
|
22
|
-
const currentForkBoundary = forkBoundariesAscendingEpochOrder[i];
|
|
23
|
-
const nextForkBoundary = forkBoundariesAscendingEpochOrder[i + 1];
|
|
24
|
-
|
|
25
|
-
const currentEpoch = currentForkBoundary.epoch;
|
|
26
|
-
const nextEpoch = nextForkBoundary !== undefined ? nextForkBoundary.epoch : Infinity;
|
|
27
|
-
|
|
28
|
-
// Edge case: If multiple fork boundaries start at the same epoch, only consider the latest one
|
|
29
|
-
if (currentEpoch === nextEpoch) {
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const forkDigest = computeForkDigest(chainForkConfig, genesisValidatorsRoot, currentEpoch);
|
|
34
|
-
const forkDigestHex = toHexStringNoPrefix(forkDigest);
|
|
35
|
-
|
|
36
|
-
epochByForkDigest.set(forkDigestHex, currentEpoch);
|
|
37
|
-
forkDigestByEpoch.set(currentEpoch, forkDigest);
|
|
38
|
-
forkDigestHexByEpoch.set(currentEpoch, forkDigestHex);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
genesisValidatorsRoot,
|
|
43
|
-
|
|
44
|
-
getDomain(stateSlot: Slot, domainType: DomainType, messageSlot?: Slot): Uint8Array {
|
|
45
|
-
// ```py
|
|
46
|
-
// def get_domain(state: BeaconState, domain_type: DomainType, epoch: Epoch=None) -> Domain:
|
|
47
|
-
// """
|
|
48
|
-
// Return the signature domain (fork version concatenated with domain type) of a message.
|
|
49
|
-
// """
|
|
50
|
-
// epoch = get_current_epoch(state) if epoch is None else epoch
|
|
51
|
-
// fork_version = state.fork.previous_version if epoch < state.fork.epoch else state.fork.current_version
|
|
52
|
-
// return compute_domain(domain_type, fork_version, state.genesis_validators_root)
|
|
53
|
-
// ```
|
|
54
|
-
|
|
55
|
-
const epoch = Math.floor((messageSlot ?? stateSlot) / SLOTS_PER_EPOCH);
|
|
56
|
-
// Get pre-computed fork schedule, which _should_ match the one in the state
|
|
57
|
-
const stateForkInfo = chainForkConfig.getForkInfo(stateSlot);
|
|
58
|
-
// Only allow to select either current or previous fork respective of the fork schedule at stateSlot
|
|
59
|
-
const forkName = epoch < stateForkInfo.epoch ? stateForkInfo.prevForkName : stateForkInfo.name;
|
|
60
|
-
const forkInfo = chainForkConfig.forks[forkName];
|
|
61
|
-
|
|
62
|
-
let domainByType = domainCache.get(forkInfo.name);
|
|
63
|
-
if (!domainByType) {
|
|
64
|
-
domainByType = new Map<DomainType, Uint8Array>();
|
|
65
|
-
domainCache.set(forkInfo.name, domainByType);
|
|
66
|
-
}
|
|
67
|
-
let domain = domainByType.get(domainType);
|
|
68
|
-
if (!domain) {
|
|
69
|
-
domain = computeDomain(domainType, forkInfo.version, genesisValidatorsRoot);
|
|
70
|
-
domainByType.set(domainType, domain);
|
|
71
|
-
}
|
|
72
|
-
return domain;
|
|
73
|
-
},
|
|
74
|
-
|
|
75
|
-
getDomainAtFork(forkName: ForkName, domainType: DomainType): Uint8Array {
|
|
76
|
-
// For some of the messages, irrespective of which slot they are signed
|
|
77
|
-
// they need to use a fixed fork version even if other forks are scheduled
|
|
78
|
-
// at the same fork.
|
|
79
|
-
//
|
|
80
|
-
// For e.g. BLSToExecutionChange has to be signed using GENESIS_FORK_VERSION
|
|
81
|
-
// corresponding to phase0
|
|
82
|
-
const forkInfo = chainForkConfig.forks[forkName];
|
|
83
|
-
let domainByType = domainCache.get(forkInfo.name);
|
|
84
|
-
if (!domainByType) {
|
|
85
|
-
domainByType = new Map<DomainType, Uint8Array>();
|
|
86
|
-
domainCache.set(forkInfo.name, domainByType);
|
|
87
|
-
}
|
|
88
|
-
let domain = domainByType.get(domainType);
|
|
89
|
-
if (!domain) {
|
|
90
|
-
domain = computeDomain(domainType, forkInfo.version, genesisValidatorsRoot);
|
|
91
|
-
domainByType.set(domainType, domain);
|
|
92
|
-
}
|
|
93
|
-
return domain;
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
getDomainForVoluntaryExit(stateSlot: Slot, messageSlot?: Slot) {
|
|
97
|
-
// Deneb onwards the signature domain fork is fixed to capella
|
|
98
|
-
const domain =
|
|
99
|
-
stateSlot < chainForkConfig.DENEB_FORK_EPOCH * SLOTS_PER_EPOCH
|
|
100
|
-
? this.getDomain(stateSlot, DOMAIN_VOLUNTARY_EXIT, messageSlot)
|
|
101
|
-
: this.getDomainAtFork(ForkName.capella, DOMAIN_VOLUNTARY_EXIT);
|
|
102
|
-
|
|
103
|
-
return domain;
|
|
104
|
-
},
|
|
105
|
-
|
|
106
|
-
forkDigest2ForkBoundary(forkDigest: ForkDigest | ForkDigestHex): ForkBoundary {
|
|
107
|
-
const forkDigestHex = toHexStringNoPrefix(forkDigest);
|
|
108
|
-
const epoch = epochByForkDigest.get(forkDigestHex);
|
|
109
|
-
if (epoch == null) {
|
|
110
|
-
throw Error(`Unknown forkDigest ${forkDigestHex}`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return chainForkConfig.getForkBoundaryAtEpoch(epoch);
|
|
114
|
-
},
|
|
115
|
-
|
|
116
|
-
forkDigest2ForkBoundaryOption(forkDigest: ForkDigest | ForkDigestHex): ForkBoundary | null {
|
|
117
|
-
const forkDigestHex = toHexStringNoPrefix(forkDigest);
|
|
118
|
-
const epoch = epochByForkDigest.get(forkDigestHex);
|
|
119
|
-
if (epoch == null) {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return chainForkConfig.getForkBoundaryAtEpoch(epoch);
|
|
124
|
-
},
|
|
125
|
-
|
|
126
|
-
forkBoundary2ForkDigest(boundary: ForkBoundary): ForkDigest {
|
|
127
|
-
const forkDigest = forkDigestByEpoch.get(boundary.epoch);
|
|
128
|
-
if (!forkDigest) {
|
|
129
|
-
throw Error(`No precomputed forkDigest for ${boundary.epoch}`);
|
|
130
|
-
}
|
|
131
|
-
return forkDigest;
|
|
132
|
-
},
|
|
133
|
-
|
|
134
|
-
forkBoundary2ForkDigestHex(boundary: ForkBoundary): ForkDigestHex {
|
|
135
|
-
const forkDigestHex = forkDigestHexByEpoch.get(boundary.epoch);
|
|
136
|
-
if (!forkDigestHex) {
|
|
137
|
-
throw Error(`No precomputed forkDigest for ${boundary.epoch}`);
|
|
138
|
-
}
|
|
139
|
-
return toHexStringNoPrefix(forkDigestHex);
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function computeDomain(domainType: DomainType, forkVersion: Version, genesisValidatorRoot: Root): Uint8Array {
|
|
145
|
-
const forkDataRoot = computeForkDataRoot(forkVersion, genesisValidatorRoot);
|
|
146
|
-
const domain = new Uint8Array(32);
|
|
147
|
-
domain.set(domainType, 0);
|
|
148
|
-
domain.set(forkDataRoot.slice(0, 28), 4);
|
|
149
|
-
return domain;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function computeForkDataRoot(currentVersion: Version, genesisValidatorsRoot: Root): Uint8Array {
|
|
153
|
-
const forkData: phase0.ForkData = {
|
|
154
|
-
currentVersion,
|
|
155
|
-
genesisValidatorsRoot,
|
|
156
|
-
};
|
|
157
|
-
return ssz.phase0.ForkData.hashTreeRoot(forkData);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function toHexStringNoPrefix(hex: string | Uint8Array): string {
|
|
161
|
-
return strip0xPrefix(typeof hex === "string" ? hex : toHex(hex));
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export function computeForkDigest(config: ChainForkConfig, genesisValidatorsRoot: Root, epoch: Epoch): ForkDigest {
|
|
165
|
-
const currentFork = config.getForkInfoAtEpoch(epoch);
|
|
166
|
-
const baseDigest = computeForkDataRoot(currentFork.version, genesisValidatorsRoot);
|
|
167
|
-
|
|
168
|
-
if (currentFork.seq < ForkSeq.fulu) {
|
|
169
|
-
return baseDigest.slice(0, 4);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const blobParameters = config.getBlobParameters(epoch);
|
|
173
|
-
|
|
174
|
-
return xor(
|
|
175
|
-
baseDigest,
|
|
176
|
-
digest(
|
|
177
|
-
Buffer.concat([intToBytes(blobParameters.epoch, 8, "le"), intToBytes(blobParameters.maxBlobsPerBlock, 8, "le")])
|
|
178
|
-
)
|
|
179
|
-
).slice(0, 4);
|
|
180
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import {ForkName} from "@lodestar/params";
|
|
2
|
-
import {DomainType, ForkDigest, Root, Slot} from "@lodestar/types";
|
|
3
|
-
import {ForkBoundary} from "../forkConfig/types.js";
|
|
4
|
-
|
|
5
|
-
export type ForkDigestHex = string;
|
|
6
|
-
|
|
7
|
-
export type ForkDigestContext = {
|
|
8
|
-
forkDigest2ForkBoundary(forkDigest: ForkDigest | ForkDigestHex): ForkBoundary;
|
|
9
|
-
forkDigest2ForkBoundaryOption(forkDigest: ForkDigest | ForkDigestHex): ForkBoundary | null;
|
|
10
|
-
forkBoundary2ForkDigest(boundary: ForkBoundary): ForkDigest;
|
|
11
|
-
forkBoundary2ForkDigestHex(boundary: ForkBoundary): ForkDigestHex;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export interface CachedGenesis extends ForkDigestContext {
|
|
15
|
-
/**
|
|
16
|
-
* Return the signature domain (fork version concatenated with domain type) of a message.
|
|
17
|
-
*
|
|
18
|
-
* Note: The configured fork schedule is always used rather than on-chain fork schedule.
|
|
19
|
-
*/
|
|
20
|
-
getDomain(stateSlot: Slot, domainType: DomainType, messageSlot?: Slot): Uint8Array;
|
|
21
|
-
/**
|
|
22
|
-
* Return the signature domain corresponding to a particular fork version
|
|
23
|
-
*/
|
|
24
|
-
getDomainAtFork(forkName: ForkName, domainType: DomainType): Uint8Array;
|
|
25
|
-
|
|
26
|
-
getDomainForVoluntaryExit(stateSlot: Slot, messageSlot?: Slot): Uint8Array;
|
|
27
|
-
|
|
28
|
-
readonly genesisValidatorsRoot: Root;
|
|
29
|
-
}
|
package/src/index.ts
DELETED
package/src/networks.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import {ChainConfig} from "./chainConfig/index.js";
|
|
2
|
-
import {chiadoChainConfig} from "./chainConfig/networks/chiado.js";
|
|
3
|
-
import {ephemeryChainConfig} from "./chainConfig/networks/ephemery.js";
|
|
4
|
-
import {gnosisChainConfig} from "./chainConfig/networks/gnosis.js";
|
|
5
|
-
import {holeskyChainConfig} from "./chainConfig/networks/holesky.js";
|
|
6
|
-
import {hoodiChainConfig} from "./chainConfig/networks/hoodi.js";
|
|
7
|
-
import {mainnetChainConfig} from "./chainConfig/networks/mainnet.js";
|
|
8
|
-
import {sepoliaChainConfig} from "./chainConfig/networks/sepolia.js";
|
|
9
|
-
|
|
10
|
-
export {
|
|
11
|
-
mainnetChainConfig,
|
|
12
|
-
gnosisChainConfig,
|
|
13
|
-
sepoliaChainConfig,
|
|
14
|
-
holeskyChainConfig,
|
|
15
|
-
hoodiChainConfig,
|
|
16
|
-
chiadoChainConfig,
|
|
17
|
-
ephemeryChainConfig,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export type NetworkName = "mainnet" | "gnosis" | "sepolia" | "holesky" | "hoodi" | "chiado" | "ephemery";
|
|
21
|
-
export const networksChainConfig: Record<NetworkName, ChainConfig> = {
|
|
22
|
-
mainnet: mainnetChainConfig,
|
|
23
|
-
gnosis: gnosisChainConfig,
|
|
24
|
-
sepolia: sepoliaChainConfig,
|
|
25
|
-
holesky: holeskyChainConfig,
|
|
26
|
-
hoodi: hoodiChainConfig,
|
|
27
|
-
chiado: chiadoChainConfig,
|
|
28
|
-
ephemery: ephemeryChainConfig,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export type GenesisData = {
|
|
32
|
-
genesisTime: number;
|
|
33
|
-
genesisValidatorsRoot: string;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const genesisData: Record<NetworkName, GenesisData> = {
|
|
37
|
-
mainnet: {
|
|
38
|
-
genesisTime: 1606824023,
|
|
39
|
-
genesisValidatorsRoot: "0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95",
|
|
40
|
-
},
|
|
41
|
-
gnosis: {
|
|
42
|
-
genesisTime: 1638993340,
|
|
43
|
-
genesisValidatorsRoot: "0xf5dcb5564e829aab27264b9becd5dfaa017085611224cb3036f573368dbb9d47",
|
|
44
|
-
},
|
|
45
|
-
sepolia: {
|
|
46
|
-
genesisTime: 1655733600,
|
|
47
|
-
genesisValidatorsRoot: "0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078",
|
|
48
|
-
},
|
|
49
|
-
holesky: {
|
|
50
|
-
genesisTime: 1695902400,
|
|
51
|
-
genesisValidatorsRoot: "0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1",
|
|
52
|
-
},
|
|
53
|
-
hoodi: {
|
|
54
|
-
genesisTime: 1742213400,
|
|
55
|
-
genesisValidatorsRoot: "0x212f13fc4df078b6cb7db228f1c8307566dcecf900867401a92023d7ba99cb5f",
|
|
56
|
-
},
|
|
57
|
-
chiado: {
|
|
58
|
-
genesisTime: 1665396300,
|
|
59
|
-
genesisValidatorsRoot: "0x9d642dac73058fbf39c0ae41ab1e34e4d889043cb199851ded7095bc99eb4c1e",
|
|
60
|
-
},
|
|
61
|
-
ephemery: {
|
|
62
|
-
genesisTime: ephemeryChainConfig.MIN_GENESIS_TIME + ephemeryChainConfig.GENESIS_DELAY,
|
|
63
|
-
genesisValidatorsRoot: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
64
|
-
},
|
|
65
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import {MAX_BLOB_COMMITMENTS_PER_BLOCK} from "@lodestar/params";
|
|
2
|
-
import {BlobSchedule} from "../chainConfig/types.js";
|
|
3
|
-
|
|
4
|
-
export function validateBlobSchedule(blobSchedule: BlobSchedule): void {
|
|
5
|
-
if (blobSchedule.length === 0) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let previousEpoch: number | undefined;
|
|
10
|
-
|
|
11
|
-
for (const [i, entry] of blobSchedule.entries()) {
|
|
12
|
-
if (previousEpoch !== undefined) {
|
|
13
|
-
if (entry.EPOCH < previousEpoch) {
|
|
14
|
-
throw Error(
|
|
15
|
-
`Invalid BLOB_SCHEDULE expected entries to be sorted by EPOCH in ascending order, ${entry.EPOCH} < ${previousEpoch} at index ${i}`
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
if (entry.EPOCH === previousEpoch) {
|
|
19
|
-
throw Error(
|
|
20
|
-
`Invalid BLOB_SCHEDULE[${i}] entry with the same epoch value ${entry.EPOCH} as previous BLOB_SCHEDULE[${i - 1}] entry`
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (entry.MAX_BLOBS_PER_BLOCK > MAX_BLOB_COMMITMENTS_PER_BLOCK) {
|
|
25
|
-
throw Error(
|
|
26
|
-
`Invalid BLOB_SCHEDULE[${i}].MAX_BLOBS_PER_BLOCK value ${entry.MAX_BLOBS_PER_BLOCK} exceeds limit ${MAX_BLOB_COMMITMENTS_PER_BLOCK}`
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
previousEpoch = entry.EPOCH;
|
|
31
|
-
}
|
|
32
|
-
}
|