@lodestar/fork-choice 1.45.0-dev.905415417a → 1.45.0-dev.955b4c884a
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/fastConfirmation/data.d.ts.map +1 -1
- package/lib/forkChoice/fastConfirmation/data.js +1 -0
- package/lib/forkChoice/fastConfirmation/data.js.map +1 -1
- package/lib/forkChoice/fastConfirmation/types.d.ts +3 -0
- package/lib/forkChoice/fastConfirmation/types.d.ts.map +1 -1
- package/lib/forkChoice/fastConfirmation/types.js.map +1 -1
- package/lib/forkChoice/fastConfirmation/utils.d.ts +3 -3
- package/lib/forkChoice/fastConfirmation/utils.d.ts.map +1 -1
- package/lib/forkChoice/fastConfirmation/utils.js +27 -19
- package/lib/forkChoice/fastConfirmation/utils.js.map +1 -1
- package/lib/forkChoice/forkChoice.d.ts +25 -7
- package/lib/forkChoice/forkChoice.d.ts.map +1 -1
- package/lib/forkChoice/forkChoice.js +23 -12
- package/lib/forkChoice/forkChoice.js.map +1 -1
- package/lib/forkChoice/interface.d.ts +10 -2
- package/lib/forkChoice/interface.d.ts.map +1 -1
- package/lib/forkChoice/interface.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/protoArray/computeDeltas.d.ts.map +1 -1
- package/lib/protoArray/computeDeltas.js +19 -15
- package/lib/protoArray/computeDeltas.js.map +1 -1
- package/lib/protoArray/protoArray.d.ts +19 -0
- package/lib/protoArray/protoArray.d.ts.map +1 -1
- package/lib/protoArray/protoArray.js +63 -4
- package/lib/protoArray/protoArray.js.map +1 -1
- package/package.json +9 -9
- package/src/forkChoice/fastConfirmation/data.ts +1 -0
- package/src/forkChoice/fastConfirmation/types.ts +4 -0
- package/src/forkChoice/fastConfirmation/utils.ts +39 -16
- package/src/forkChoice/forkChoice.ts +26 -12
- package/src/forkChoice/interface.ts +7 -12
- package/src/index.ts +1 -1
- package/src/protoArray/computeDeltas.ts +21 -17
- package/src/protoArray/protoArray.ts +68 -4
|
@@ -672,6 +672,28 @@ export class ProtoArray {
|
|
|
672
672
|
this.maybeUpdateBestChildAndDescendant(pendingIndex, fullIndex, currentSlot, proposerBoostRoot);
|
|
673
673
|
}
|
|
674
674
|
|
|
675
|
+
/**
|
|
676
|
+
* Count gloas blocks with fromSlot <= slot <= toSlot and how many of them have a revealed
|
|
677
|
+
* payload (FULL variant exists). Used by the builder circuit breaker.
|
|
678
|
+
*/
|
|
679
|
+
getPayloadRevealCounts(fromSlot: Slot, toSlot: Slot): {blocksPresent: number; payloadsRevealed: number} {
|
|
680
|
+
let blocksPresent = 0;
|
|
681
|
+
let payloadsRevealed = 0;
|
|
682
|
+
// Full scan, nodes are in import order not slot order (an old block can be imported after newer
|
|
683
|
+
// ones during sync or reorg resolution), so we cannot stop early on an out-of-window slot
|
|
684
|
+
for (const node of this.nodes) {
|
|
685
|
+
// Count each gloas block once via its PENDING variant, pre-gloas nodes are FULL only
|
|
686
|
+
if (node.slot < fromSlot || node.slot > toSlot || node.payloadStatus !== PayloadStatus.PENDING) {
|
|
687
|
+
continue;
|
|
688
|
+
}
|
|
689
|
+
blocksPresent++;
|
|
690
|
+
if (this.hasPayload(node.blockRoot)) {
|
|
691
|
+
payloadsRevealed++;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
return {blocksPresent, payloadsRevealed};
|
|
695
|
+
}
|
|
696
|
+
|
|
675
697
|
/**
|
|
676
698
|
* Update PTC votes for multiple validators attesting to a block
|
|
677
699
|
* Spec: gloas/fork-choice.md#new-notify_ptc_messages
|
|
@@ -1541,6 +1563,38 @@ export class ProtoArray {
|
|
|
1541
1563
|
return correctJustified && correctFinalized;
|
|
1542
1564
|
}
|
|
1543
1565
|
|
|
1566
|
+
/** Weights are in EFFECTIVE_BALANCE_INCREMENT units (NOT Gwei); callers scale as needed. */
|
|
1567
|
+
getViableHeads(currentSlot: Slot): {root: RootHex; payloadStatus: PayloadStatus; weight: number}[] {
|
|
1568
|
+
// Mirror the spec's `get_filtered_block_tree`, which is rooted at the store's justified
|
|
1569
|
+
// checkpoint: a viable head is a leaf (no viable descendant, i.e. `bestChild === undefined`)
|
|
1570
|
+
// that descends from the justified checkpoint block AND is itself viable for head. Iterating
|
|
1571
|
+
// all nodes without the justified-descendant filter would wrongly include FFG-viable leaves
|
|
1572
|
+
// that hang off the finalized checkpoint on a branch not under the current justified checkpoint.
|
|
1573
|
+
const justifiedVariant = this.getDefaultVariant(this.justifiedRoot);
|
|
1574
|
+
// Gloas payload-status variants of one blockRoot are distinct nodes in the spec's filtered
|
|
1575
|
+
// tree, identified by (root, payload_status, weight) — emit one entry per variant.
|
|
1576
|
+
const heads: {root: RootHex; payloadStatus: PayloadStatus; weight: number}[] = [];
|
|
1577
|
+
for (const node of this.nodes) {
|
|
1578
|
+
if (node.bestChild !== undefined || !this.nodeIsViableForHead(node, currentSlot)) {
|
|
1579
|
+
continue;
|
|
1580
|
+
}
|
|
1581
|
+
if (this.justifiedEpoch !== GENESIS_EPOCH) {
|
|
1582
|
+
// Same-root short-circuit: every payload-status variant of the justified block itself is
|
|
1583
|
+
// in the filtered tree, but `isDescendant` from the default (PENDING) variant does not
|
|
1584
|
+
// reach the sibling EMPTY/FULL variants of the same root.
|
|
1585
|
+
const descendsFromJustified =
|
|
1586
|
+
node.blockRoot === this.justifiedRoot ||
|
|
1587
|
+
(justifiedVariant !== undefined &&
|
|
1588
|
+
this.isDescendant(this.justifiedRoot, justifiedVariant, node.blockRoot, node.payloadStatus));
|
|
1589
|
+
if (!descendsFromJustified) {
|
|
1590
|
+
continue;
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
heads.push({root: node.blockRoot, payloadStatus: node.payloadStatus, weight: node.weight});
|
|
1594
|
+
}
|
|
1595
|
+
return heads;
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1544
1598
|
/**
|
|
1545
1599
|
* Return `true` if `node` is equal to or a descendant of the finalized node.
|
|
1546
1600
|
* This function helps improve performance of nodeIsViableForHead a lot by avoiding
|
|
@@ -1941,6 +1995,11 @@ export class ProtoArray {
|
|
|
1941
1995
|
* Returns `true` if the `descendantRoot` has an ancestor with `ancestorRoot`.
|
|
1942
1996
|
* Always returns `false` if either input roots are unknown.
|
|
1943
1997
|
* Still returns `true` if `ancestorRoot` === `descendantRoot` and payload statuses match.
|
|
1998
|
+
*
|
|
1999
|
+
* Gloas payload-status matching: a `PENDING` ancestor matches any payload variant
|
|
2000
|
+
* (PENDING/EMPTY/FULL) of the same block, so this can also return `true` for the same
|
|
2001
|
+
* root when statuses differ (e.g. ancestor `PENDING`, descendant `EMPTY`/`FULL`).
|
|
2002
|
+
* `EMPTY` and `FULL` are mutually exclusive siblings and never match each other.
|
|
1944
2003
|
*/
|
|
1945
2004
|
isDescendant(
|
|
1946
2005
|
ancestorRoot: RootHex,
|
|
@@ -1958,11 +2017,16 @@ export class ProtoArray {
|
|
|
1958
2017
|
}
|
|
1959
2018
|
|
|
1960
2019
|
for (const node of this.iterateAncestorNodes(descendantRoot, descendantPayloadStatus)) {
|
|
1961
|
-
if (node.
|
|
1962
|
-
|
|
2020
|
+
if (node.blockRoot === ancestorNode.blockRoot) {
|
|
2021
|
+
// Gloas is_ancestor: a PENDING ancestor matches any payload variant of the same block.
|
|
2022
|
+
return (
|
|
2023
|
+
node.payloadStatus === ancestorNode.payloadStatus || ancestorNode.payloadStatus === PayloadStatus.PENDING
|
|
2024
|
+
);
|
|
1963
2025
|
}
|
|
1964
|
-
|
|
1965
|
-
|
|
2026
|
+
// Ancestors are iterated in decreasing slot, so once we reach the ancestor's slot
|
|
2027
|
+
// without a root match it cannot be in this chain.
|
|
2028
|
+
if (node.slot <= ancestorNode.slot) {
|
|
2029
|
+
return false;
|
|
1966
2030
|
}
|
|
1967
2031
|
}
|
|
1968
2032
|
return false;
|