@lodestar/fork-choice 1.41.0-dev.f36ec31497 → 1.41.0-dev.f7a5f4ddda
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/forkChoice/errors.js +6 -3
- package/lib/forkChoice/errors.js.map +1 -1
- package/lib/forkChoice/forkChoice.d.ts +11 -11
- package/lib/forkChoice/forkChoice.d.ts.map +1 -1
- package/lib/forkChoice/forkChoice.js +18 -23
- package/lib/forkChoice/forkChoice.js.map +1 -1
- package/lib/forkChoice/interface.d.ts +11 -11
- package/lib/forkChoice/interface.d.ts.map +1 -1
- package/lib/forkChoice/interface.js +6 -3
- package/lib/forkChoice/interface.js.map +1 -1
- package/lib/forkChoice/safeBlocks.js.map +1 -1
- package/lib/forkChoice/store.d.ts +10 -10
- package/lib/forkChoice/store.d.ts.map +1 -1
- package/lib/forkChoice/store.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/metrics.d.ts.map +1 -1
- package/lib/metrics.js.map +1 -1
- package/lib/protoArray/computeDeltas.js.map +1 -1
- package/lib/protoArray/errors.js +4 -2
- package/lib/protoArray/errors.js.map +1 -1
- package/lib/protoArray/interface.js +4 -2
- package/lib/protoArray/interface.js.map +1 -1
- package/lib/protoArray/protoArray.d.ts +8 -8
- package/lib/protoArray/protoArray.d.ts.map +1 -1
- package/lib/protoArray/protoArray.js +16 -32
- package/lib/protoArray/protoArray.js.map +1 -1
- package/package.json +9 -9
- package/src/forkChoice/forkChoice.ts +33 -33
- package/src/forkChoice/interface.ts +18 -10
- package/src/forkChoice/store.ts +11 -11
- package/src/index.ts +1 -1
- package/src/protoArray/protoArray.ts +24 -35
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.41.0-dev.
|
|
14
|
+
"version": "1.41.0-dev.f7a5f4ddda",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
],
|
|
28
28
|
"scripts": {
|
|
29
29
|
"clean": "rm -rf lib && rm -f *.tsbuildinfo",
|
|
30
|
-
"build": "
|
|
30
|
+
"build": "tsgo -p tsconfig.build.json",
|
|
31
31
|
"build:watch": "pnpm run build --watch",
|
|
32
32
|
"build:release": "pnpm clean && pnpm run build",
|
|
33
33
|
"check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"",
|
|
34
|
-
"check-types": "
|
|
34
|
+
"check-types": "tsgo",
|
|
35
35
|
"lint": "biome check src/ test/",
|
|
36
36
|
"lint:fix": "pnpm run lint --write",
|
|
37
37
|
"test": "pnpm test:unit",
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@chainsafe/ssz": "^1.2.2",
|
|
43
|
-
"@lodestar/config": "^1.41.0-dev.
|
|
44
|
-
"@lodestar/params": "^1.41.0-dev.
|
|
45
|
-
"@lodestar/state-transition": "^1.41.0-dev.
|
|
46
|
-
"@lodestar/types": "^1.41.0-dev.
|
|
47
|
-
"@lodestar/utils": "^1.41.0-dev.
|
|
43
|
+
"@lodestar/config": "^1.41.0-dev.f7a5f4ddda",
|
|
44
|
+
"@lodestar/params": "^1.41.0-dev.f7a5f4ddda",
|
|
45
|
+
"@lodestar/state-transition": "^1.41.0-dev.f7a5f4ddda",
|
|
46
|
+
"@lodestar/types": "^1.41.0-dev.f7a5f4ddda",
|
|
47
|
+
"@lodestar/utils": "^1.41.0-dev.f7a5f4ddda"
|
|
48
48
|
},
|
|
49
49
|
"keywords": [
|
|
50
50
|
"ethereum",
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"beacon",
|
|
53
53
|
"blockchain"
|
|
54
54
|
],
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "4e275225295e0987e05ef15f8c48633c8e5e5960"
|
|
56
56
|
}
|
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
NotReorgedReason,
|
|
55
55
|
ShouldOverrideForkChoiceUpdateResult,
|
|
56
56
|
} from "./interface.js";
|
|
57
|
-
import {
|
|
57
|
+
import {CheckpointWithPayloadStatus, IForkChoiceStore, JustifiedBalances, toCheckpointWithPayload} from "./store.js";
|
|
58
58
|
|
|
59
59
|
export type ForkChoiceOpts = {
|
|
60
60
|
proposerBoost?: boolean;
|
|
@@ -557,11 +557,11 @@ export class ForkChoice implements IForkChoice {
|
|
|
557
557
|
return this.protoArray.nodes;
|
|
558
558
|
}
|
|
559
559
|
|
|
560
|
-
getFinalizedCheckpoint():
|
|
560
|
+
getFinalizedCheckpoint(): CheckpointWithPayloadStatus {
|
|
561
561
|
return this.fcStore.finalizedCheckpoint;
|
|
562
562
|
}
|
|
563
563
|
|
|
564
|
-
getJustifiedCheckpoint():
|
|
564
|
+
getJustifiedCheckpoint(): CheckpointWithPayloadStatus {
|
|
565
565
|
return this.fcStore.justified.checkpoint;
|
|
566
566
|
}
|
|
567
567
|
|
|
@@ -700,8 +700,8 @@ export class ForkChoice implements IForkChoice {
|
|
|
700
700
|
// This is an optimization. It should reduce the amount of times we run
|
|
701
701
|
// `process_justification_and_finalization` by approximately 1/3rd when the chain is
|
|
702
702
|
// performing optimally.
|
|
703
|
-
let unrealizedJustifiedCheckpoint:
|
|
704
|
-
let unrealizedFinalizedCheckpoint:
|
|
703
|
+
let unrealizedJustifiedCheckpoint: CheckpointWithPayloadStatus;
|
|
704
|
+
let unrealizedFinalizedCheckpoint: CheckpointWithPayloadStatus;
|
|
705
705
|
if (this.opts?.computeUnrealized) {
|
|
706
706
|
if (
|
|
707
707
|
parentBlock.unrealizedJustifiedEpoch === blockEpoch &&
|
|
@@ -1133,8 +1133,13 @@ export class ForkChoice implements IForkChoice {
|
|
|
1133
1133
|
* Always returns `false` if either input roots are unknown.
|
|
1134
1134
|
* Still returns `true` if `ancestorRoot===descendantRoot` (and the roots are known)
|
|
1135
1135
|
*/
|
|
1136
|
-
isDescendant(
|
|
1137
|
-
|
|
1136
|
+
isDescendant(
|
|
1137
|
+
ancestorRoot: RootHex,
|
|
1138
|
+
ancestorPayloadStatus: PayloadStatus,
|
|
1139
|
+
descendantRoot: RootHex,
|
|
1140
|
+
descendantPayloadStatus: PayloadStatus
|
|
1141
|
+
): boolean {
|
|
1142
|
+
return this.protoArray.isDescendant(ancestorRoot, ancestorPayloadStatus, descendantRoot, descendantPayloadStatus);
|
|
1138
1143
|
}
|
|
1139
1144
|
|
|
1140
1145
|
/**
|
|
@@ -1177,16 +1182,16 @@ export class ForkChoice implements IForkChoice {
|
|
|
1177
1182
|
* Iterates backwards through block summaries, starting from a block root.
|
|
1178
1183
|
* Return only the non-finalized blocks.
|
|
1179
1184
|
*/
|
|
1180
|
-
iterateAncestorBlocks(blockRoot: RootHex): IterableIterator<ProtoBlock> {
|
|
1181
|
-
return this.protoArray.iterateAncestorNodes(blockRoot);
|
|
1185
|
+
iterateAncestorBlocks(blockRoot: RootHex, payloadStatus: PayloadStatus): IterableIterator<ProtoBlock> {
|
|
1186
|
+
return this.protoArray.iterateAncestorNodes(blockRoot, payloadStatus);
|
|
1182
1187
|
}
|
|
1183
1188
|
|
|
1184
1189
|
/**
|
|
1185
1190
|
* Returns all blocks backwards starting from a block root.
|
|
1186
1191
|
* Return only the non-finalized blocks.
|
|
1187
1192
|
*/
|
|
1188
|
-
getAllAncestorBlocks(blockRoot: RootHex): ProtoBlock[] {
|
|
1189
|
-
const blocks = this.protoArray.getAllAncestorNodes(blockRoot);
|
|
1193
|
+
getAllAncestorBlocks(blockRoot: RootHex, payloadStatus: PayloadStatus): ProtoBlock[] {
|
|
1194
|
+
const blocks = this.protoArray.getAllAncestorNodes(blockRoot, payloadStatus);
|
|
1190
1195
|
// the last node is the previous finalized one, it's there to check onBlock finalized checkpoint only.
|
|
1191
1196
|
return blocks.slice(0, blocks.length - 1);
|
|
1192
1197
|
}
|
|
@@ -1194,15 +1199,18 @@ export class ForkChoice implements IForkChoice {
|
|
|
1194
1199
|
/**
|
|
1195
1200
|
* The same to iterateAncestorBlocks but this gets non-ancestor nodes instead of ancestor nodes.
|
|
1196
1201
|
*/
|
|
1197
|
-
getAllNonAncestorBlocks(blockRoot: RootHex): ProtoBlock[] {
|
|
1198
|
-
return this.protoArray.getAllNonAncestorNodes(blockRoot);
|
|
1202
|
+
getAllNonAncestorBlocks(blockRoot: RootHex, payloadStatus: PayloadStatus): ProtoBlock[] {
|
|
1203
|
+
return this.protoArray.getAllNonAncestorNodes(blockRoot, payloadStatus);
|
|
1199
1204
|
}
|
|
1200
1205
|
|
|
1201
1206
|
/**
|
|
1202
1207
|
* Returns both ancestor and non-ancestor blocks in a single traversal.
|
|
1203
1208
|
*/
|
|
1204
|
-
getAllAncestorAndNonAncestorBlocks(
|
|
1205
|
-
|
|
1209
|
+
getAllAncestorAndNonAncestorBlocks(
|
|
1210
|
+
blockRoot: RootHex,
|
|
1211
|
+
payloadStatus: PayloadStatus
|
|
1212
|
+
): {ancestors: ProtoBlock[]; nonAncestors: ProtoBlock[]} {
|
|
1213
|
+
const {ancestors, nonAncestors} = this.protoArray.getAllAncestorAndNonAncestorNodes(blockRoot, payloadStatus);
|
|
1206
1214
|
|
|
1207
1215
|
return {
|
|
1208
1216
|
// the last node is the previous finalized one, it's there to check onBlock finalized checkpoint only.
|
|
@@ -1217,7 +1225,7 @@ export class ForkChoice implements IForkChoice {
|
|
|
1217
1225
|
return this.head;
|
|
1218
1226
|
}
|
|
1219
1227
|
|
|
1220
|
-
for (const block of this.protoArray.iterateAncestorNodes(this.head.blockRoot)) {
|
|
1228
|
+
for (const block of this.protoArray.iterateAncestorNodes(this.head.blockRoot, this.head.payloadStatus)) {
|
|
1221
1229
|
if (block.blockRoot === blockRootHex) {
|
|
1222
1230
|
return block;
|
|
1223
1231
|
}
|
|
@@ -1235,7 +1243,7 @@ export class ForkChoice implements IForkChoice {
|
|
|
1235
1243
|
return this.head;
|
|
1236
1244
|
}
|
|
1237
1245
|
|
|
1238
|
-
for (const block of this.protoArray.iterateAncestorNodes(this.head.blockRoot)) {
|
|
1246
|
+
for (const block of this.protoArray.iterateAncestorNodes(this.head.blockRoot, this.head.payloadStatus)) {
|
|
1239
1247
|
if (block.slot === slot) {
|
|
1240
1248
|
return block;
|
|
1241
1249
|
}
|
|
@@ -1248,7 +1256,7 @@ export class ForkChoice implements IForkChoice {
|
|
|
1248
1256
|
return this.head;
|
|
1249
1257
|
}
|
|
1250
1258
|
|
|
1251
|
-
for (const block of this.protoArray.iterateAncestorNodes(this.head.blockRoot)) {
|
|
1259
|
+
for (const block of this.protoArray.iterateAncestorNodes(this.head.blockRoot, this.head.payloadStatus)) {
|
|
1252
1260
|
if (slot >= block.slot) {
|
|
1253
1261
|
return block;
|
|
1254
1262
|
}
|
|
@@ -1261,24 +1269,16 @@ export class ForkChoice implements IForkChoice {
|
|
|
1261
1269
|
return this.protoArray.nodes;
|
|
1262
1270
|
}
|
|
1263
1271
|
|
|
1264
|
-
|
|
1265
|
-
// also consumer may want PENDING or EMPTY only
|
|
1266
|
-
*forwardIterateDescendants(blockRoot: RootHex): IterableIterator<ProtoBlock> {
|
|
1272
|
+
*forwardIterateDescendants(blockRoot: RootHex, payloadStatus: PayloadStatus): IterableIterator<ProtoBlock> {
|
|
1267
1273
|
const rootsInChain = new Set([blockRoot]);
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
if (blockVariants === undefined) {
|
|
1274
|
+
const blockIndex = this.protoArray.getNodeIndexByRootAndStatus(blockRoot, payloadStatus);
|
|
1275
|
+
if (blockIndex === undefined) {
|
|
1271
1276
|
throw new ForkChoiceError({
|
|
1272
1277
|
code: ForkChoiceErrorCode.MISSING_PROTO_ARRAY_BLOCK,
|
|
1273
1278
|
root: blockRoot,
|
|
1274
1279
|
});
|
|
1275
1280
|
}
|
|
1276
1281
|
|
|
1277
|
-
// Find the minimum index among all variants to start iteration
|
|
1278
|
-
const blockIndex = Array.isArray(blockVariants)
|
|
1279
|
-
? Math.min(...blockVariants.filter((idx) => idx !== undefined))
|
|
1280
|
-
: blockVariants;
|
|
1281
|
-
|
|
1282
1282
|
for (let i = blockIndex + 1; i < this.protoArray.nodes.length; i++) {
|
|
1283
1283
|
const node = this.protoArray.nodes[i];
|
|
1284
1284
|
if (rootsInChain.has(node.parentRoot)) {
|
|
@@ -1478,8 +1478,8 @@ export class ForkChoice implements IForkChoice {
|
|
|
1478
1478
|
* Since this balances are already available the getter is just `() => balances`, without cache interaction
|
|
1479
1479
|
*/
|
|
1480
1480
|
private updateCheckpoints(
|
|
1481
|
-
justifiedCheckpoint:
|
|
1482
|
-
finalizedCheckpoint:
|
|
1481
|
+
justifiedCheckpoint: CheckpointWithPayloadStatus,
|
|
1482
|
+
finalizedCheckpoint: CheckpointWithPayloadStatus,
|
|
1483
1483
|
getJustifiedBalances: () => JustifiedBalances
|
|
1484
1484
|
): void {
|
|
1485
1485
|
// Update justified checkpoint.
|
|
@@ -1499,8 +1499,8 @@ export class ForkChoice implements IForkChoice {
|
|
|
1499
1499
|
* Update unrealized checkpoints in store if necessary
|
|
1500
1500
|
*/
|
|
1501
1501
|
private updateUnrealizedCheckpoints(
|
|
1502
|
-
unrealizedJustifiedCheckpoint:
|
|
1503
|
-
unrealizedFinalizedCheckpoint:
|
|
1502
|
+
unrealizedJustifiedCheckpoint: CheckpointWithPayloadStatus,
|
|
1503
|
+
unrealizedFinalizedCheckpoint: CheckpointWithPayloadStatus,
|
|
1504
1504
|
getJustifiedBalances: () => JustifiedBalances
|
|
1505
1505
|
): void {
|
|
1506
1506
|
if (unrealizedJustifiedCheckpoint.epoch > this.fcStore.unrealizedJustified.checkpoint.epoch) {
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
ProtoNode,
|
|
13
13
|
} from "../protoArray/interface.js";
|
|
14
14
|
import {UpdateAndGetHeadOpt} from "./forkChoice.js";
|
|
15
|
-
import {CheckpointWithHex,
|
|
15
|
+
import {CheckpointWithHex, CheckpointWithPayloadStatus} from "./store.js";
|
|
16
16
|
|
|
17
17
|
export type CheckpointHex = {
|
|
18
18
|
epoch: Epoch;
|
|
@@ -25,7 +25,7 @@ export type CheckpointsWithHex = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export type CheckpointWithPayloadAndBalance = {
|
|
28
|
-
checkpoint:
|
|
28
|
+
checkpoint: CheckpointWithPayloadStatus;
|
|
29
29
|
balances: EffectiveBalanceIncrements;
|
|
30
30
|
};
|
|
31
31
|
|
|
@@ -124,8 +124,8 @@ export interface IForkChoice {
|
|
|
124
124
|
* Retrieve all nodes for the debug API.
|
|
125
125
|
*/
|
|
126
126
|
getAllNodes(): ProtoNode[];
|
|
127
|
-
getFinalizedCheckpoint():
|
|
128
|
-
getJustifiedCheckpoint():
|
|
127
|
+
getFinalizedCheckpoint(): CheckpointWithPayloadStatus;
|
|
128
|
+
getJustifiedCheckpoint(): CheckpointWithPayloadStatus;
|
|
129
129
|
/**
|
|
130
130
|
* Add `block` to the fork choice DAG.
|
|
131
131
|
*
|
|
@@ -246,7 +246,12 @@ export interface IForkChoice {
|
|
|
246
246
|
* Always returns `false` if either input roots are unknown.
|
|
247
247
|
* Still returns `true` if `ancestorRoot===descendantRoot` (and the roots are known)
|
|
248
248
|
*/
|
|
249
|
-
isDescendant(
|
|
249
|
+
isDescendant(
|
|
250
|
+
ancestorRoot: RootHex,
|
|
251
|
+
ancestorPayloadStatus: PayloadStatus,
|
|
252
|
+
descendantRoot: RootHex,
|
|
253
|
+
descendantPayloadStatus: PayloadStatus
|
|
254
|
+
): boolean;
|
|
250
255
|
/**
|
|
251
256
|
* Prune items up to a finalized root.
|
|
252
257
|
*/
|
|
@@ -255,16 +260,19 @@ export interface IForkChoice {
|
|
|
255
260
|
/**
|
|
256
261
|
* Iterates backwards through ancestor block summaries, starting from a block root
|
|
257
262
|
*/
|
|
258
|
-
iterateAncestorBlocks(blockRoot: RootHex): IterableIterator<ProtoBlock>;
|
|
259
|
-
getAllAncestorBlocks(blockRoot: RootHex): ProtoBlock[];
|
|
263
|
+
iterateAncestorBlocks(blockRoot: RootHex, payloadStatus: PayloadStatus): IterableIterator<ProtoBlock>;
|
|
264
|
+
getAllAncestorBlocks(blockRoot: RootHex, payloadStatus: PayloadStatus): ProtoBlock[];
|
|
260
265
|
/**
|
|
261
266
|
* The same to iterateAncestorBlocks but this gets non-ancestor nodes instead of ancestor nodes.
|
|
262
267
|
*/
|
|
263
|
-
getAllNonAncestorBlocks(blockRoot: RootHex): ProtoBlock[];
|
|
268
|
+
getAllNonAncestorBlocks(blockRoot: RootHex, payloadStatus: PayloadStatus): ProtoBlock[];
|
|
264
269
|
/**
|
|
265
270
|
* Returns both ancestor and non-ancestor blocks in a single traversal.
|
|
266
271
|
*/
|
|
267
|
-
getAllAncestorAndNonAncestorBlocks(
|
|
272
|
+
getAllAncestorAndNonAncestorBlocks(
|
|
273
|
+
blockRoot: RootHex,
|
|
274
|
+
payloadStatus: PayloadStatus
|
|
275
|
+
): {ancestors: ProtoBlock[]; nonAncestors: ProtoBlock[]};
|
|
268
276
|
getCanonicalBlockByRoot(blockRoot: Root): ProtoBlock | null;
|
|
269
277
|
getCanonicalBlockAtSlot(slot: Slot): ProtoBlock | null;
|
|
270
278
|
getCanonicalBlockClosestLteSlot(slot: Slot): ProtoBlock | null;
|
|
@@ -275,7 +283,7 @@ export interface IForkChoice {
|
|
|
275
283
|
/**
|
|
276
284
|
* Iterates forward descendants of blockRoot. Does not yield blockRoot itself
|
|
277
285
|
*/
|
|
278
|
-
forwardIterateDescendants(blockRoot: RootHex): IterableIterator<ProtoBlock>;
|
|
286
|
+
forwardIterateDescendants(blockRoot: RootHex, payloadStatus: PayloadStatus): IterableIterator<ProtoBlock>;
|
|
279
287
|
getBlockSummariesByParentRoot(parentRoot: RootHex): ProtoBlock[];
|
|
280
288
|
getBlockSummariesAtSlot(slot: Slot): ProtoBlock[];
|
|
281
289
|
/** Returns the distance of common ancestor of nodes to the max of the newNode and the prevNode. */
|
package/src/forkChoice/store.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type CheckpointWithHex = phase0.Checkpoint & {rootHex: RootHex};
|
|
|
18
18
|
* Pre-Gloas: payloadStatus is always FULL (payload embedded in block)
|
|
19
19
|
* Gloas: determined by state.execution_payload_availability
|
|
20
20
|
*/
|
|
21
|
-
export type
|
|
21
|
+
export type CheckpointWithPayloadStatus = CheckpointWithHex & {payloadStatus: PayloadStatus};
|
|
22
22
|
|
|
23
23
|
export type JustifiedBalances = EffectiveBalanceIncrements;
|
|
24
24
|
|
|
@@ -29,7 +29,7 @@ export type JustifiedBalances = EffectiveBalanceIncrements;
|
|
|
29
29
|
* @param blockState state that declares justified checkpoint `checkpoint`
|
|
30
30
|
*/
|
|
31
31
|
export type JustifiedBalancesGetter = (
|
|
32
|
-
checkpoint:
|
|
32
|
+
checkpoint: CheckpointWithPayloadStatus,
|
|
33
33
|
blockState: CachedBeaconStateAllForks
|
|
34
34
|
) => JustifiedBalances;
|
|
35
35
|
|
|
@@ -50,8 +50,8 @@ export interface IForkChoiceStore {
|
|
|
50
50
|
get justified(): CheckpointWithPayloadAndTotalBalance;
|
|
51
51
|
set justified(justified: CheckpointWithPayloadAndBalance);
|
|
52
52
|
unrealizedJustified: CheckpointWithPayloadAndBalance;
|
|
53
|
-
finalizedCheckpoint:
|
|
54
|
-
unrealizedFinalizedCheckpoint:
|
|
53
|
+
finalizedCheckpoint: CheckpointWithPayloadStatus;
|
|
54
|
+
unrealizedFinalizedCheckpoint: CheckpointWithPayloadStatus;
|
|
55
55
|
justifiedBalancesGetter: JustifiedBalancesGetter;
|
|
56
56
|
equivocatingIndices: Set<ValidatorIndex>;
|
|
57
57
|
}
|
|
@@ -62,8 +62,8 @@ export interface IForkChoiceStore {
|
|
|
62
62
|
export class ForkChoiceStore implements IForkChoiceStore {
|
|
63
63
|
private _justified: CheckpointWithPayloadAndTotalBalance;
|
|
64
64
|
unrealizedJustified: CheckpointWithPayloadAndBalance;
|
|
65
|
-
private _finalizedCheckpoint:
|
|
66
|
-
unrealizedFinalizedCheckpoint:
|
|
65
|
+
private _finalizedCheckpoint: CheckpointWithPayloadStatus;
|
|
66
|
+
unrealizedFinalizedCheckpoint: CheckpointWithPayloadStatus;
|
|
67
67
|
equivocatingIndices = new Set<ValidatorIndex>();
|
|
68
68
|
justifiedBalancesGetter: JustifiedBalancesGetter;
|
|
69
69
|
currentSlot: Slot;
|
|
@@ -87,8 +87,8 @@ export class ForkChoiceStore implements IForkChoiceStore {
|
|
|
87
87
|
*/
|
|
88
88
|
finalizedPayloadStatus: PayloadStatus,
|
|
89
89
|
private readonly events?: {
|
|
90
|
-
onJustified: (cp:
|
|
91
|
-
onFinalized: (cp:
|
|
90
|
+
onJustified: (cp: CheckpointWithPayloadStatus) => void;
|
|
91
|
+
onFinalized: (cp: CheckpointWithPayloadStatus) => void;
|
|
92
92
|
}
|
|
93
93
|
) {
|
|
94
94
|
this.justifiedBalancesGetter = justifiedBalancesGetter;
|
|
@@ -112,10 +112,10 @@ export class ForkChoiceStore implements IForkChoiceStore {
|
|
|
112
112
|
this.events?.onJustified(justified.checkpoint);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
get finalizedCheckpoint():
|
|
115
|
+
get finalizedCheckpoint(): CheckpointWithPayloadStatus {
|
|
116
116
|
return this._finalizedCheckpoint;
|
|
117
117
|
}
|
|
118
|
-
set finalizedCheckpoint(checkpoint:
|
|
118
|
+
set finalizedCheckpoint(checkpoint: CheckpointWithPayloadStatus) {
|
|
119
119
|
const cp = toCheckpointWithPayload(checkpoint, checkpoint.payloadStatus);
|
|
120
120
|
this._finalizedCheckpoint = cp;
|
|
121
121
|
this.events?.onFinalized(cp);
|
|
@@ -136,7 +136,7 @@ export function toCheckpointWithHex(checkpoint: phase0.Checkpoint): CheckpointWi
|
|
|
136
136
|
export function toCheckpointWithPayload(
|
|
137
137
|
checkpoint: phase0.Checkpoint,
|
|
138
138
|
payloadStatus: PayloadStatus
|
|
139
|
-
):
|
|
139
|
+
): CheckpointWithPayloadStatus {
|
|
140
140
|
return {
|
|
141
141
|
...toCheckpointWithHex(checkpoint),
|
|
142
142
|
payloadStatus,
|
package/src/index.ts
CHANGED
|
@@ -1477,11 +1477,8 @@ export class ProtoArray {
|
|
|
1477
1477
|
* For Gloas blocks: returns EMPTY/FULL variants (not PENDING) based on parent payload status
|
|
1478
1478
|
* For pre-Gloas blocks: returns FULL variants
|
|
1479
1479
|
*/
|
|
1480
|
-
*iterateAncestorNodes(blockRoot: RootHex): IterableIterator<ProtoNode> {
|
|
1481
|
-
|
|
1482
|
-
const defaultStatus = this.getDefaultVariant(blockRoot);
|
|
1483
|
-
const startIndex =
|
|
1484
|
-
defaultStatus !== undefined ? this.getNodeIndexByRootAndStatus(blockRoot, defaultStatus) : undefined;
|
|
1480
|
+
*iterateAncestorNodes(blockRoot: RootHex, payloadStatus: PayloadStatus): IterableIterator<ProtoNode> {
|
|
1481
|
+
const startIndex = this.getNodeIndexByRootAndStatus(blockRoot, payloadStatus);
|
|
1485
1482
|
if (startIndex === undefined) {
|
|
1486
1483
|
return;
|
|
1487
1484
|
}
|
|
@@ -1520,11 +1517,8 @@ export class ProtoArray {
|
|
|
1520
1517
|
* For Gloas blocks: returns EMPTY/FULL variants (not PENDING) based on parent payload status
|
|
1521
1518
|
* For pre-Gloas blocks: returns FULL variants
|
|
1522
1519
|
*/
|
|
1523
|
-
getAllAncestorNodes(blockRoot: RootHex): ProtoNode[] {
|
|
1524
|
-
|
|
1525
|
-
const defaultStatus = this.getDefaultVariant(blockRoot);
|
|
1526
|
-
const startIndex =
|
|
1527
|
-
defaultStatus !== undefined ? this.getNodeIndexByRootAndStatus(blockRoot, defaultStatus) : undefined;
|
|
1520
|
+
getAllAncestorNodes(blockRoot: RootHex, payloadStatus: PayloadStatus): ProtoNode[] {
|
|
1521
|
+
const startIndex = this.getNodeIndexByRootAndStatus(blockRoot, payloadStatus);
|
|
1528
1522
|
if (startIndex === undefined) {
|
|
1529
1523
|
return [];
|
|
1530
1524
|
}
|
|
@@ -1537,12 +1531,10 @@ export class ProtoArray {
|
|
|
1537
1531
|
});
|
|
1538
1532
|
}
|
|
1539
1533
|
|
|
1540
|
-
//
|
|
1541
|
-
// Reason why we exclude post-gloas is because node is always default variant (PENDING)
|
|
1542
|
-
// which we want to exclude.
|
|
1534
|
+
// Exclude PENDING variant from returned ancestors.
|
|
1543
1535
|
const nodes: ProtoNode[] = [];
|
|
1544
1536
|
|
|
1545
|
-
if (
|
|
1537
|
+
if (node.payloadStatus !== PayloadStatus.PENDING) {
|
|
1546
1538
|
nodes.push(node);
|
|
1547
1539
|
}
|
|
1548
1540
|
|
|
@@ -1567,13 +1559,8 @@ export class ProtoArray {
|
|
|
1567
1559
|
* For Gloas blocks: returns EMPTY/FULL variants (not PENDING) based on parent payload status
|
|
1568
1560
|
* For pre-Gloas blocks: returns FULL variants
|
|
1569
1561
|
*/
|
|
1570
|
-
getAllNonAncestorNodes(blockRoot: RootHex): ProtoNode[] {
|
|
1571
|
-
|
|
1572
|
-
const defaultStatus = this.getDefaultVariant(blockRoot);
|
|
1573
|
-
if (defaultStatus === undefined) {
|
|
1574
|
-
return [];
|
|
1575
|
-
}
|
|
1576
|
-
const startIndex = this.getNodeIndexByRootAndStatus(blockRoot, defaultStatus);
|
|
1562
|
+
getAllNonAncestorNodes(blockRoot: RootHex, payloadStatus: PayloadStatus): ProtoNode[] {
|
|
1563
|
+
const startIndex = this.getNodeIndexByRootAndStatus(blockRoot, payloadStatus);
|
|
1577
1564
|
if (startIndex === undefined) {
|
|
1578
1565
|
return [];
|
|
1579
1566
|
}
|
|
@@ -1613,11 +1600,11 @@ export class ProtoArray {
|
|
|
1613
1600
|
* For Gloas blocks: returns EMPTY/FULL variants (not PENDING) based on parent payload status
|
|
1614
1601
|
* For pre-Gloas blocks: returns FULL variants
|
|
1615
1602
|
*/
|
|
1616
|
-
getAllAncestorAndNonAncestorNodes(
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1603
|
+
getAllAncestorAndNonAncestorNodes(
|
|
1604
|
+
blockRoot: RootHex,
|
|
1605
|
+
payloadStatus: PayloadStatus
|
|
1606
|
+
): {ancestors: ProtoNode[]; nonAncestors: ProtoNode[]} {
|
|
1607
|
+
const startIndex = this.getNodeIndexByRootAndStatus(blockRoot, payloadStatus);
|
|
1621
1608
|
if (startIndex === undefined) {
|
|
1622
1609
|
return {ancestors: [], nonAncestors: []};
|
|
1623
1610
|
}
|
|
@@ -1735,26 +1722,28 @@ export class ProtoArray {
|
|
|
1735
1722
|
/**
|
|
1736
1723
|
* Returns `true` if the `descendantRoot` has an ancestor with `ancestorRoot`.
|
|
1737
1724
|
* Always returns `false` if either input roots are unknown.
|
|
1738
|
-
* Still returns `true` if `ancestorRoot` === `descendantRoot`
|
|
1725
|
+
* Still returns `true` if `ancestorRoot` === `descendantRoot` and payload statuses match.
|
|
1739
1726
|
*/
|
|
1740
|
-
isDescendant(
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1727
|
+
isDescendant(
|
|
1728
|
+
ancestorRoot: RootHex,
|
|
1729
|
+
ancestorPayloadStatus: PayloadStatus,
|
|
1730
|
+
descendantRoot: RootHex,
|
|
1731
|
+
descendantPayloadStatus: PayloadStatus
|
|
1732
|
+
): boolean {
|
|
1733
|
+
const ancestorNode = this.getNode(ancestorRoot, ancestorPayloadStatus);
|
|
1745
1734
|
if (!ancestorNode) {
|
|
1746
1735
|
return false;
|
|
1747
1736
|
}
|
|
1748
1737
|
|
|
1749
|
-
if (ancestorRoot === descendantRoot) {
|
|
1738
|
+
if (ancestorRoot === descendantRoot && ancestorPayloadStatus === descendantPayloadStatus) {
|
|
1750
1739
|
return true;
|
|
1751
1740
|
}
|
|
1752
1741
|
|
|
1753
|
-
for (const node of this.iterateAncestorNodes(descendantRoot)) {
|
|
1742
|
+
for (const node of this.iterateAncestorNodes(descendantRoot, descendantPayloadStatus)) {
|
|
1754
1743
|
if (node.slot < ancestorNode.slot) {
|
|
1755
1744
|
return false;
|
|
1756
1745
|
}
|
|
1757
|
-
if (node.blockRoot === ancestorNode.blockRoot) {
|
|
1746
|
+
if (node.blockRoot === ancestorNode.blockRoot && node.payloadStatus === ancestorNode.payloadStatus) {
|
|
1758
1747
|
return true;
|
|
1759
1748
|
}
|
|
1760
1749
|
}
|