@lodestar/fork-choice 1.44.0-dev.4ac6f45830 → 1.44.0-dev.4b91ba8c2f

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.
Files changed (64) hide show
  1. package/lib/forkChoice/fastConfirmation/data.d.ts +4 -0
  2. package/lib/forkChoice/fastConfirmation/data.d.ts.map +1 -0
  3. package/lib/forkChoice/fastConfirmation/data.js +31 -0
  4. package/lib/forkChoice/fastConfirmation/data.js.map +1 -0
  5. package/lib/forkChoice/fastConfirmation/fastConfirmationRule.d.ts +17 -0
  6. package/lib/forkChoice/fastConfirmation/fastConfirmationRule.d.ts.map +1 -0
  7. package/lib/forkChoice/fastConfirmation/fastConfirmationRule.js +139 -0
  8. package/lib/forkChoice/fastConfirmation/fastConfirmationRule.js.map +1 -0
  9. package/lib/forkChoice/fastConfirmation/index.d.ts +4 -0
  10. package/lib/forkChoice/fastConfirmation/index.d.ts.map +1 -0
  11. package/lib/forkChoice/fastConfirmation/index.js +4 -0
  12. package/lib/forkChoice/fastConfirmation/index.js.map +1 -0
  13. package/lib/forkChoice/fastConfirmation/metrics.d.ts +24 -0
  14. package/lib/forkChoice/fastConfirmation/metrics.d.ts.map +1 -0
  15. package/lib/forkChoice/fastConfirmation/metrics.js +55 -0
  16. package/lib/forkChoice/fastConfirmation/metrics.js.map +1 -0
  17. package/lib/forkChoice/fastConfirmation/rules.d.ts +9 -0
  18. package/lib/forkChoice/fastConfirmation/rules.d.ts.map +1 -0
  19. package/lib/forkChoice/fastConfirmation/rules.js +114 -0
  20. package/lib/forkChoice/fastConfirmation/rules.js.map +1 -0
  21. package/lib/forkChoice/fastConfirmation/types.d.ts +115 -0
  22. package/lib/forkChoice/fastConfirmation/types.d.ts.map +1 -0
  23. package/lib/forkChoice/fastConfirmation/types.js +22 -0
  24. package/lib/forkChoice/fastConfirmation/types.js.map +1 -0
  25. package/lib/forkChoice/fastConfirmation/utils.d.ts +47 -0
  26. package/lib/forkChoice/fastConfirmation/utils.d.ts.map +1 -0
  27. package/lib/forkChoice/fastConfirmation/utils.js +687 -0
  28. package/lib/forkChoice/fastConfirmation/utils.js.map +1 -0
  29. package/lib/forkChoice/forkChoice.d.ts +8 -0
  30. package/lib/forkChoice/forkChoice.d.ts.map +1 -1
  31. package/lib/forkChoice/forkChoice.js +93 -5
  32. package/lib/forkChoice/forkChoice.js.map +1 -1
  33. package/lib/forkChoice/interface.d.ts +2 -0
  34. package/lib/forkChoice/interface.d.ts.map +1 -1
  35. package/lib/forkChoice/safeBlocks.d.ts +2 -6
  36. package/lib/forkChoice/safeBlocks.d.ts.map +1 -1
  37. package/lib/forkChoice/safeBlocks.js +15 -7
  38. package/lib/forkChoice/safeBlocks.js.map +1 -1
  39. package/lib/forkChoice/store.d.ts +33 -2
  40. package/lib/forkChoice/store.d.ts.map +1 -1
  41. package/lib/forkChoice/store.js +37 -1
  42. package/lib/forkChoice/store.js.map +1 -1
  43. package/lib/index.d.ts +1 -0
  44. package/lib/index.d.ts.map +1 -1
  45. package/lib/index.js +1 -0
  46. package/lib/index.js.map +1 -1
  47. package/lib/metrics.d.ts +15 -1
  48. package/lib/metrics.d.ts.map +1 -1
  49. package/lib/metrics.js +2 -0
  50. package/lib/metrics.js.map +1 -1
  51. package/package.json +7 -7
  52. package/src/forkChoice/fastConfirmation/data.ts +43 -0
  53. package/src/forkChoice/fastConfirmation/fastConfirmationRule.ts +173 -0
  54. package/src/forkChoice/fastConfirmation/index.ts +3 -0
  55. package/src/forkChoice/fastConfirmation/metrics.ts +57 -0
  56. package/src/forkChoice/fastConfirmation/rules.ts +151 -0
  57. package/src/forkChoice/fastConfirmation/types.ts +137 -0
  58. package/src/forkChoice/fastConfirmation/utils.ts +975 -0
  59. package/src/forkChoice/forkChoice.ts +111 -6
  60. package/src/forkChoice/interface.ts +2 -0
  61. package/src/forkChoice/safeBlocks.ts +15 -7
  62. package/src/forkChoice/store.ts +45 -1
  63. package/src/index.ts +11 -0
  64. package/src/metrics.ts +3 -1
@@ -1,5 +1,6 @@
1
1
  import { EffectiveBalanceIncrements, IBeaconStateView } from "@lodestar/state-transition";
2
2
  import { RootHex, Slot, ValidatorIndex, phase0 } from "@lodestar/types";
3
+ import { ForkChoiceStateGetter, IFastConfirmationStore } from "./fastConfirmation/types.ts";
3
4
  import { CheckpointWithBalance, CheckpointWithTotalBalance } from "./interface.js";
4
5
  /**
5
6
  * Stores checkpoints in a hybrid format:
@@ -29,7 +30,7 @@ export type JustifiedBalancesGetter = (checkpoint: CheckpointWithHex, blockState
29
30
  * - The actual block DAG in `ProtoArray`.
30
31
  * - `time` is represented using `Slot` instead of UNIX epoch `u64`.
31
32
  */
32
- export interface IForkChoiceStore {
33
+ export interface IForkChoiceStore extends IFastConfirmationStore {
33
34
  currentSlot: Slot;
34
35
  get justified(): CheckpointWithTotalBalance;
35
36
  set justified(justified: CheckpointWithBalance);
@@ -38,6 +39,11 @@ export interface IForkChoiceStore {
38
39
  unrealizedFinalizedCheckpoint: CheckpointWithHex;
39
40
  justifiedBalancesGetter: JustifiedBalancesGetter;
40
41
  equivocatingIndices: Set<ValidatorIndex>;
42
+ notifyFastConfirmation?(data: {
43
+ block: RootHex;
44
+ slot: Slot;
45
+ currentSlot: Slot;
46
+ }): void;
41
47
  }
42
48
  /**
43
49
  * IForkChoiceStore implementer which emits forkChoice events on updated justified and finalized checkpoints.
@@ -51,14 +57,39 @@ export declare class ForkChoiceStore implements IForkChoiceStore {
51
57
  equivocatingIndices: Set<number>;
52
58
  justifiedBalancesGetter: JustifiedBalancesGetter;
53
59
  currentSlot: Slot;
54
- constructor(currentSlot: Slot, justifiedCheckpoint: phase0.Checkpoint, finalizedCheckpoint: phase0.Checkpoint, justifiedBalances: EffectiveBalanceIncrements, justifiedBalancesGetter: JustifiedBalancesGetter, events?: {
60
+ confirmedRoot: RootHex;
61
+ previousEpochObservedJustifiedCheckpoint: CheckpointWithHex;
62
+ currentEpochObservedJustifiedCheckpoint: CheckpointWithHex;
63
+ previousEpochGreatestUnrealizedCheckpoint: CheckpointWithHex;
64
+ previousSlotHead: RootHex;
65
+ currentSlotHead: RootHex;
66
+ previousEpochObservedJustifiedBalances: JustifiedBalances;
67
+ currentEpochObservedJustifiedBalances: JustifiedBalances;
68
+ previousEpochGreatestUnrealizedBalances: JustifiedBalances;
69
+ stateGetter: ForkChoiceStateGetter;
70
+ constructor(currentSlot: Slot, justifiedCheckpoint: phase0.Checkpoint, finalizedCheckpoint: phase0.Checkpoint, justifiedBalances: EffectiveBalanceIncrements, justifiedBalancesGetter: JustifiedBalancesGetter, stateGetter: ForkChoiceStateGetter, events?: {
55
71
  onJustified: (cp: CheckpointWithHex) => void;
56
72
  onFinalized: (cp: CheckpointWithHex) => void;
73
+ onFastConfirmation?: ((data: {
74
+ block: string;
75
+ slot: number;
76
+ currentSlot: number;
77
+ }) => void) | undefined;
57
78
  } | undefined);
58
79
  get justified(): CheckpointWithTotalBalance;
59
80
  set justified(justified: CheckpointWithBalance);
60
81
  get finalizedCheckpoint(): CheckpointWithHex;
61
82
  set finalizedCheckpoint(checkpoint: CheckpointWithHex);
83
+ /**
84
+ * Notify subscribers that the Fast Confirmation Rule executed and produced
85
+ * `data.block` at `data.slot`. Fires once per FCR execution, even when
86
+ * `confirmedRoot` did not change from the prior slot.
87
+ */
88
+ notifyFastConfirmation(data: {
89
+ block: RootHex;
90
+ slot: Slot;
91
+ currentSlot: Slot;
92
+ }): void;
62
93
  }
63
94
  export declare function toCheckpointWithHex(checkpoint: phase0.Checkpoint): CheckpointWithHex;
64
95
  export declare function equalCheckpointWithHex(a: CheckpointWithHex, b: CheckpointWithHex): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/forkChoice/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,0BAA0B,EAAE,gBAAgB,EAAC,MAAM,4BAA4B,CAAC;AACxF,OAAO,EAAC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAC,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAC,qBAAqB,EAAE,0BAA0B,EAAC,MAAM,gBAAgB,CAAC;AAEjF;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,UAAU,GAAG;IAAC,OAAO,EAAE,OAAO,CAAA;CAAC,CAAC;AAEvE,MAAM,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,CACpC,UAAU,EAAE,iBAAiB,EAC7B,UAAU,EAAE,gBAAgB,KACzB,iBAAiB,CAAC;AAEvB;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,IAAI,CAAC;IAClB,IAAI,SAAS,IAAI,0BAA0B,CAAC;IAC5C,IAAI,SAAS,CAAC,SAAS,EAAE,qBAAqB,EAAE;IAChD,mBAAmB,EAAE,qBAAqB,CAAC;IAC3C,mBAAmB,EAAE,iBAAiB,CAAC;IACvC,6BAA6B,EAAE,iBAAiB,CAAC;IACjD,uBAAuB,EAAE,uBAAuB,CAAC;IACjD,mBAAmB,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;CAC1C;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;IAepD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAd1B,OAAO,CAAC,UAAU,CAA6B;IAC/C,mBAAmB,EAAE,qBAAqB,CAAC;IAC3C,OAAO,CAAC,oBAAoB,CAAoB;IAChD,6BAA6B,EAAE,iBAAiB,CAAC;IACjD,mBAAmB,cAA6B;IAChD,uBAAuB,EAAE,uBAAuB,CAAC;IACjD,WAAW,EAAE,IAAI,CAAC;IAElB,YACE,WAAW,EAAE,IAAI,EACjB,mBAAmB,EAAE,MAAM,CAAC,UAAU,EACtC,mBAAmB,EAAE,MAAM,CAAC,UAAU,EACtC,iBAAiB,EAAE,0BAA0B,EAC7C,uBAAuB,EAAE,uBAAuB,EAC/B,MAAM,CAAC;;;iBAGvB,EAaF;IAED,IAAI,SAAS,IAAI,0BAA0B,CAE1C;IACD,IAAI,SAAS,CAAC,SAAS,EAAE,qBAAqB,EAG7C;IAED,IAAI,mBAAmB,IAAI,iBAAiB,CAE3C;IACD,IAAI,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,EAIpD;CACF;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,GAAG,iBAAiB,CASpF;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAE1F;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,0BAA0B,GAAG,MAAM,CAMhF"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/forkChoice/store.ts"],"names":[],"mappings":"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"}
@@ -11,10 +11,23 @@ export class ForkChoiceStore {
11
11
  equivocatingIndices = new Set();
12
12
  justifiedBalancesGetter;
13
13
  currentSlot;
14
- constructor(currentSlot, justifiedCheckpoint, finalizedCheckpoint, justifiedBalances, justifiedBalancesGetter, events) {
14
+ // Fast Confirmation Rule spec fields
15
+ confirmedRoot;
16
+ previousEpochObservedJustifiedCheckpoint;
17
+ currentEpochObservedJustifiedCheckpoint;
18
+ previousEpochGreatestUnrealizedCheckpoint;
19
+ previousSlotHead;
20
+ currentSlotHead;
21
+ // Fast Confirmation Rule internal fields
22
+ previousEpochObservedJustifiedBalances;
23
+ currentEpochObservedJustifiedBalances;
24
+ previousEpochGreatestUnrealizedBalances;
25
+ stateGetter;
26
+ constructor(currentSlot, justifiedCheckpoint, finalizedCheckpoint, justifiedBalances, justifiedBalancesGetter, stateGetter, events) {
15
27
  this.events = events;
16
28
  this.justifiedBalancesGetter = justifiedBalancesGetter;
17
29
  this.currentSlot = currentSlot;
30
+ this.stateGetter = stateGetter;
18
31
  const justified = {
19
32
  checkpoint: toCheckpointWithHex(justifiedCheckpoint),
20
33
  balances: justifiedBalances,
@@ -24,6 +37,21 @@ export class ForkChoiceStore {
24
37
  this.unrealizedJustified = justified;
25
38
  this._finalizedCheckpoint = toCheckpointWithHex(finalizedCheckpoint);
26
39
  this.unrealizedFinalizedCheckpoint = this._finalizedCheckpoint;
40
+ // Initialize Fast Confirmation fields conservatively from finalized, matching
41
+ // the spec's get_fast_confirmation_store() behavior.
42
+ const finalizedCheckpointWithHex = toCheckpointWithHex(finalizedCheckpoint);
43
+ const finalizedState = stateGetter({ checkpoint: finalizedCheckpointWithHex });
44
+ const finalizedBalances = finalizedState?.effectiveBalanceIncrements ?? justifiedBalances;
45
+ const anchorRoot = finalizedCheckpointWithHex.rootHex;
46
+ this.previousEpochObservedJustifiedCheckpoint = finalizedCheckpointWithHex;
47
+ this.currentEpochObservedJustifiedCheckpoint = finalizedCheckpointWithHex;
48
+ this.previousEpochGreatestUnrealizedCheckpoint = finalizedCheckpointWithHex;
49
+ this.confirmedRoot = anchorRoot;
50
+ this.previousEpochObservedJustifiedBalances = finalizedBalances;
51
+ this.currentEpochObservedJustifiedBalances = finalizedBalances;
52
+ this.previousEpochGreatestUnrealizedBalances = finalizedBalances;
53
+ this.previousSlotHead = anchorRoot;
54
+ this.currentSlotHead = anchorRoot;
27
55
  }
28
56
  get justified() {
29
57
  return this._justified;
@@ -40,6 +68,14 @@ export class ForkChoiceStore {
40
68
  this._finalizedCheckpoint = cp;
41
69
  this.events?.onFinalized(cp);
42
70
  }
71
+ /**
72
+ * Notify subscribers that the Fast Confirmation Rule executed and produced
73
+ * `data.block` at `data.slot`. Fires once per FCR execution, even when
74
+ * `confirmedRoot` did not change from the prior slot.
75
+ */
76
+ notifyFastConfirmation(data) {
77
+ this.events?.onFastConfirmation?.(data);
78
+ }
43
79
  }
44
80
  export function toCheckpointWithHex(checkpoint) {
45
81
  // `valueOf` coerses the checkpoint, which may be tree-backed, into a javascript object
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/forkChoice/store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AA8C1C;;GAEG;AACH,MAAM,OAAO,eAAe;IAeP,MAAM;IAdjB,UAAU,CAA6B;IAC/C,mBAAmB,CAAwB;IACnC,oBAAoB,CAAoB;IAChD,6BAA6B,CAAoB;IACjD,mBAAmB,GAAG,IAAI,GAAG,EAAkB,CAAC;IAChD,uBAAuB,CAA0B;IACjD,WAAW,CAAO;IAElB,YACE,WAAiB,EACjB,mBAAsC,EACtC,mBAAsC,EACtC,iBAA6C,EAC7C,uBAAgD,EAC/B,MAGhB,EACD;sBAJiB,MAAM;QAKvB,IAAI,CAAC,uBAAuB,GAAG,uBAAuB,CAAC;QACvD,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,MAAM,SAAS,GAAG;YAChB,UAAU,EAAE,mBAAmB,CAAC,mBAAmB,CAAC;YACpD,QAAQ,EAAE,iBAAiB;YAC3B,YAAY,EAAE,mBAAmB,CAAC,iBAAiB,CAAC;SACrD,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;QACrC,IAAI,CAAC,oBAAoB,GAAG,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;QACrE,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC,oBAAoB,CAAC;IAAA,CAChE;IAED,IAAI,SAAS,GAA+B;QAC1C,OAAO,IAAI,CAAC,UAAU,CAAC;IAAA,CACxB;IACD,IAAI,SAAS,CAAC,SAAgC,EAAE;QAC9C,IAAI,CAAC,UAAU,GAAG,EAAC,GAAG,SAAS,EAAE,YAAY,EAAE,mBAAmB,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAC,CAAC;QACxF,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAAA,CAChD;IAED,IAAI,mBAAmB,GAAsB;QAC3C,OAAO,IAAI,CAAC,oBAAoB,CAAC;IAAA,CAClC;IACD,IAAI,mBAAmB,CAAC,UAA6B,EAAE;QACrD,MAAM,EAAE,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IAAA,CAC9B;CACF;AAED,MAAM,UAAU,mBAAmB,CAAC,UAA6B,EAAqB;IACpF,uFAAuF;IACvF,wDAAwD;IACxD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;IAC7B,OAAO;QACL,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,IAAI;QACJ,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC;KACzB,CAAC;AAAA,CACH;AAED,MAAM,UAAU,sBAAsB,CAAC,CAAoB,EAAE,CAAoB,EAAW;IAC1F,OAAO,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC;AAAA,CACvD;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAoC,EAAU;IAChF,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,YAAY,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,YAAY,CAAC;AAAA,CACrB"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/forkChoice/store.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { ForkChoiceError, ForkChoiceErrorCode, type InvalidAttestation, InvalidAttestationCode, type InvalidBlock, InvalidBlockCode, } from "./forkChoice/errors.js";
2
+ export { type FastConfirmationBalanceSource, type FastConfirmationContext, type FastConfirmationMetrics, type FastConfirmationResult, FastConfirmationRule, type ForkChoiceStateGetter, type IFastConfirmationRule, type IFastConfirmationStore, getFastConfirmationMetrics, } from "./forkChoice/fastConfirmation/fastConfirmationRule.ts";
2
3
  export { ForkChoice, type ForkChoiceOpts, UpdateHeadOpt } from "./forkChoice/forkChoice.js";
3
4
  export { type AncestorResult, AncestorStatus, type CheckpointWithBalance, type CheckpointWithTotalBalance, EpochDifference, type IForkChoice, NotReorgedReason, } from "./forkChoice/interface.js";
4
5
  export * from "./forkChoice/safeBlocks.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,sBAAsB,EACtB,KAAK,YAAY,EACjB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAC,UAAU,EAAE,KAAK,cAAc,EAAE,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EACL,KAAK,cAAc,EACnB,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,eAAe,EACf,KAAK,WAAW,EAChB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,OAAO,EACL,KAAK,iBAAiB,EACtB,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAC,KAAK,iBAAiB,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAC1E,YAAY,EACV,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,SAAS,GACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAC,eAAe,EAAE,aAAa,EAAE,YAAY,EAAC,MAAM,2BAA2B,CAAC;AACvF,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,sBAAsB,EACtB,KAAK,YAAY,EACjB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,oBAAoB,EACpB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,0BAA0B,GAC3B,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAAC,UAAU,EAAE,KAAK,cAAc,EAAE,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EACL,KAAK,cAAc,EACnB,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,eAAe,EACf,KAAK,WAAW,EAChB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,OAAO,EACL,KAAK,iBAAiB,EACtB,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAC,KAAK,iBAAiB,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAC1E,YAAY,EACV,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,SAAS,GACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAC,eAAe,EAAE,aAAa,EAAE,YAAY,EAAC,MAAM,2BAA2B,CAAC;AACvF,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAC"}
package/lib/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { ForkChoiceError, ForkChoiceErrorCode, InvalidAttestationCode, InvalidBlockCode, } from "./forkChoice/errors.js";
2
+ export { FastConfirmationRule, getFastConfirmationMetrics, } from "./forkChoice/fastConfirmation/fastConfirmationRule.js";
2
3
  export { ForkChoice, UpdateHeadOpt } from "./forkChoice/forkChoice.js";
3
4
  export { AncestorStatus, EpochDifference, NotReorgedReason, } from "./forkChoice/interface.js";
4
5
  export * from "./forkChoice/safeBlocks.js";
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EAEnB,sBAAsB,EAEtB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAC,UAAU,EAAuB,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EAEL,cAAc,EAGd,eAAe,EAEf,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,OAAO,EAEL,eAAe,GAGhB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAyB,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAU1E,OAAO,EAAC,eAAe,EAAE,aAAa,EAAE,YAAY,EAAC,MAAM,2BAA2B,CAAC;AACvF,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EAEnB,sBAAsB,EAEtB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAKL,oBAAoB,EAIpB,0BAA0B,GAC3B,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAAC,UAAU,EAAuB,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EAEL,cAAc,EAGd,eAAe,EAEf,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,OAAO,EAEL,eAAe,GAGhB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAyB,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAU1E,OAAO,EAAC,eAAe,EAAE,aAAa,EAAE,YAAY,EAAC,MAAM,2BAA2B,CAAC;AACvF,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAC"}
package/lib/metrics.d.ts CHANGED
@@ -1,8 +1,22 @@
1
1
  import { MetricsRegisterExtra } from "@lodestar/utils";
2
+ import { FastConfirmationMetrics } from "./forkChoice/fastConfirmation/metrics.ts";
2
3
  import { UpdateHeadOpt } from "./forkChoice/forkChoice.js";
3
4
  import { NotReorgedReason } from "./forkChoice/interface.js";
4
- export type ForkChoiceMetrics = ReturnType<typeof getForkChoiceMetrics>;
5
+ export type ForkChoiceMetrics = ReturnType<typeof getForkChoiceMetrics> & FastConfirmationMetrics;
5
6
  export declare function getForkChoiceMetrics(register: MetricsRegisterExtra): {
7
+ fastConfirmation: {
8
+ totalDuration: import("@lodestar/utils").Histogram<import("@lodestar/utils").NoLabels>;
9
+ stepsDuration: import("@lodestar/utils").Histogram<{
10
+ step: import("./forkChoice/fastConfirmation/metrics.ts").FastConfirmationSteps;
11
+ }>;
12
+ confirmedEpoch: import("@lodestar/utils").GaugeExtra<import("@lodestar/utils").NoLabels>;
13
+ votesTracked: import("@lodestar/utils").GaugeExtra<import("@lodestar/utils").NoLabels>;
14
+ resets: import("@lodestar/utils").Counter<import("@lodestar/utils").NoLabels>;
15
+ slot: import("@lodestar/utils").GaugeExtra<import("@lodestar/utils").NoLabels>;
16
+ reorgs: import("@lodestar/utils").Counter<import("@lodestar/utils").NoLabels>;
17
+ fallbacks: import("@lodestar/utils").Counter<import("@lodestar/utils").NoLabels>;
18
+ restarts: import("@lodestar/utils").Counter<import("@lodestar/utils").NoLabels>;
19
+ };
6
20
  forkChoice: {
7
21
  findHead: import("@lodestar/utils").Histogram<{
8
22
  caller: string;
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAC,gBAAgB,EAAC,MAAM,2BAA2B,CAAC;AAE3D,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmGlE"}
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAC,uBAAuB,EAA6B,MAAM,0CAA0C,CAAC;AAC7G,OAAO,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAC,gBAAgB,EAAC,MAAM,2BAA2B,CAAC;AAE3D,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,GAAG,uBAAuB,CAAC;AAElG,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoGlE"}
package/lib/metrics.js CHANGED
@@ -1,5 +1,7 @@
1
+ import { getFastConfirmationMetrics } from "./forkChoice/fastConfirmation/metrics.js";
1
2
  export function getForkChoiceMetrics(register) {
2
3
  return {
4
+ ...getFastConfirmationMetrics(register),
3
5
  forkChoice: {
4
6
  findHead: register.histogram({
5
7
  name: "beacon_fork_choice_find_head_seconds",
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,0BAA0B,EAAC,MAAM,0CAA0C,CAAC;AAM7G,MAAM,UAAU,oBAAoB,CAAC,QAA8B,EAAE;IACnE,OAAO;QACL,GAAG,0BAA0B,CAAC,QAAQ,CAAC;QACvC,UAAU,EAAE;YACV,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAmB;gBAC7C,IAAI,EAAE,sCAAsC;gBAC5C,IAAI,EAAE,oCAAoC;gBAC1C,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrB,UAAU,EAAE,CAAC,QAAQ,CAAC;aACvB,CAAC;YACF,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACvB,IAAI,EAAE,mCAAmC;gBACzC,IAAI,EAAE,+DAA+D;aACtE,CAAC;YACF,MAAM,EAAE,QAAQ,CAAC,KAAK,CAA8B;gBAClD,IAAI,EAAE,iCAAiC;gBACvC,IAAI,EAAE,uFAAuF;gBAC7F,UAAU,EAAE,CAAC,YAAY,CAAC;aAC3B,CAAC;YACF,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC;gBAC1B,IAAI,EAAE,uCAAuC;gBAC7C,IAAI,EAAE,qDAAqD;aAC5D,CAAC;YACF,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACpB,IAAI,EAAE,gCAAgC;gBACtC,IAAI,EAAE,kEAAkE;aACzE,CAAC;YACF,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAC;gBAChC,IAAI,EAAE,mCAAmC;gBACzC,IAAI,EAAE,8BAA8B;gBACpC,yFAAyF;gBACzF,8FAA8F;gBAC9F,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC;aAC9C,CAAC;YACF,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACpB,IAAI,EAAE,gCAAgC;gBACtC,IAAI,EAAE,uDAAuD;aAC9D,CAAC;YACF,kBAAkB,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACjC,IAAI,EAAE,8CAA8C;gBACpD,IAAI,EAAE,sDAAsD;aAC7D,CAAC;YACF,yBAAyB,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACxC,IAAI,EAAE,sDAAsD;gBAC5D,IAAI,EAAE,2EAA2E;aAClF,CAAC;YACF,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC;gBAC7B,IAAI,EAAE,oCAAoC;gBAC1C,IAAI,EAAE,2DAA2D;aAClE,CAAC;YACF,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACpB,IAAI,EAAE,gCAAgC;gBACtC,IAAI,EAAE,uDAAuD;aAC9D,CAAC;YACF,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACtB,IAAI,EAAE,kCAAkC;gBACxC,IAAI,EAAE,yDAAyD;aAChE,CAAC;YACF,gBAAgB,EAAE,QAAQ,CAAC,OAAO,CAA6B;gBAC7D,IAAI,EAAE,6CAA6C;gBACnD,IAAI,EAAE,iDAAiD;gBACvD,UAAU,EAAE,CAAC,QAAQ,CAAC;aACvB,CAAC;YACF,aAAa,EAAE;gBACb,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC;oBAC3B,IAAI,EAAE,2CAA2C;oBACjD,IAAI,EAAE,yCAAyC;oBAC/C,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;iBAChC,CAAC;gBACF,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC;oBAC1B,IAAI,EAAE,gDAAgD;oBACtD,IAAI,EAAE,0BAA0B;iBACjC,CAAC;gBACF,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC;oBAC9B,IAAI,EAAE,qDAAqD;oBAC3D,IAAI,EAAE,gCAAgC;iBACvC,CAAC;gBACF,sBAAsB,EAAE,QAAQ,CAAC,KAAK,CAAC;oBACrC,IAAI,EAAE,iEAAiE;oBACvE,IAAI,EAAE,4CAA4C;iBACnD,CAAC;gBACF,qBAAqB,EAAE,QAAQ,CAAC,KAAK,CAAC;oBACpC,IAAI,EAAE,iEAAiE;oBACvE,IAAI,EAAE,4CAA4C;iBACnD,CAAC;gBACF,qBAAqB,EAAE,QAAQ,CAAC,KAAK,CAAC;oBACpC,IAAI,EAAE,iEAAiE;oBACvE,IAAI,EAAE,4CAA4C;iBACnD,CAAC;gBACF,uBAAuB,EAAE,QAAQ,CAAC,KAAK,CAAC;oBACtC,IAAI,EAAE,mEAAmE;oBACzE,IAAI,EAAE,8CAA8C;iBACrD,CAAC;gBACF,iBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC;oBAChC,IAAI,EAAE,6DAA6D;oBACnE,IAAI,EAAE,wCAAwC;iBAC/C,CAAC;aACH;SACF;KACF,CAAC;AAAA,CACH"}
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.44.0-dev.4ac6f45830",
14
+ "version": "1.44.0-dev.4b91ba8c2f",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
@@ -40,11 +40,11 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@chainsafe/ssz": "^1.4.0",
43
- "@lodestar/config": "^1.44.0-dev.4ac6f45830",
44
- "@lodestar/params": "^1.44.0-dev.4ac6f45830",
45
- "@lodestar/state-transition": "^1.44.0-dev.4ac6f45830",
46
- "@lodestar/types": "^1.44.0-dev.4ac6f45830",
47
- "@lodestar/utils": "^1.44.0-dev.4ac6f45830"
43
+ "@lodestar/config": "^1.44.0-dev.4b91ba8c2f",
44
+ "@lodestar/params": "^1.44.0-dev.4b91ba8c2f",
45
+ "@lodestar/state-transition": "^1.44.0-dev.4b91ba8c2f",
46
+ "@lodestar/types": "^1.44.0-dev.4b91ba8c2f",
47
+ "@lodestar/utils": "^1.44.0-dev.4b91ba8c2f"
48
48
  },
49
49
  "keywords": [
50
50
  "ethereum",
@@ -52,5 +52,5 @@
52
52
  "beacon",
53
53
  "blockchain"
54
54
  ],
55
- "gitHead": "af6656f7c372f4c0f17fc3c92d6143e6cee1d084"
55
+ "gitHead": "94480c8e538894b5d438e638e7ba5040a9b35bf8"
56
56
  }
@@ -0,0 +1,43 @@
1
+ import {computeEpochAtSlot} from "@lodestar/state-transition";
2
+ import {
3
+ FastConfirmationCache,
4
+ FastConfirmationContext,
5
+ FastConfirmationSnapshot,
6
+ IFastConfirmationStore,
7
+ } from "./types.ts";
8
+ import {getBlock, getUnrealizedJustification} from "./utils.ts";
9
+
10
+ export function createFastConfirmationCache(): FastConfirmationCache {
11
+ return {
12
+ blockByRoot: new Map(),
13
+ ancestorRoots: new Map(),
14
+ committeeBySlot: new Map(),
15
+ isDescendantByRootPair: new Map(),
16
+ voteWeightBySource: new Map(),
17
+ checkpointStateByKey: new Map(),
18
+ };
19
+ }
20
+
21
+ export function buildFastConfirmationSnapshot(
22
+ ctx: FastConfirmationContext,
23
+ store: IFastConfirmationStore,
24
+ cache: FastConfirmationCache
25
+ ): FastConfirmationSnapshot {
26
+ const currentSlot = ctx.getCurrentSlot();
27
+ const currentEpoch = computeEpochAtSlot(currentSlot);
28
+ const headRoot = ctx.getHead().blockRoot;
29
+ const confirmedRoot = store.confirmedRoot;
30
+ const confirmedBlock = getBlock(ctx, cache, confirmedRoot);
31
+
32
+ return {
33
+ currentSlot,
34
+ currentEpoch,
35
+ headRoot,
36
+ confirmedRoot,
37
+ confirmedEpoch: confirmedBlock ? computeEpochAtSlot(confirmedBlock.slot) : null,
38
+ confirmedSlot: confirmedBlock?.slot ?? null,
39
+ observedJustified: store.currentEpochObservedJustifiedCheckpoint,
40
+ headUnrealized: getUnrealizedJustification(ctx, cache, headRoot),
41
+ finalizedRoot: ctx.getFinalizedCheckpoint().rootHex,
42
+ };
43
+ }
@@ -0,0 +1,173 @@
1
+ import {computeEpochAtSlot, isStartSlotOfEpoch} from "@lodestar/state-transition";
2
+ import {RootHex} from "@lodestar/types";
3
+ import {Logger, withObservedDuration} from "@lodestar/utils";
4
+ import {buildFastConfirmationSnapshot, createFastConfirmationCache} from "./data.ts";
5
+ import {FastConfirmationMetrics, FastConfirmationSteps} from "./metrics.ts";
6
+ import {runFastConfirmationRules} from "./rules.ts";
7
+ import {
8
+ FastConfirmationContext,
9
+ FastConfirmationResult,
10
+ FastConfirmationRunResult,
11
+ IFastConfirmationRule,
12
+ IFastConfirmationStore,
13
+ } from "./types.ts";
14
+
15
+ export * from "./metrics.ts";
16
+ export * from "./types.ts";
17
+
18
+ export class FastConfirmationRule implements IFastConfirmationRule {
19
+ constructor(
20
+ private readonly store: IFastConfirmationStore,
21
+ readonly metrics: FastConfirmationMetrics | null,
22
+ readonly logger?: Logger
23
+ ) {}
24
+
25
+ getConfirmedRoot(): RootHex {
26
+ return this.store.confirmedRoot;
27
+ }
28
+
29
+ onSlotStartAfterPastAttestationsApplied(ctx: FastConfirmationContext): FastConfirmationResult {
30
+ const currentSlot = ctx.getCurrentSlot();
31
+ const previousConfirmedRoot = this.store.confirmedRoot;
32
+
33
+ this.logger?.debug("Running fast confirmation rule", {
34
+ slot: currentSlot,
35
+ epoch: computeEpochAtSlot(currentSlot),
36
+ });
37
+ this.updateFastConfirmationVariables(ctx);
38
+
39
+ const cache = withObservedDuration(
40
+ this.metrics?.fastConfirmation.stepsDuration.startTimer({
41
+ step: FastConfirmationSteps.buildCache,
42
+ }),
43
+ createFastConfirmationCache
44
+ );
45
+
46
+ const snapshot = withObservedDuration(
47
+ this.metrics?.fastConfirmation.stepsDuration.startTimer({
48
+ step: FastConfirmationSteps.buildSnapshot,
49
+ }),
50
+ () => buildFastConfirmationSnapshot(ctx, this.store, cache)
51
+ );
52
+
53
+ this.logger?.verbose("Built fast confirmation snapshot", {
54
+ confirmedSlot: snapshot.confirmedSlot,
55
+ confirmedEpoch: snapshot.confirmedEpoch,
56
+ confirmedRoot: snapshot.confirmedRoot,
57
+ headRoot: snapshot.headRoot,
58
+ finalizedRoot: snapshot.finalizedRoot,
59
+ headUnrealizedRoot: snapshot.headUnrealized?.rootHex,
60
+ headUnrealizedEpoch: snapshot.headUnrealized?.epoch,
61
+ observedJustifiedRoot: snapshot.observedJustified.rootHex,
62
+ observedJustifiedEpoch: snapshot.observedJustified.epoch,
63
+ });
64
+
65
+ const {confirmedRoot, didReset, reason, resetReason, didReorg, didFallback, didRestart} = withObservedDuration(
66
+ this.metrics?.fastConfirmation.stepsDuration.startTimer({step: FastConfirmationSteps.runRules}),
67
+ () => runFastConfirmationRules(snapshot, ctx, this.store, cache, this.logger)
68
+ );
69
+
70
+ const changed = confirmedRoot !== previousConfirmedRoot;
71
+ const confirmedBlock = cache.blockByRoot.get(confirmedRoot) ?? null;
72
+ const confirmedSlot = confirmedBlock?.slot ?? null;
73
+ const confirmedEpoch = confirmedBlock ? computeEpochAtSlot(confirmedBlock.slot) : null;
74
+ const logContext = {
75
+ previousConfirmedRoot,
76
+ confirmedRoot,
77
+ changed,
78
+ didReset,
79
+ reason,
80
+ resetReason,
81
+ confirmedSlot,
82
+ confirmedEpoch,
83
+ };
84
+
85
+ if (changed) {
86
+ if (didReset) {
87
+ this.logger?.warn("Reset fast confirmation", logContext);
88
+ } else {
89
+ this.logger?.debug("Updated fast confirmation", logContext);
90
+ }
91
+ } else {
92
+ this.logger?.debug("Unchanged fast confirmation", logContext);
93
+ }
94
+
95
+ this.store.confirmedRoot = confirmedRoot;
96
+ this.updateFastConfirmationMetrics(ctx, {confirmedRoot, didReset, didReorg, didFallback, didRestart});
97
+
98
+ return {confirmedRoot, didReset};
99
+ }
100
+
101
+ private updateFastConfirmationVariables(ctx: FastConfirmationContext): void {
102
+ const previousSlotHead = this.store.currentSlotHead;
103
+ const currentSlotHead = ctx.getHead().blockRoot;
104
+ const currentSlot = ctx.getCurrentSlot();
105
+ const isStartSlotOfCurrentEpoch = isStartSlotOfEpoch(currentSlot);
106
+ const isLastSlotOfCurrentEpoch = isStartSlotOfEpoch(currentSlot + 1);
107
+
108
+ this.store.previousSlotHead = previousSlotHead;
109
+ this.store.currentSlotHead = currentSlotHead;
110
+
111
+ this.logger?.verbose("Updating fast confirmation variables", {
112
+ previousSlotHead,
113
+ currentSlotHead,
114
+ currentSlot,
115
+ isStartSlotOfCurrentEpoch,
116
+ isLastSlotOfCurrentEpoch,
117
+ });
118
+
119
+ // Spec step 1: freeze the greatest unrealized justified checkpoint at the
120
+ // last slot of the epoch so the next epoch consumes a stable snapshot.
121
+ if (isLastSlotOfCurrentEpoch) {
122
+ const unrealized = ctx.getUnrealizedJustified();
123
+ this.store.previousEpochGreatestUnrealizedCheckpoint = unrealized.checkpoint;
124
+ this.store.previousEpochGreatestUnrealizedBalances = unrealized.balances;
125
+
126
+ this.logger?.verbose("Updated fast confirmation greatest unrealized snapshot", {
127
+ previousEpochGreatestUnrealizedCheckpointRoot: this.store.previousEpochGreatestUnrealizedCheckpoint.rootHex,
128
+ previousEpochGreatestUnrealizedCheckpointEpoch: this.store.previousEpochGreatestUnrealizedCheckpoint.epoch,
129
+ });
130
+ }
131
+
132
+ // Spec step 2: rotate observed justified checkpoints at the first slot of
133
+ // the new epoch using the snapshot taken at the end of the previous epoch.
134
+ if (isStartSlotOfCurrentEpoch) {
135
+ this.store.previousEpochObservedJustifiedCheckpoint = this.store.currentEpochObservedJustifiedCheckpoint;
136
+ this.store.previousEpochObservedJustifiedBalances = this.store.currentEpochObservedJustifiedBalances;
137
+ this.store.currentEpochObservedJustifiedCheckpoint = this.store.previousEpochGreatestUnrealizedCheckpoint;
138
+ this.store.currentEpochObservedJustifiedBalances = this.store.previousEpochGreatestUnrealizedBalances;
139
+
140
+ this.logger?.verbose("Updated fast confirmation observed justified checkpoints", {
141
+ previousEpochObservedJustifiedCheckpointRoot: this.store.previousEpochObservedJustifiedCheckpoint.rootHex,
142
+ previousEpochObservedJustifiedCheckpointEpoch: this.store.previousEpochObservedJustifiedCheckpoint.epoch,
143
+ currentEpochObservedJustifiedCheckpointRoot: this.store.currentEpochObservedJustifiedCheckpoint.rootHex,
144
+ currentEpochObservedJustifiedCheckpointEpoch: this.store.currentEpochObservedJustifiedCheckpoint.epoch,
145
+ });
146
+ }
147
+ }
148
+
149
+ private updateFastConfirmationMetrics(
150
+ ctx: FastConfirmationContext,
151
+ result: Omit<FastConfirmationRunResult, "reason" | "resetReason">
152
+ ): void {
153
+ if (!this.metrics) return;
154
+ const confirmedBlock = ctx.getBlock(result.confirmedRoot);
155
+ if (confirmedBlock) {
156
+ this.metrics.fastConfirmation.confirmedEpoch.set(computeEpochAtSlot(confirmedBlock.slot));
157
+ this.metrics.fastConfirmation.slot.set(confirmedBlock.slot);
158
+ }
159
+ if (result.didReset) {
160
+ this.metrics.fastConfirmation.resets.inc();
161
+ }
162
+ if (result.didReorg) {
163
+ this.metrics.fastConfirmation.reorgs.inc();
164
+ }
165
+ if (result.didFallback) {
166
+ this.metrics.fastConfirmation.fallbacks.inc();
167
+ }
168
+ if (result.didRestart) {
169
+ this.metrics.fastConfirmation.restarts.inc();
170
+ }
171
+ this.metrics.fastConfirmation.votesTracked.set(ctx.getTrackedVotesCount());
172
+ }
173
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./fastConfirmationRule.ts";
2
+ export * from "./metrics.ts";
3
+ export * from "./types.ts";
@@ -0,0 +1,57 @@
1
+ import {MetricsRegisterExtra} from "@lodestar/utils";
2
+
3
+ export type FastConfirmationMetrics = ReturnType<typeof getFastConfirmationMetrics>;
4
+
5
+ export enum FastConfirmationSteps {
6
+ updateHead = "updateHead",
7
+ buildCache = "buildCache",
8
+ buildSnapshot = "buildSnapshot",
9
+ runRules = "runRules",
10
+ }
11
+
12
+ export function getFastConfirmationMetrics(register: MetricsRegisterExtra) {
13
+ return {
14
+ fastConfirmation: {
15
+ totalDuration: register.histogram({
16
+ name: "lodestar_fast_confirmation_duration_seconds",
17
+ help: "Time to run Fast Confirmation Rule algorithm",
18
+ buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 2],
19
+ }),
20
+ stepsDuration: register.histogram<{step: FastConfirmationSteps}>({
21
+ name: "lodestar_fast_confirmation_steps_duration_seconds",
22
+ help: "Time to run Fast Confirmation Steps",
23
+ buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 2],
24
+ labelNames: ["step"],
25
+ }),
26
+ confirmedEpoch: register.gauge({
27
+ name: "lodestar_fast_confirmation_confirmed_epoch",
28
+ help: "Current confirmed epoch from fast confirmation",
29
+ }),
30
+ votesTracked: register.gauge({
31
+ name: "lodestar_fast_confirmation_votes_tracked",
32
+ help: "Number of checkpoint votes tracked by fast confirmation",
33
+ }),
34
+ resets: register.counter({
35
+ name: "lodestar_fast_confirmation_resets_total",
36
+ help: "Total number of fast confirmation resets (any cause)",
37
+ }),
38
+ // Standardized Fast Confirmation metrics
39
+ slot: register.gauge({
40
+ name: "beacon_fast_confirmation_slot",
41
+ help: "Slot of the most recent confirmed block",
42
+ }),
43
+ reorgs: register.counter({
44
+ name: "beacon_fast_confirmation_reorgs_total",
45
+ help: "Total number of confirmed block reorganizations",
46
+ }),
47
+ fallbacks: register.counter({
48
+ name: "beacon_fast_confirmation_fallbacks_total",
49
+ help: "Total number of fallbacks to finality",
50
+ }),
51
+ restarts: register.counter({
52
+ name: "beacon_fast_confirmation_restarts_total",
53
+ help: "Total number of restarts from a safe unrealized justified block",
54
+ }),
55
+ },
56
+ };
57
+ }