@lodestar/fork-choice 1.50.0-dev.6ce21fd8a2 → 1.50.0-dev.6d20ee6eb8
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/types.d.ts +3 -1
- package/lib/forkChoice/fastConfirmation/types.d.ts.map +1 -1
- package/lib/forkChoice/fastConfirmation/utils.d.ts +2 -2
- package/lib/forkChoice/fastConfirmation/utils.d.ts.map +1 -1
- package/lib/forkChoice/fastConfirmation/utils.js +8 -3
- package/lib/forkChoice/fastConfirmation/utils.js.map +1 -1
- package/lib/forkChoice/forkChoice.d.ts +2 -1
- package/lib/forkChoice/forkChoice.d.ts.map +1 -1
- package/lib/forkChoice/forkChoice.js +31 -2
- package/lib/forkChoice/forkChoice.js.map +1 -1
- package/lib/forkChoice/interface.d.ts +9 -1
- package/lib/forkChoice/interface.d.ts.map +1 -1
- package/lib/forkChoice/interface.js.map +1 -1
- package/lib/forkChoice/store.d.ts +4 -1
- package/lib/forkChoice/store.d.ts.map +1 -1
- package/lib/forkChoice/store.js +3 -0
- package/lib/forkChoice/store.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/metrics.d.ts +3 -0
- package/lib/metrics.d.ts.map +1 -1
- package/lib/metrics.js +5 -0
- package/lib/metrics.js.map +1 -1
- package/lib/protoArray/interface.d.ts +15 -0
- package/lib/protoArray/interface.d.ts.map +1 -1
- package/lib/protoArray/interface.js +13 -0
- package/lib/protoArray/interface.js.map +1 -1
- package/lib/protoArray/protoArray.d.ts +13 -1
- package/lib/protoArray/protoArray.d.ts.map +1 -1
- package/lib/protoArray/protoArray.js +49 -0
- package/lib/protoArray/protoArray.js.map +1 -1
- package/package.json +8 -8
- package/src/forkChoice/fastConfirmation/types.ts +3 -2
- package/src/forkChoice/fastConfirmation/utils.ts +12 -5
- package/src/forkChoice/forkChoice.ts +32 -1
- package/src/forkChoice/interface.ts +6 -0
- package/src/forkChoice/store.ts +7 -1
- package/src/index.ts +3 -1
- package/src/metrics.ts +5 -0
- package/src/protoArray/interface.ts +21 -0
- package/src/protoArray/protoArray.ts +54 -0
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
PayloadStatus,
|
|
14
14
|
ProtoBlock,
|
|
15
15
|
ProtoNode,
|
|
16
|
+
PtcQuorum,
|
|
16
17
|
isGloasBlock,
|
|
17
18
|
} from "./interface.js";
|
|
18
19
|
|
|
@@ -52,6 +53,12 @@ export function countNoVotes(attended: BitArray, yes: BitArray): number {
|
|
|
52
53
|
return count;
|
|
53
54
|
}
|
|
54
55
|
|
|
56
|
+
function majorityVote(attended: BitArray, yes: BitArray, threshold: number): boolean | null {
|
|
57
|
+
if (bitCount(yes.uint8Array) > threshold) return true;
|
|
58
|
+
if (countNoVotes(attended, yes) > threshold) return false;
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
55
62
|
export const DEFAULT_PRUNE_THRESHOLD = 0;
|
|
56
63
|
type ProposerBoost = {root: RootHex; score: bigint};
|
|
57
64
|
|
|
@@ -801,6 +808,23 @@ export class ProtoArray {
|
|
|
801
808
|
};
|
|
802
809
|
}
|
|
803
810
|
|
|
811
|
+
/**
|
|
812
|
+
* PTC majority per vote field from the raw tallies, regardless of whether the payload is locally
|
|
813
|
+
* available. Returns `null` for pre-Gloas (or pruned) roots, which have no vote maps.
|
|
814
|
+
*/
|
|
815
|
+
getPtcQuorum(blockRoot: RootHex): PtcQuorum | null {
|
|
816
|
+
const attended = this.ptcAttested.get(blockRoot);
|
|
817
|
+
const timelinessVotes = this.payloadTimelinessVotes.get(blockRoot);
|
|
818
|
+
const daVotes = this.payloadDataAvailabilityVotes.get(blockRoot);
|
|
819
|
+
if (attended === undefined || timelinessVotes === undefined || daVotes === undefined) {
|
|
820
|
+
return null;
|
|
821
|
+
}
|
|
822
|
+
return {
|
|
823
|
+
payloadPresent: majorityVote(attended, timelinessVotes, PAYLOAD_TIMELY_THRESHOLD),
|
|
824
|
+
blobDataAvailable: majorityVote(attended, daVotes, DATA_AVAILABILITY_TIMELY_THRESHOLD),
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
|
|
804
828
|
getPreviousProposerBoostRoot(): RootHex {
|
|
805
829
|
return this.previousProposerBoost?.root ?? HEX_ZERO_HASH;
|
|
806
830
|
}
|
|
@@ -1043,6 +1067,8 @@ export class ProtoArray {
|
|
|
1043
1067
|
|
|
1044
1068
|
private propagateValidExecutionStatusByIndex(validNodeIndex: number): void {
|
|
1045
1069
|
let nodeIndex: number | undefined = validNodeIndex;
|
|
1070
|
+
// Payloads that transitioned to VALID, their gloas dependents are validated below
|
|
1071
|
+
const validatedPayloadHashes = new Set<RootHex>();
|
|
1046
1072
|
// propagate till we keep encountering syncing status
|
|
1047
1073
|
while (nodeIndex !== undefined) {
|
|
1048
1074
|
const node = this.getNodeFromIndex(nodeIndex);
|
|
@@ -1050,8 +1076,36 @@ export class ProtoArray {
|
|
|
1050
1076
|
break;
|
|
1051
1077
|
}
|
|
1052
1078
|
this.validateNodeByIndex(nodeIndex);
|
|
1079
|
+
if (node.payloadStatus === PayloadStatus.FULL && node.executionPayloadBlockHash !== null) {
|
|
1080
|
+
validatedPayloadHashes.add(node.executionPayloadBlockHash);
|
|
1081
|
+
}
|
|
1053
1082
|
nodeIndex = node.parent;
|
|
1054
1083
|
}
|
|
1084
|
+
|
|
1085
|
+
if (validatedPayloadHashes.size > 0) {
|
|
1086
|
+
this.validatePayloadDependents(validatedPayloadHashes);
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* Gloas PENDING and EMPTY variants have no payload of their own, they inherit the execution status of
|
|
1092
|
+
* the payload they build on, which is their `executionPayloadBlockHash`. Once that payload is VALID, all
|
|
1093
|
+
* of them are, not only the ones on the chain the validation walked up (e.g. siblings, or blocks
|
|
1094
|
+
* building on a sibling's EMPTY variant).
|
|
1095
|
+
*/
|
|
1096
|
+
private validatePayloadDependents(payloadHashes: Set<RootHex>): void {
|
|
1097
|
+
for (let nodeIndex = 0; nodeIndex < this.nodes.length; nodeIndex++) {
|
|
1098
|
+
const node = this.nodes[nodeIndex];
|
|
1099
|
+
if (
|
|
1100
|
+
node.payloadStatus === PayloadStatus.PENDING &&
|
|
1101
|
+
node.executionStatus === ExecutionStatus.Syncing &&
|
|
1102
|
+
node.executionPayloadBlockHash !== null &&
|
|
1103
|
+
payloadHashes.has(node.executionPayloadBlockHash)
|
|
1104
|
+
) {
|
|
1105
|
+
// Also flips the sibling EMPTY variant
|
|
1106
|
+
this.validateNodeByIndex(nodeIndex);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1055
1109
|
}
|
|
1056
1110
|
|
|
1057
1111
|
/**
|