@lodestar/fork-choice 1.45.0-dev.77f7452c30 → 1.45.0-dev.7a06691aa8
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/metrics.d.ts +1 -0
- package/lib/forkChoice/fastConfirmation/metrics.d.ts.map +1 -1
- package/lib/forkChoice/fastConfirmation/metrics.js +4 -0
- package/lib/forkChoice/fastConfirmation/metrics.js.map +1 -1
- package/lib/forkChoice/forkChoice.d.ts +39 -0
- package/lib/forkChoice/forkChoice.d.ts.map +1 -1
- package/lib/forkChoice/forkChoice.js +160 -37
- package/lib/forkChoice/forkChoice.js.map +1 -1
- package/lib/forkChoice/interface.d.ts +12 -0
- package/lib/forkChoice/interface.d.ts.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/metrics.d.ts +1 -0
- package/lib/metrics.d.ts.map +1 -1
- package/lib/protoArray/computeDeltas.d.ts +3 -3
- package/lib/protoArray/computeDeltas.d.ts.map +1 -1
- package/lib/protoArray/computeDeltas.js +12 -12
- package/lib/protoArray/computeDeltas.js.map +1 -1
- package/lib/protoArray/interface.d.ts +6 -0
- package/lib/protoArray/interface.d.ts.map +1 -1
- package/lib/protoArray/protoArray.d.ts +22 -2
- package/lib/protoArray/protoArray.d.ts.map +1 -1
- package/lib/protoArray/protoArray.js +93 -13
- package/lib/protoArray/protoArray.js.map +1 -1
- package/package.json +8 -8
- package/src/forkChoice/fastConfirmation/metrics.ts +4 -0
- package/src/forkChoice/forkChoice.ts +175 -38
- package/src/forkChoice/interface.ts +9 -0
- package/src/index.ts +1 -1
- package/src/protoArray/computeDeltas.ts +13 -13
- package/src/protoArray/interface.ts +6 -0
- package/src/protoArray/protoArray.ts +102 -17
|
@@ -14,6 +14,7 @@ export declare function getFastConfirmationMetrics(register: MetricsRegisterExtr
|
|
|
14
14
|
}>;
|
|
15
15
|
confirmedEpoch: import("@lodestar/utils").GaugeExtra<import("@lodestar/utils").NoLabels>;
|
|
16
16
|
votesTracked: import("@lodestar/utils").GaugeExtra<import("@lodestar/utils").NoLabels>;
|
|
17
|
+
paused: import("@lodestar/utils").GaugeExtra<import("@lodestar/utils").NoLabels>;
|
|
17
18
|
resets: import("@lodestar/utils").Counter<import("@lodestar/utils").NoLabels>;
|
|
18
19
|
slot: import("@lodestar/utils").GaugeExtra<import("@lodestar/utils").NoLabels>;
|
|
19
20
|
reorgs: import("@lodestar/utils").Counter<import("@lodestar/utils").NoLabels>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/forkChoice/fastConfirmation/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AAErD,MAAM,MAAM,uBAAuB,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAEpF,oBAAY,qBAAqB;IAC/B,UAAU,eAAe;IACzB,UAAU,eAAe;IACzB,aAAa,kBAAkB;IAC/B,QAAQ,aAAa;CACtB;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,oBAAoB
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/forkChoice/fastConfirmation/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AAErD,MAAM,MAAM,uBAAuB,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAEpF,oBAAY,qBAAqB;IAC/B,UAAU,eAAe;IACzB,UAAU,eAAe;IACzB,aAAa,kBAAkB;IAC/B,QAAQ,aAAa;CACtB;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,oBAAoB;;;;;;;;;;;;;;;EAiDxE"}
|
|
@@ -28,6 +28,10 @@ export function getFastConfirmationMetrics(register) {
|
|
|
28
28
|
name: "lodestar_fast_confirmation_votes_tracked",
|
|
29
29
|
help: "Number of checkpoint votes tracked by fast confirmation",
|
|
30
30
|
}),
|
|
31
|
+
paused: register.gauge({
|
|
32
|
+
name: "lodestar_fast_confirmation_paused",
|
|
33
|
+
help: "Whether the fast confirmation rule is paused (1 while node is syncing, 0 while running)",
|
|
34
|
+
}),
|
|
31
35
|
resets: register.counter({
|
|
32
36
|
name: "lodestar_fast_confirmation_resets_total",
|
|
33
37
|
help: "Total number of fast confirmation resets (any cause)",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/forkChoice/fastConfirmation/metrics.ts"],"names":[],"mappings":"SAIY,qBAAqB;AAAjC,IAAY,qBAKX;AALD,WAAY,qBAAqB;IAC/B,kDAAyB,CAAA;IACzB,kDAAyB,CAAA;IACzB,wDAA+B,CAAA;IAC/B,8CAAqB,CAAA;AAAC,CACxB,EALY,qBAAqB,KAArB,qBAAqB,QAKhC;AAED,MAAM,UAAU,0BAA0B,CAAC,QAA8B,EAAE;IACzE,OAAO;QACL,gBAAgB,EAAE;YAChB,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAC;gBAChC,IAAI,EAAE,6CAA6C;gBACnD,IAAI,EAAE,8CAA8C;gBACpD,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;aACpD,CAAC;YACF,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAgC;gBAC/D,IAAI,EAAE,mDAAmD;gBACzD,IAAI,EAAE,qCAAqC;gBAC3C,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBACnD,UAAU,EAAE,CAAC,MAAM,CAAC;aACrB,CAAC;YACF,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC;gBAC7B,IAAI,EAAE,4CAA4C;gBAClD,IAAI,EAAE,gDAAgD;aACvD,CAAC;YACF,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC;gBAC3B,IAAI,EAAE,0CAA0C;gBAChD,IAAI,EAAE,yDAAyD;aAChE,CAAC;YACF,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC;gBACvB,IAAI,EAAE,yCAAyC;gBAC/C,IAAI,EAAE,sDAAsD;aAC7D,CAAC;YACF,yCAAyC;YACzC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACnB,IAAI,EAAE,+BAA+B;gBACrC,IAAI,EAAE,yCAAyC;aAChD,CAAC;YACF,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC;gBACvB,IAAI,EAAE,uCAAuC;gBAC7C,IAAI,EAAE,iDAAiD;aACxD,CAAC;YACF,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC;gBAC1B,IAAI,EAAE,0CAA0C;gBAChD,IAAI,EAAE,uCAAuC;aAC9C,CAAC;YACF,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC;gBACzB,IAAI,EAAE,yCAAyC;gBAC/C,IAAI,EAAE,iEAAiE;aACxE,CAAC;SACH;KACF,CAAC;AAAA,CACH"}
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/forkChoice/fastConfirmation/metrics.ts"],"names":[],"mappings":"SAIY,qBAAqB;AAAjC,IAAY,qBAKX;AALD,WAAY,qBAAqB;IAC/B,kDAAyB,CAAA;IACzB,kDAAyB,CAAA;IACzB,wDAA+B,CAAA;IAC/B,8CAAqB,CAAA;AAAC,CACxB,EALY,qBAAqB,KAArB,qBAAqB,QAKhC;AAED,MAAM,UAAU,0BAA0B,CAAC,QAA8B,EAAE;IACzE,OAAO;QACL,gBAAgB,EAAE;YAChB,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAC;gBAChC,IAAI,EAAE,6CAA6C;gBACnD,IAAI,EAAE,8CAA8C;gBACpD,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;aACpD,CAAC;YACF,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAgC;gBAC/D,IAAI,EAAE,mDAAmD;gBACzD,IAAI,EAAE,qCAAqC;gBAC3C,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBACnD,UAAU,EAAE,CAAC,MAAM,CAAC;aACrB,CAAC;YACF,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC;gBAC7B,IAAI,EAAE,4CAA4C;gBAClD,IAAI,EAAE,gDAAgD;aACvD,CAAC;YACF,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC;gBAC3B,IAAI,EAAE,0CAA0C;gBAChD,IAAI,EAAE,yDAAyD;aAChE,CAAC;YACF,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACrB,IAAI,EAAE,mCAAmC;gBACzC,IAAI,EAAE,yFAAyF;aAChG,CAAC;YACF,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC;gBACvB,IAAI,EAAE,yCAAyC;gBAC/C,IAAI,EAAE,sDAAsD;aAC7D,CAAC;YACF,yCAAyC;YACzC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACnB,IAAI,EAAE,+BAA+B;gBACrC,IAAI,EAAE,yCAAyC;aAChD,CAAC;YACF,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC;gBACvB,IAAI,EAAE,uCAAuC;gBAC7C,IAAI,EAAE,iDAAiD;aACxD,CAAC;YACF,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC;gBAC1B,IAAI,EAAE,0CAA0C;gBAChD,IAAI,EAAE,uCAAuC;aAC9C,CAAC;YACF,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC;gBACzB,IAAI,EAAE,yCAAyC;gBAC/C,IAAI,EAAE,iEAAiE;aACxE,CAAC;SACH;KACF,CAAC;AAAA,CACH"}
|
|
@@ -97,6 +97,7 @@ export declare class ForkChoice implements IForkChoice {
|
|
|
97
97
|
/** Optional fast confirmation rule implementation */
|
|
98
98
|
private readonly fastConfirmationRule?;
|
|
99
99
|
private readonly fastConfirmationContext?;
|
|
100
|
+
private fastConfirmationPaused;
|
|
100
101
|
/**
|
|
101
102
|
* Instantiates a Fork Choice from some existing components
|
|
102
103
|
*
|
|
@@ -128,6 +129,10 @@ export declare class ForkChoice implements IForkChoice {
|
|
|
128
129
|
getHead(): ProtoBlock;
|
|
129
130
|
getConfirmedRoot(): RootHex;
|
|
130
131
|
getConfirmedBlock(): ProtoBlock | null;
|
|
132
|
+
resumeFastConfirmation(): void;
|
|
133
|
+
pauseFastConfirmation(): void;
|
|
134
|
+
private toggleFastConfirmation;
|
|
135
|
+
private notifyConfirmedRoot;
|
|
131
136
|
/**
|
|
132
137
|
*
|
|
133
138
|
* A multiplexer to wrap around the traditional `updateHead()` according to the scenario
|
|
@@ -199,8 +204,26 @@ export declare class ForkChoice implements IForkChoice {
|
|
|
199
204
|
* @param windowStart is the slot after which (excluding) to provide present slots
|
|
200
205
|
*/
|
|
201
206
|
getSlotsPresent(windowStart: number): number;
|
|
207
|
+
getPayloadRevealCounts(fromSlot: Slot, toSlot: Slot): {
|
|
208
|
+
blocksPresent: number;
|
|
209
|
+
payloadsRevealed: number;
|
|
210
|
+
};
|
|
202
211
|
/** Very expensive function, iterates the entire ProtoArray. Called only in debug API */
|
|
203
212
|
getHeads(): ProtoBlock[];
|
|
213
|
+
/**
|
|
214
|
+
* weight is in EFFECTIVE_BALANCE_INCREMENTS not gwei.
|
|
215
|
+
* For compliance test use only
|
|
216
|
+
*/
|
|
217
|
+
getViableHeads(): {
|
|
218
|
+
root: RootHex;
|
|
219
|
+
payloadStatus: PayloadStatus;
|
|
220
|
+
weight: number;
|
|
221
|
+
}[];
|
|
222
|
+
/**
|
|
223
|
+
* The cached justified total active balance, in EFFECTIVE_BALANCE_INCREMENT units.
|
|
224
|
+
* For compliance test use only
|
|
225
|
+
*/
|
|
226
|
+
getJustifiedTotalActiveBalanceByIncrement(): number;
|
|
204
227
|
/** This is for the debug API only */
|
|
205
228
|
getAllNodes(): ProtoNode[];
|
|
206
229
|
getFinalizedCheckpoint(): CheckpointWithHex;
|
|
@@ -423,6 +446,22 @@ export declare class ForkChoice implements IForkChoice {
|
|
|
423
446
|
* its parent
|
|
424
447
|
*/
|
|
425
448
|
private isProposerBoostSameDependentRoot;
|
|
449
|
+
/**
|
|
450
|
+
* Return true if the block is "weak" ie. its weight is below REORG_HEAD_WEIGHT_THRESHOLD of the
|
|
451
|
+
* total attester weight per slot.
|
|
452
|
+
*
|
|
453
|
+
* https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/phase0/fork-choice.md#is_head_weak
|
|
454
|
+
* https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/fork-choice.md#modified-is_head_weak
|
|
455
|
+
*/
|
|
456
|
+
private isHeadWeak;
|
|
457
|
+
/**
|
|
458
|
+
* Return true if the parent block is "strong" ie. its weight exceeds REORG_PARENT_WEIGHT_THRESHOLD
|
|
459
|
+
* of the total attester weight per slot.
|
|
460
|
+
*
|
|
461
|
+
* https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.12/specs/phase0/fork-choice.md#is_parent_strong
|
|
462
|
+
* https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.12/specs/gloas/fork-choice.md#modified-is_parent_strong
|
|
463
|
+
*/
|
|
464
|
+
private isParentStrong;
|
|
426
465
|
/**
|
|
427
466
|
* Return true if the block is timely for the current slot.
|
|
428
467
|
* Child class can overwrite this for testing purpose.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forkChoice.d.ts","sourceRoot":"","sources":["../../src/forkChoice/forkChoice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EACL,sBAAsB,EAEtB,gBAAgB,EAQjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,gBAAgB,EAChB,WAAW,EAEX,kBAAkB,EAClB,IAAI,EACJ,OAAO,EACP,IAAI,EAKL,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAC,MAAM,EAAmD,MAAM,iBAAiB,CAAC;AACzF,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAGhD,OAAO,EACL,oBAAoB,EAGpB,eAAe,EAEf,sBAAsB,EACtB,aAAa,EACb,UAAU,EACV,SAAS,EAGV,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,UAAU,EAAC,MAAM,6BAA6B,CAAC;AAQvD,OAAO,EACL,cAAc,EAEd,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,oCAAoC,EACrC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAC,iBAAiB,EAAE,gBAAgB,EAAyC,MAAM,YAAY,CAAC;AAEvG,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,oBAAY,aAAa;IACvB,gBAAgB,qBAAqB;IACrC,eAAe,oBAAoB;IACnC,wBAAwB,6BAA6B;CACtD;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAC,IAAI,EAAE,aAAa,CAAC,gBAAgB,CAAA;CAAC,GACtC;IAAC,IAAI,EAAE,aAAa,CAAC,eAAe,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAC,GACtE;IAAC,IAAI,EAAE,aAAa,CAAC,wBAAwB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAC,CAAC;AAKpF;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,UAAW,YAAW,WAAW;
|
|
1
|
+
{"version":3,"file":"forkChoice.d.ts","sourceRoot":"","sources":["../../src/forkChoice/forkChoice.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MIN_SEED_LOOKAHEAD, SLOTS_PER_EPOCH } from "@lodestar/params";
|
|
1
|
+
import { MIN_SEED_LOOKAHEAD, SLOTS_PER_EPOCH, isForkPostGloas } from "@lodestar/params";
|
|
2
2
|
import { DataAvailabilityStatus, ZERO_HASH, computeEpochAtSlot, computeSlotsSinceEpochStart, computeStartSlotAtEpoch, getAttesterSlashableIndices, isExecutionBlockBodyType, isStatePostBellatrix, } from "@lodestar/state-transition";
|
|
3
3
|
import { isGloasBeaconBlock, ssz, } from "@lodestar/types";
|
|
4
4
|
import { MapDef, fromHex, toRootHex, withObservedDuration } from "@lodestar/utils";
|
|
@@ -89,6 +89,7 @@ export class ForkChoice {
|
|
|
89
89
|
/** Optional fast confirmation rule implementation */
|
|
90
90
|
fastConfirmationRule;
|
|
91
91
|
fastConfirmationContext;
|
|
92
|
+
fastConfirmationPaused = false;
|
|
92
93
|
/**
|
|
93
94
|
* Instantiates a Fork Choice from some existing components
|
|
94
95
|
*
|
|
@@ -113,6 +114,7 @@ export class ForkChoice {
|
|
|
113
114
|
if (this.opts?.fastConfirmation) {
|
|
114
115
|
this.fastConfirmationRule = new FastConfirmationRule(this.fcStore, metrics, this.logger);
|
|
115
116
|
this.fastConfirmationContext = this.createFastConfirmationContext();
|
|
117
|
+
metrics?.fastConfirmation.paused.set(0);
|
|
116
118
|
}
|
|
117
119
|
metrics?.forkChoice.votes.addCollect(() => {
|
|
118
120
|
metrics.forkChoice.votes.set(this.voteNextSlots.length);
|
|
@@ -156,6 +158,46 @@ export class ForkChoice {
|
|
|
156
158
|
getConfirmedBlock() {
|
|
157
159
|
return this.getBlockHexDefaultStatus(this.getConfirmedRoot());
|
|
158
160
|
}
|
|
161
|
+
resumeFastConfirmation() {
|
|
162
|
+
this.toggleFastConfirmation(false);
|
|
163
|
+
}
|
|
164
|
+
pauseFastConfirmation() {
|
|
165
|
+
this.toggleFastConfirmation(true);
|
|
166
|
+
}
|
|
167
|
+
toggleFastConfirmation(paused) {
|
|
168
|
+
if (!this.fastConfirmationRule)
|
|
169
|
+
return;
|
|
170
|
+
if (paused === this.fastConfirmationPaused)
|
|
171
|
+
return;
|
|
172
|
+
this.fastConfirmationPaused = paused;
|
|
173
|
+
if (paused) {
|
|
174
|
+
// Pin immediately: block imports report the safe block hash to the EL before the next slot tick
|
|
175
|
+
this.fcStore.confirmedRoot = this.fcStore.finalizedCheckpoint.rootHex;
|
|
176
|
+
try {
|
|
177
|
+
this.notifyConfirmedRoot();
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
// Callers run in clock/network handler context with no catch above
|
|
181
|
+
this.logger?.debug("Fast confirmation notify failed", { slot: this.fcStore.currentSlot }, err);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
this.metrics?.fastConfirmation.paused.set(paused ? 1 : 0);
|
|
185
|
+
this.logger?.info(paused ? "Paused fast confirmation" : "Resumed fast confirmation", {
|
|
186
|
+
slot: this.fcStore.currentSlot,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
notifyConfirmedRoot() {
|
|
190
|
+
const confirmedRoot = this.fcStore.confirmedRoot;
|
|
191
|
+
const confirmedBlock = this.getBlockHexDefaultStatus(confirmedRoot);
|
|
192
|
+
if (confirmedBlock === null) {
|
|
193
|
+
throw new Error(`Fast confirmation produced root not in protoArray: ${confirmedRoot}`);
|
|
194
|
+
}
|
|
195
|
+
this.fcStore.notifyFastConfirmation?.({
|
|
196
|
+
block: confirmedRoot,
|
|
197
|
+
slot: confirmedBlock.slot,
|
|
198
|
+
currentSlot: this.fcStore.currentSlot,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
159
201
|
/**
|
|
160
202
|
*
|
|
161
203
|
* A multiplexer to wrap around the traditional `updateHead()` according to the scenario
|
|
@@ -327,29 +369,11 @@ export class ForkChoice {
|
|
|
327
369
|
return { proposerHead, isHeadTimely, notReorgedReason: NotReorgedReason.ProposerBoostNotWornOff };
|
|
328
370
|
}
|
|
329
371
|
// No reorg if headBlock is "not weak" ie. headBlock's weight exceeds (REORG_HEAD_WEIGHT_THRESHOLD = 20)% of total attester weight
|
|
330
|
-
|
|
331
|
-
const reorgThreshold = getCommitteeFraction(this.fcStore.justified.totalBalance, {
|
|
332
|
-
slotsPerEpoch: SLOTS_PER_EPOCH,
|
|
333
|
-
committeePercent: this.config.REORG_HEAD_WEIGHT_THRESHOLD,
|
|
334
|
-
});
|
|
335
|
-
const headNode = this.protoArray.getNode(headBlock.blockRoot, headBlock.payloadStatus);
|
|
336
|
-
// If headNode is unavailable, give up reorg
|
|
337
|
-
if (headNode === undefined || headNode.weight >= reorgThreshold) {
|
|
372
|
+
if (!this.isHeadWeak(headBlock.blockRoot)) {
|
|
338
373
|
return { proposerHead, isHeadTimely, notReorgedReason: NotReorgedReason.HeadBlockNotWeak };
|
|
339
374
|
}
|
|
340
375
|
// No reorg if parentBlock is "not strong" ie. parentBlock's weight is less than or equal to (REORG_PARENT_WEIGHT_THRESHOLD = 160)% of total attester weight
|
|
341
|
-
|
|
342
|
-
// For Gloas: measure support for the parent beacon block root regardless of its payload status by
|
|
343
|
-
// looking up the PENDING variant.
|
|
344
|
-
// https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/fork-choice.md#modified-is_parent_strong
|
|
345
|
-
const parentThreshold = getCommitteeFraction(this.fcStore.justified.totalBalance, {
|
|
346
|
-
slotsPerEpoch: SLOTS_PER_EPOCH,
|
|
347
|
-
committeePercent: this.config.REORG_PARENT_WEIGHT_THRESHOLD,
|
|
348
|
-
});
|
|
349
|
-
const parentStrongVariant = isGloasBlock(parentBlock) ? PayloadStatus.PENDING : PayloadStatus.FULL;
|
|
350
|
-
const parentNode = this.protoArray.getNode(parentBlock.blockRoot, parentStrongVariant);
|
|
351
|
-
// If parentNode is unavailable, give up reorg
|
|
352
|
-
if (parentNode === undefined || parentNode.weight <= parentThreshold) {
|
|
376
|
+
if (!this.isParentStrong(parentBlock.blockRoot)) {
|
|
353
377
|
return { proposerHead, isHeadTimely, notReorgedReason: NotReorgedReason.ParentBlockNotStrong };
|
|
354
378
|
}
|
|
355
379
|
// Reorg if all above checks fail
|
|
@@ -385,10 +409,10 @@ export class ForkChoice {
|
|
|
385
409
|
const newBalances = this.fcStore.justified.balances;
|
|
386
410
|
const computeDeltasMetrics = this.metrics?.forkChoice.computeDeltas;
|
|
387
411
|
const timer = computeDeltasMetrics?.duration.startTimer();
|
|
388
|
-
const {
|
|
412
|
+
const { attestationDeltas, equivocatingValidators, oldInactiveValidators, newInactiveValidators, unchangedVoteValidators, newVoteValidators, } = computeDeltas(this.protoArray.nodes.length, this.voteCurrentIndices, this.voteNextIndices, oldBalances, newBalances, this.fcStore.equivocatingIndices);
|
|
389
413
|
timer?.();
|
|
390
|
-
computeDeltasMetrics?.deltasCount.set(
|
|
391
|
-
computeDeltasMetrics?.zeroDeltasCount.set(
|
|
414
|
+
computeDeltasMetrics?.deltasCount.set(attestationDeltas.length);
|
|
415
|
+
computeDeltasMetrics?.zeroDeltasCount.set(attestationDeltas.filter((d) => d === 0).length);
|
|
392
416
|
computeDeltasMetrics?.equivocatingValidators.set(equivocatingValidators);
|
|
393
417
|
computeDeltasMetrics?.oldInactiveValidators.set(oldInactiveValidators);
|
|
394
418
|
computeDeltasMetrics?.newInactiveValidators.set(newInactiveValidators);
|
|
@@ -411,7 +435,7 @@ export class ForkChoice {
|
|
|
411
435
|
}
|
|
412
436
|
const currentSlot = this.fcStore.currentSlot;
|
|
413
437
|
this.protoArray.applyScoreChanges({
|
|
414
|
-
|
|
438
|
+
attestationDeltas,
|
|
415
439
|
proposerBoost,
|
|
416
440
|
justifiedEpoch: this.fcStore.justified.checkpoint.epoch,
|
|
417
441
|
justifiedRoot: this.fcStore.justified.checkpoint.rootHex,
|
|
@@ -432,10 +456,27 @@ export class ForkChoice {
|
|
|
432
456
|
getSlotsPresent(windowStart) {
|
|
433
457
|
return this.protoArray.nodes.filter((node) => node.slot > windowStart).length;
|
|
434
458
|
}
|
|
459
|
+
getPayloadRevealCounts(fromSlot, toSlot) {
|
|
460
|
+
return this.protoArray.getPayloadRevealCounts(fromSlot, toSlot);
|
|
461
|
+
}
|
|
435
462
|
/** Very expensive function, iterates the entire ProtoArray. Called only in debug API */
|
|
436
463
|
getHeads() {
|
|
437
464
|
return this.protoArray.nodes.filter((node) => node.bestChild === undefined);
|
|
438
465
|
}
|
|
466
|
+
/**
|
|
467
|
+
* weight is in EFFECTIVE_BALANCE_INCREMENTS not gwei.
|
|
468
|
+
* For compliance test use only
|
|
469
|
+
*/
|
|
470
|
+
getViableHeads() {
|
|
471
|
+
return this.protoArray.getViableHeads(this.fcStore.currentSlot);
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* The cached justified total active balance, in EFFECTIVE_BALANCE_INCREMENT units.
|
|
475
|
+
* For compliance test use only
|
|
476
|
+
*/
|
|
477
|
+
getJustifiedTotalActiveBalanceByIncrement() {
|
|
478
|
+
return this.fcStore.justified.totalBalance;
|
|
479
|
+
}
|
|
439
480
|
/** This is for the debug API only */
|
|
440
481
|
getAllNodes() {
|
|
441
482
|
return this.protoArray.nodes;
|
|
@@ -1227,6 +1268,82 @@ export class ForkChoice {
|
|
|
1227
1268
|
}
|
|
1228
1269
|
return headDependentRoot === blockDependentRoot;
|
|
1229
1270
|
}
|
|
1271
|
+
/**
|
|
1272
|
+
* Return true if the block is "weak" ie. its weight is below REORG_HEAD_WEIGHT_THRESHOLD of the
|
|
1273
|
+
* total attester weight per slot.
|
|
1274
|
+
*
|
|
1275
|
+
* https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/phase0/fork-choice.md#is_head_weak
|
|
1276
|
+
* https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/fork-choice.md#modified-is_head_weak
|
|
1277
|
+
*/
|
|
1278
|
+
isHeadWeak(blockRoot) {
|
|
1279
|
+
// The default variant is PENDING for gloas, FULL pre-gloas. PENDING is the variant gloas measures
|
|
1280
|
+
// support on, ie. support for the beacon block root regardless of its payload status.
|
|
1281
|
+
// Only ever called on a block already in fork choice, so a miss is a broken invariant.
|
|
1282
|
+
const node = this.protoArray.getNodeDefaultStatus(blockRoot);
|
|
1283
|
+
if (node === undefined) {
|
|
1284
|
+
// this is called for head so we should always have this in forkchoice, otherwise we have a serious error
|
|
1285
|
+
throw new ForkChoiceError({ code: ForkChoiceErrorCode.MISSING_PROTO_ARRAY_BLOCK, root: blockRoot });
|
|
1286
|
+
}
|
|
1287
|
+
const reorgThreshold = getCommitteeFraction(this.fcStore.justified.totalBalance, {
|
|
1288
|
+
slotsPerEpoch: SLOTS_PER_EPOCH,
|
|
1289
|
+
committeePercent: this.config.REORG_HEAD_WEIGHT_THRESHOLD,
|
|
1290
|
+
});
|
|
1291
|
+
if (!isForkPostGloas(this.config.getForkName(node.slot))) {
|
|
1292
|
+
return node.weight < reorgThreshold;
|
|
1293
|
+
}
|
|
1294
|
+
let headWeight = node.attestationScore;
|
|
1295
|
+
const { equivocatingIndices } = this.fcStore;
|
|
1296
|
+
// Equivocators are extremely rare (none in normal operation), and with none the added weight is
|
|
1297
|
+
// always 0. Return before fetching the state and walking the block's committees.
|
|
1298
|
+
if (equivocatingIndices.size > 0) {
|
|
1299
|
+
const state = this.fcStore.stateGetter({ stateRoot: node.stateRoot });
|
|
1300
|
+
// Only ever called on the head, so the state is always cached.
|
|
1301
|
+
// A miss is a broken invariant, not a recoverable state.
|
|
1302
|
+
if (state === null) {
|
|
1303
|
+
throw new ForkChoiceError({
|
|
1304
|
+
code: ForkChoiceErrorCode.BEACON_STATE_ERROR,
|
|
1305
|
+
error: new Error(`Missing state for isHeadWeak, blockRoot=${blockRoot} stateRoot=${node.stateRoot}`),
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
const epoch = computeEpochAtSlot(node.slot);
|
|
1309
|
+
for (let index = 0; index < state.getBeaconCommitteeCountPerSlot(epoch); index++) {
|
|
1310
|
+
for (const validatorIndex of state.getBeaconCommittee(node.slot, index)) {
|
|
1311
|
+
if (equivocatingIndices.has(validatorIndex)) {
|
|
1312
|
+
// the spec specifies to use effective_balance of the justified state
|
|
1313
|
+
let balance = this.fcStore.justified.balances[validatorIndex];
|
|
1314
|
+
if (!balance) {
|
|
1315
|
+
// 0 (zeroed by getEffectiveBalanceIncrementsZeroInactive) or undefined (validator not in
|
|
1316
|
+
// the justified state) - fall back to the head state's effective balance
|
|
1317
|
+
balance = state.effectiveBalanceIncrements[validatorIndex];
|
|
1318
|
+
}
|
|
1319
|
+
headWeight += balance;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
return headWeight < reorgThreshold;
|
|
1325
|
+
}
|
|
1326
|
+
/**
|
|
1327
|
+
* Return true if the parent block is "strong" ie. its weight exceeds REORG_PARENT_WEIGHT_THRESHOLD
|
|
1328
|
+
* of the total attester weight per slot.
|
|
1329
|
+
*
|
|
1330
|
+
* https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.12/specs/phase0/fork-choice.md#is_parent_strong
|
|
1331
|
+
* https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.12/specs/gloas/fork-choice.md#modified-is_parent_strong
|
|
1332
|
+
*/
|
|
1333
|
+
isParentStrong(parentRoot) {
|
|
1334
|
+
const node = this.protoArray.getNodeDefaultStatus(parentRoot);
|
|
1335
|
+
// If parentNode is unavailable, give up reorg
|
|
1336
|
+
if (node === undefined) {
|
|
1337
|
+
return false;
|
|
1338
|
+
}
|
|
1339
|
+
const parentThreshold = getCommitteeFraction(this.fcStore.justified.totalBalance, {
|
|
1340
|
+
slotsPerEpoch: SLOTS_PER_EPOCH,
|
|
1341
|
+
committeePercent: this.config.REORG_PARENT_WEIGHT_THRESHOLD,
|
|
1342
|
+
});
|
|
1343
|
+
// pre-gloas uses get_weight() (boost-inclusive), gloas uses get_attestation_score() (boost-excluded)
|
|
1344
|
+
const parentWeight = isForkPostGloas(this.config.getForkName(node.slot)) ? node.attestationScore : node.weight;
|
|
1345
|
+
return parentWeight > parentThreshold;
|
|
1346
|
+
}
|
|
1230
1347
|
/**
|
|
1231
1348
|
* Return true if the block is timely for the current slot.
|
|
1232
1349
|
* Child class can overwrite this for testing purpose.
|
|
@@ -1601,24 +1718,30 @@ export class ForkChoice {
|
|
|
1601
1718
|
return { prelimProposerHead };
|
|
1602
1719
|
}
|
|
1603
1720
|
runFastConfirmation() {
|
|
1721
|
+
const fastConfirmationRule = this.fastConfirmationRule;
|
|
1722
|
+
const fastConfirmationContext = this.fastConfirmationContext;
|
|
1723
|
+
if (!fastConfirmationRule || !fastConfirmationContext)
|
|
1724
|
+
return;
|
|
1725
|
+
if (this.fastConfirmationPaused) {
|
|
1726
|
+
// Keep consumers on a safe, available root while the rule is paused
|
|
1727
|
+
this.fcStore.confirmedRoot = this.fcStore.finalizedCheckpoint.rootHex;
|
|
1728
|
+
try {
|
|
1729
|
+
this.notifyConfirmedRoot();
|
|
1730
|
+
}
|
|
1731
|
+
catch (err) {
|
|
1732
|
+
// Runs outside the timed try/catch below; a throw would escape to the clock listener
|
|
1733
|
+
this.logger?.debug("Fast confirmation notify failed", { slot: this.fcStore.currentSlot }, err);
|
|
1734
|
+
}
|
|
1735
|
+
return;
|
|
1736
|
+
}
|
|
1604
1737
|
withObservedDuration(this.metrics?.fastConfirmation.totalDuration.startTimer(), () => {
|
|
1605
|
-
if (!this.fastConfirmationRule || !this.fastConfirmationContext)
|
|
1606
|
-
return;
|
|
1607
1738
|
try {
|
|
1608
1739
|
withObservedDuration(this.metrics?.fastConfirmation.stepsDuration.startTimer({
|
|
1609
1740
|
step: FastConfirmationSteps.updateHead,
|
|
1610
1741
|
}), () => this.updateHead());
|
|
1611
|
-
const result =
|
|
1742
|
+
const result = fastConfirmationRule.onSlotStartAfterPastAttestationsApplied(fastConfirmationContext);
|
|
1612
1743
|
this.fcStore.confirmedRoot = result.confirmedRoot;
|
|
1613
|
-
|
|
1614
|
-
if (confirmedBlock === null) {
|
|
1615
|
-
throw new Error(`Fast confirmation produced root not in protoArray: ${result.confirmedRoot}`);
|
|
1616
|
-
}
|
|
1617
|
-
this.fcStore.notifyFastConfirmation?.({
|
|
1618
|
-
block: result.confirmedRoot,
|
|
1619
|
-
slot: confirmedBlock.slot,
|
|
1620
|
-
currentSlot: this.fcStore.currentSlot,
|
|
1621
|
-
});
|
|
1744
|
+
this.notifyConfirmedRoot();
|
|
1622
1745
|
}
|
|
1623
1746
|
catch (err) {
|
|
1624
1747
|
this.logger?.debug("Fast confirmation failed", { slot: this.fcStore.currentSlot, head: this.head.blockRoot, confirmedRoot: this.fcStore.confirmedRoot }, err);
|