@lodestar/config 1.35.0-dev.8ea34e52ba → 1.35.0-dev.901d719660

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 (78) hide show
  1. package/README.md +4 -4
  2. package/lib/beaconConfig.d.ts.map +1 -0
  3. package/lib/chainConfig/configs/mainnet.d.ts.map +1 -0
  4. package/lib/chainConfig/configs/mainnet.js +24 -1
  5. package/lib/chainConfig/configs/mainnet.js.map +1 -1
  6. package/lib/chainConfig/configs/minimal.d.ts.map +1 -0
  7. package/lib/chainConfig/configs/minimal.js +24 -1
  8. package/lib/chainConfig/configs/minimal.js.map +1 -1
  9. package/lib/chainConfig/default.d.ts.map +1 -0
  10. package/lib/chainConfig/index.d.ts +2 -2
  11. package/lib/chainConfig/index.d.ts.map +1 -0
  12. package/lib/chainConfig/index.js +7 -2
  13. package/lib/chainConfig/index.js.map +1 -1
  14. package/lib/chainConfig/json.d.ts.map +1 -0
  15. package/lib/chainConfig/networks/chiado.d.ts.map +1 -0
  16. package/lib/chainConfig/networks/chiado.js +3 -0
  17. package/lib/chainConfig/networks/chiado.js.map +1 -1
  18. package/lib/chainConfig/networks/ephemery.d.ts.map +1 -0
  19. package/lib/chainConfig/networks/ephemery.js +3 -0
  20. package/lib/chainConfig/networks/ephemery.js.map +1 -1
  21. package/lib/chainConfig/networks/gnosis.d.ts.map +1 -0
  22. package/lib/chainConfig/networks/gnosis.js +3 -0
  23. package/lib/chainConfig/networks/gnosis.js.map +1 -1
  24. package/lib/chainConfig/networks/holesky.d.ts.map +1 -0
  25. package/lib/chainConfig/networks/holesky.js +14 -2
  26. package/lib/chainConfig/networks/holesky.js.map +1 -1
  27. package/lib/chainConfig/networks/hoodi.d.ts.map +1 -0
  28. package/lib/chainConfig/networks/hoodi.js +14 -2
  29. package/lib/chainConfig/networks/hoodi.js.map +1 -1
  30. package/lib/chainConfig/networks/mainnet.d.ts.map +1 -0
  31. package/lib/chainConfig/networks/sepolia.d.ts.map +1 -0
  32. package/lib/chainConfig/networks/sepolia.js +14 -2
  33. package/lib/chainConfig/networks/sepolia.js.map +1 -1
  34. package/lib/chainConfig/types.d.ts +12 -0
  35. package/lib/chainConfig/types.d.ts.map +1 -0
  36. package/lib/chainConfig/types.js +12 -0
  37. package/lib/chainConfig/types.js.map +1 -1
  38. package/lib/configs.d.ts.map +1 -0
  39. package/lib/default.d.ts +1 -1
  40. package/lib/default.d.ts.map +1 -0
  41. package/lib/forkConfig/index.d.ts.map +1 -0
  42. package/lib/forkConfig/index.js +31 -1
  43. package/lib/forkConfig/index.js.map +1 -1
  44. package/lib/forkConfig/types.d.ts +7 -0
  45. package/lib/forkConfig/types.d.ts.map +1 -0
  46. package/lib/genesisConfig/index.d.ts.map +1 -0
  47. package/lib/genesisConfig/index.js.map +1 -1
  48. package/lib/genesisConfig/types.d.ts.map +1 -0
  49. package/lib/index.d.ts +2 -2
  50. package/lib/index.d.ts.map +1 -0
  51. package/lib/index.js +2 -2
  52. package/lib/index.js.map +1 -1
  53. package/lib/networks.d.ts.map +1 -0
  54. package/lib/utils/validateBlobSchedule.d.ts.map +1 -0
  55. package/package.json +12 -10
  56. package/src/beaconConfig.ts +31 -0
  57. package/src/chainConfig/configs/mainnet.ts +172 -0
  58. package/src/chainConfig/configs/minimal.ts +167 -0
  59. package/src/chainConfig/default.ts +19 -0
  60. package/src/chainConfig/index.ts +33 -0
  61. package/src/chainConfig/json.ts +175 -0
  62. package/src/chainConfig/networks/chiado.ts +52 -0
  63. package/src/chainConfig/networks/ephemery.ts +74 -0
  64. package/src/chainConfig/networks/gnosis.ts +77 -0
  65. package/src/chainConfig/networks/holesky.ts +67 -0
  66. package/src/chainConfig/networks/hoodi.ts +67 -0
  67. package/src/chainConfig/networks/mainnet.ts +19 -0
  68. package/src/chainConfig/networks/sepolia.ts +64 -0
  69. package/src/chainConfig/types.ts +267 -0
  70. package/src/configs.ts +4 -0
  71. package/src/default.ts +6 -0
  72. package/src/forkConfig/index.ts +236 -0
  73. package/src/forkConfig/types.ts +68 -0
  74. package/src/genesisConfig/index.ts +180 -0
  75. package/src/genesisConfig/types.ts +29 -0
  76. package/src/index.ts +4 -0
  77. package/src/networks.ts +65 -0
  78. package/src/utils/validateBlobSchedule.ts +32 -0
@@ -0,0 +1,180 @@
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
+ }
@@ -0,0 +1,29 @@
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 ADDED
@@ -0,0 +1,4 @@
1
+ export * from "./beaconConfig.js";
2
+ export * from "./chainConfig/index.js";
3
+ export * from "./forkConfig/index.js";
4
+ export * from "./genesisConfig/index.js";
@@ -0,0 +1,65 @@
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
+ };
@@ -0,0 +1,32 @@
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
+ }