@lodestar/state-transition 1.49.0-dev.fbb58f7280 → 1.49.0

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 (65) hide show
  1. package/lib/block/processAttestationPhase0.d.ts +1 -1
  2. package/lib/block/processAttestationPhase0.js +1 -1
  3. package/lib/cache/epochTransitionCache.d.ts +2 -7
  4. package/lib/cache/epochTransitionCache.d.ts.map +1 -1
  5. package/lib/cache/epochTransitionCache.js +10 -7
  6. package/lib/cache/epochTransitionCache.js.map +1 -1
  7. package/lib/epoch/processSlashings.d.ts.map +1 -1
  8. package/lib/epoch/processSlashings.js +2 -1
  9. package/lib/epoch/processSlashings.js.map +1 -1
  10. package/lib/metrics.d.ts +4 -4
  11. package/lib/metrics.d.ts.map +1 -1
  12. package/lib/metrics.js +5 -6
  13. package/lib/metrics.js.map +1 -1
  14. package/lib/stateTransition.d.ts +2 -3
  15. package/lib/stateTransition.d.ts.map +1 -1
  16. package/lib/stateTransition.js +8 -10
  17. package/lib/stateTransition.js.map +1 -1
  18. package/lib/stateView/beaconStateView.d.ts +1 -2
  19. package/lib/stateView/beaconStateView.d.ts.map +1 -1
  20. package/lib/stateView/beaconStateView.js +3 -3
  21. package/lib/stateView/beaconStateView.js.map +1 -1
  22. package/lib/stateView/computeNewStateRoot.d.ts +2 -2
  23. package/lib/stateView/computeNewStateRoot.d.ts.map +1 -1
  24. package/lib/stateView/computeNewStateRoot.js +4 -7
  25. package/lib/stateView/computeNewStateRoot.js.map +1 -1
  26. package/lib/stateView/interface.d.ts +2 -2
  27. package/lib/stateView/interface.d.ts.map +1 -1
  28. package/lib/stateView/interface.js.map +1 -1
  29. package/lib/stateView/nativeBeaconStateView.d.ts +1 -2
  30. package/lib/stateView/nativeBeaconStateView.d.ts.map +1 -1
  31. package/lib/stateView/nativeBeaconStateView.js +3 -3
  32. package/lib/stateView/nativeBeaconStateView.js.map +1 -1
  33. package/lib/testUtils/index.d.ts +0 -1
  34. package/lib/testUtils/index.d.ts.map +1 -1
  35. package/lib/testUtils/index.js +0 -1
  36. package/lib/testUtils/index.js.map +1 -1
  37. package/lib/util/epochShuffling.d.ts +0 -1
  38. package/lib/util/epochShuffling.d.ts.map +1 -1
  39. package/lib/util/epochShuffling.js +1 -15
  40. package/lib/util/epochShuffling.js.map +1 -1
  41. package/lib/util/seed.js +1 -2
  42. package/lib/util/seed.js.map +1 -1
  43. package/package.json +7 -8
  44. package/src/block/processAttestationPhase0.ts +1 -1
  45. package/src/cache/epochTransitionCache.ts +11 -18
  46. package/src/epoch/processSlashings.ts +3 -2
  47. package/src/metrics.ts +6 -7
  48. package/src/stateTransition.ts +8 -12
  49. package/src/stateView/beaconStateView.ts +3 -8
  50. package/src/stateView/computeNewStateRoot.ts +5 -10
  51. package/src/stateView/interface.ts +2 -6
  52. package/src/stateView/nativeBeaconStateView.ts +3 -8
  53. package/src/testUtils/index.ts +0 -1
  54. package/src/util/epochShuffling.ts +1 -19
  55. package/src/util/seed.ts +4 -4
  56. package/lib/testUtils/infura.d.ts +0 -3
  57. package/lib/testUtils/infura.d.ts.map +0 -1
  58. package/lib/testUtils/infura.js +0 -8
  59. package/lib/testUtils/infura.js.map +0 -1
  60. package/lib/testUtils/testFileCache.d.ts +0 -17
  61. package/lib/testUtils/testFileCache.d.ts.map +0 -1
  62. package/lib/testUtils/testFileCache.js +0 -99
  63. package/lib/testUtils/testFileCache.js.map +0 -1
  64. package/src/testUtils/infura.ts +0 -10
  65. package/src/testUtils/testFileCache.ts +0 -130
@@ -4,7 +4,7 @@ import {toRootHex} from "@lodestar/utils";
4
4
  import {BlockExternalData, DataAvailabilityStatus, ExecutionPayloadStatus} from "./block/externalData.js";
5
5
  import {processBlock} from "./block/index.js";
6
6
  import {ProcessBlockOpts} from "./block/types.js";
7
- import {EpochTransitionCache, EpochTransitionCacheOpts, beforeProcessEpoch} from "./cache/epochTransitionCache.js";
7
+ import {EpochTransitionCache, beforeProcessEpoch} from "./cache/epochTransitionCache.js";
8
8
  import {EpochTransitionStep, processEpoch} from "./epoch/index.js";
9
9
  import {BeaconStateTransitionMetrics, onPostStateMetrics, onStateCloneMetrics} from "./metrics.js";
10
10
  import {verifyProposerSignature} from "./signatureSets/index.js";
@@ -36,7 +36,6 @@ import {computeEpochAtSlot} from "./util/index.js";
36
36
 
37
37
  // NOTE DENEB: Mandatory BlockExternalData to decide if block is available or not
38
38
  export type StateTransitionOpts = BlockExternalData &
39
- EpochTransitionCacheOpts &
40
39
  ProcessBlockOpts & {
41
40
  verifyStateRoot?: boolean;
42
41
  verifyProposer?: boolean;
@@ -110,7 +109,7 @@ export function stateTransition(
110
109
 
111
110
  // Process slots (including those with no blocks) since block.
112
111
  // Includes state upgrades
113
- postState = processSlotsWithTransientCache(postState, blockSlot, options, {metrics, validatorMonitor});
112
+ postState = processSlotsWithTransientCache(postState, blockSlot, {metrics, validatorMonitor});
114
113
 
115
114
  // Verify proposer signature only
116
115
  if (verifyProposer && !verifyProposerSignature(postState.config, signedBlock)) {
@@ -137,12 +136,10 @@ export function stateTransition(
137
136
  }
138
137
 
139
138
  // Verify state root
139
+ // Only spec tests enable verifyStateRoot. beacon-node always passes false and computes the root at the
140
+ // call site, where it is timed per source, so there is nothing to record here.
140
141
  if (verifyStateRoot) {
141
- const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
142
- source: StateHashTreeRootSource.stateTransition,
143
- });
144
142
  const stateRoot = postState.hashTreeRoot();
145
- hashTreeRootTimer?.();
146
143
 
147
144
  if (!ssz.Root.equals(block.stateRoot, stateRoot)) {
148
145
  throw new Error(
@@ -164,11 +161,11 @@ export function stateTransition(
164
161
  export function processSlots(
165
162
  state: CachedBeaconStateAllForks,
166
163
  slot: Slot,
167
- epochTransitionCacheOpts?: EpochTransitionCacheOpts & {dontTransferCache?: boolean},
164
+ opts?: {dontTransferCache?: boolean},
168
165
  {metrics, validatorMonitor}: StateTransitionModules = {}
169
166
  ): CachedBeaconStateAllForks {
170
167
  // .clone() before mutating state in state transition
171
- let postState = state.clone(epochTransitionCacheOpts?.dontTransferCache);
168
+ let postState = state.clone(opts?.dontTransferCache);
172
169
 
173
170
  if (metrics) {
174
171
  onStateCloneMetrics(postState, metrics, StateCloneSource.processSlots);
@@ -177,7 +174,7 @@ export function processSlots(
177
174
  // State is already a ViewDU, which won't commit changes. Equivalent to .setStateCachesAsTransient()
178
175
  // postState.setStateCachesAsTransient();
179
176
 
180
- postState = processSlotsWithTransientCache(postState, slot, epochTransitionCacheOpts, {metrics, validatorMonitor});
177
+ postState = processSlotsWithTransientCache(postState, slot, {metrics, validatorMonitor});
181
178
 
182
179
  // Apply changes to state, must do before hashing
183
180
  postState.commit();
@@ -210,7 +207,6 @@ export function processSlots(
210
207
  function processSlotsWithTransientCache(
211
208
  postState: CachedBeaconStateAllForks,
212
209
  slot: Slot,
213
- epochTransitionCacheOpts?: EpochTransitionCacheOpts,
214
210
  {metrics, validatorMonitor}: StateTransitionModules = {}
215
211
  ): CachedBeaconStateAllForks {
216
212
  const {config} = postState;
@@ -231,7 +227,7 @@ function processSlotsWithTransientCache(
231
227
  let epochTransitionCache: EpochTransitionCache;
232
228
  {
233
229
  const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.beforeProcessEpoch});
234
- epochTransitionCache = beforeProcessEpoch(postState, epochTransitionCacheOpts);
230
+ epochTransitionCache = beforeProcessEpoch(postState, metrics);
235
231
  timer?.();
236
232
  }
237
233
 
@@ -33,7 +33,6 @@ import {applyParentExecutionPayload} from "../block/processParentExecutionPayloa
33
33
  import {VoluntaryExitValidity, getVoluntaryExitValidity} from "../block/processVoluntaryExit.js";
34
34
  import {getExpectedWithdrawals} from "../block/processWithdrawals.js";
35
35
  import {EffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js";
36
- import {EpochTransitionCacheOpts} from "../cache/epochTransitionCache.js";
37
36
  import {RewardCache} from "../cache/rewardCache.js";
38
37
  import {
39
38
  CachedBeaconStateAllForks,
@@ -851,7 +850,7 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
851
850
  const postState = new BeaconStateView(
852
851
  stateTransition(this.cachedState, block, computeNewStateRootStateTransitionOpts, modules)
853
852
  );
854
- return getComputeNewStateRootResult(postState, modules);
853
+ return getComputeNewStateRootResult(postState);
855
854
  }
856
855
 
857
856
  stateTransition(
@@ -863,12 +862,8 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
863
862
  return new BeaconStateView(newState);
864
863
  }
865
864
 
866
- processSlots(
867
- slot: Slot,
868
- epochTransitionCacheOpts?: EpochTransitionCacheOpts & {dontTransferCache?: boolean},
869
- modules?: StateTransitionModules
870
- ): IBeaconStateView {
871
- const newState = processSlots(this.cachedState, slot, epochTransitionCacheOpts, modules);
865
+ processSlots(slot: Slot, opts?: {dontTransferCache?: boolean}, modules?: StateTransitionModules): IBeaconStateView {
866
+ const newState = processSlots(this.cachedState, slot, opts, modules);
872
867
  return new BeaconStateView(newState);
873
868
  }
874
869
 
@@ -1,5 +1,5 @@
1
1
  import {DataAvailabilityStatus, ExecutionPayloadStatus} from "../block/externalData.js";
2
- import {StateHashTreeRootSource, StateTransitionModules, StateTransitionOpts} from "../stateTransition.js";
2
+ import {StateTransitionOpts} from "../stateTransition.js";
3
3
  import {ComputeNewStateRootResult, IBeaconStateView} from "./interface.js";
4
4
 
5
5
  /** State transition options for computing the state root of a locally produced block. */
@@ -18,18 +18,13 @@ export const computeNewStateRootStateTransitionOpts: StateTransitionOpts = {
18
18
  dontTransferCache: true,
19
19
  };
20
20
 
21
- export function getComputeNewStateRootResult(
22
- postState: IBeaconStateView,
23
- {metrics}: StateTransitionModules
24
- ): ComputeNewStateRootResult {
21
+ export function getComputeNewStateRootResult(postState: IBeaconStateView): ComputeNewStateRootResult {
25
22
  const {attestations, syncAggregate, slashing} = postState.proposerRewards;
26
23
  const proposerReward = BigInt(attestations + syncAggregate + slashing);
27
24
 
28
- const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
29
- source: StateHashTreeRootSource.computeNewStateRoot,
30
- });
25
+ const start = Date.now();
31
26
  const newStateRoot = postState.hashTreeRoot();
32
- hashTreeRootTimer?.();
27
+ const hashTreeRootTime = (Date.now() - start) / 1000;
33
28
 
34
- return {newStateRoot, proposerReward, postState};
29
+ return {newStateRoot, proposerReward, postState, hashTreeRootTime};
35
30
  }
@@ -48,7 +48,6 @@ import {
48
48
  import {Checkpoint, Fork} from "@lodestar/types/phase0";
49
49
  import {VoluntaryExitValidity} from "../block/processVoluntaryExit.js";
50
50
  import {EffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js";
51
- import {EpochTransitionCacheOpts} from "../cache/epochTransitionCache.js";
52
51
  import {RewardCache} from "../cache/rewardCache.js";
53
52
  import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
54
53
  import {SyncCommitteeWitness} from "../lightClient/types.js";
@@ -68,6 +67,7 @@ export type ComputeNewStateRootResult = {
68
67
  newStateRoot: Root;
69
68
  proposerReward: Gwei;
70
69
  postState: IBeaconStateView;
70
+ hashTreeRootTime: number;
71
71
  };
72
72
 
73
73
  /**
@@ -184,11 +184,7 @@ export interface IBeaconStateView {
184
184
  options: StateTransitionOpts,
185
185
  modules: StateTransitionModules
186
186
  ): IBeaconStateView;
187
- processSlots(
188
- slot: Slot,
189
- epochTransitionCacheOpts?: EpochTransitionCacheOpts & {dontTransferCache?: boolean},
190
- modules?: StateTransitionModules
191
- ): IBeaconStateView;
187
+ processSlots(slot: Slot, opts?: {dontTransferCache?: boolean}, modules?: StateTransitionModules): IBeaconStateView;
192
188
  }
193
189
 
194
190
  /** Altair+ state fields — use isStatePostAltair() guard */
@@ -29,7 +29,6 @@ import {
29
29
  import {Checkpoint, Fork} from "@lodestar/types/phase0";
30
30
  import {VoluntaryExitValidity} from "../block/processVoluntaryExit.js";
31
31
  import {EffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js";
32
- import {EpochTransitionCacheOpts} from "../cache/epochTransitionCache.js";
33
32
  import {RewardCache} from "../cache/rewardCache.js";
34
33
  import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
35
34
  import {SyncCommitteeWitness} from "../lightClient/types.js";
@@ -652,7 +651,7 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
652
651
  const postState = new NativeBeaconStateView(
653
652
  this.binding.stateTransition(input.block, computeNewStateRootStateTransitionOpts, modules)
654
653
  );
655
- return getComputeNewStateRootResult(postState, modules);
654
+ return getComputeNewStateRootResult(postState);
656
655
  }
657
656
 
658
657
  stateTransition(
@@ -663,12 +662,8 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
663
662
  return new NativeBeaconStateView(this.binding.stateTransition(signedBlock, options, modules));
664
663
  }
665
664
 
666
- processSlots(
667
- slot: Slot,
668
- epochTransitionCacheOpts?: EpochTransitionCacheOpts & {dontTransferCache?: boolean},
669
- modules?: StateTransitionModules
670
- ): IBeaconStateView {
671
- return new NativeBeaconStateView(this.binding.processSlots(slot, epochTransitionCacheOpts, modules));
665
+ processSlots(slot: Slot, opts?: {dontTransferCache?: boolean}, modules?: StateTransitionModules): IBeaconStateView {
666
+ return new NativeBeaconStateView(this.binding.processSlots(slot, opts, modules));
672
667
  }
673
668
 
674
669
  // ─── altair ──────────────────────────────────────────────────────────────
@@ -2,5 +2,4 @@ export * from "./cache.js";
2
2
  export * from "./interop.js";
3
3
  export * from "./interopPubkeyCache.js";
4
4
  export * from "./params.js";
5
- export * from "./testFileCache.js";
6
5
  export * from "./util.js";
@@ -1,4 +1,4 @@
1
- import {asyncUnshuffleList, unshuffleList} from "@chainsafe/swap-or-not-shuffle";
1
+ import {unshuffleList} from "@chainsafe/lodestar-z/shuffle";
2
2
  import {BeaconConfig} from "@lodestar/config";
3
3
  import {
4
4
  DOMAIN_BEACON_ATTESTER,
@@ -105,24 +105,6 @@ export function computeEpochShuffling(
105
105
  };
106
106
  }
107
107
 
108
- export async function computeEpochShufflingAsync(
109
- // TODO: (@matthewkeil) remove state/epoch and pass in seed to clean this up
110
- state: BeaconStateAllForks,
111
- activeIndices: Uint32Array,
112
- epoch: Epoch
113
- ): Promise<EpochShuffling> {
114
- const seed = getSeed(state, epoch, DOMAIN_BEACON_ATTESTER);
115
- const shuffling = await asyncUnshuffleList(activeIndices, seed, SHUFFLE_ROUND_COUNT);
116
- const committees = buildCommitteesFromShuffling(shuffling);
117
- return {
118
- epoch,
119
- activeIndices,
120
- shuffling,
121
- committees,
122
- committeesPerSlot: committees[0].length,
123
- };
124
- }
125
-
126
108
  export function calculateDecisionRoot(state: BeaconStateAllForks, epoch: Epoch): RootHex {
127
109
  const pivotSlot = Math.max(GENESIS_SLOT, computeStartSlotAtEpoch(epoch - 1) - 1);
128
110
  return toRootHex(getBlockRootAtSlot(state, pivotSlot));
package/src/util/seed.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import {digest} from "@chainsafe/as-sha256";
2
- import {computePtcIndicesForEpoch} from "@chainsafe/lodestar-z/shuffle";
3
2
  import {
3
+ computePtcIndicesForEpoch,
4
4
  computeProposerIndex as nativeComputeProposerIndex,
5
5
  computeSyncCommitteeIndices as nativeComputeSyncCommitteeIndices,
6
- } from "@chainsafe/swap-or-not-shuffle";
6
+ } from "@chainsafe/lodestar-z/shuffle";
7
7
  import {
8
8
  DOMAIN_BEACON_PROPOSER,
9
9
  DOMAIN_PTC_ATTESTER,
@@ -118,7 +118,7 @@ export function computeProposerIndex(
118
118
  }
119
119
 
120
120
  let maxEffectiveBalance: number;
121
- let randByteCount: number;
121
+ let randByteCount: 1 | 2;
122
122
  if (fork >= ForkSeq.electra) {
123
123
  maxEffectiveBalance = MAX_EFFECTIVE_BALANCE_ELECTRA;
124
124
  randByteCount = 2;
@@ -245,7 +245,7 @@ export function getNextSyncCommitteeIndices(
245
245
  effectiveBalanceIncrements: EffectiveBalanceIncrements
246
246
  ): Uint32Array {
247
247
  let maxEffectiveBalance: number;
248
- let randByteCount: number;
248
+ let randByteCount: 1 | 2;
249
249
 
250
250
  if (fork >= ForkSeq.electra) {
251
251
  maxEffectiveBalance = MAX_EFFECTIVE_BALANCE_ELECTRA;
@@ -1,3 +0,0 @@
1
- import { NetworkName } from "@lodestar/config/networks";
2
- export declare function getInfuraBeaconUrl(network: NetworkName): string;
3
- //# sourceMappingURL=infura.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"infura.d.ts","sourceRoot":"","sources":["../../src/testUtils/infura.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,2BAA2B,CAAC;AAEtD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAO/D"}
@@ -1,8 +0,0 @@
1
- export function getInfuraBeaconUrl(network) {
2
- const INFURA_ETH2_CREDENTIALS = process.env.INFURA_ETH2_CREDENTIALS;
3
- if (!INFURA_ETH2_CREDENTIALS) {
4
- throw Error("Must set ENV INFURA_ETH2_CREDENTIALS");
5
- }
6
- return `https://${INFURA_ETH2_CREDENTIALS}@eth2-beacon-${network}.infura.io`;
7
- }
8
- //# sourceMappingURL=infura.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"infura.js","sourceRoot":"","sources":["../../src/testUtils/infura.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,kBAAkB,CAAC,OAAoB;IACrD,MAAM,uBAAuB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IACpE,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC7B,MAAM,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,WAAW,uBAAuB,gBAAgB,OAAO,YAAY,CAAC;AAC/E,CAAC"}
@@ -1,17 +0,0 @@
1
- import { ChainForkConfig } from "@lodestar/config";
2
- import { NetworkName } from "@lodestar/config/networks";
3
- import { SignedBeaconBlock } from "@lodestar/types";
4
- import { CachedBeaconStateAllForks } from "../index.js";
5
- /**
6
- * Create a network config from known network params
7
- */
8
- export declare function getNetworkConfig(network: NetworkName): ChainForkConfig;
9
- /**
10
- * Download a state from Infura. Caches states in local fs by network and slot to only download once.
11
- */
12
- export declare function getNetworkCachedState(network: NetworkName, slot: number, timeout?: number): Promise<CachedBeaconStateAllForks>;
13
- /**
14
- * Download a state from Infura. Caches states in local fs by network and slot to only download once.
15
- */
16
- export declare function getNetworkCachedBlock(network: NetworkName, slot: number, timeout?: number): Promise<SignedBeaconBlock>;
17
- //# sourceMappingURL=testFileCache.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"testFileCache.d.ts","sourceRoot":"","sources":["../../src/testUtils/testFileCache.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,eAAe,EAAwB,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAC,WAAW,EAAsB,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAC,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAC,yBAAyB,EAAC,MAAM,aAAa,CAAC;AAYtD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe,CAGtE;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,yBAAyB,CAAC,CA4BpC;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAyB5B"}
@@ -1,99 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { pubkeyCache } from "@chainsafe/lodestar-z/pubkeys";
4
- import { getClient } from "@lodestar/api";
5
- import { createChainForkConfig } from "@lodestar/config";
6
- import { networksChainConfig } from "@lodestar/config/networks";
7
- import { fetch } from "@lodestar/utils";
8
- import { testCachePath } from "./cache.js";
9
- import { getInfuraBeaconUrl } from "./infura.js";
10
- import { createCachedBeaconStateTest } from "./state.js";
11
- /**
12
- * Full link example:
13
- * ```
14
- * https://github.com/dapplion/ethereum-consensus-test-data/releases/download/v0.1.0/block_mainnet_3766821.ssz
15
- * ``` */
16
- const TEST_FILES_BASE_URL = "https://github.com/dapplion/ethereum-consensus-test-data/releases/download/v0.1.0";
17
- /**
18
- * Create a network config from known network params
19
- */
20
- export function getNetworkConfig(network) {
21
- const configNetwork = networksChainConfig[network];
22
- return createChainForkConfig(configNetwork);
23
- }
24
- /**
25
- * Download a state from Infura. Caches states in local fs by network and slot to only download once.
26
- */
27
- export async function getNetworkCachedState(network, slot, timeout) {
28
- const config = getNetworkConfig(network);
29
- const fileId = `state_${network}_${slot}.ssz`;
30
- const filepath = path.join(testCachePath, fileId);
31
- if (fs.existsSync(filepath)) {
32
- const stateSsz = fs.readFileSync(filepath);
33
- pubkeyCache.reset();
34
- return createCachedBeaconStateTest(config.getForkTypes(slot).BeaconState.deserializeToViewDU(stateSsz), config);
35
- }
36
- const stateSsz = await tryEach([
37
- () => downloadTestFile(fileId),
38
- () => {
39
- const client = getClient({ baseUrl: getInfuraBeaconUrl(network), globalInit: { timeoutMs: timeout ?? 300_000 } }, { config });
40
- return client.debug.getStateV2({ stateId: slot }).then((r) => {
41
- return r.ssz();
42
- });
43
- },
44
- ]);
45
- fs.writeFileSync(filepath, stateSsz);
46
- pubkeyCache.reset();
47
- return createCachedBeaconStateTest(config.getForkTypes(slot).BeaconState.deserializeToViewDU(stateSsz), config);
48
- }
49
- /**
50
- * Download a state from Infura. Caches states in local fs by network and slot to only download once.
51
- */
52
- export async function getNetworkCachedBlock(network, slot, timeout) {
53
- const config = getNetworkConfig(network);
54
- const fileId = `block_${network}_${slot}.ssz`;
55
- const filepath = path.join(testCachePath, fileId);
56
- if (fs.existsSync(filepath)) {
57
- const blockSsz = fs.readFileSync(filepath);
58
- return config.getForkTypes(slot).SignedBeaconBlock.deserialize(blockSsz);
59
- }
60
- const blockSsz = await tryEach([
61
- () => downloadTestFile(fileId),
62
- async () => {
63
- const client = getClient({ baseUrl: getInfuraBeaconUrl(network), globalInit: { timeoutMs: timeout ?? 300_000 } }, { config });
64
- return (await client.beacon.getBlockV2({ blockId: slot })).ssz();
65
- },
66
- ]);
67
- fs.writeFileSync(filepath, blockSsz);
68
- return config.getForkTypes(slot).SignedBeaconBlock.deserialize(blockSsz);
69
- }
70
- async function downloadTestFile(fileId) {
71
- const fileUrl = `${TEST_FILES_BASE_URL}/${fileId}`;
72
- // biome-ignore lint/suspicious/noConsole: We explicity need to log to console
73
- console.log(`Downloading file ${fileUrl}`);
74
- try {
75
- const res = await fetch(fileUrl);
76
- if (!res.ok) {
77
- throw new Error(`Error downloading ${fileUrl}: ${res.status} ${res.statusText}`);
78
- }
79
- return new Uint8Array(await res.arrayBuffer());
80
- }
81
- catch (e) {
82
- const error = e;
83
- error.message = `Error downloading ${fileUrl}: ${error.message}`;
84
- throw error;
85
- }
86
- }
87
- async function tryEach(promises) {
88
- const errors = [];
89
- for (let i = 0; i < promises.length; i++) {
90
- try {
91
- return await promises[i]();
92
- }
93
- catch (e) {
94
- errors.push(e);
95
- }
96
- }
97
- throw Error(errors.map((e, i) => `Error[${i}] ${e.message}`).join("\n"));
98
- }
99
- //# sourceMappingURL=testFileCache.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"testFileCache.js","sourceRoot":"","sources":["../../src/testUtils/testFileCache.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- import {NetworkName} from "@lodestar/config/networks";
2
-
3
- export function getInfuraBeaconUrl(network: NetworkName): string {
4
- const INFURA_ETH2_CREDENTIALS = process.env.INFURA_ETH2_CREDENTIALS;
5
- if (!INFURA_ETH2_CREDENTIALS) {
6
- throw Error("Must set ENV INFURA_ETH2_CREDENTIALS");
7
- }
8
-
9
- return `https://${INFURA_ETH2_CREDENTIALS}@eth2-beacon-${network}.infura.io`;
10
- }
@@ -1,130 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import {pubkeyCache} from "@chainsafe/lodestar-z/pubkeys";
4
- import {getClient} from "@lodestar/api";
5
- import {ChainForkConfig, createChainForkConfig} from "@lodestar/config";
6
- import {NetworkName, networksChainConfig} from "@lodestar/config/networks";
7
- import {SignedBeaconBlock} from "@lodestar/types";
8
- import {fetch} from "@lodestar/utils";
9
- import {CachedBeaconStateAllForks} from "../index.js";
10
- import {testCachePath} from "./cache.js";
11
- import {getInfuraBeaconUrl} from "./infura.js";
12
- import {createCachedBeaconStateTest} from "./state.js";
13
-
14
- /**
15
- * Full link example:
16
- * ```
17
- * https://github.com/dapplion/ethereum-consensus-test-data/releases/download/v0.1.0/block_mainnet_3766821.ssz
18
- * ``` */
19
- const TEST_FILES_BASE_URL = "https://github.com/dapplion/ethereum-consensus-test-data/releases/download/v0.1.0";
20
-
21
- /**
22
- * Create a network config from known network params
23
- */
24
- export function getNetworkConfig(network: NetworkName): ChainForkConfig {
25
- const configNetwork = networksChainConfig[network];
26
- return createChainForkConfig(configNetwork);
27
- }
28
-
29
- /**
30
- * Download a state from Infura. Caches states in local fs by network and slot to only download once.
31
- */
32
- export async function getNetworkCachedState(
33
- network: NetworkName,
34
- slot: number,
35
- timeout?: number
36
- ): Promise<CachedBeaconStateAllForks> {
37
- const config = getNetworkConfig(network);
38
- const fileId = `state_${network}_${slot}.ssz`;
39
-
40
- const filepath = path.join(testCachePath, fileId);
41
-
42
- if (fs.existsSync(filepath)) {
43
- const stateSsz = fs.readFileSync(filepath);
44
- pubkeyCache.reset();
45
- return createCachedBeaconStateTest(config.getForkTypes(slot).BeaconState.deserializeToViewDU(stateSsz), config);
46
- }
47
-
48
- const stateSsz = await tryEach([
49
- () => downloadTestFile(fileId),
50
- () => {
51
- const client = getClient(
52
- {baseUrl: getInfuraBeaconUrl(network), globalInit: {timeoutMs: timeout ?? 300_000}},
53
- {config}
54
- );
55
- return client.debug.getStateV2({stateId: slot}).then((r) => {
56
- return r.ssz();
57
- });
58
- },
59
- ]);
60
-
61
- fs.writeFileSync(filepath, stateSsz);
62
- pubkeyCache.reset();
63
- return createCachedBeaconStateTest(config.getForkTypes(slot).BeaconState.deserializeToViewDU(stateSsz), config);
64
- }
65
-
66
- /**
67
- * Download a state from Infura. Caches states in local fs by network and slot to only download once.
68
- */
69
- export async function getNetworkCachedBlock(
70
- network: NetworkName,
71
- slot: number,
72
- timeout?: number
73
- ): Promise<SignedBeaconBlock> {
74
- const config = getNetworkConfig(network);
75
- const fileId = `block_${network}_${slot}.ssz`;
76
-
77
- const filepath = path.join(testCachePath, fileId);
78
-
79
- if (fs.existsSync(filepath)) {
80
- const blockSsz = fs.readFileSync(filepath);
81
- return config.getForkTypes(slot).SignedBeaconBlock.deserialize(blockSsz);
82
- }
83
-
84
- const blockSsz = await tryEach([
85
- () => downloadTestFile(fileId),
86
- async () => {
87
- const client = getClient(
88
- {baseUrl: getInfuraBeaconUrl(network), globalInit: {timeoutMs: timeout ?? 300_000}},
89
- {config}
90
- );
91
-
92
- return (await client.beacon.getBlockV2({blockId: slot})).ssz();
93
- },
94
- ]);
95
-
96
- fs.writeFileSync(filepath, blockSsz);
97
- return config.getForkTypes(slot).SignedBeaconBlock.deserialize(blockSsz);
98
- }
99
-
100
- async function downloadTestFile(fileId: string): Promise<Uint8Array> {
101
- const fileUrl = `${TEST_FILES_BASE_URL}/${fileId}`;
102
- // biome-ignore lint/suspicious/noConsole: We explicity need to log to console
103
- console.log(`Downloading file ${fileUrl}`);
104
-
105
- try {
106
- const res = await fetch(fileUrl);
107
- if (!res.ok) {
108
- throw new Error(`Error downloading ${fileUrl}: ${res.status} ${res.statusText}`);
109
- }
110
- return new Uint8Array(await res.arrayBuffer());
111
- } catch (e) {
112
- const error = e as Error;
113
- error.message = `Error downloading ${fileUrl}: ${error.message}`;
114
- throw error;
115
- }
116
- }
117
-
118
- async function tryEach<T>(promises: (() => Promise<T>)[]): Promise<T> {
119
- const errors: Error[] = [];
120
-
121
- for (let i = 0; i < promises.length; i++) {
122
- try {
123
- return await promises[i]();
124
- } catch (e) {
125
- errors.push(e as Error);
126
- }
127
- }
128
-
129
- throw Error(errors.map((e, i) => `Error[${i}] ${e.message}`).join("\n"));
130
- }