@lodestar/state-transition 1.43.0 → 1.44.0-dev.00facd40a8

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 (95) hide show
  1. package/lib/block/processDepositRequest.d.ts +3 -11
  2. package/lib/block/processDepositRequest.d.ts.map +1 -1
  3. package/lib/block/processDepositRequest.js +27 -35
  4. package/lib/block/processDepositRequest.js.map +1 -1
  5. package/lib/block/processParentExecutionPayload.d.ts.map +1 -1
  6. package/lib/block/processParentExecutionPayload.js +4 -3
  7. package/lib/block/processParentExecutionPayload.js.map +1 -1
  8. package/lib/cache/epochCache.d.ts.map +1 -1
  9. package/lib/cache/epochCache.js +10 -7
  10. package/lib/cache/epochCache.js.map +1 -1
  11. package/lib/epoch/processProposerLookahead.d.ts.map +1 -1
  12. package/lib/epoch/processProposerLookahead.js +7 -2
  13. package/lib/epoch/processProposerLookahead.js.map +1 -1
  14. package/lib/lightClient/spec/index.d.ts +22 -0
  15. package/lib/lightClient/spec/index.d.ts.map +1 -0
  16. package/lib/lightClient/spec/index.js +58 -0
  17. package/lib/lightClient/spec/index.js.map +1 -0
  18. package/lib/lightClient/spec/isBetterUpdate.d.ts +23 -0
  19. package/lib/lightClient/spec/isBetterUpdate.d.ts.map +1 -0
  20. package/lib/lightClient/spec/isBetterUpdate.js +66 -0
  21. package/lib/lightClient/spec/isBetterUpdate.js.map +1 -0
  22. package/lib/lightClient/spec/processLightClientUpdate.d.ts +12 -0
  23. package/lib/lightClient/spec/processLightClientUpdate.d.ts.map +1 -0
  24. package/lib/lightClient/spec/processLightClientUpdate.js +80 -0
  25. package/lib/lightClient/spec/processLightClientUpdate.js.map +1 -0
  26. package/lib/lightClient/spec/store.d.ts +45 -0
  27. package/lib/lightClient/spec/store.d.ts.map +1 -0
  28. package/lib/lightClient/spec/store.js +56 -0
  29. package/lib/lightClient/spec/store.js.map +1 -0
  30. package/lib/lightClient/spec/utils.d.ts +47 -0
  31. package/lib/lightClient/spec/utils.d.ts.map +1 -0
  32. package/lib/lightClient/spec/utils.js +197 -0
  33. package/lib/lightClient/spec/utils.js.map +1 -0
  34. package/lib/lightClient/spec/validateLightClientBootstrap.d.ts +4 -0
  35. package/lib/lightClient/spec/validateLightClientBootstrap.d.ts.map +1 -0
  36. package/lib/lightClient/spec/validateLightClientBootstrap.js +22 -0
  37. package/lib/lightClient/spec/validateLightClientBootstrap.js.map +1 -0
  38. package/lib/lightClient/spec/validateLightClientUpdate.d.ts +5 -0
  39. package/lib/lightClient/spec/validateLightClientUpdate.d.ts.map +1 -0
  40. package/lib/lightClient/spec/validateLightClientUpdate.js +88 -0
  41. package/lib/lightClient/spec/validateLightClientUpdate.js.map +1 -0
  42. package/lib/slot/upgradeStateToGloas.d.ts.map +1 -1
  43. package/lib/slot/upgradeStateToGloas.js +35 -29
  44. package/lib/slot/upgradeStateToGloas.js.map +1 -1
  45. package/lib/stateView/beaconStateView.d.ts +9 -3
  46. package/lib/stateView/beaconStateView.d.ts.map +1 -1
  47. package/lib/stateView/beaconStateView.js +23 -4
  48. package/lib/stateView/beaconStateView.js.map +1 -1
  49. package/lib/stateView/interface.d.ts +27 -1
  50. package/lib/stateView/interface.d.ts.map +1 -1
  51. package/lib/stateView/interface.js.map +1 -1
  52. package/lib/stateView/nativeBeaconStateView.d.ts +226 -0
  53. package/lib/stateView/nativeBeaconStateView.d.ts.map +1 -0
  54. package/lib/stateView/nativeBeaconStateView.js +698 -0
  55. package/lib/stateView/nativeBeaconStateView.js.map +1 -0
  56. package/lib/stateView/stateViewFactory.d.ts.map +1 -1
  57. package/lib/stateView/stateViewFactory.js +2 -0
  58. package/lib/stateView/stateViewFactory.js.map +1 -1
  59. package/lib/util/gloas.d.ts +14 -0
  60. package/lib/util/gloas.d.ts.map +1 -1
  61. package/lib/util/gloas.js +24 -0
  62. package/lib/util/gloas.js.map +1 -1
  63. package/lib/util/index.d.ts +1 -0
  64. package/lib/util/index.d.ts.map +1 -1
  65. package/lib/util/index.js +1 -0
  66. package/lib/util/index.js.map +1 -1
  67. package/lib/util/pendingDepositsLookup.d.ts +40 -0
  68. package/lib/util/pendingDepositsLookup.d.ts.map +1 -0
  69. package/lib/util/pendingDepositsLookup.js +84 -0
  70. package/lib/util/pendingDepositsLookup.js.map +1 -0
  71. package/lib/util/shuffling.d.ts +6 -5
  72. package/lib/util/shuffling.d.ts.map +1 -1
  73. package/lib/util/shuffling.js +13 -15
  74. package/lib/util/shuffling.js.map +1 -1
  75. package/package.json +12 -7
  76. package/src/block/processDepositRequest.ts +29 -47
  77. package/src/block/processParentExecutionPayload.ts +4 -3
  78. package/src/cache/epochCache.ts +10 -7
  79. package/src/epoch/processProposerLookahead.ts +8 -1
  80. package/src/lightClient/spec/index.ts +101 -0
  81. package/src/lightClient/spec/isBetterUpdate.ts +94 -0
  82. package/src/lightClient/spec/processLightClientUpdate.ts +119 -0
  83. package/src/lightClient/spec/store.ts +106 -0
  84. package/src/lightClient/spec/utils.ts +317 -0
  85. package/src/lightClient/spec/validateLightClientBootstrap.ts +39 -0
  86. package/src/lightClient/spec/validateLightClientUpdate.ts +145 -0
  87. package/src/slot/upgradeStateToGloas.ts +43 -45
  88. package/src/stateView/beaconStateView.ts +23 -4
  89. package/src/stateView/interface.ts +31 -1
  90. package/src/stateView/nativeBeaconStateView.ts +893 -0
  91. package/src/stateView/stateViewFactory.ts +2 -0
  92. package/src/util/gloas.ts +28 -0
  93. package/src/util/index.ts +1 -0
  94. package/src/util/pendingDepositsLookup.ts +105 -0
  95. package/src/util/shuffling.ts +17 -15
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isBetterUpdate.js","sourceRoot":"","sources":["../../../src/lightClient/spec/isBetterUpdate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { ChainForkConfig } from "@lodestar/config";
2
+ import { LightClientUpdate, Slot, SyncPeriod } from "@lodestar/types";
3
+ import { LightClientUpdateSummary } from "./isBetterUpdate.js";
4
+ import { type ILightClientStore, type SyncCommitteeFast } from "./store.js";
5
+ export interface ProcessUpdateOpts {
6
+ allowForcedUpdates?: boolean;
7
+ updateHeadersOnForcedUpdate?: boolean;
8
+ }
9
+ export declare function processLightClientUpdate(config: ChainForkConfig, store: ILightClientStore, currentSlot: Slot, opts: ProcessUpdateOpts, update: LightClientUpdate): void;
10
+ export declare function getSyncCommitteeAtPeriod(store: ILightClientStore, period: SyncPeriod, opts: ProcessUpdateOpts): SyncCommitteeFast;
11
+ export declare function isSafeLightClientUpdate(update: LightClientUpdateSummary): boolean;
12
+ //# sourceMappingURL=processLightClientUpdate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processLightClientUpdate.d.ts","sourceRoot":"","sources":["../../../src/lightClient/spec/processLightClientUpdate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAC,iBAAiB,EAAE,IAAI,EAAE,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EAAC,wBAAwB,EAA6C,MAAM,qBAAqB,CAAC;AACzG,OAAO,EAAC,KAAK,iBAAiB,EAA0B,KAAK,iBAAiB,EAAC,MAAM,YAAY,CAAC;AAIlG,MAAM,WAAW,iBAAiB;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,iBAAiB,EACxB,WAAW,EAAE,IAAI,EACjB,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,iBAAiB,GACxB,IAAI,CA8CN;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,iBAAiB,GACtB,iBAAiB,CAuCnB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAIjF"}
@@ -0,0 +1,80 @@
1
+ import { SYNC_COMMITTEE_SIZE } from "@lodestar/params";
2
+ import { pruneSetToMax } from "@lodestar/utils";
3
+ import { computeSyncPeriodAtSlot } from "../../util/epoch.js";
4
+ import { isBetterUpdate, toLightClientUpdateSummary } from "./isBetterUpdate.js";
5
+ import { MAX_SYNC_PERIODS_CACHE } from "./store.js";
6
+ import { deserializeSyncCommittee, getSafetyThreshold, isSyncCommitteeUpdate, sumBits } from "./utils.js";
7
+ import { validateLightClientUpdate } from "./validateLightClientUpdate.js";
8
+ export function processLightClientUpdate(config, store, currentSlot, opts, update) {
9
+ if (update.signatureSlot > currentSlot) {
10
+ throw Error(`update slot ${update.signatureSlot} must not be in the future, current slot ${currentSlot}`);
11
+ }
12
+ const updateSignaturePeriod = computeSyncPeriodAtSlot(update.signatureSlot);
13
+ // TODO: Consider attempting to retrieve LightClientUpdate from transport if missing
14
+ // Note: store.getSyncCommitteeAtPeriod() may advance store
15
+ const syncCommittee = getSyncCommitteeAtPeriod(store, updateSignaturePeriod, opts);
16
+ validateLightClientUpdate(config, store, update, syncCommittee);
17
+ // Track the maximum number of active participants in the committee signatures
18
+ const syncCommitteeTrueBits = sumBits(update.syncAggregate.syncCommitteeBits);
19
+ store.setActiveParticipants(updateSignaturePeriod, syncCommitteeTrueBits);
20
+ // Update the optimistic header
21
+ if (syncCommitteeTrueBits > getSafetyThreshold(store.getMaxActiveParticipants(updateSignaturePeriod)) &&
22
+ update.attestedHeader.beacon.slot > store.optimisticHeader.beacon.slot) {
23
+ store.optimisticHeader = update.attestedHeader;
24
+ }
25
+ // Update finalized header
26
+ if (syncCommitteeTrueBits * 3 >= SYNC_COMMITTEE_SIZE * 2 &&
27
+ update.finalizedHeader.beacon.slot > store.finalizedHeader.beacon.slot) {
28
+ store.finalizedHeader = update.finalizedHeader;
29
+ if (store.finalizedHeader.beacon.slot > store.optimisticHeader.beacon.slot) {
30
+ store.optimisticHeader = store.finalizedHeader;
31
+ }
32
+ }
33
+ if (isSyncCommitteeUpdate(update)) {
34
+ // Update the best update in case we have to force-update to it if the timeout elapses
35
+ const bestValidUpdate = store.bestValidUpdates.get(updateSignaturePeriod);
36
+ const updateSummary = toLightClientUpdateSummary(update);
37
+ if (!bestValidUpdate || isBetterUpdate(updateSummary, bestValidUpdate.summary)) {
38
+ store.bestValidUpdates.set(updateSignaturePeriod, { update, summary: updateSummary });
39
+ pruneSetToMax(store.bestValidUpdates, MAX_SYNC_PERIODS_CACHE);
40
+ }
41
+ // Note: defer update next sync committee to a future getSyncCommitteeAtPeriod() call
42
+ }
43
+ }
44
+ export function getSyncCommitteeAtPeriod(store, period, opts) {
45
+ const syncCommittee = store.syncCommittees.get(period);
46
+ if (syncCommittee) {
47
+ return syncCommittee;
48
+ }
49
+ const bestValidUpdate = store.bestValidUpdates.get(period - 1);
50
+ if (bestValidUpdate && (isSafeLightClientUpdate(bestValidUpdate.summary) || opts.allowForcedUpdates)) {
51
+ const { update } = bestValidUpdate;
52
+ const syncCommittee = deserializeSyncCommittee(update.nextSyncCommittee);
53
+ store.syncCommittees.set(period, syncCommittee);
54
+ pruneSetToMax(store.syncCommittees, MAX_SYNC_PERIODS_CACHE);
55
+ store.bestValidUpdates.delete(period - 1);
56
+ if (opts.updateHeadersOnForcedUpdate) {
57
+ // From https://github.com/ethereum/consensus-specs/blob/a57e15636013eeba3610ff3ade41781dba1bb0cd/specs/altair/light-client/sync-protocol.md?plain=1#L403
58
+ if (update.finalizedHeader.beacon.slot <= store.finalizedHeader.beacon.slot) {
59
+ update.finalizedHeader = update.attestedHeader;
60
+ }
61
+ // From https://github.com/ethereum/consensus-specs/blob/a57e15636013eeba3610ff3ade41781dba1bb0cd/specs/altair/light-client/sync-protocol.md?plain=1#L374
62
+ if (update.finalizedHeader.beacon.slot > store.finalizedHeader.beacon.slot) {
63
+ store.finalizedHeader = update.finalizedHeader;
64
+ }
65
+ if (store.finalizedHeader.beacon.slot > store.optimisticHeader.beacon.slot) {
66
+ store.optimisticHeader = store.finalizedHeader;
67
+ }
68
+ }
69
+ return syncCommittee;
70
+ }
71
+ const availableSyncCommittees = Array.from(store.syncCommittees.keys());
72
+ const availableBestValidUpdates = Array.from(store.bestValidUpdates.keys());
73
+ throw Error(`No SyncCommittee for period ${period}` +
74
+ ` available syncCommittees ${JSON.stringify(availableSyncCommittees)}` +
75
+ ` available bestValidUpdates ${JSON.stringify(availableBestValidUpdates)}`);
76
+ }
77
+ export function isSafeLightClientUpdate(update) {
78
+ return (update.activeParticipants * 3 >= SYNC_COMMITTEE_SIZE * 2 && update.isFinalityUpdate && update.isSyncCommitteeUpdate);
79
+ }
80
+ //# sourceMappingURL=processLightClientUpdate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processLightClientUpdate.js","sourceRoot":"","sources":["../../../src/lightClient/spec/processLightClientUpdate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { PublicKey } from "@chainsafe/blst";
2
+ import { BeaconConfig } from "@lodestar/config";
3
+ import { LightClientBootstrap, LightClientHeader, LightClientUpdate, SyncPeriod } from "@lodestar/types";
4
+ import type { LightClientUpdateSummary } from "./isBetterUpdate.js";
5
+ export declare const MAX_SYNC_PERIODS_CACHE = 2;
6
+ export interface ILightClientStore {
7
+ readonly config: BeaconConfig;
8
+ /** Map of trusted SyncCommittee to be used for sig validation */
9
+ readonly syncCommittees: Map<SyncPeriod, SyncCommitteeFast>;
10
+ /** Map of best valid updates */
11
+ readonly bestValidUpdates: Map<SyncPeriod, LightClientUpdateWithSummary>;
12
+ getMaxActiveParticipants(period: SyncPeriod): number;
13
+ setActiveParticipants(period: SyncPeriod, activeParticipants: number): void;
14
+ finalizedHeader: LightClientHeader;
15
+ optimisticHeader: LightClientHeader;
16
+ }
17
+ export interface LightClientStoreEvents {
18
+ onSetFinalizedHeader?: (header: LightClientHeader) => void;
19
+ onSetOptimisticHeader?: (header: LightClientHeader) => void;
20
+ }
21
+ export declare class LightClientStore implements ILightClientStore {
22
+ readonly config: BeaconConfig;
23
+ private readonly events;
24
+ readonly syncCommittees: Map<number, SyncCommitteeFast>;
25
+ readonly bestValidUpdates: Map<number, LightClientUpdateWithSummary>;
26
+ private finalizedHeaderValue;
27
+ private optimisticHeaderValue;
28
+ private readonly maxActiveParticipants;
29
+ constructor(config: BeaconConfig, bootstrap: LightClientBootstrap, events: LightClientStoreEvents);
30
+ get finalizedHeader(): LightClientHeader;
31
+ set finalizedHeader(value: LightClientHeader);
32
+ get optimisticHeader(): LightClientHeader;
33
+ set optimisticHeader(value: LightClientHeader);
34
+ getMaxActiveParticipants(period: SyncPeriod): number;
35
+ setActiveParticipants(period: SyncPeriod, activeParticipants: number): void;
36
+ }
37
+ export type SyncCommitteeFast = {
38
+ pubkeys: PublicKey[];
39
+ aggregatePubkey: PublicKey;
40
+ };
41
+ export type LightClientUpdateWithSummary = {
42
+ update: LightClientUpdate;
43
+ summary: LightClientUpdateSummary;
44
+ };
45
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/lightClient/spec/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAC,oBAAoB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAEvG,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,qBAAqB,CAAC;AAGlE,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAE9B,iEAAiE;IACjE,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IAC5D,gCAAgC;IAChC,QAAQ,CAAC,gBAAgB,EAAE,GAAG,CAAC,UAAU,EAAE,4BAA4B,CAAC,CAAC;IAEzE,wBAAwB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;IACrD,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAG5E,eAAe,EAAE,iBAAiB,CAAC;IAGnC,gBAAgB,EAAE,iBAAiB,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACrC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC3D,qBAAqB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC7D;AAED,qBAAa,gBAAiB,YAAW,iBAAiB;IAUtD,QAAQ,CAAC,MAAM,EAAE,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAXzB,QAAQ,CAAC,cAAc,iCAA4C;IACnE,QAAQ,CAAC,gBAAgB,4CAAuD;IAEhF,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,qBAAqB,CAAoB;IAEjD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiC;IAEvE,YACW,MAAM,EAAE,YAAY,EAC7B,SAAS,EAAE,oBAAoB,EACd,MAAM,EAAE,sBAAsB,EAMhD;IAED,IAAI,eAAe,IAAI,iBAAiB,CAEvC;IAED,IAAI,eAAe,CAAC,KAAK,EAAE,iBAAiB,EAG3C;IAED,IAAI,gBAAgB,IAAI,iBAAiB,CAExC;IAED,IAAI,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,EAG5C;IAED,wBAAwB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAKnD;IAED,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAY1E;CACF;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,eAAe,EAAE,SAAS,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,wBAAwB,CAAC;CACnC,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { computeSyncPeriodAtSlot } from "../../util/epoch.js";
2
+ import { deserializeSyncCommittee } from "./utils.js";
3
+ export const MAX_SYNC_PERIODS_CACHE = 2;
4
+ export class LightClientStore {
5
+ config;
6
+ events;
7
+ syncCommittees = new Map();
8
+ bestValidUpdates = new Map();
9
+ finalizedHeaderValue;
10
+ optimisticHeaderValue;
11
+ maxActiveParticipants = new Map();
12
+ constructor(config, bootstrap, events) {
13
+ this.config = config;
14
+ this.events = events;
15
+ const bootstrapPeriod = computeSyncPeriodAtSlot(bootstrap.header.beacon.slot);
16
+ this.syncCommittees.set(bootstrapPeriod, deserializeSyncCommittee(bootstrap.currentSyncCommittee));
17
+ this.finalizedHeaderValue = bootstrap.header;
18
+ this.optimisticHeaderValue = bootstrap.header;
19
+ }
20
+ get finalizedHeader() {
21
+ return this.finalizedHeaderValue;
22
+ }
23
+ set finalizedHeader(value) {
24
+ this.finalizedHeaderValue = value;
25
+ this.events.onSetFinalizedHeader?.(value);
26
+ }
27
+ get optimisticHeader() {
28
+ return this.optimisticHeaderValue;
29
+ }
30
+ set optimisticHeader(value) {
31
+ this.optimisticHeaderValue = value;
32
+ this.events.onSetOptimisticHeader?.(value);
33
+ }
34
+ getMaxActiveParticipants(period) {
35
+ const currMaxParticipants = this.maxActiveParticipants.get(period) ?? 0;
36
+ const prevMaxParticipants = this.maxActiveParticipants.get(period - 1) ?? 0;
37
+ return Math.max(currMaxParticipants, prevMaxParticipants);
38
+ }
39
+ setActiveParticipants(period, activeParticipants) {
40
+ const maxActiveParticipants = this.maxActiveParticipants.get(period) ?? 0;
41
+ if (activeParticipants > maxActiveParticipants) {
42
+ this.maxActiveParticipants.set(period, activeParticipants);
43
+ }
44
+ // Prune old entries
45
+ for (const key of this.maxActiveParticipants.keys()) {
46
+ if (key < period - MAX_SYNC_PERIODS_CACHE) {
47
+ this.maxActiveParticipants.delete(key);
48
+ }
49
+ }
50
+ }
51
+ }
52
+ // === storePeriod ? store.currentSyncCommittee : store.nextSyncCommittee;
53
+ // if (!syncCommittee) {
54
+ // throw Error(`syncCommittee not available for signature period ${updateSignaturePeriod}`);
55
+ // }
56
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/lightClient/spec/store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,uBAAuB,EAAC,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EAAC,wBAAwB,EAAC,MAAM,YAAY,CAAC;AAEpD,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAyBxC,MAAM,OAAO,gBAAgB;IAUhB,MAAM;IAEE,MAAM;IAXhB,cAAc,GAAG,IAAI,GAAG,EAAiC,CAAC;IAC1D,gBAAgB,GAAG,IAAI,GAAG,EAA4C,CAAC;IAExE,oBAAoB,CAAoB;IACxC,qBAAqB,CAAoB;IAEhC,qBAAqB,GAAG,IAAI,GAAG,EAAsB,CAAC;IAEvE,YACW,MAAoB,EAC7B,SAA+B,EACd,MAA8B,EAC/C;sBAHS,MAAM;sBAEE,MAAM;QAEvB,MAAM,eAAe,GAAG,uBAAuB,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9E,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,eAAe,EAAE,wBAAwB,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC;QACnG,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC,MAAM,CAAC;QAC7C,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC,MAAM,CAAC;IAAA,CAC/C;IAED,IAAI,eAAe,GAAsB;QACvC,OAAO,IAAI,CAAC,oBAAoB,CAAC;IAAA,CAClC;IAED,IAAI,eAAe,CAAC,KAAwB,EAAE;QAC5C,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC,KAAK,CAAC,CAAC;IAAA,CAC3C;IAED,IAAI,gBAAgB,GAAsB;QACxC,OAAO,IAAI,CAAC,qBAAqB,CAAC;IAAA,CACnC;IAED,IAAI,gBAAgB,CAAC,KAAwB,EAAE;QAC7C,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,CAAC;IAAA,CAC5C;IAED,wBAAwB,CAAC,MAAkB,EAAU;QACnD,MAAM,mBAAmB,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxE,MAAM,mBAAmB,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QAE5E,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;IAAA,CAC3D;IAED,qBAAqB,CAAC,MAAkB,EAAE,kBAA0B,EAAQ;QAC1E,MAAM,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1E,IAAI,kBAAkB,GAAG,qBAAqB,EAAE,CAAC;YAC/C,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;QAC7D,CAAC;QAED,oBAAoB;QACpB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,EAAE,CAAC;YACpD,IAAI,GAAG,GAAG,MAAM,GAAG,sBAAsB,EAAE,CAAC;gBAC1C,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;IAAA,CACF;CACF;AAYD,0EAA0E;AAC1E,wBAAwB;AACxB,8FAA8F;AAC9F,IAAI"}
@@ -0,0 +1,47 @@
1
+ import { BitArray } from "@chainsafe/ssz";
2
+ import { ChainForkConfig } from "@lodestar/config";
3
+ import { ForkName } from "@lodestar/params";
4
+ import { BeaconBlockHeader, LightClientFinalityUpdate, LightClientHeader, LightClientOptimisticUpdate, LightClientUpdate, Slot, SyncCommittee } from "@lodestar/types";
5
+ import type { LightClientStore, SyncCommitteeFast } from "./store.js";
6
+ export declare const GENESIS_SLOT = 0;
7
+ export declare const ZERO_HASH: Uint8Array<ArrayBuffer>;
8
+ export declare const ZERO_PUBKEY: Uint8Array<ArrayBuffer>;
9
+ export declare const ZERO_SYNC_COMMITTEE: import("@chainsafe/ssz").ValueOfFields<{
10
+ pubkeys: import("@chainsafe/ssz").VectorCompositeType<import("@chainsafe/ssz").ByteVectorType>;
11
+ aggregatePubkey: import("@chainsafe/ssz").ByteVectorType;
12
+ }>;
13
+ export declare const ZERO_HEADER: import("@chainsafe/ssz").ValueOfFields<{
14
+ slot: import("@chainsafe/ssz").UintNumberType;
15
+ proposerIndex: import("@chainsafe/ssz").UintNumberType;
16
+ parentRoot: import("@chainsafe/ssz").ByteVectorType;
17
+ stateRoot: import("@chainsafe/ssz").ByteVectorType;
18
+ bodyRoot: import("@chainsafe/ssz").ByteVectorType;
19
+ }>;
20
+ export declare function sumBits(bits: BitArray): number;
21
+ /**
22
+ * Util to guarantee that all bits have a corresponding pubkey.
23
+ */
24
+ export declare function getParticipantPubkeys<T>(pubkeys: T[], bits: BitArray): T[];
25
+ export declare function deserializeSyncCommittee(syncCommittee: SyncCommittee): SyncCommitteeFast;
26
+ export declare function serializeSyncCommittee(syncCommittee: SyncCommitteeFast): SyncCommittee;
27
+ export declare function getSafetyThreshold(maxActiveParticipants: number): number;
28
+ export declare function getZeroSyncCommitteeBranch(fork: ForkName): Uint8Array[];
29
+ export declare function getZeroFinalityBranch(fork: ForkName): Uint8Array[];
30
+ export declare function isSyncCommitteeUpdate(update: LightClientUpdate): boolean;
31
+ export declare function isFinalityUpdate(update: LightClientUpdate): boolean;
32
+ export declare function isZeroedHeader(header: BeaconBlockHeader): boolean;
33
+ export declare function isZeroedSyncCommittee(syncCommittee: SyncCommittee): boolean;
34
+ export declare function isValidMerkleBranch(leaf: Uint8Array, branch: Uint8Array[], depth: number, index: number, root: Uint8Array): boolean;
35
+ export declare function normalizeMerkleBranch(branch: Uint8Array[], depth: number): Uint8Array[];
36
+ export declare function upgradeLightClientHeader(config: ChainForkConfig, targetFork: ForkName, header: LightClientHeader): LightClientHeader;
37
+ export declare function isValidLightClientHeader(config: ChainForkConfig, header: LightClientHeader): boolean;
38
+ export declare function upgradeLightClientUpdate(config: ChainForkConfig, targetFork: ForkName, update: LightClientUpdate): LightClientUpdate;
39
+ export declare function upgradeLightClientFinalityUpdate(config: ChainForkConfig, targetFork: ForkName, finalityUpdate: LightClientFinalityUpdate): LightClientFinalityUpdate;
40
+ export declare function upgradeLightClientOptimisticUpdate(config: ChainForkConfig, targetFork: ForkName, optimisticUpdate: LightClientOptimisticUpdate): LightClientOptimisticUpdate;
41
+ /**
42
+ * Currently this upgradation is not required because all processing is done based on the
43
+ * summary that the store generates and maintains. In case store needs to be saved to disk,
44
+ * this could be required depending on the format the store is saved to the disk
45
+ */
46
+ export declare function upgradeLightClientStore(config: ChainForkConfig, targetFork: ForkName, store: LightClientStore, signatureSlot: Slot): LightClientStore;
47
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lightClient/spec/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,197 @@
1
+ import { PublicKey } from "@chainsafe/blst";
2
+ import { BLOCK_BODY_EXECUTION_PAYLOAD_DEPTH as EXECUTION_PAYLOAD_DEPTH, BLOCK_BODY_EXECUTION_PAYLOAD_INDEX as EXECUTION_PAYLOAD_INDEX, FINALIZED_ROOT_DEPTH, FINALIZED_ROOT_DEPTH_ELECTRA, ForkName, ForkSeq, NEXT_SYNC_COMMITTEE_DEPTH, NEXT_SYNC_COMMITTEE_DEPTH_ELECTRA, isForkPostElectra, } from "@lodestar/params";
3
+ import { isElectraLightClientUpdate, ssz, } from "@lodestar/types";
4
+ import { byteArrayEquals, verifyMerkleBranch } from "@lodestar/utils";
5
+ import { computeEpochAtSlot, computeSyncPeriodAtSlot } from "../../util/epoch.js";
6
+ export const GENESIS_SLOT = 0;
7
+ export const ZERO_HASH = new Uint8Array(32);
8
+ export const ZERO_PUBKEY = new Uint8Array(48);
9
+ export const ZERO_SYNC_COMMITTEE = ssz.altair.SyncCommittee.defaultValue();
10
+ export const ZERO_HEADER = ssz.phase0.BeaconBlockHeader.defaultValue();
11
+ /** From https://notes.ethereum.org/@vbuterin/extended_light_client_protocol#Optimistic-head-determining-function */
12
+ const SAFETY_THRESHOLD_FACTOR = 2;
13
+ export function sumBits(bits) {
14
+ return bits.getTrueBitIndexes().length;
15
+ }
16
+ /**
17
+ * Util to guarantee that all bits have a corresponding pubkey.
18
+ */
19
+ export function getParticipantPubkeys(pubkeys, bits) {
20
+ // BitArray.intersectValues() checks the length is correct.
21
+ return bits.intersectValues(pubkeys);
22
+ }
23
+ function deserializePubkeys(pubkeys) {
24
+ return pubkeys.map((pk) => PublicKey.fromBytes(pk, true));
25
+ }
26
+ function serializePubkeys(pubkeys) {
27
+ return pubkeys.map((pk) => pk.toBytes());
28
+ }
29
+ export function deserializeSyncCommittee(syncCommittee) {
30
+ return {
31
+ pubkeys: deserializePubkeys(syncCommittee.pubkeys),
32
+ aggregatePubkey: PublicKey.fromBytes(syncCommittee.aggregatePubkey, true),
33
+ };
34
+ }
35
+ export function serializeSyncCommittee(syncCommittee) {
36
+ return {
37
+ pubkeys: serializePubkeys(syncCommittee.pubkeys),
38
+ aggregatePubkey: syncCommittee.aggregatePubkey.toBytes(),
39
+ };
40
+ }
41
+ export function getSafetyThreshold(maxActiveParticipants) {
42
+ return Math.floor(maxActiveParticipants / SAFETY_THRESHOLD_FACTOR);
43
+ }
44
+ export function getZeroSyncCommitteeBranch(fork) {
45
+ const nextSyncCommitteeDepth = isForkPostElectra(fork)
46
+ ? NEXT_SYNC_COMMITTEE_DEPTH_ELECTRA
47
+ : NEXT_SYNC_COMMITTEE_DEPTH;
48
+ return Array.from({ length: nextSyncCommitteeDepth }, () => ZERO_HASH);
49
+ }
50
+ export function getZeroFinalityBranch(fork) {
51
+ const finalizedRootDepth = isForkPostElectra(fork) ? FINALIZED_ROOT_DEPTH_ELECTRA : FINALIZED_ROOT_DEPTH;
52
+ return Array.from({ length: finalizedRootDepth }, () => ZERO_HASH);
53
+ }
54
+ export function isSyncCommitteeUpdate(update) {
55
+ return (
56
+ // Fast return for when constructing full LightClientUpdate from partial updates
57
+ update.nextSyncCommitteeBranch !==
58
+ getZeroSyncCommitteeBranch(isElectraLightClientUpdate(update) ? ForkName.electra : ForkName.altair) &&
59
+ update.nextSyncCommitteeBranch.some((branch) => !byteArrayEquals(branch, ZERO_HASH)));
60
+ }
61
+ export function isFinalityUpdate(update) {
62
+ return (
63
+ // Fast return for when constructing full LightClientUpdate from partial updates
64
+ update.finalityBranch !==
65
+ getZeroFinalityBranch(isElectraLightClientUpdate(update) ? ForkName.electra : ForkName.altair) &&
66
+ update.finalityBranch.some((branch) => !byteArrayEquals(branch, ZERO_HASH)));
67
+ }
68
+ export function isZeroedHeader(header) {
69
+ // Fast return for when constructing full LightClientUpdate from partial updates
70
+ return header === ZERO_HEADER || byteArrayEquals(header.bodyRoot, ZERO_HASH);
71
+ }
72
+ export function isZeroedSyncCommittee(syncCommittee) {
73
+ // Fast return for when constructing full LightClientUpdate from partial updates
74
+ return syncCommittee === ZERO_SYNC_COMMITTEE || byteArrayEquals(syncCommittee.pubkeys[0], ZERO_PUBKEY);
75
+ }
76
+ export function isValidMerkleBranch(leaf, branch, depth, index, root) {
77
+ if (branch.length !== depth) {
78
+ return false;
79
+ }
80
+ return verifyMerkleBranch(leaf, branch, depth, index, root);
81
+ }
82
+ export function normalizeMerkleBranch(branch, depth) {
83
+ const numExtraDepth = depth - branch.length;
84
+ return [...Array.from({ length: numExtraDepth }, () => ZERO_HASH), ...branch];
85
+ }
86
+ export function upgradeLightClientHeader(config, targetFork, header) {
87
+ const headerFork = config.getForkName(header.beacon.slot);
88
+ if (ForkSeq[headerFork] >= ForkSeq[targetFork]) {
89
+ throw Error(`Invalid upgrade request from headerFork=${headerFork} to targetFork=${targetFork}`);
90
+ }
91
+ // We are modifying the same header object, may be we could create a copy, but its
92
+ // not required as of now
93
+ const upgradedHeader = header;
94
+ const startUpgradeFromFork = Object.values(ForkName)[ForkSeq[headerFork] + 1];
95
+ switch (startUpgradeFromFork) {
96
+ // biome-ignore lint/suspicious/useDefaultSwitchClauseLast: We want default to evaluate at first to throw error early
97
+ default:
98
+ throw Error(`Invalid startUpgradeFromFork=${startUpgradeFromFork} for headerFork=${headerFork} in upgradeLightClientHeader to targetFork=${targetFork}`);
99
+ case ForkName.altair:
100
+ // biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here
101
+ case ForkName.bellatrix:
102
+ // Break if no further upgradation is required else fall through
103
+ if (ForkSeq[targetFork] <= ForkSeq.bellatrix)
104
+ break;
105
+ // biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here
106
+ case ForkName.capella:
107
+ upgradedHeader.execution =
108
+ ssz.capella.LightClientHeader.fields.execution.defaultValue();
109
+ upgradedHeader.executionBranch =
110
+ ssz.capella.LightClientHeader.fields.executionBranch.defaultValue();
111
+ // Break if no further upgradation is required else fall through
112
+ if (ForkSeq[targetFork] <= ForkSeq.capella)
113
+ break;
114
+ // biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here
115
+ case ForkName.deneb:
116
+ upgradedHeader.execution.blobGasUsed =
117
+ ssz.deneb.LightClientHeader.fields.execution.fields.blobGasUsed.defaultValue();
118
+ upgradedHeader.execution.excessBlobGas =
119
+ ssz.deneb.LightClientHeader.fields.execution.fields.excessBlobGas.defaultValue();
120
+ // Break if no further upgradation is required else fall through
121
+ if (ForkSeq[targetFork] <= ForkSeq.deneb)
122
+ break;
123
+ // biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here
124
+ case ForkName.electra:
125
+ // No changes to LightClientHeader in Electra
126
+ // Break if no further upgrades is required else fall through
127
+ if (ForkSeq[targetFork] <= ForkSeq.electra)
128
+ break;
129
+ // biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here
130
+ case ForkName.fulu:
131
+ // No changes to LightClientHeader in Fulu
132
+ // Break if no further upgrades is required else fall through
133
+ if (ForkSeq[targetFork] <= ForkSeq.fulu)
134
+ break;
135
+ case ForkName.gloas:
136
+ // No changes to LightClientHeader in Gloas
137
+ // Break if no further upgrades is required else fall through
138
+ if (ForkSeq[targetFork] <= ForkSeq.gloas)
139
+ break;
140
+ }
141
+ return upgradedHeader;
142
+ }
143
+ export function isValidLightClientHeader(config, header) {
144
+ const epoch = computeEpochAtSlot(header.beacon.slot);
145
+ if (epoch < config.CAPELLA_FORK_EPOCH) {
146
+ return ((header.execution === undefined ||
147
+ ssz.capella.ExecutionPayloadHeader.equals(header.execution, ssz.capella.LightClientHeader.fields.execution.defaultValue())) &&
148
+ (header.executionBranch === undefined ||
149
+ ssz.capella.LightClientHeader.fields.executionBranch.equals(ssz.capella.LightClientHeader.fields.executionBranch.defaultValue(), header.executionBranch)));
150
+ }
151
+ if (epoch < config.DENEB_FORK_EPOCH &&
152
+ ((header.execution.blobGasUsed &&
153
+ header.execution.blobGasUsed !== BigInt(0)) ||
154
+ (header.execution.excessBlobGas &&
155
+ header.execution.excessBlobGas !== BigInt(0)))) {
156
+ return false;
157
+ }
158
+ return isValidMerkleBranch(config
159
+ .getPostBellatrixForkTypes(header.beacon.slot)
160
+ .ExecutionPayloadHeader.hashTreeRoot(header.execution), header.executionBranch, EXECUTION_PAYLOAD_DEPTH, EXECUTION_PAYLOAD_INDEX, header.beacon.bodyRoot);
161
+ }
162
+ export function upgradeLightClientUpdate(config, targetFork, update) {
163
+ update.attestedHeader = upgradeLightClientHeader(config, targetFork, update.attestedHeader);
164
+ update.finalizedHeader = upgradeLightClientHeader(config, targetFork, update.finalizedHeader);
165
+ update.nextSyncCommitteeBranch = normalizeMerkleBranch(update.nextSyncCommitteeBranch, isForkPostElectra(targetFork) ? NEXT_SYNC_COMMITTEE_DEPTH_ELECTRA : NEXT_SYNC_COMMITTEE_DEPTH);
166
+ update.finalityBranch = normalizeMerkleBranch(update.finalityBranch, isForkPostElectra(targetFork) ? FINALIZED_ROOT_DEPTH_ELECTRA : FINALIZED_ROOT_DEPTH);
167
+ return update;
168
+ }
169
+ export function upgradeLightClientFinalityUpdate(config, targetFork, finalityUpdate) {
170
+ finalityUpdate.attestedHeader = upgradeLightClientHeader(config, targetFork, finalityUpdate.attestedHeader);
171
+ finalityUpdate.finalizedHeader = upgradeLightClientHeader(config, targetFork, finalityUpdate.finalizedHeader);
172
+ finalityUpdate.finalityBranch = normalizeMerkleBranch(finalityUpdate.finalityBranch, isForkPostElectra(targetFork) ? FINALIZED_ROOT_DEPTH_ELECTRA : FINALIZED_ROOT_DEPTH);
173
+ return finalityUpdate;
174
+ }
175
+ export function upgradeLightClientOptimisticUpdate(config, targetFork, optimisticUpdate) {
176
+ optimisticUpdate.attestedHeader = upgradeLightClientHeader(config, targetFork, optimisticUpdate.attestedHeader);
177
+ return optimisticUpdate;
178
+ }
179
+ /**
180
+ * Currently this upgradation is not required because all processing is done based on the
181
+ * summary that the store generates and maintains. In case store needs to be saved to disk,
182
+ * this could be required depending on the format the store is saved to the disk
183
+ */
184
+ export function upgradeLightClientStore(config, targetFork, store, signatureSlot) {
185
+ const updateSignaturePeriod = computeSyncPeriodAtSlot(signatureSlot);
186
+ const bestValidUpdate = store.bestValidUpdates.get(updateSignaturePeriod);
187
+ if (bestValidUpdate) {
188
+ store.bestValidUpdates.set(updateSignaturePeriod, {
189
+ update: upgradeLightClientUpdate(config, targetFork, bestValidUpdate.update),
190
+ summary: bestValidUpdate.summary,
191
+ });
192
+ }
193
+ store.finalizedHeader = upgradeLightClientHeader(config, targetFork, store.finalizedHeader);
194
+ store.optimisticHeader = upgradeLightClientHeader(config, targetFork, store.optimisticHeader);
195
+ return store;
196
+ }
197
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/lightClient/spec/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { ChainForkConfig } from "@lodestar/config";
2
+ import { LightClientBootstrap, Root } from "@lodestar/types";
3
+ export declare function validateLightClientBootstrap(config: ChainForkConfig, trustedBlockRoot: Root, bootstrap: LightClientBootstrap): void;
4
+ //# sourceMappingURL=validateLightClientBootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateLightClientBootstrap.d.ts","sourceRoot":"","sources":["../../../src/lightClient/spec/validateLightClientBootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAC,oBAAoB,EAAE,IAAI,EAAM,MAAM,iBAAiB,CAAC;AAShE,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,eAAe,EACvB,gBAAgB,EAAE,IAAI,EACtB,SAAS,EAAE,oBAAoB,GAC9B,IAAI,CAuBN"}
@@ -0,0 +1,22 @@
1
+ import { isForkPostElectra } from "@lodestar/params";
2
+ import { ssz } from "@lodestar/types";
3
+ import { byteArrayEquals, toHex } from "@lodestar/utils";
4
+ import { isValidLightClientHeader, isValidMerkleBranch } from "./utils.js";
5
+ const CURRENT_SYNC_COMMITTEE_INDEX = 22;
6
+ const CURRENT_SYNC_COMMITTEE_DEPTH = 5;
7
+ const CURRENT_SYNC_COMMITTEE_INDEX_ELECTRA = 22;
8
+ const CURRENT_SYNC_COMMITTEE_DEPTH_ELECTRA = 6;
9
+ export function validateLightClientBootstrap(config, trustedBlockRoot, bootstrap) {
10
+ const headerRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(bootstrap.header.beacon);
11
+ const fork = config.getForkName(bootstrap.header.beacon.slot);
12
+ if (!isValidLightClientHeader(config, bootstrap.header)) {
13
+ throw Error("Bootstrap Header is not Valid Light Client Header");
14
+ }
15
+ if (!byteArrayEquals(headerRoot, trustedBlockRoot)) {
16
+ throw Error(`bootstrap header root ${toHex(headerRoot)} != trusted root ${toHex(trustedBlockRoot)}`);
17
+ }
18
+ if (!isValidMerkleBranch(ssz.altair.SyncCommittee.hashTreeRoot(bootstrap.currentSyncCommittee), bootstrap.currentSyncCommitteeBranch, isForkPostElectra(fork) ? CURRENT_SYNC_COMMITTEE_DEPTH_ELECTRA : CURRENT_SYNC_COMMITTEE_DEPTH, isForkPostElectra(fork) ? CURRENT_SYNC_COMMITTEE_INDEX_ELECTRA : CURRENT_SYNC_COMMITTEE_INDEX, bootstrap.header.beacon.stateRoot)) {
19
+ throw Error("Invalid currentSyncCommittee merkle branch");
20
+ }
21
+ }
22
+ //# sourceMappingURL=validateLightClientBootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateLightClientBootstrap.js","sourceRoot":"","sources":["../../../src/lightClient/spec/validateLightClientBootstrap.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAA6B,GAAG,EAAC,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAC,eAAe,EAAE,KAAK,EAAC,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAC,wBAAwB,EAAE,mBAAmB,EAAC,MAAM,YAAY,CAAC;AAEzE,MAAM,4BAA4B,GAAG,EAAE,CAAC;AACxC,MAAM,4BAA4B,GAAG,CAAC,CAAC;AACvC,MAAM,oCAAoC,GAAG,EAAE,CAAC;AAChD,MAAM,oCAAoC,GAAG,CAAC,CAAC;AAE/C,MAAM,UAAU,4BAA4B,CAC1C,MAAuB,EACvB,gBAAsB,EACtB,SAA+B,EACzB;IACN,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtF,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAE9D,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QACxD,MAAM,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAAE,CAAC;QACnD,MAAM,KAAK,CAAC,yBAAyB,KAAK,CAAC,UAAU,CAAC,oBAAoB,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACvG,CAAC;IAED,IACE,CAAC,mBAAmB,CAClB,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,oBAAoB,CAAC,EACrE,SAAS,CAAC,0BAA0B,EACpC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,4BAA4B,EAC7F,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,4BAA4B,EAC7F,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAClC,EACD,CAAC;QACD,MAAM,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC5D,CAAC;AAAA,CACF"}
@@ -0,0 +1,5 @@
1
+ import { ChainForkConfig } from "@lodestar/config";
2
+ import { LightClientUpdate } from "@lodestar/types";
3
+ import type { ILightClientStore, SyncCommitteeFast } from "./store.js";
4
+ export declare function validateLightClientUpdate(config: ChainForkConfig, store: ILightClientStore, update: LightClientUpdate, syncCommittee: SyncCommitteeFast): void;
5
+ //# sourceMappingURL=validateLightClientUpdate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateLightClientUpdate.d.ts","sourceRoot":"","sources":["../../../src/lightClient/spec/validateLightClientUpdate.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAcjD,OAAO,EAAC,iBAAiB,EAAwC,MAAM,iBAAiB,CAAC;AACzF,OAAO,KAAK,EAAC,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,YAAY,CAAC;AAarE,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,iBAAiB,GAC/B,IAAI,CA0FN"}