@lodestar/fork-choice 1.41.0-dev.09945f6589 → 1.41.0-dev.0df187678b
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/forkChoice.d.ts +10 -9
- package/lib/forkChoice/forkChoice.d.ts.map +1 -1
- package/lib/forkChoice/forkChoice.js +27 -21
- package/lib/forkChoice/forkChoice.js.map +1 -1
- package/lib/forkChoice/interface.d.ts +11 -10
- package/lib/forkChoice/interface.d.ts.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/protoArray/protoArray.d.ts +6 -6
- 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 +7 -7
- package/src/forkChoice/forkChoice.ts +47 -32
- package/src/forkChoice/interface.ts +19 -10
- package/src/forkChoice/store.ts +11 -11
- package/src/index.ts +1 -1
- package/src/protoArray/protoArray.ts +24 -35
|
@@ -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,20 @@ 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[]};
|
|
276
|
+
getCanonicalBlockByRoot(blockRoot: Root): ProtoBlock | null;
|
|
268
277
|
getCanonicalBlockAtSlot(slot: Slot): ProtoBlock | null;
|
|
269
278
|
getCanonicalBlockClosestLteSlot(slot: Slot): ProtoBlock | null;
|
|
270
279
|
/**
|
|
@@ -274,7 +283,7 @@ export interface IForkChoice {
|
|
|
274
283
|
/**
|
|
275
284
|
* Iterates forward descendants of blockRoot. Does not yield blockRoot itself
|
|
276
285
|
*/
|
|
277
|
-
forwardIterateDescendants(blockRoot: RootHex): IterableIterator<ProtoBlock>;
|
|
286
|
+
forwardIterateDescendants(blockRoot: RootHex, payloadStatus: PayloadStatus): IterableIterator<ProtoBlock>;
|
|
278
287
|
getBlockSummariesByParentRoot(parentRoot: RootHex): ProtoBlock[];
|
|
279
288
|
getBlockSummariesAtSlot(slot: Slot): ProtoBlock[];
|
|
280
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
|
}
|