@lodestar/state-transition 1.46.0-dev.22517ea3d8 → 1.46.0-dev.3d8f7cf440
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/block/externalData.js +2 -4
- package/lib/block/externalData.js.map +1 -1
- package/lib/block/index.js.map +1 -1
- package/lib/block/initiateValidatorExit.js.map +1 -1
- package/lib/block/isValidIndexedAttestation.js.map +1 -1
- package/lib/block/isValidIndexedPayloadAttestation.js.map +1 -1
- package/lib/block/processAttestationPhase0.js.map +1 -1
- package/lib/block/processAttestations.js.map +1 -1
- package/lib/block/processAttestationsAltair.js.map +1 -1
- package/lib/block/processAttesterSlashing.js.map +1 -1
- package/lib/block/processBlobKzgCommitments.js.map +1 -1
- package/lib/block/processBlockHeader.js.map +1 -1
- package/lib/block/processBlsToExecutionChange.js.map +1 -1
- package/lib/block/processBuilderDepositRequest.js.map +1 -1
- package/lib/block/processBuilderExitRequest.js.map +1 -1
- package/lib/block/processConsolidationRequest.js.map +1 -1
- package/lib/block/processDeposit.d.ts +15 -0
- package/lib/block/processDeposit.d.ts.map +1 -1
- package/lib/block/processDeposit.js +73 -1
- package/lib/block/processDeposit.js.map +1 -1
- package/lib/block/processDepositRequest.js.map +1 -1
- package/lib/block/processEth1Data.js.map +1 -1
- package/lib/block/processExecutionPayload.js.map +1 -1
- package/lib/block/processExecutionPayloadBid.d.ts +2 -2
- package/lib/block/processExecutionPayloadBid.d.ts.map +1 -1
- package/lib/block/processExecutionPayloadBid.js +8 -3
- package/lib/block/processExecutionPayloadBid.js.map +1 -1
- package/lib/block/processOperations.js.map +1 -1
- package/lib/block/processParentExecutionPayload.js.map +1 -1
- package/lib/block/processPayloadAttestation.js.map +1 -1
- package/lib/block/processProposerSlashing.js.map +1 -1
- package/lib/block/processRandao.js.map +1 -1
- package/lib/block/processSyncCommittee.js.map +1 -1
- package/lib/block/processVoluntaryExit.js +1 -2
- package/lib/block/processVoluntaryExit.js.map +1 -1
- package/lib/block/processWithdrawalRequest.js.map +1 -1
- package/lib/block/processWithdrawals.js.map +1 -1
- package/lib/block/slashValidator.js.map +1 -1
- package/lib/block/types.js +1 -2
- package/lib/block/types.js.map +1 -1
- package/lib/cache/builderDepositSignatureCache.d.ts +48 -0
- package/lib/cache/builderDepositSignatureCache.d.ts.map +1 -0
- package/lib/cache/builderDepositSignatureCache.js +70 -0
- package/lib/cache/builderDepositSignatureCache.js.map +1 -0
- package/lib/cache/effectiveBalanceIncrements.js.map +1 -1
- package/lib/cache/epochCache.d.ts +9 -0
- package/lib/cache/epochCache.d.ts.map +1 -1
- package/lib/cache/epochCache.js +14 -2
- package/lib/cache/epochCache.js.map +1 -1
- package/lib/cache/epochTransitionCache.js.map +1 -1
- package/lib/cache/pubkeyCache.js.map +1 -1
- package/lib/cache/rewardCache.js.map +1 -1
- package/lib/cache/stateCache.d.ts +2 -1
- package/lib/cache/stateCache.d.ts.map +1 -1
- package/lib/cache/stateCache.js +3 -2
- package/lib/cache/stateCache.js.map +1 -1
- package/lib/cache/syncCommitteeCache.js.map +1 -1
- package/lib/cache/types.d.ts +1 -0
- package/lib/cache/types.d.ts.map +1 -1
- package/lib/epoch/computeUnrealizedCheckpoints.js.map +1 -1
- package/lib/epoch/getAttestationDeltas.js.map +1 -1
- package/lib/epoch/getRewardsAndPenalties.js.map +1 -1
- package/lib/epoch/index.js +1 -2
- package/lib/epoch/index.js.map +1 -1
- package/lib/epoch/processBuilderPendingPayments.js.map +1 -1
- package/lib/epoch/processEffectiveBalanceUpdates.js.map +1 -1
- package/lib/epoch/processEth1DataReset.js.map +1 -1
- package/lib/epoch/processHistoricalRootsUpdate.js.map +1 -1
- package/lib/epoch/processHistoricalSummariesUpdate.js.map +1 -1
- package/lib/epoch/processInactivityUpdates.js.map +1 -1
- package/lib/epoch/processJustificationAndFinalization.js.map +1 -1
- package/lib/epoch/processParticipationFlagUpdates.js.map +1 -1
- package/lib/epoch/processParticipationRecordUpdates.js.map +1 -1
- package/lib/epoch/processPendingAttestations.js.map +1 -1
- package/lib/epoch/processPendingConsolidations.js.map +1 -1
- package/lib/epoch/processPendingDeposits.js.map +1 -1
- package/lib/epoch/processProposerLookahead.js.map +1 -1
- package/lib/epoch/processPtcWindow.js.map +1 -1
- package/lib/epoch/processRandaoMixesReset.js.map +1 -1
- package/lib/epoch/processRegistryUpdates.js.map +1 -1
- package/lib/epoch/processRewardsAndPenalties.js.map +1 -1
- package/lib/epoch/processSlashings.js.map +1 -1
- package/lib/epoch/processSlashingsReset.js.map +1 -1
- package/lib/epoch/processSyncCommitteeUpdates.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/lightClient/proofs.js.map +1 -1
- package/lib/lightClient/spec/index.js.map +1 -1
- package/lib/lightClient/spec/isBetterUpdate.js.map +1 -1
- package/lib/lightClient/spec/processLightClientUpdate.js.map +1 -1
- package/lib/lightClient/spec/store.js.map +1 -1
- package/lib/lightClient/spec/utils.d.ts +0 -2
- package/lib/lightClient/spec/utils.d.ts.map +1 -1
- package/lib/lightClient/spec/utils.js +8 -2
- package/lib/lightClient/spec/utils.js.map +1 -1
- package/lib/lightClient/spec/validateLightClientBootstrap.js.map +1 -1
- package/lib/lightClient/spec/validateLightClientUpdate.js.map +1 -1
- package/lib/metrics.d.ts.map +1 -1
- package/lib/metrics.js +3 -2
- package/lib/metrics.js.map +1 -1
- package/lib/rewards/attestationsRewards.js.map +1 -1
- package/lib/rewards/blockRewards.js.map +1 -1
- package/lib/rewards/syncCommitteeRewards.js.map +1 -1
- package/lib/signatureSets/attesterSlashings.js.map +1 -1
- package/lib/signatureSets/blsToExecutionChange.js.map +1 -1
- package/lib/signatureSets/executionPayloadBid.d.ts +2 -2
- package/lib/signatureSets/executionPayloadBid.d.ts.map +1 -1
- package/lib/signatureSets/executionPayloadBid.js +7 -5
- package/lib/signatureSets/executionPayloadBid.js.map +1 -1
- package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -1
- package/lib/signatureSets/index.js.map +1 -1
- package/lib/signatureSets/indexedAttestation.js.map +1 -1
- package/lib/signatureSets/indexedPayloadAttestation.js.map +1 -1
- package/lib/signatureSets/proposer.js.map +1 -1
- package/lib/signatureSets/proposerPreferences.js.map +1 -1
- package/lib/signatureSets/proposerSlashings.js.map +1 -1
- package/lib/signatureSets/randao.js.map +1 -1
- package/lib/signatureSets/voluntaryExits.js.map +1 -1
- package/lib/slot/index.d.ts +1 -0
- package/lib/slot/index.d.ts.map +1 -1
- package/lib/slot/index.js +1 -0
- package/lib/slot/index.js.map +1 -1
- package/lib/slot/upgradeStateToAltair.js.map +1 -1
- package/lib/slot/upgradeStateToBellatrix.js.map +1 -1
- package/lib/slot/upgradeStateToCapella.js.map +1 -1
- package/lib/slot/upgradeStateToDeneb.js.map +1 -1
- package/lib/slot/upgradeStateToElectra.js.map +1 -1
- package/lib/slot/upgradeStateToFulu.js.map +1 -1
- package/lib/slot/upgradeStateToGloas.js +13 -7
- package/lib/slot/upgradeStateToGloas.js.map +1 -1
- package/lib/slot/upgradeStateToHeze.d.ts +7 -0
- package/lib/slot/upgradeStateToHeze.d.ts.map +1 -0
- package/lib/slot/upgradeStateToHeze.js +83 -0
- package/lib/slot/upgradeStateToHeze.js.map +1 -0
- package/lib/stateTransition.d.ts.map +1 -1
- package/lib/stateTransition.js +6 -5
- package/lib/stateTransition.js.map +1 -1
- package/lib/stateView/beaconStateView.d.ts +3 -0
- package/lib/stateView/beaconStateView.d.ts.map +1 -1
- package/lib/stateView/beaconStateView.js +7 -0
- package/lib/stateView/beaconStateView.js.map +1 -1
- package/lib/stateView/interface.d.ts +16 -3
- package/lib/stateView/interface.d.ts.map +1 -1
- package/lib/stateView/interface.js +4 -1
- package/lib/stateView/interface.js.map +1 -1
- package/lib/stateView/nativeBeaconStateView.d.ts +3 -0
- package/lib/stateView/nativeBeaconStateView.d.ts.map +1 -1
- package/lib/stateView/nativeBeaconStateView.js +6 -0
- package/lib/stateView/nativeBeaconStateView.js.map +1 -1
- package/lib/stateView/stateViewFactory.js.map +1 -1
- package/lib/testUtils/infura.js.map +1 -1
- package/lib/testUtils/interop.js.map +1 -1
- package/lib/testUtils/params.d.ts.map +1 -1
- package/lib/testUtils/state.js +1 -1
- package/lib/testUtils/state.js.map +1 -1
- package/lib/testUtils/testFileCache.js.map +1 -1
- package/lib/testUtils/util.d.ts +17 -2
- package/lib/testUtils/util.d.ts.map +1 -1
- package/lib/testUtils/util.js +57 -4
- package/lib/testUtils/util.js.map +1 -1
- package/lib/types.d.ts +2 -2
- package/lib/types.d.ts.map +1 -1
- package/lib/util/aggregator.js.map +1 -1
- package/lib/util/altair.js.map +1 -1
- package/lib/util/array.js.map +1 -1
- package/lib/util/attestation.js.map +1 -1
- package/lib/util/attesterStatus.js.map +1 -1
- package/lib/util/balance.js.map +1 -1
- package/lib/util/blindedBlock.js.map +1 -1
- package/lib/util/blockRoot.js.map +1 -1
- package/lib/util/capella.js.map +1 -1
- package/lib/util/clock.d.ts +6 -0
- package/lib/util/clock.d.ts.map +1 -1
- package/lib/util/clock.js +1 -2
- package/lib/util/clock.js.map +1 -1
- package/lib/util/computeAnchorCheckpoint.js.map +1 -1
- package/lib/util/deposit.d.ts.map +1 -1
- package/lib/util/deposit.js +10 -8
- package/lib/util/deposit.js.map +1 -1
- package/lib/util/domain.js.map +1 -1
- package/lib/util/electra.js.map +1 -1
- package/lib/util/epoch.js.map +1 -1
- package/lib/util/epochShuffling.js.map +1 -1
- package/lib/util/execution.js.map +1 -1
- package/lib/util/finality.js.map +1 -1
- package/lib/util/fulu.js.map +1 -1
- package/lib/util/genesis.d.ts.map +1 -1
- package/lib/util/genesis.js +7 -2
- package/lib/util/genesis.js.map +1 -1
- package/lib/util/gloas.js.map +1 -1
- package/lib/util/index.d.ts +1 -0
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +1 -0
- package/lib/util/index.js.map +1 -1
- package/lib/util/interop.js.map +1 -1
- package/lib/util/loadState/findModifiedInactivityScores.js.map +1 -1
- package/lib/util/loadState/findModifiedValidators.js.map +1 -1
- package/lib/util/loadState/loadState.d.ts.map +1 -1
- package/lib/util/loadState/loadState.js +36 -5
- package/lib/util/loadState/loadState.js.map +1 -1
- package/lib/util/loadState/loadValidator.js.map +1 -1
- package/lib/util/pendingDepositsLookup.d.ts +7 -10
- package/lib/util/pendingDepositsLookup.d.ts.map +1 -1
- package/lib/util/pendingDepositsLookup.js +10 -19
- package/lib/util/pendingDepositsLookup.js.map +1 -1
- package/lib/util/preVerifyBuilderDeposits.d.ts +52 -0
- package/lib/util/preVerifyBuilderDeposits.d.ts.map +1 -0
- package/lib/util/preVerifyBuilderDeposits.js +124 -0
- package/lib/util/preVerifyBuilderDeposits.js.map +1 -0
- package/lib/util/rootCache.js.map +1 -1
- package/lib/util/seed.js.map +1 -1
- package/lib/util/shuffling.js +1 -2
- package/lib/util/shuffling.js.map +1 -1
- package/lib/util/signatureSets.js +1 -2
- package/lib/util/signatureSets.js.map +1 -1
- package/lib/util/signingRoot.js.map +1 -1
- package/lib/util/slot.js.map +1 -1
- package/lib/util/ssz.d.ts +5 -0
- package/lib/util/ssz.d.ts.map +1 -1
- package/lib/util/ssz.js +8 -1
- package/lib/util/ssz.js.map +1 -1
- package/lib/util/sszBytes.js.map +1 -1
- package/lib/util/syncCommittee.js.map +1 -1
- package/lib/util/targetUnslashedBalance.js.map +1 -1
- package/lib/util/validator.d.ts +5 -0
- package/lib/util/validator.d.ts.map +1 -1
- package/lib/util/validator.js +9 -0
- package/lib/util/validator.js.map +1 -1
- package/lib/util/weakSubjectivity.d.ts +1 -0
- package/lib/util/weakSubjectivity.d.ts.map +1 -1
- package/lib/util/weakSubjectivity.js +20 -8
- package/lib/util/weakSubjectivity.js.map +1 -1
- package/package.json +9 -9
- package/src/block/processDeposit.ts +75 -1
- package/src/block/processExecutionPayloadBid.ts +18 -8
- package/src/cache/builderDepositSignatureCache.ts +81 -0
- package/src/cache/epochCache.ts +14 -0
- package/src/cache/stateCache.ts +5 -2
- package/src/cache/types.ts +1 -0
- package/src/index.ts +4 -0
- package/src/lightClient/spec/utils.ts +9 -2
- package/src/metrics.ts +3 -2
- package/src/signatureSets/executionPayloadBid.ts +7 -9
- package/src/slot/index.ts +1 -0
- package/src/slot/upgradeStateToGloas.ts +17 -10
- package/src/slot/upgradeStateToHeze.ts +91 -0
- package/src/stateTransition.ts +5 -0
- package/src/stateView/beaconStateView.ts +13 -0
- package/src/stateView/interface.ts +21 -2
- package/src/stateView/nativeBeaconStateView.ts +9 -0
- package/src/testUtils/state.ts +1 -1
- package/src/testUtils/util.ts +75 -5
- package/src/types.ts +2 -0
- package/src/util/deposit.ts +11 -9
- package/src/util/genesis.ts +8 -2
- package/src/util/index.ts +1 -0
- package/src/util/loadState/loadState.ts +50 -11
- package/src/util/pendingDepositsLookup.ts +13 -24
- package/src/util/preVerifyBuilderDeposits.ts +153 -0
- package/src/util/ssz.ts +9 -1
- package/src/util/validator.ts +17 -0
- package/src/util/weakSubjectivity.ts +61 -22
package/src/stateTransition.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
upgradeStateToDeneb,
|
|
17
17
|
upgradeStateToElectra,
|
|
18
18
|
upgradeStateToGloas,
|
|
19
|
+
upgradeStateToHeze,
|
|
19
20
|
} from "./slot/index.js";
|
|
20
21
|
import {upgradeStateToFulu} from "./slot/upgradeStateToFulu.js";
|
|
21
22
|
import {
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
CachedBeaconStateDeneb,
|
|
27
28
|
CachedBeaconStateElectra,
|
|
28
29
|
CachedBeaconStateFulu,
|
|
30
|
+
CachedBeaconStateGloas,
|
|
29
31
|
CachedBeaconStatePhase0,
|
|
30
32
|
} from "./types.js";
|
|
31
33
|
import {computeEpochAtSlot} from "./util/index.js";
|
|
@@ -278,6 +280,9 @@ function processSlotsWithTransientCache(
|
|
|
278
280
|
if (stateEpoch === config.GLOAS_FORK_EPOCH) {
|
|
279
281
|
postState = upgradeStateToGloas(postState as CachedBeaconStateFulu) as CachedBeaconStateAllForks;
|
|
280
282
|
}
|
|
283
|
+
if (stateEpoch === config.HEZE_FORK_EPOCH) {
|
|
284
|
+
postState = upgradeStateToHeze(postState as CachedBeaconStateGloas) as CachedBeaconStateAllForks;
|
|
285
|
+
}
|
|
281
286
|
|
|
282
287
|
{
|
|
283
288
|
const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.finalProcessEpoch});
|
|
@@ -67,6 +67,7 @@ import {
|
|
|
67
67
|
} from "../util/execution.js";
|
|
68
68
|
import {canBuilderCoverBid} from "../util/gloas.js";
|
|
69
69
|
import {loadState} from "../util/loadState/loadState.js";
|
|
70
|
+
import {PreVerifyBuilderDepositsResult, preVerifyBuilderDepositsPreGloas} from "../util/preVerifyBuilderDeposits.js";
|
|
70
71
|
import {getRandaoMix} from "../util/seed.js";
|
|
71
72
|
import {getLatestWeakSubjectivityCheckpointEpoch} from "../util/weakSubjectivity.js";
|
|
72
73
|
import {IBeaconStateView, IBeaconStateViewGloas, IBeaconStateViewLatestFork, isStatePostGloas} from "./interface.js";
|
|
@@ -341,6 +342,18 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
341
342
|
return this._proposerLookahead;
|
|
342
343
|
}
|
|
343
344
|
|
|
345
|
+
preVerifyBuilderDepositsPreGloas(maxBuilderDeposits: number, maxDurationMs: number): PreVerifyBuilderDepositsResult {
|
|
346
|
+
return preVerifyBuilderDepositsPreGloas(
|
|
347
|
+
this.cachedState as CachedBeaconStateFulu,
|
|
348
|
+
maxBuilderDeposits,
|
|
349
|
+
maxDurationMs
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
clearPreGloasBuilderDepositCache(): void {
|
|
354
|
+
this.cachedState.epochCtx.builderDepositSignatureCache.clear();
|
|
355
|
+
}
|
|
356
|
+
|
|
344
357
|
// gloas
|
|
345
358
|
|
|
346
359
|
get latestBlockHash(): Bytes32 {
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
ForkPostElectra,
|
|
10
10
|
ForkPostFulu,
|
|
11
11
|
ForkPostGloas,
|
|
12
|
+
ForkPostHeze,
|
|
12
13
|
isForkPostAltair,
|
|
13
14
|
isForkPostBellatrix,
|
|
14
15
|
isForkPostCapella,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
isForkPostElectra,
|
|
17
18
|
isForkPostFulu,
|
|
18
19
|
isForkPostGloas,
|
|
20
|
+
isForkPostHeze,
|
|
19
21
|
} from "@lodestar/params";
|
|
20
22
|
import {
|
|
21
23
|
BeaconBlock,
|
|
@@ -50,6 +52,7 @@ import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
|
|
|
50
52
|
import {SyncCommitteeWitness} from "../lightClient/types.js";
|
|
51
53
|
import {StateTransitionModules, StateTransitionOpts} from "../stateTransition.js";
|
|
52
54
|
import {EpochShuffling} from "../util/epochShuffling.js";
|
|
55
|
+
import {PreVerifyBuilderDepositsResult} from "../util/preVerifyBuilderDeposits.js";
|
|
53
56
|
|
|
54
57
|
/**
|
|
55
58
|
* A read-only view of the BeaconState.
|
|
@@ -240,6 +243,13 @@ export interface IBeaconStateViewElectra extends IBeaconStateViewDeneb {
|
|
|
240
243
|
export interface IBeaconStateViewFulu extends IBeaconStateViewElectra {
|
|
241
244
|
forkName: ForkPostFulu;
|
|
242
245
|
proposerLookahead: fulu.ProposerLookahead;
|
|
246
|
+
/**
|
|
247
|
+
* Pre-verify a slice of builder-prefix pending deposits and cache the results on the underlying
|
|
248
|
+
* `BuilderDepositSignatureCache` (Fulu is the fork immediately before Gloas).
|
|
249
|
+
*/
|
|
250
|
+
preVerifyBuilderDepositsPreGloas(maxBuilderDeposits: number, maxDurationMs: number): PreVerifyBuilderDepositsResult;
|
|
251
|
+
/** Drop the pre-Gloas builder-deposit signature cache (called once the Gloas fork is finalized). */
|
|
252
|
+
clearPreGloasBuilderDepositCache(): void;
|
|
243
253
|
}
|
|
244
254
|
|
|
245
255
|
/** Gloas+ state fields — use isStatePostGloas() guard */
|
|
@@ -267,14 +277,19 @@ export interface IBeaconStateViewGloas extends IBeaconStateViewFulu {
|
|
|
267
277
|
withParentPayloadApplied(executionRequests: gloas.ExecutionRequests): IBeaconStateViewGloas;
|
|
268
278
|
}
|
|
269
279
|
|
|
280
|
+
/** Heze+ state fields — use isStatePostHeze() guard */
|
|
281
|
+
export interface IBeaconStateViewHeze extends IBeaconStateViewGloas {
|
|
282
|
+
forkName: ForkPostHeze;
|
|
283
|
+
}
|
|
284
|
+
|
|
270
285
|
/**
|
|
271
286
|
* Type constraint for the concrete BeaconStateView class.
|
|
272
|
-
* Requires all fields from the latest fork interface (
|
|
287
|
+
* Requires all fields from the latest fork interface (IBeaconStateViewHeze) but keeps
|
|
273
288
|
* forkName as ForkName since the class wraps any fork's state.
|
|
274
289
|
* Sub-interfaces retain their narrowed forkName discriminants for caller-side type guards.
|
|
275
290
|
*/
|
|
276
291
|
export type IBeaconStateViewLatestFork = Omit<
|
|
277
|
-
|
|
292
|
+
IBeaconStateViewHeze,
|
|
278
293
|
"forkName" | "latestExecutionPayloadHeader" | "payloadBlockNumber"
|
|
279
294
|
> & {
|
|
280
295
|
forkName: ForkName;
|
|
@@ -337,3 +352,7 @@ export function isStatePostFulu(state: IBeaconStateView): state is IBeaconStateV
|
|
|
337
352
|
export function isStatePostGloas(state: IBeaconStateView): state is IBeaconStateViewGloas {
|
|
338
353
|
return isForkPostGloas(state.forkName);
|
|
339
354
|
}
|
|
355
|
+
|
|
356
|
+
export function isStatePostHeze(state: IBeaconStateView): state is IBeaconStateViewHeze {
|
|
357
|
+
return isForkPostHeze(state.forkName);
|
|
358
|
+
}
|
|
@@ -35,6 +35,7 @@ import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
|
|
|
35
35
|
import {SyncCommitteeWitness} from "../lightClient/types.js";
|
|
36
36
|
import {StateTransitionModules, StateTransitionOpts} from "../stateTransition.js";
|
|
37
37
|
import {EpochShuffling} from "../util/epochShuffling.js";
|
|
38
|
+
import {PreVerifyBuilderDepositsResult} from "../util/preVerifyBuilderDeposits.js";
|
|
38
39
|
import {
|
|
39
40
|
IBeaconStateView,
|
|
40
41
|
IBeaconStateViewGloas,
|
|
@@ -845,6 +846,14 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
845
846
|
return this._proposerLookahead;
|
|
846
847
|
}
|
|
847
848
|
|
|
849
|
+
preVerifyBuilderDepositsPreGloas(maxBuilderDeposits: number, maxDurationMs: number): PreVerifyBuilderDepositsResult {
|
|
850
|
+
return this.binding.preVerifyBuilderDepositsPreGloas(maxBuilderDeposits, maxDurationMs);
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
clearPreGloasBuilderDepositCache(): void {
|
|
854
|
+
this.binding.clearPreGloasBuilderDepositCache();
|
|
855
|
+
}
|
|
856
|
+
|
|
848
857
|
// ─── gloas ───────────────────────────────────────────────────────────────
|
|
849
858
|
|
|
850
859
|
get latestBlockHash(): Bytes32 {
|
package/src/testUtils/state.ts
CHANGED
package/src/testUtils/util.ts
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
import {PublicKey, SecretKey} from "@chainsafe/blst";
|
|
2
2
|
import {BitArray, fromHexString} from "@chainsafe/ssz";
|
|
3
|
-
import {createBeaconConfig, createChainForkConfig} from "@lodestar/config";
|
|
3
|
+
import {BeaconConfig, createBeaconConfig, createChainForkConfig} from "@lodestar/config";
|
|
4
4
|
import {config} from "@lodestar/config/default";
|
|
5
5
|
import {
|
|
6
|
+
BUILDER_WITHDRAWAL_PREFIX,
|
|
7
|
+
DOMAIN_DEPOSIT,
|
|
6
8
|
EPOCHS_PER_ETH1_VOTING_PERIOD,
|
|
7
9
|
EPOCHS_PER_HISTORICAL_VECTOR,
|
|
8
10
|
ForkName,
|
|
9
11
|
ForkSeq,
|
|
12
|
+
GENESIS_SLOT,
|
|
10
13
|
MAX_ATTESTATIONS,
|
|
11
14
|
MAX_EFFECTIVE_BALANCE,
|
|
12
15
|
SLOTS_PER_EPOCH,
|
|
13
16
|
SLOTS_PER_HISTORICAL_ROOT,
|
|
14
17
|
} from "@lodestar/params";
|
|
15
|
-
import {BeaconState, Slot, phase0, ssz} from "@lodestar/types";
|
|
18
|
+
import {BeaconState, Slot, electra, phase0, ssz} from "@lodestar/types";
|
|
16
19
|
import {getEffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js";
|
|
20
|
+
import {ZERO_HASH} from "../constants/index.js";
|
|
17
21
|
import {
|
|
18
22
|
computeCommitteeCount,
|
|
19
23
|
computeEpochAtSlot,
|
|
20
24
|
createCachedBeaconState,
|
|
21
25
|
createPubkeyCache,
|
|
22
|
-
interopSecretKey,
|
|
23
26
|
newFilledArray,
|
|
24
27
|
processSlots,
|
|
25
28
|
} from "../index.js";
|
|
@@ -32,6 +35,9 @@ import {
|
|
|
32
35
|
CachedBeaconStateElectra,
|
|
33
36
|
CachedBeaconStatePhase0,
|
|
34
37
|
} from "../types.js";
|
|
38
|
+
import {computeDomain} from "../util/domain.js";
|
|
39
|
+
import {interopSecretKey} from "../util/interop.js";
|
|
40
|
+
import {computeSigningRoot} from "../util/signingRoot.js";
|
|
35
41
|
import {getNextSyncCommittee} from "../util/syncCommittee.js";
|
|
36
42
|
import {getActiveValidatorIndices} from "../util/validator.js";
|
|
37
43
|
import {interopPubkeysCached} from "./interop.js";
|
|
@@ -437,13 +443,13 @@ function buildPerformanceStatePhase0(pubkeysArg?: Uint8Array[]): phase0.BeaconSt
|
|
|
437
443
|
historicalRoots: [],
|
|
438
444
|
// Eth1
|
|
439
445
|
eth1Data: {
|
|
440
|
-
depositCount: pubkeys.length,
|
|
446
|
+
depositCount: BigInt(pubkeys.length),
|
|
441
447
|
depositRoot: fromHexString("0xcb1f89a924cfd31224823db5a41b1643f10faa7aedf231f1e28887f6ee98c047"),
|
|
442
448
|
blockHash: fromHexString("0x701fb2869ce16d0f1d14f6705725adb0dec6799da29006dfc6fff83960298f21"),
|
|
443
449
|
},
|
|
444
450
|
// minus one so that inserting 1 from block works
|
|
445
451
|
eth1DataVotes: newFilledArray(EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH - 1, {
|
|
446
|
-
depositCount:
|
|
452
|
+
depositCount: 1n,
|
|
447
453
|
depositRoot: Buffer.alloc(32, 1),
|
|
448
454
|
blockHash: Buffer.alloc(32, 1),
|
|
449
455
|
}),
|
|
@@ -541,3 +547,67 @@ export function generateTestCachedBeaconStateOnlyValidators({
|
|
|
541
547
|
{skipSyncPubkeys: true}
|
|
542
548
|
);
|
|
543
549
|
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Generate `count` validly-signed builder pending deposits with distinct interop pubkeys
|
|
553
|
+
* [startIndex, startIndex + count). Withdrawal credentials carry the BUILDER_WITHDRAWAL_PREFIX so
|
|
554
|
+
* `isBuilderWithdrawalCredential` recognizes them. Used to exercise the pre-Gloas builder-deposit
|
|
555
|
+
* pre-verify scanner and the fork-transition onboarding path.
|
|
556
|
+
*/
|
|
557
|
+
export function generateBuilderPendingDeposits(
|
|
558
|
+
config: BeaconConfig,
|
|
559
|
+
count: number,
|
|
560
|
+
startIndex: number
|
|
561
|
+
): electra.PendingDeposit[] {
|
|
562
|
+
// Deposits use a fork-agnostic domain, see `isValidDepositSignature`
|
|
563
|
+
const domain = computeDomain(DOMAIN_DEPOSIT, config.GENESIS_FORK_VERSION, ZERO_HASH);
|
|
564
|
+
const amount = 1_000_000_000; // 1 ETH in Gwei
|
|
565
|
+
const deposits: electra.PendingDeposit[] = [];
|
|
566
|
+
|
|
567
|
+
for (let i = 0; i < count; i++) {
|
|
568
|
+
const sk = interopSecretKey(startIndex + i);
|
|
569
|
+
const pubkey = sk.toPublicKey().toBytes();
|
|
570
|
+
|
|
571
|
+
const withdrawalCredentials = Buffer.alloc(32, 0);
|
|
572
|
+
withdrawalCredentials[0] = BUILDER_WITHDRAWAL_PREFIX;
|
|
573
|
+
// bytes [12, 32) hold the 20-byte builder execution address
|
|
574
|
+
withdrawalCredentials.fill((startIndex + i) & 0xff, 12, 32);
|
|
575
|
+
|
|
576
|
+
const signingRoot = computeSigningRoot(ssz.phase0.DepositMessage, {pubkey, withdrawalCredentials, amount}, domain);
|
|
577
|
+
|
|
578
|
+
deposits.push({
|
|
579
|
+
pubkey,
|
|
580
|
+
withdrawalCredentials,
|
|
581
|
+
amount,
|
|
582
|
+
signature: sk.sign(signingRoot).toBytes(),
|
|
583
|
+
slot: GENESIS_SLOT,
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
return deposits;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Generate a validly-signed *validator* (0x00-prefix) pending deposit for interop key `keyIndex`.
|
|
592
|
+
* Shares its pubkey with `generateBuilderPendingDeposits(config, 1, keyIndex)`, so it stands in for a
|
|
593
|
+
* validator deposit competing with a builder deposit for the same pubkey (the `hasPendingValidator`
|
|
594
|
+
* path). `amount` lets callers build otherwise-identical-but-distinct deposit value objects.
|
|
595
|
+
*/
|
|
596
|
+
export function generateValidatorPendingDeposit(
|
|
597
|
+
config: BeaconConfig,
|
|
598
|
+
keyIndex: number,
|
|
599
|
+
amount = 32_000_000_000
|
|
600
|
+
): electra.PendingDeposit {
|
|
601
|
+
const domain = computeDomain(DOMAIN_DEPOSIT, config.GENESIS_FORK_VERSION, ZERO_HASH);
|
|
602
|
+
const sk = interopSecretKey(keyIndex);
|
|
603
|
+
const pubkey = sk.toPublicKey().toBytes();
|
|
604
|
+
const withdrawalCredentials = Buffer.alloc(32, 0); // 0x00 prefix → validator, not a builder
|
|
605
|
+
const signingRoot = computeSigningRoot(ssz.phase0.DepositMessage, {pubkey, withdrawalCredentials, amount}, domain);
|
|
606
|
+
return {
|
|
607
|
+
pubkey,
|
|
608
|
+
withdrawalCredentials,
|
|
609
|
+
amount,
|
|
610
|
+
signature: sk.sign(signingRoot).toBytes(),
|
|
611
|
+
slot: GENESIS_SLOT,
|
|
612
|
+
};
|
|
613
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type {
|
|
|
10
10
|
CachedBeaconStateExecutions,
|
|
11
11
|
CachedBeaconStateFulu,
|
|
12
12
|
CachedBeaconStateGloas,
|
|
13
|
+
CachedBeaconStateHeze,
|
|
13
14
|
CachedBeaconStatePhase0,
|
|
14
15
|
} from "./cache/stateCache.js";
|
|
15
16
|
export type {
|
|
@@ -22,6 +23,7 @@ export type {
|
|
|
22
23
|
BeaconStateExecutions,
|
|
23
24
|
BeaconStateFulu,
|
|
24
25
|
BeaconStateGloas,
|
|
26
|
+
BeaconStateHeze,
|
|
25
27
|
BeaconStatePhase0,
|
|
26
28
|
ShufflingGetter,
|
|
27
29
|
} from "./cache/types.js";
|
package/src/util/deposit.ts
CHANGED
|
@@ -4,19 +4,21 @@ import {CachedBeaconStateAllForks, CachedBeaconStateElectra} from "../types.js";
|
|
|
4
4
|
|
|
5
5
|
export function getEth1DepositCount(state: CachedBeaconStateAllForks, eth1Data?: phase0.Eth1Data): UintNum64 {
|
|
6
6
|
const eth1DataToUse = eth1Data ?? state.eth1Data;
|
|
7
|
+
// Proposer can set any value, use in bigint until the result is bounded by MAX_DEPOSITS
|
|
8
|
+
const depositCount = eth1DataToUse.depositCount;
|
|
9
|
+
const eth1DepositIndex = BigInt(state.eth1DepositIndex);
|
|
10
|
+
const maxDeposits = BigInt(MAX_DEPOSITS);
|
|
7
11
|
if (state.config.getForkSeq(state.slot) >= ForkSeq.electra) {
|
|
8
12
|
const electraState = state as CachedBeaconStateElectra;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const eth1DataIndexLimit: UintNum64 =
|
|
12
|
-
eth1DataToUse.depositCount < electraState.depositRequestsStartIndex
|
|
13
|
-
? eth1DataToUse.depositCount
|
|
14
|
-
: Number(electraState.depositRequestsStartIndex);
|
|
13
|
+
const eth1DataIndexLimit =
|
|
14
|
+
depositCount < electraState.depositRequestsStartIndex ? depositCount : electraState.depositRequestsStartIndex;
|
|
15
15
|
|
|
16
|
-
if (
|
|
17
|
-
|
|
16
|
+
if (eth1DepositIndex < eth1DataIndexLimit) {
|
|
17
|
+
const available = eth1DataIndexLimit - eth1DepositIndex;
|
|
18
|
+
return Number(available < maxDeposits ? available : maxDeposits);
|
|
18
19
|
}
|
|
19
20
|
return 0;
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
+
const available = depositCount - eth1DepositIndex;
|
|
23
|
+
return Number(available < maxDeposits ? available : maxDeposits);
|
|
22
24
|
}
|
package/src/util/genesis.ts
CHANGED
|
@@ -139,7 +139,7 @@ export function applyDeposits(
|
|
|
139
139
|
const fullDepositDataRootArr = fullDepositDataRootList ? fullDepositDataRootList.getAllReadonlyValues() : null;
|
|
140
140
|
|
|
141
141
|
if (fullDepositDataRootArr) {
|
|
142
|
-
const depositCount = state.eth1Data.depositCount;
|
|
142
|
+
const depositCount = Number(state.eth1Data.depositCount);
|
|
143
143
|
for (let index = 0; index < depositCount; index++) {
|
|
144
144
|
depositDataRootList.push(fullDepositDataRootArr[index]);
|
|
145
145
|
}
|
|
@@ -160,7 +160,7 @@ export function applyDeposits(
|
|
|
160
160
|
);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
state.eth1Data.depositCount +=
|
|
163
|
+
state.eth1Data.depositCount += 1n;
|
|
164
164
|
|
|
165
165
|
const fork = config.getForkSeq(GENESIS_SLOT);
|
|
166
166
|
processDeposit(fork, state, deposit);
|
|
@@ -334,6 +334,12 @@ export function initializeBeaconStateFromEth1(
|
|
|
334
334
|
stateGloas.fork.currentVersion = config.GLOAS_FORK_VERSION;
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
+
if (fork >= ForkSeq.heze) {
|
|
338
|
+
const stateHeze = state as CompositeViewDU<typeof ssz.heze.BeaconState>;
|
|
339
|
+
stateHeze.fork.previousVersion = config.HEZE_FORK_VERSION;
|
|
340
|
+
stateHeze.fork.currentVersion = config.HEZE_FORK_VERSION;
|
|
341
|
+
}
|
|
342
|
+
|
|
337
343
|
state.commit();
|
|
338
344
|
|
|
339
345
|
return state;
|
package/src/util/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ export * from "./gloas.js";
|
|
|
20
20
|
export * from "./interop.js";
|
|
21
21
|
export * from "./loadState/index.js";
|
|
22
22
|
export * from "./pendingDepositsLookup.js";
|
|
23
|
+
export * from "./preVerifyBuilderDeposits.js";
|
|
23
24
|
export * from "./rootCache.js";
|
|
24
25
|
export * from "./seed.js";
|
|
25
26
|
export * from "./shuffling.js";
|
|
@@ -25,10 +25,29 @@ export function loadState(
|
|
|
25
25
|
): MigrateStateOutput {
|
|
26
26
|
// casting only to make typescript happy
|
|
27
27
|
const stateType = getStateTypeFromBytes(config, stateBytes) as typeof ssz.capella.BeaconState;
|
|
28
|
+
const fork = getForkFromStateBytes(config, stateBytes);
|
|
29
|
+
const seedFork = config.getForkSeq(seedState.slot);
|
|
30
|
+
|
|
28
31
|
const dataView = new DataView(stateBytes.buffer, stateBytes.byteOffset, stateBytes.byteLength);
|
|
29
32
|
const fieldRanges = stateType.getFieldRanges(dataView, 0, stateBytes.length);
|
|
30
33
|
const allFields = Object.keys(stateType.fields);
|
|
31
34
|
const validatorsFieldIndex = allFields.indexOf("validators");
|
|
35
|
+
const validatorsRange = fieldRanges[validatorsFieldIndex];
|
|
36
|
+
const newValidatorsBytes = stateBytes.subarray(validatorsRange.start, validatorsRange.end);
|
|
37
|
+
|
|
38
|
+
// EIP-7688 replaces List with ProgressiveList for validators and inactivityScores at gloas,
|
|
39
|
+
// changing the merkle tree shape. Seed nodes cannot be reused when one state is pre-gloas
|
|
40
|
+
// and the other post-gloas.
|
|
41
|
+
const crossesGloasFork =
|
|
42
|
+
(fork >= ForkSeq.gloas && seedFork < ForkSeq.gloas) || (fork < ForkSeq.gloas && seedFork >= ForkSeq.gloas);
|
|
43
|
+
if (crossesGloasFork) {
|
|
44
|
+
const migratedState = stateType.deserializeToViewDU(stateBytes) as BeaconStateAllForks;
|
|
45
|
+
// modified validators must still be reported so that the pubkey cache is refreshed for
|
|
46
|
+
// any index that differs from the seed state, which may not be an ancestor of this state
|
|
47
|
+
const modifiedValidators = findModifiedAndAppendedValidators(seedState, newValidatorsBytes, seedValidatorsBytes);
|
|
48
|
+
return {state: migratedState, modifiedValidators};
|
|
49
|
+
}
|
|
50
|
+
|
|
32
51
|
// start with default view has the same performance to start with seed state
|
|
33
52
|
// and it is not fork dependent
|
|
34
53
|
const migratedState = deserializeContainerIgnoreFields(
|
|
@@ -39,19 +58,10 @@ export function loadState(
|
|
|
39
58
|
) as BeaconStateAllForks;
|
|
40
59
|
|
|
41
60
|
// validators are rarely changed
|
|
42
|
-
const
|
|
43
|
-
const modifiedValidators = loadValidators(
|
|
44
|
-
migratedState,
|
|
45
|
-
seedState,
|
|
46
|
-
stateBytes.subarray(validatorsRange.start, validatorsRange.end),
|
|
47
|
-
seedValidatorsBytes
|
|
48
|
-
);
|
|
61
|
+
const modifiedValidators = loadValidators(migratedState, seedState, newValidatorsBytes, seedValidatorsBytes);
|
|
49
62
|
|
|
50
63
|
// inactivityScores are rarely changed
|
|
51
64
|
// this saves ~500ms of hashTreeRoot() time of state
|
|
52
|
-
const fork = getForkFromStateBytes(config, stateBytes);
|
|
53
|
-
const seedFork = config.getForkSeq(seedState.slot);
|
|
54
|
-
|
|
55
65
|
if (fork >= ForkSeq.altair && seedFork >= ForkSeq.altair) {
|
|
56
66
|
const inactivityScoresIndex = allFields.indexOf("inactivityScores");
|
|
57
67
|
const inactivityScoresRange = fieldRanges[inactivityScoresIndex];
|
|
@@ -141,7 +151,9 @@ function loadInactivityScores(
|
|
|
141
151
|
}
|
|
142
152
|
} else {
|
|
143
153
|
if (newValidator - 1 < 0) {
|
|
144
|
-
|
|
154
|
+
// use the state's own field type, the list shape differs between altair (List) and gloas (ProgressiveList)
|
|
155
|
+
const inactivityScoresType = (migratedState.type as typeof ssz.altair.BeaconState).fields.inactivityScores;
|
|
156
|
+
migratedState.inactivityScores = inactivityScoresType.defaultViewDU();
|
|
145
157
|
} else {
|
|
146
158
|
migratedState.inactivityScores = migratedState.inactivityScores.sliceTo(newValidator - 1);
|
|
147
159
|
}
|
|
@@ -177,6 +189,33 @@ function loadInactivityScores(
|
|
|
177
189
|
* @param migratedState state to be migrated, the validators are loaded to this state
|
|
178
190
|
* @returns modified validator indices
|
|
179
191
|
*/
|
|
192
|
+
/**
|
|
193
|
+
* Find indices of validators whose serialized bytes differ from the seed state, plus indices
|
|
194
|
+
* appended past the seed state's validator count. Unlike loadValidators() this only diffs
|
|
195
|
+
* bytes and does not share the seed state's tree.
|
|
196
|
+
*/
|
|
197
|
+
function findModifiedAndAppendedValidators(
|
|
198
|
+
seedState: BeaconStateAllForks,
|
|
199
|
+
newValidatorsBytes: Uint8Array,
|
|
200
|
+
seedStateValidatorsBytes?: Uint8Array
|
|
201
|
+
): number[] {
|
|
202
|
+
const seedValidatorCount = seedState.validators.length;
|
|
203
|
+
const newValidatorCount = Math.floor(newValidatorsBytes.length / VALIDATOR_BYTES_SIZE);
|
|
204
|
+
const minValidatorCount = Math.min(seedValidatorCount, newValidatorCount);
|
|
205
|
+
const seedValidatorsBytes = seedStateValidatorsBytes ?? seedState.validators.serialize();
|
|
206
|
+
const modifiedValidators: number[] = [];
|
|
207
|
+
findModifiedValidators(
|
|
208
|
+
seedValidatorsBytes.subarray(0, minValidatorCount * VALIDATOR_BYTES_SIZE),
|
|
209
|
+
newValidatorsBytes.subarray(0, minValidatorCount * VALIDATOR_BYTES_SIZE),
|
|
210
|
+
modifiedValidators
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
for (let validatorIndex = seedValidatorCount; validatorIndex < newValidatorCount; validatorIndex++) {
|
|
214
|
+
modifiedValidators.push(validatorIndex);
|
|
215
|
+
}
|
|
216
|
+
return modifiedValidators;
|
|
217
|
+
}
|
|
218
|
+
|
|
180
219
|
function loadValidators(
|
|
181
220
|
migratedState: BeaconStateAllForks,
|
|
182
221
|
seedState: BeaconStateAllForks,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
2
|
import {PubkeyHex, electra} from "@lodestar/types";
|
|
3
|
-
import {toPubkeyHex} from "@lodestar/utils";
|
|
4
3
|
import {isValidDepositSignature} from "../block/processDeposit.js";
|
|
5
|
-
import {
|
|
4
|
+
import {BuilderDepositSignatureCache} from "../cache/builderDepositSignatureCache.js";
|
|
6
5
|
|
|
7
6
|
type PendingDepositsValidation = {
|
|
8
7
|
hasValidSignature: boolean;
|
|
@@ -34,28 +33,14 @@ export class PendingDepositsLookup {
|
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
/**
|
|
37
|
-
*
|
|
38
|
-
* No BLS work is done here; signature verification happens lazily in `hasPendingValidator`.
|
|
36
|
+
* Append a pending deposit to the represented sequence, keyed by its (precomputed) `pubkeyHex`.
|
|
39
37
|
*/
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
for (const pendingDeposit of state.pendingDeposits.getAllReadonly()) {
|
|
43
|
-
lookup.add(pendingDeposit);
|
|
44
|
-
}
|
|
45
|
-
return lookup;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Append a pending deposit to the represented sequence.
|
|
50
|
-
* Pass `pubkeyHex` if the caller has already computed it.
|
|
51
|
-
*/
|
|
52
|
-
add(pendingDeposit: electra.PendingDeposit, pubkeyHex?: PubkeyHex): void {
|
|
53
|
-
const key = pubkeyHex ?? toPubkeyHex(pendingDeposit.pubkey);
|
|
54
|
-
const existing = this.depositsByPubkey.get(key);
|
|
38
|
+
add(pendingDeposit: electra.PendingDeposit, pubkeyHex: PubkeyHex): void {
|
|
39
|
+
const existing = this.depositsByPubkey.get(pubkeyHex);
|
|
55
40
|
if (existing) {
|
|
56
41
|
existing.push(pendingDeposit);
|
|
57
42
|
} else {
|
|
58
|
-
this.depositsByPubkey.set(
|
|
43
|
+
this.depositsByPubkey.set(pubkeyHex, [pendingDeposit]);
|
|
59
44
|
}
|
|
60
45
|
}
|
|
61
46
|
|
|
@@ -63,8 +48,11 @@ export class PendingDepositsLookup {
|
|
|
63
48
|
* Returns true if any pending deposit for `pubkeyHex` has a valid BLS deposit signature.
|
|
64
49
|
* Memoizes the result in `validationCache` so repeated checks for the same pubkey
|
|
65
50
|
* within a block only verify deposits that have not already been checked.
|
|
51
|
+
*
|
|
52
|
+
* Most of the time it should hit the BuilderDepositSignatureCache so we don't have to validate
|
|
53
|
+
* signatures here.
|
|
66
54
|
*/
|
|
67
|
-
hasPendingValidator(config: BeaconConfig, pubkeyHex: PubkeyHex): boolean {
|
|
55
|
+
hasPendingValidator(config: BeaconConfig, pubkeyHex: PubkeyHex, cache: BuilderDepositSignatureCache): boolean {
|
|
68
56
|
const validation = this.validationCache.get(pubkeyHex);
|
|
69
57
|
if (validation?.hasValidSignature === true) {
|
|
70
58
|
return true;
|
|
@@ -85,15 +73,16 @@ export class PendingDepositsLookup {
|
|
|
85
73
|
|
|
86
74
|
for (let i = startIndex; i < deposits.length; i++) {
|
|
87
75
|
const deposit = deposits[i];
|
|
88
|
-
|
|
76
|
+
const isValid =
|
|
77
|
+
cache.getSignatureValidity(deposit) ??
|
|
89
78
|
isValidDepositSignature(
|
|
90
79
|
config,
|
|
91
80
|
deposit.pubkey,
|
|
92
81
|
deposit.withdrawalCredentials,
|
|
93
82
|
deposit.amount,
|
|
94
83
|
deposit.signature
|
|
95
|
-
)
|
|
96
|
-
) {
|
|
84
|
+
);
|
|
85
|
+
if (isValid) {
|
|
97
86
|
this.validationCache.set(pubkeyHex, {hasValidSignature: true, validatedCount: i + 1});
|
|
98
87
|
return true;
|
|
99
88
|
}
|