@lodestar/state-transition 1.43.0-dev.ade910fc78 → 1.43.0-dev.ca1fc40294
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/processExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/block/processExecutionPayloadEnvelope.js +4 -7
- package/lib/block/processExecutionPayloadEnvelope.js.map +1 -1
- package/lib/cache/epochCache.d.ts +3 -1
- package/lib/cache/epochCache.d.ts.map +1 -1
- package/lib/cache/epochCache.js +31 -13
- package/lib/cache/epochCache.js.map +1 -1
- package/lib/cache/epochTransitionCache.d.ts +5 -0
- package/lib/cache/epochTransitionCache.d.ts.map +1 -1
- package/lib/cache/epochTransitionCache.js +1 -0
- package/lib/cache/epochTransitionCache.js.map +1 -1
- package/lib/epoch/index.d.ts +3 -1
- package/lib/epoch/index.d.ts.map +1 -1
- package/lib/epoch/index.js +8 -1
- package/lib/epoch/index.js.map +1 -1
- package/lib/epoch/processPtcWindow.d.ts +11 -0
- package/lib/epoch/processPtcWindow.d.ts.map +1 -0
- package/lib/epoch/processPtcWindow.js +28 -0
- package/lib/epoch/processPtcWindow.js.map +1 -0
- package/lib/signatureSets/executionPayloadEnvelope.js +1 -1
- package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -1
- package/lib/slot/upgradeStateToGloas.d.ts.map +1 -1
- package/lib/slot/upgradeStateToGloas.js +2 -1
- package/lib/slot/upgradeStateToGloas.js.map +1 -1
- package/lib/stateTransition.d.ts +1 -2
- package/lib/stateTransition.d.ts.map +1 -1
- package/lib/stateTransition.js +1 -2
- package/lib/stateTransition.js.map +1 -1
- package/lib/stateView/beaconStateView.d.ts +4 -8
- package/lib/stateView/beaconStateView.d.ts.map +1 -1
- package/lib/stateView/beaconStateView.js +19 -29
- package/lib/stateView/beaconStateView.js.map +1 -1
- package/lib/stateView/interface.d.ts +13 -9
- package/lib/stateView/interface.d.ts.map +1 -1
- package/lib/stateView/interface.js.map +1 -1
- package/lib/util/execution.d.ts +4 -2
- package/lib/util/execution.d.ts.map +1 -1
- package/lib/util/execution.js +7 -0
- package/lib/util/execution.js.map +1 -1
- package/lib/util/gloas.d.ts +8 -3
- package/lib/util/gloas.d.ts.map +1 -1
- package/lib/util/gloas.js +27 -1
- package/lib/util/gloas.js.map +1 -1
- package/package.json +8 -8
- package/src/block/processExecutionPayloadEnvelope.ts +4 -10
- package/src/cache/epochCache.ts +32 -30
- package/src/cache/epochTransitionCache.ts +7 -0
- package/src/epoch/index.ts +9 -0
- package/src/epoch/processPtcWindow.ts +38 -0
- package/src/signatureSets/executionPayloadEnvelope.ts +1 -1
- package/src/slot/upgradeStateToGloas.ts +2 -1
- package/src/stateTransition.ts +1 -2
- package/src/stateView/beaconStateView.ts +31 -33
- package/src/stateView/interface.ts +20 -9
- package/src/util/execution.ts +11 -1
- package/src/util/gloas.ts +50 -3
package/lib/util/gloas.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { BUILDER_INDEX_FLAG, BUILDER_PAYMENT_THRESHOLD_DENOMINATOR, BUILDER_PAYMENT_THRESHOLD_NUMERATOR, BUILDER_WITHDRAWAL_PREFIX, EFFECTIVE_BALANCE_INCREMENT, FAR_FUTURE_EPOCH, MIN_DEPOSIT_AMOUNT, SLOTS_PER_EPOCH, } from "@lodestar/params";
|
|
1
|
+
import { BUILDER_INDEX_FLAG, BUILDER_PAYMENT_THRESHOLD_DENOMINATOR, BUILDER_PAYMENT_THRESHOLD_NUMERATOR, BUILDER_WITHDRAWAL_PREFIX, EFFECTIVE_BALANCE_INCREMENT, FAR_FUTURE_EPOCH, MIN_DEPOSIT_AMOUNT, MIN_SEED_LOOKAHEAD, PTC_SIZE, SLOTS_PER_EPOCH, } from "@lodestar/params";
|
|
2
2
|
import { byteArrayEquals } from "@lodestar/utils";
|
|
3
3
|
import { getBlockRootAtSlot } from "./blockRoot.js";
|
|
4
4
|
import { computeEpochAtSlot } from "./epoch.js";
|
|
5
|
+
import { computeEpochShuffling } from "./epochShuffling.js";
|
|
6
|
+
import { computePayloadTimelinessCommitteesForEpoch } from "./seed.js";
|
|
7
|
+
import { getActiveValidatorIndices } from "./validator.js";
|
|
5
8
|
export function isBuilderWithdrawalCredential(withdrawalCredentials) {
|
|
6
9
|
return withdrawalCredentials[0] === BUILDER_WITHDRAWAL_PREFIX;
|
|
7
10
|
}
|
|
@@ -122,7 +125,30 @@ export function isAttestationSameSlotRootCache(rootCache, data) {
|
|
|
122
125
|
const isCurrentBlockRoot = !byteArrayEquals(data.beaconBlockRoot, rootCache.getBlockRootAtSlot(data.slot - 1));
|
|
123
126
|
return isMatchingBlockRoot && isCurrentBlockRoot;
|
|
124
127
|
}
|
|
128
|
+
// TODO GLOAS: This function no longer exists in v1.7.0-alpha.5 specs. Remove it when appropriate to do so
|
|
125
129
|
export function isParentBlockFull(state) {
|
|
126
130
|
return byteArrayEquals(state.latestExecutionPayloadBid.blockHash, state.latestBlockHash);
|
|
127
131
|
}
|
|
132
|
+
export function initializePtcWindow(state) {
|
|
133
|
+
const ptcWindow = Array.from({ length: SLOTS_PER_EPOCH }, () => new Uint32Array(PTC_SIZE));
|
|
134
|
+
const currentEpoch = state.epochCtx.epoch;
|
|
135
|
+
for (let epochOffset = 0; epochOffset <= MIN_SEED_LOOKAHEAD; epochOffset++) {
|
|
136
|
+
const epoch = currentEpoch + epochOffset;
|
|
137
|
+
const shuffling = state.epochCtx.getShufflingAtEpochOrNull(epoch) ??
|
|
138
|
+
computeEpochShuffling(state, getActiveValidatorIndices(state, epoch), epoch);
|
|
139
|
+
ptcWindow.push(...computePayloadTimelinessCommitteesForEpoch(state, epoch, shuffling.committees, state.epochCtx.effectiveBalanceIncrements));
|
|
140
|
+
}
|
|
141
|
+
return ptcWindow;
|
|
142
|
+
}
|
|
143
|
+
export function getPtcWindowEpochCacheData(state) {
|
|
144
|
+
const toUint32Arrays = (views) => views.map((v) => Uint32Array.from(v.getAll()));
|
|
145
|
+
const previousPtcWindow = state.ptcWindow.getReadonlyByRange(0, SLOTS_PER_EPOCH);
|
|
146
|
+
const currentPtcWindow = state.ptcWindow.getReadonlyByRange(SLOTS_PER_EPOCH, SLOTS_PER_EPOCH);
|
|
147
|
+
const nextPtcWindow = state.ptcWindow.getReadonlyByRange(2 * SLOTS_PER_EPOCH, SLOTS_PER_EPOCH);
|
|
148
|
+
return {
|
|
149
|
+
previousPayloadTimelinessCommittees: toUint32Arrays(previousPtcWindow),
|
|
150
|
+
payloadTimelinessCommittees: toUint32Arrays(currentPtcWindow),
|
|
151
|
+
nextPayloadTimelinessCommittees: toUint32Arrays(nextPtcWindow),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
128
154
|
//# sourceMappingURL=gloas.js.map
|
package/lib/util/gloas.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gloas.js","sourceRoot":"","sources":["../../src/util/gloas.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,qCAAqC,EACrC,mCAAmC,EACnC,yBAAyB,EACzB,2BAA2B,EAC3B,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"gloas.js","sourceRoot":"","sources":["../../src/util/gloas.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/ChainSafe/lodestar/issues"
|
|
13
13
|
},
|
|
14
|
-
"version": "1.43.0-dev.
|
|
14
|
+
"version": "1.43.0-dev.ca1fc40294",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -65,16 +65,16 @@
|
|
|
65
65
|
"@chainsafe/persistent-merkle-tree": "^1.2.1",
|
|
66
66
|
"@chainsafe/persistent-ts": "^1.0.0",
|
|
67
67
|
"@chainsafe/pubkey-index-map": "^3.0.0",
|
|
68
|
-
"@chainsafe/ssz": "^1.
|
|
68
|
+
"@chainsafe/ssz": "^1.4.0",
|
|
69
69
|
"@chainsafe/swap-or-not-shuffle": "^1.2.1",
|
|
70
|
-
"@lodestar/config": "^1.43.0-dev.
|
|
71
|
-
"@lodestar/params": "^1.43.0-dev.
|
|
72
|
-
"@lodestar/types": "^1.43.0-dev.
|
|
73
|
-
"@lodestar/utils": "^1.43.0-dev.
|
|
70
|
+
"@lodestar/config": "^1.43.0-dev.ca1fc40294",
|
|
71
|
+
"@lodestar/params": "^1.43.0-dev.ca1fc40294",
|
|
72
|
+
"@lodestar/types": "^1.43.0-dev.ca1fc40294",
|
|
73
|
+
"@lodestar/utils": "^1.43.0-dev.ca1fc40294",
|
|
74
74
|
"@vekexasia/bigint-buffer2": "^1.1.1"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
-
"@lodestar/api": "^1.43.0-dev.
|
|
77
|
+
"@lodestar/api": "^1.43.0-dev.ca1fc40294"
|
|
78
78
|
},
|
|
79
79
|
"keywords": [
|
|
80
80
|
"ethereum",
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"beacon",
|
|
83
83
|
"blockchain"
|
|
84
84
|
],
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "b9b4b6a67243378ab112c8d86a5681931be9bcc9"
|
|
86
86
|
}
|
|
@@ -24,10 +24,10 @@ export function processExecutionPayloadEnvelope(
|
|
|
24
24
|
signedEnvelope: gloas.SignedExecutionPayloadEnvelope,
|
|
25
25
|
opts?: ProcessExecutionPayloadEnvelopeOpts
|
|
26
26
|
): CachedBeaconStateGloas {
|
|
27
|
-
const {verifySignature = true
|
|
27
|
+
const {verifySignature = true} = opts ?? {};
|
|
28
28
|
const envelope = signedEnvelope.message;
|
|
29
29
|
const payload = envelope.payload;
|
|
30
|
-
const fork = state.config.getForkSeq(
|
|
30
|
+
const fork = state.config.getForkSeq(payload.slotNumber);
|
|
31
31
|
|
|
32
32
|
if (verifySignature && !verifyExecutionPayloadEnvelopeSignature(state, signedEnvelope)) {
|
|
33
33
|
throw Error(`Execution payload envelope has invalid signature builderIndex=${envelope.builderIndex}`);
|
|
@@ -74,12 +74,6 @@ export function processExecutionPayloadEnvelope(
|
|
|
74
74
|
|
|
75
75
|
postState.commit();
|
|
76
76
|
|
|
77
|
-
if (verifyStateRoot && !byteArrayEquals(envelope.stateRoot, postState.hashTreeRoot())) {
|
|
78
|
-
throw new Error(
|
|
79
|
-
`Envelope's state root does not match state envelope=${toRootHex(envelope.stateRoot)} state=${toRootHex(postState.hashTreeRoot())}`
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
77
|
return postState;
|
|
84
78
|
}
|
|
85
79
|
|
|
@@ -102,8 +96,8 @@ function validateExecutionPayloadEnvelope(
|
|
|
102
96
|
);
|
|
103
97
|
}
|
|
104
98
|
|
|
105
|
-
if (
|
|
106
|
-
throw new Error(`Slot mismatch between
|
|
99
|
+
if (payload.slotNumber !== state.slot) {
|
|
100
|
+
throw new Error(`Slot mismatch between payload and state payload=${payload.slotNumber} state=${state.slot}`);
|
|
107
101
|
}
|
|
108
102
|
|
|
109
103
|
// Verify consistency with the committed bid
|
package/src/cache/epochCache.ts
CHANGED
|
@@ -32,10 +32,10 @@ import {
|
|
|
32
32
|
calculateShufflingDecisionRoot,
|
|
33
33
|
computeEpochShuffling,
|
|
34
34
|
} from "../util/epochShuffling.js";
|
|
35
|
+
import {getPtcWindowEpochCacheData} from "../util/gloas.js";
|
|
35
36
|
import {
|
|
36
37
|
computeActivationExitEpoch,
|
|
37
38
|
computeEpochAtSlot,
|
|
38
|
-
computePayloadTimelinessCommitteesForEpoch,
|
|
39
39
|
computeProposers,
|
|
40
40
|
computeSyncPeriodAtEpoch,
|
|
41
41
|
getActivationChurnLimit,
|
|
@@ -56,7 +56,7 @@ import {sumTargetUnslashedBalanceIncrements} from "../util/targetUnslashedBalanc
|
|
|
56
56
|
import {EffectiveBalanceIncrements, getEffectiveBalanceIncrementsWithLen} from "./effectiveBalanceIncrements.js";
|
|
57
57
|
import {EpochTransitionCache} from "./epochTransitionCache.js";
|
|
58
58
|
import {PubkeyCache, createPubkeyCache, syncPubkeys} from "./pubkeyCache.js";
|
|
59
|
-
import {CachedBeaconStateAllForks, CachedBeaconStateFulu} from "./stateCache.js";
|
|
59
|
+
import {CachedBeaconStateAllForks, CachedBeaconStateFulu, CachedBeaconStateGloas} from "./stateCache.js";
|
|
60
60
|
import {
|
|
61
61
|
SyncCommitteeCache,
|
|
62
62
|
SyncCommitteeCacheEmpty,
|
|
@@ -226,11 +226,12 @@ export class EpochCache {
|
|
|
226
226
|
/** TODO: Indexed SyncCommitteeCache */
|
|
227
227
|
nextSyncCommitteeIndexed: SyncCommitteeCache;
|
|
228
228
|
|
|
229
|
-
// TODO GLOAS: See if we need to cache PTC for next epoch
|
|
230
229
|
// PTC for previous epoch, required for slot N block validating slot N-1 attestations
|
|
231
230
|
previousPayloadTimelinessCommittees: Uint32Array[];
|
|
232
231
|
// PTC for current epoch, computed eagerly at epoch transition
|
|
233
232
|
payloadTimelinessCommittees: Uint32Array[];
|
|
233
|
+
// PTC for next epoch, precomputed from the ptc window for future duty serving
|
|
234
|
+
nextPayloadTimelinessCommittees: Uint32Array[];
|
|
234
235
|
|
|
235
236
|
// TODO: Helper stats
|
|
236
237
|
syncPeriod: SyncPeriod;
|
|
@@ -270,6 +271,7 @@ export class EpochCache {
|
|
|
270
271
|
nextSyncCommitteeIndexed: SyncCommitteeCache;
|
|
271
272
|
previousPayloadTimelinessCommittees: Uint32Array[];
|
|
272
273
|
payloadTimelinessCommittees: Uint32Array[];
|
|
274
|
+
nextPayloadTimelinessCommittees: Uint32Array[];
|
|
273
275
|
epoch: Epoch;
|
|
274
276
|
syncPeriod: SyncPeriod;
|
|
275
277
|
}) {
|
|
@@ -301,6 +303,7 @@ export class EpochCache {
|
|
|
301
303
|
this.nextSyncCommitteeIndexed = data.nextSyncCommitteeIndexed;
|
|
302
304
|
this.previousPayloadTimelinessCommittees = data.previousPayloadTimelinessCommittees;
|
|
303
305
|
this.payloadTimelinessCommittees = data.payloadTimelinessCommittees;
|
|
306
|
+
this.nextPayloadTimelinessCommittees = data.nextPayloadTimelinessCommittees;
|
|
304
307
|
this.epoch = data.epoch;
|
|
305
308
|
this.syncPeriod = data.syncPeriod;
|
|
306
309
|
}
|
|
@@ -451,25 +454,13 @@ export class EpochCache {
|
|
|
451
454
|
nextSyncCommitteeIndexed = new SyncCommitteeCacheEmpty();
|
|
452
455
|
}
|
|
453
456
|
|
|
454
|
-
//
|
|
457
|
+
// Copy previous/current epoch PTC slices from state.ptcWindow once, then serve hot-path lookups from epochCtx.
|
|
455
458
|
let previousPayloadTimelinessCommittees: Uint32Array[] = [];
|
|
456
459
|
let payloadTimelinessCommittees: Uint32Array[] = [];
|
|
460
|
+
let nextPayloadTimelinessCommittees: Uint32Array[] = [];
|
|
457
461
|
if (currentEpoch >= config.GLOAS_FORK_EPOCH) {
|
|
458
|
-
payloadTimelinessCommittees =
|
|
459
|
-
state
|
|
460
|
-
currentEpoch,
|
|
461
|
-
currentShuffling.committees,
|
|
462
|
-
effectiveBalanceIncrements
|
|
463
|
-
);
|
|
464
|
-
|
|
465
|
-
if (!isGenesis && previousEpoch >= config.GLOAS_FORK_EPOCH) {
|
|
466
|
-
previousPayloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch(
|
|
467
|
-
state,
|
|
468
|
-
previousEpoch,
|
|
469
|
-
previousShuffling.committees,
|
|
470
|
-
effectiveBalanceIncrements
|
|
471
|
-
);
|
|
472
|
-
}
|
|
462
|
+
({previousPayloadTimelinessCommittees, payloadTimelinessCommittees, nextPayloadTimelinessCommittees} =
|
|
463
|
+
getPtcWindowEpochCacheData(state as CachedBeaconStateGloas));
|
|
473
464
|
}
|
|
474
465
|
|
|
475
466
|
// Precompute churnLimit for efficient initiateValidatorExit() during block proposing MUST be recompute everytime the
|
|
@@ -546,6 +537,7 @@ export class EpochCache {
|
|
|
546
537
|
nextSyncCommitteeIndexed,
|
|
547
538
|
previousPayloadTimelinessCommittees,
|
|
548
539
|
payloadTimelinessCommittees,
|
|
540
|
+
nextPayloadTimelinessCommittees,
|
|
549
541
|
epoch: currentEpoch,
|
|
550
542
|
syncPeriod: computeSyncPeriodAtEpoch(currentEpoch),
|
|
551
543
|
});
|
|
@@ -592,6 +584,7 @@ export class EpochCache {
|
|
|
592
584
|
nextSyncCommitteeIndexed: this.nextSyncCommitteeIndexed,
|
|
593
585
|
previousPayloadTimelinessCommittees: this.previousPayloadTimelinessCommittees,
|
|
594
586
|
payloadTimelinessCommittees: this.payloadTimelinessCommittees,
|
|
587
|
+
nextPayloadTimelinessCommittees: this.nextPayloadTimelinessCommittees,
|
|
595
588
|
epoch: this.epoch,
|
|
596
589
|
syncPeriod: this.syncPeriod,
|
|
597
590
|
});
|
|
@@ -695,21 +688,26 @@ export class EpochCache {
|
|
|
695
688
|
/**
|
|
696
689
|
* At fork boundary, this runs post-fork logic and it happens after `upgradeState*` is called.
|
|
697
690
|
*/
|
|
698
|
-
finalProcessEpoch(state: CachedBeaconStateAllForks): void {
|
|
691
|
+
finalProcessEpoch(state: CachedBeaconStateAllForks, epochTransitionCache: EpochTransitionCache): void {
|
|
699
692
|
// this.epoch was updated at the end of afterProcessEpoch()
|
|
700
693
|
const upcomingEpoch = this.epoch;
|
|
701
694
|
const epochAfterUpcoming = upcomingEpoch + 1;
|
|
702
695
|
|
|
703
696
|
this.proposersPrevEpoch = this.proposers;
|
|
704
697
|
if (upcomingEpoch >= this.config.GLOAS_FORK_EPOCH) {
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
698
|
+
if (epochTransitionCache.nextEpochPayloadTimelinessCommittees) {
|
|
699
|
+
// shift arrays from transition cache
|
|
700
|
+
this.previousPayloadTimelinessCommittees = this.payloadTimelinessCommittees;
|
|
701
|
+
this.payloadTimelinessCommittees = this.nextPayloadTimelinessCommittees;
|
|
702
|
+
this.nextPayloadTimelinessCommittees = epochTransitionCache.nextEpochPayloadTimelinessCommittees;
|
|
703
|
+
} else {
|
|
704
|
+
// Fork boundary: processPtcWindow didn't run, read from freshly initialized state.ptcWindow
|
|
705
|
+
({
|
|
706
|
+
previousPayloadTimelinessCommittees: this.previousPayloadTimelinessCommittees,
|
|
707
|
+
payloadTimelinessCommittees: this.payloadTimelinessCommittees,
|
|
708
|
+
nextPayloadTimelinessCommittees: this.nextPayloadTimelinessCommittees,
|
|
709
|
+
} = getPtcWindowEpochCacheData(state as CachedBeaconStateGloas));
|
|
710
|
+
}
|
|
713
711
|
}
|
|
714
712
|
if (upcomingEpoch >= this.config.FULU_FORK_EPOCH) {
|
|
715
713
|
// Populate proposer cache with lookahead from state
|
|
@@ -1034,12 +1032,16 @@ export class EpochCache {
|
|
|
1034
1032
|
throw new Error("Payload Timeliness Committee is not available before gloas fork");
|
|
1035
1033
|
}
|
|
1036
1034
|
|
|
1035
|
+
if (epoch === this.epoch - 1) {
|
|
1036
|
+
return this.previousPayloadTimelinessCommittees[slot % SLOTS_PER_EPOCH];
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1037
1039
|
if (epoch === this.epoch) {
|
|
1038
1040
|
return this.payloadTimelinessCommittees[slot % SLOTS_PER_EPOCH];
|
|
1039
1041
|
}
|
|
1040
1042
|
|
|
1041
|
-
if (epoch === this.epoch
|
|
1042
|
-
return this.
|
|
1043
|
+
if (epoch === this.epoch + 1) {
|
|
1044
|
+
return this.nextPayloadTimelinessCommittees[slot % SLOTS_PER_EPOCH];
|
|
1043
1045
|
}
|
|
1044
1046
|
|
|
1045
1047
|
throw new Error(`Payload Timeliness Committee is not available for slot=${slot}`);
|
|
@@ -158,6 +158,12 @@ export interface EpochTransitionCache {
|
|
|
158
158
|
*/
|
|
159
159
|
nextShuffling: EpochShuffling | null;
|
|
160
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Pre-computed PTC for epoch N + MIN_SEED_LOOKAHEAD + 1, populated by processPtcWindow (Gloas+).
|
|
163
|
+
* Used by finalProcessEpoch to shift PTC arrays in epoch cache without reading from state.
|
|
164
|
+
*/
|
|
165
|
+
nextEpochPayloadTimelinessCommittees: Uint32Array[] | null;
|
|
166
|
+
|
|
161
167
|
/**
|
|
162
168
|
* Altair specific, this is total active balances for the next epoch.
|
|
163
169
|
* This is only used in `afterProcessEpoch` to compute base reward and sync participant reward.
|
|
@@ -502,6 +508,7 @@ export function beforeProcessEpoch(
|
|
|
502
508
|
indicesToEject,
|
|
503
509
|
nextShufflingActiveIndices,
|
|
504
510
|
nextShuffling: null,
|
|
511
|
+
nextEpochPayloadTimelinessCommittees: null,
|
|
505
512
|
// to be updated in processEffectiveBalanceUpdates
|
|
506
513
|
nextEpochTotalActiveBalanceByIncrement: 0,
|
|
507
514
|
isActivePrevEpoch,
|
package/src/epoch/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {processParticipationRecordUpdates} from "./processParticipationRecordUpd
|
|
|
28
28
|
import {processPendingConsolidations} from "./processPendingConsolidations.js";
|
|
29
29
|
import {processPendingDeposits} from "./processPendingDeposits.js";
|
|
30
30
|
import {processProposerLookahead} from "./processProposerLookahead.js";
|
|
31
|
+
import {processPtcWindow} from "./processPtcWindow.js";
|
|
31
32
|
import {processRandaoMixesReset} from "./processRandaoMixesReset.js";
|
|
32
33
|
import {processRegistryUpdates} from "./processRegistryUpdates.js";
|
|
33
34
|
import {processRewardsAndPenalties} from "./processRewardsAndPenalties.js";
|
|
@@ -55,6 +56,7 @@ export {
|
|
|
55
56
|
processPendingDeposits,
|
|
56
57
|
processPendingConsolidations,
|
|
57
58
|
processProposerLookahead,
|
|
59
|
+
processPtcWindow,
|
|
58
60
|
processBuilderPendingPayments,
|
|
59
61
|
};
|
|
60
62
|
|
|
@@ -81,6 +83,7 @@ export enum EpochTransitionStep {
|
|
|
81
83
|
processPendingDeposits = "processPendingDeposits",
|
|
82
84
|
processPendingConsolidations = "processPendingConsolidations",
|
|
83
85
|
processProposerLookahead = "processProposerLookahead",
|
|
86
|
+
processPtcWindow = "processPtcWindow",
|
|
84
87
|
processBuilderPendingPayments = "processBuilderPendingPayments",
|
|
85
88
|
}
|
|
86
89
|
|
|
@@ -211,4 +214,10 @@ export function processEpoch(
|
|
|
211
214
|
processProposerLookahead(fork, state as CachedBeaconStateFulu, cache);
|
|
212
215
|
timer?.();
|
|
213
216
|
}
|
|
217
|
+
|
|
218
|
+
if (fork >= ForkSeq.gloas) {
|
|
219
|
+
const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.processPtcWindow});
|
|
220
|
+
processPtcWindow(state as CachedBeaconStateGloas, cache);
|
|
221
|
+
timer?.();
|
|
222
|
+
}
|
|
214
223
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {MIN_SEED_LOOKAHEAD} from "@lodestar/params";
|
|
2
|
+
import {ssz} from "@lodestar/types";
|
|
3
|
+
import {CachedBeaconStateGloas, EpochTransitionCache} from "../types.js";
|
|
4
|
+
import {computeEpochShuffling} from "../util/epochShuffling.js";
|
|
5
|
+
import {computePayloadTimelinessCommitteesForEpoch} from "../util/seed.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Update the `ptc_window` field in the beacon state by shifting out the oldest epoch's
|
|
9
|
+
* PTC entries and appending newly computed entries for the next lookahead epoch.
|
|
10
|
+
* Stashes the computed PTCs in the transition cache for finalProcessEpoch to shift
|
|
11
|
+
* into the epoch cache without reading from state.
|
|
12
|
+
*
|
|
13
|
+
* Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.4/specs/gloas/beacon-chain.md#new-process_ptc_window
|
|
14
|
+
*/
|
|
15
|
+
export function processPtcWindow(state: CachedBeaconStateGloas, cache: EpochTransitionCache): void {
|
|
16
|
+
const nextEpoch = state.epochCtx.epoch + MIN_SEED_LOOKAHEAD + 1;
|
|
17
|
+
const nextEpochShuffling =
|
|
18
|
+
cache.nextShuffling ?? computeEpochShuffling(state, cache.nextShufflingActiveIndices, nextEpoch);
|
|
19
|
+
cache.nextShuffling = nextEpochShuffling;
|
|
20
|
+
|
|
21
|
+
const newNextPayloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch(
|
|
22
|
+
state,
|
|
23
|
+
nextEpoch,
|
|
24
|
+
nextEpochShuffling.committees,
|
|
25
|
+
state.epochCtx.effectiveBalanceIncrements
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// Stash for finalProcessEpoch to shift into epoch cache
|
|
29
|
+
cache.nextEpochPayloadTimelinessCommittees = newNextPayloadTimelinessCommittees;
|
|
30
|
+
|
|
31
|
+
// Write shifted window to state: current(N) + next(N+1) + newlyComputed(N+2)
|
|
32
|
+
// From the perspective of upcoming epoch N+1, this is previous + current + next
|
|
33
|
+
state.ptcWindow = ssz.gloas.PtcWindow.toViewDU([
|
|
34
|
+
...state.epochCtx.payloadTimelinessCommittees,
|
|
35
|
+
...state.epochCtx.nextPayloadTimelinessCommittees,
|
|
36
|
+
...newNextPayloadTimelinessCommittees,
|
|
37
|
+
]);
|
|
38
|
+
}
|
|
@@ -11,7 +11,7 @@ export function getExecutionPayloadEnvelopeSigningRoot(
|
|
|
11
11
|
config: BeaconConfig,
|
|
12
12
|
envelope: gloas.ExecutionPayloadEnvelope
|
|
13
13
|
): Uint8Array {
|
|
14
|
-
const domain = config.getDomain(envelope.
|
|
14
|
+
const domain = config.getDomain(envelope.payload.slotNumber, DOMAIN_BEACON_BUILDER);
|
|
15
15
|
|
|
16
16
|
return computeSigningRoot(ssz.gloas.ExecutionPayloadEnvelope, envelope, domain);
|
|
17
17
|
}
|
|
@@ -5,7 +5,7 @@ import {isValidDepositSignature} from "../block/processDeposit.js";
|
|
|
5
5
|
import {applyDepositForBuilder} from "../block/processDepositRequest.js";
|
|
6
6
|
import {getCachedBeaconState} from "../cache/stateCache.js";
|
|
7
7
|
import {CachedBeaconStateFulu, CachedBeaconStateGloas} from "../types.js";
|
|
8
|
-
import {isBuilderWithdrawalCredential} from "../util/gloas.js";
|
|
8
|
+
import {initializePtcWindow, isBuilderWithdrawalCredential} from "../util/gloas.js";
|
|
9
9
|
import {isValidatorKnown} from "../util/index.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -61,6 +61,7 @@ export function upgradeStateToGloas(stateFulu: CachedBeaconStateFulu): CachedBea
|
|
|
61
61
|
stateGloasView.pendingPartialWithdrawals = stateGloasCloned.pendingPartialWithdrawals;
|
|
62
62
|
stateGloasView.pendingConsolidations = stateGloasCloned.pendingConsolidations;
|
|
63
63
|
stateGloasView.proposerLookahead = stateGloasCloned.proposerLookahead;
|
|
64
|
+
stateGloasView.ptcWindow = ssz.gloas.PtcWindow.toViewDU(initializePtcWindow(stateFulu));
|
|
64
65
|
|
|
65
66
|
for (let i = 0; i < SLOTS_PER_HISTORICAL_ROOT; i++) {
|
|
66
67
|
stateGloasView.executionPayloadAvailability.set(i, true);
|
package/src/stateTransition.ts
CHANGED
|
@@ -76,7 +76,6 @@ export enum StateHashTreeRootSource {
|
|
|
76
76
|
prepareNextEpoch = "prepare_next_epoch",
|
|
77
77
|
regenState = "regen_state",
|
|
78
78
|
computeNewStateRoot = "compute_new_state_root",
|
|
79
|
-
computePayloadEnvelopeStateRoot = "compute_payload_envelope_state_root",
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
/**
|
|
@@ -283,7 +282,7 @@ function processSlotsWithTransientCache(
|
|
|
283
282
|
{
|
|
284
283
|
const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.finalProcessEpoch});
|
|
285
284
|
// last step to prepare epoch data that depends on the upgraded state, for example proposerLookahead of BeaconStateFulu
|
|
286
|
-
postState.epochCtx.finalProcessEpoch(postState);
|
|
285
|
+
postState.epochCtx.finalProcessEpoch(postState, epochTransitionCache);
|
|
287
286
|
timer?.();
|
|
288
287
|
}
|
|
289
288
|
|
|
@@ -59,7 +59,12 @@ import {getBlockRootAtSlot} from "../util/blockRoot.js";
|
|
|
59
59
|
import {computeAnchorCheckpoint} from "../util/computeAnchorCheckpoint.js";
|
|
60
60
|
import {computeEpochAtSlot, computeStartSlotAtEpoch} from "../util/epoch.js";
|
|
61
61
|
import {EpochShuffling} from "../util/epochShuffling.js";
|
|
62
|
-
import {
|
|
62
|
+
import {
|
|
63
|
+
isExecutionEnabled,
|
|
64
|
+
isExecutionStateType,
|
|
65
|
+
isGloasStateType,
|
|
66
|
+
isMergeTransitionComplete,
|
|
67
|
+
} from "../util/execution.js";
|
|
63
68
|
import {canBuilderCoverBid} from "../util/gloas.js";
|
|
64
69
|
import {loadState} from "../util/loadState/loadState.js";
|
|
65
70
|
import {getRandaoMix} from "../util/seed.js";
|
|
@@ -79,8 +84,6 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
79
84
|
private _currentEpochParticipation: Uint8Array | null = null;
|
|
80
85
|
// bellatrix
|
|
81
86
|
private _latestExecutionPayloadHeader: ExecutionPayloadHeader | null = null;
|
|
82
|
-
// Caches the cross-fork latestBlockHash value
|
|
83
|
-
private _latestBlockHash: Bytes32 | null = null;
|
|
84
87
|
// capella
|
|
85
88
|
private _historicalSummaries: capella.HistoricalSummaries | null = null;
|
|
86
89
|
// electra
|
|
@@ -213,9 +216,13 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
213
216
|
// bellatrix
|
|
214
217
|
|
|
215
218
|
get latestExecutionPayloadHeader(): ExecutionPayloadHeader {
|
|
216
|
-
|
|
219
|
+
const forkSeq = this.config.getForkSeq(this.cachedState.slot);
|
|
220
|
+
if (forkSeq < ForkSeq.bellatrix) {
|
|
217
221
|
throw new Error("latestExecutionPayloadHeader is not available before Bellatrix");
|
|
218
222
|
}
|
|
223
|
+
if (forkSeq >= ForkSeq.gloas) {
|
|
224
|
+
throw new Error("latestExecutionPayloadHeader is not available after Gloas");
|
|
225
|
+
}
|
|
219
226
|
|
|
220
227
|
if (this._latestExecutionPayloadHeader === null) {
|
|
221
228
|
this._latestExecutionPayloadHeader = (
|
|
@@ -226,30 +233,6 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
226
233
|
return this._latestExecutionPayloadHeader;
|
|
227
234
|
}
|
|
228
235
|
|
|
229
|
-
/**
|
|
230
|
-
* Cross-fork accessor for the execution block hash of the most recently included payload.
|
|
231
|
-
* Pre-gloas: reads from latestExecutionPayloadHeader.blockHash.
|
|
232
|
-
* Gloas+: reads the dedicated latestBlockHash field (EIP-7732).
|
|
233
|
-
*/
|
|
234
|
-
get latestBlockHash(): Bytes32 {
|
|
235
|
-
const forkSeq = this.config.getForkSeq(this.cachedState.slot);
|
|
236
|
-
if (forkSeq < ForkSeq.bellatrix) {
|
|
237
|
-
throw new Error("latestBlockHash is not available before Bellatrix");
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (this._latestBlockHash === null) {
|
|
241
|
-
if (forkSeq >= ForkSeq.gloas) {
|
|
242
|
-
this._latestBlockHash = (this.cachedState as CachedBeaconStateGloas).latestBlockHash;
|
|
243
|
-
} else {
|
|
244
|
-
this._latestBlockHash = (
|
|
245
|
-
this.cachedState as CachedBeaconStateExecutions
|
|
246
|
-
).latestExecutionPayloadHeader.blockHash;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
return this._latestBlockHash;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
236
|
/**
|
|
254
237
|
* The execution block number of the most recently included payload.
|
|
255
238
|
* Named payloadBlockNumber (not latestBlockNumber) to mirror ExecutionPayloadHeader.blockNumber pre-gloas.
|
|
@@ -360,6 +343,13 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
360
343
|
|
|
361
344
|
// gloas
|
|
362
345
|
|
|
346
|
+
get latestBlockHash(): Bytes32 {
|
|
347
|
+
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
348
|
+
throw new Error("latestBlockHash is not available before Gloas");
|
|
349
|
+
}
|
|
350
|
+
return (this.cachedState as CachedBeaconStateGloas).latestBlockHash;
|
|
351
|
+
}
|
|
352
|
+
|
|
363
353
|
get executionPayloadAvailability(): BitArray {
|
|
364
354
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
365
355
|
throw new Error("executionPayloadAvailability is not available before Gloas");
|
|
@@ -589,7 +579,10 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
589
579
|
}
|
|
590
580
|
|
|
591
581
|
get isMergeTransitionComplete(): boolean {
|
|
592
|
-
return
|
|
582
|
+
return (
|
|
583
|
+
(isExecutionStateType(this.cachedState) || isGloasStateType(this.cachedState)) &&
|
|
584
|
+
isMergeTransitionComplete(this.cachedState)
|
|
585
|
+
);
|
|
593
586
|
}
|
|
594
587
|
|
|
595
588
|
// Block production
|
|
@@ -711,7 +704,11 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
711
704
|
|
|
712
705
|
// Serialization
|
|
713
706
|
|
|
714
|
-
loadOtherState(
|
|
707
|
+
loadOtherState(
|
|
708
|
+
stateBytes: Uint8Array,
|
|
709
|
+
seedValidatorsBytes?: Uint8Array,
|
|
710
|
+
opts?: {preloadValidatorsAndBalances?: boolean}
|
|
711
|
+
): IBeaconStateView {
|
|
715
712
|
const {state} = loadState(this.config, this.cachedState, stateBytes, seedValidatorsBytes);
|
|
716
713
|
|
|
717
714
|
const cachedState = createCachedBeaconState(
|
|
@@ -726,9 +723,10 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
726
723
|
}
|
|
727
724
|
);
|
|
728
725
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
726
|
+
if (opts?.preloadValidatorsAndBalances) {
|
|
727
|
+
cachedState.validators.getAllReadonlyValues();
|
|
728
|
+
cachedState.balances.getAll();
|
|
729
|
+
}
|
|
732
730
|
|
|
733
731
|
return new BeaconStateView(cachedState);
|
|
734
732
|
}
|
|
@@ -138,7 +138,13 @@ export interface IBeaconStateView {
|
|
|
138
138
|
isStateValidatorsNodesPopulated(): boolean;
|
|
139
139
|
|
|
140
140
|
// Serialization
|
|
141
|
-
|
|
141
|
+
/** Set `preloadValidatorsAndBalances` only when the whole state will be consumed
|
|
142
|
+
* immediately (e.g. CP reload before block replay). */
|
|
143
|
+
loadOtherState(
|
|
144
|
+
stateBytes: Uint8Array,
|
|
145
|
+
seedValidatorsBytes?: Uint8Array,
|
|
146
|
+
opts?: {preloadValidatorsAndBalances?: boolean}
|
|
147
|
+
): IBeaconStateView;
|
|
142
148
|
toValue(): BeaconState;
|
|
143
149
|
serialize(): Uint8Array;
|
|
144
150
|
serializedSize(): number;
|
|
@@ -187,13 +193,6 @@ export interface IBeaconStateViewAltair extends IBeaconStateView {
|
|
|
187
193
|
export interface IBeaconStateViewBellatrix extends IBeaconStateViewAltair {
|
|
188
194
|
forkName: ForkPostBellatrix;
|
|
189
195
|
latestExecutionPayloadHeader: ExecutionPayloadHeader;
|
|
190
|
-
/**
|
|
191
|
-
* Cross-fork accessor for the execution block hash of the most recently included payload.
|
|
192
|
-
* Pre-gloas: returns latestExecutionPayloadHeader.blockHash (bellatrix–fulu).
|
|
193
|
-
* Gloas+: returns the dedicated latestBlockHash state field (EIP-7732).
|
|
194
|
-
* Throws before bellatrix.
|
|
195
|
-
*/
|
|
196
|
-
latestBlockHash: Bytes32;
|
|
197
196
|
/**
|
|
198
197
|
* The execution block number of the most recently included payload.
|
|
199
198
|
* Named payloadBlockNumber (not latestBlockNumber) to mirror ExecutionPayloadHeader.blockNumber pre-gloas.
|
|
@@ -244,6 +243,11 @@ export interface IBeaconStateViewFulu extends IBeaconStateViewElectra {
|
|
|
244
243
|
/** Gloas+ state fields — use isStatePostGloas() guard */
|
|
245
244
|
export interface IBeaconStateViewGloas extends IBeaconStateViewFulu {
|
|
246
245
|
forkName: ForkPostGloas;
|
|
246
|
+
/** Removed from BeaconState in gloas. Use `latestBlockHash` instead. */
|
|
247
|
+
latestExecutionPayloadHeader: never;
|
|
248
|
+
/** Removed from BeaconState in gloas. */
|
|
249
|
+
payloadBlockNumber: never;
|
|
250
|
+
latestBlockHash: Bytes32;
|
|
247
251
|
executionPayloadAvailability: BitArray;
|
|
248
252
|
latestExecutionPayloadBid: ExecutionPayloadBid;
|
|
249
253
|
payloadExpectedWithdrawals: capella.Withdrawal[];
|
|
@@ -262,7 +266,14 @@ export interface IBeaconStateViewGloas extends IBeaconStateViewFulu {
|
|
|
262
266
|
* forkName as ForkName since the class wraps any fork's state.
|
|
263
267
|
* Sub-interfaces retain their narrowed forkName discriminants for caller-side type guards.
|
|
264
268
|
*/
|
|
265
|
-
export type IBeaconStateViewLatestFork = Omit<
|
|
269
|
+
export type IBeaconStateViewLatestFork = Omit<
|
|
270
|
+
IBeaconStateViewGloas,
|
|
271
|
+
"forkName" | "latestExecutionPayloadHeader" | "payloadBlockNumber"
|
|
272
|
+
> & {
|
|
273
|
+
forkName: ForkName;
|
|
274
|
+
latestExecutionPayloadHeader: ExecutionPayloadHeader;
|
|
275
|
+
payloadBlockNumber: number;
|
|
276
|
+
};
|
|
266
277
|
export function isStatePostAltair(state: IBeaconStateView): state is IBeaconStateViewAltair {
|
|
267
278
|
return isForkPostAltair(state.forkName);
|
|
268
279
|
}
|
package/src/util/execution.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
BeaconStateBellatrix,
|
|
19
19
|
BeaconStateCapella,
|
|
20
20
|
BeaconStateExecutions,
|
|
21
|
+
BeaconStateGloas,
|
|
21
22
|
CachedBeaconStateAllForks,
|
|
22
23
|
CachedBeaconStateExecutions,
|
|
23
24
|
} from "../types.js";
|
|
@@ -46,7 +47,11 @@ export function isExecutionEnabled(state: BeaconStateExecutions, block: BeaconBl
|
|
|
46
47
|
* Merge is complete when the state includes execution layer data:
|
|
47
48
|
* state.latestExecutionPayloadHeader NOT EMPTY or state is post-capella
|
|
48
49
|
*/
|
|
49
|
-
export function isMergeTransitionComplete(state: BeaconStateExecutions): boolean {
|
|
50
|
+
export function isMergeTransitionComplete(state: BeaconStateExecutions | BeaconStateGloas): boolean {
|
|
51
|
+
if (isGloasStateType(state)) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
|
|
50
55
|
if (isCapellaStateType(state)) {
|
|
51
56
|
// All networks have completed the merge transition before capella
|
|
52
57
|
return true;
|
|
@@ -71,6 +76,11 @@ export function isCapellaStateType(state: BeaconStateAllForks): state is BeaconS
|
|
|
71
76
|
);
|
|
72
77
|
}
|
|
73
78
|
|
|
79
|
+
/** Type guard for gloas.BeaconState */
|
|
80
|
+
export function isGloasStateType(state: BeaconStateAllForks): state is BeaconStateGloas {
|
|
81
|
+
return (state as BeaconStateGloas).latestBlockHash !== undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
74
84
|
/** Type guard for bellatrix.CachedBeaconState */
|
|
75
85
|
export function isExecutionCachedStateType(state: CachedBeaconStateAllForks): state is CachedBeaconStateExecutions {
|
|
76
86
|
return (state as CachedBeaconStateExecutions).latestExecutionPayloadHeader !== undefined;
|