@lodestar/state-transition 1.12.0-dev.f77b774be2 → 1.12.0-rc.1

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 (47) hide show
  1. package/lib/block/processExecutionPayload.d.ts +1 -2
  2. package/lib/block/processExecutionPayload.js +1 -30
  3. package/lib/block/processExecutionPayload.js.map +1 -1
  4. package/lib/cache/epochCache.d.ts +7 -1
  5. package/lib/cache/epochCache.js +26 -12
  6. package/lib/cache/epochCache.js.map +1 -1
  7. package/lib/cache/pubkeyCache.js +1 -1
  8. package/lib/cache/stateCache.d.ts +7 -0
  9. package/lib/cache/stateCache.js +30 -2
  10. package/lib/cache/stateCache.js.map +1 -1
  11. package/lib/cache/types.d.ts +3 -1
  12. package/lib/epoch/processRegistryUpdates.js +1 -1
  13. package/lib/epoch/processRegistryUpdates.js.map +1 -1
  14. package/lib/index.d.ts +8 -9
  15. package/lib/index.js +1 -2
  16. package/lib/index.js.map +1 -1
  17. package/lib/stateTransition.js +1 -1
  18. package/lib/stateTransition.js.map +1 -1
  19. package/lib/types.d.ts +3 -3
  20. package/lib/util/blindedBlock.d.ts +19 -1
  21. package/lib/util/blindedBlock.js +84 -1
  22. package/lib/util/blindedBlock.js.map +1 -1
  23. package/lib/util/epochShuffling.d.ts +2 -1
  24. package/lib/util/epochShuffling.js +7 -0
  25. package/lib/util/epochShuffling.js.map +1 -1
  26. package/lib/util/execution.d.ts +2 -0
  27. package/lib/util/execution.js +29 -0
  28. package/lib/util/execution.js.map +1 -1
  29. package/lib/util/loadState/findModifiedInactivityScores.d.ts +8 -0
  30. package/lib/util/loadState/findModifiedInactivityScores.js +27 -0
  31. package/lib/util/loadState/findModifiedInactivityScores.js.map +1 -0
  32. package/lib/util/loadState/findModifiedValidators.d.ts +10 -0
  33. package/lib/util/loadState/findModifiedValidators.js +26 -0
  34. package/lib/util/loadState/findModifiedValidators.js.map +1 -0
  35. package/lib/util/loadState/loadState.d.ts +17 -0
  36. package/lib/util/loadState/loadState.js +145 -0
  37. package/lib/util/loadState/loadState.js.map +1 -0
  38. package/lib/util/loadState/loadValidator.d.ts +9 -0
  39. package/lib/util/loadState/loadValidator.js +35 -0
  40. package/lib/util/loadState/loadValidator.js.map +1 -0
  41. package/lib/util/sszBytes.d.ts +24 -0
  42. package/lib/util/sszBytes.js +44 -0
  43. package/lib/util/sszBytes.js.map +1 -0
  44. package/lib/util/validator.d.ts +2 -0
  45. package/lib/util/validator.js +9 -0
  46. package/lib/util/validator.js.map +1 -1
  47. package/package.json +9 -8
@@ -1,4 +1,6 @@
1
- import { isBlindedBeaconBlock, isBlindedBlobSidecar } from "@lodestar/types";
1
+ import { ForkSeq } from "@lodestar/params";
2
+ import { ssz, isBlindedBeaconBlock, isBlindedBlobSidecar, isSignedBlindedBlockContents, isExecutionPayloadAndBlobsBundle, } from "@lodestar/types";
3
+ import { executionPayloadToPayloadHeader } from "./execution.js";
2
4
  export function blindedOrFullBlockHashTreeRoot(config, blindedOrFull) {
3
5
  return isBlindedBeaconBlock(blindedOrFull)
4
6
  ? // Blinded
@@ -27,4 +29,85 @@ export function blindedOrFullBlockToHeader(config, blindedOrFull) {
27
29
  bodyRoot,
28
30
  };
29
31
  }
32
+ export function beaconBlockToBlinded(config, block) {
33
+ const fork = config.getForkName(block.slot);
34
+ const executionPayloadHeader = executionPayloadToPayloadHeader(ForkSeq[fork], block.body.executionPayload);
35
+ const blindedBlock = { ...block, body: { ...block.body, executionPayloadHeader } };
36
+ return blindedBlock;
37
+ }
38
+ export function blobSidecarsToBlinded(blobSidecars) {
39
+ return blobSidecars.map((blobSidecar) => {
40
+ const blobRoot = ssz.deneb.Blob.hashTreeRoot(blobSidecar.blob);
41
+ return { ...blobSidecar, blobRoot };
42
+ });
43
+ }
44
+ export function signedBlindedBlockToFull(signedBlindedBlock, executionPayload) {
45
+ const signedBlock = {
46
+ ...signedBlindedBlock,
47
+ message: {
48
+ ...signedBlindedBlock.message,
49
+ body: {
50
+ ...signedBlindedBlock.message.body,
51
+ // state transition doesn't handle null value for executionPayload in pre-bellatrix blocks
52
+ executionPayload: executionPayload ?? undefined,
53
+ },
54
+ },
55
+ };
56
+ // state transition can't seem to handle executionPayloadHeader presense in merge block
57
+ // so just delete the extra field we don't require
58
+ delete signedBlock.message.body
59
+ .executionPayloadHeader;
60
+ return signedBlock;
61
+ }
62
+ export function signedBlindedBlobSidecarsToFull(signedBlindedBlobSidecars, blobs) {
63
+ const signedBlobSidecars = signedBlindedBlobSidecars.map((signedBlindedBlobSidecar, index) => {
64
+ const signedBlobSidecar = {
65
+ ...signedBlindedBlobSidecar,
66
+ message: { ...signedBlindedBlobSidecar.message, blob: blobs[index] },
67
+ };
68
+ delete signedBlobSidecar.message.blobRoot;
69
+ return signedBlobSidecar;
70
+ });
71
+ return signedBlobSidecars;
72
+ }
73
+ export function parseSignedBlindedBlockOrContents(signedBlindedBlockOrContents) {
74
+ if (isSignedBlindedBlockContents(signedBlindedBlockOrContents)) {
75
+ const signedBlindedBlock = signedBlindedBlockOrContents.signedBlindedBlock;
76
+ const signedBlindedBlobSidecars = signedBlindedBlockOrContents.signedBlindedBlobSidecars;
77
+ return { signedBlindedBlock, signedBlindedBlobSidecars };
78
+ }
79
+ else {
80
+ return { signedBlindedBlock: signedBlindedBlockOrContents, signedBlindedBlobSidecars: null };
81
+ }
82
+ }
83
+ export function parseExecutionPayloadAndBlobsBundle(data) {
84
+ if (isExecutionPayloadAndBlobsBundle(data)) {
85
+ return data;
86
+ }
87
+ else {
88
+ return {
89
+ executionPayload: data,
90
+ blobsBundle: null,
91
+ };
92
+ }
93
+ }
94
+ export function reconstructFullBlockOrContents({ signedBlindedBlock, signedBlindedBlobSidecars }, { executionPayload, blobs }) {
95
+ const signedBlock = signedBlindedBlockToFull(signedBlindedBlock, executionPayload);
96
+ if (signedBlindedBlobSidecars !== null) {
97
+ if (executionPayload === null) {
98
+ throw Error("Missing locally produced executionPayload for deneb+ publishBlindedBlock");
99
+ }
100
+ if (blobs === null) {
101
+ throw Error("Missing blobs from the local execution cache");
102
+ }
103
+ if (blobs.length !== signedBlindedBlobSidecars.length) {
104
+ throw Error(`Length mismatch signedBlindedBlobSidecars=${signedBlindedBlobSidecars.length} blobs=${blobs.length}`);
105
+ }
106
+ const signedBlobSidecars = signedBlindedBlobSidecarsToFull(signedBlindedBlobSidecars, blobs);
107
+ return { signedBlock, signedBlobSidecars };
108
+ }
109
+ else {
110
+ return signedBlock;
111
+ }
112
+ }
30
113
  //# sourceMappingURL=blindedBlock.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"blindedBlock.js","sourceRoot":"","sources":["../../src/util/blindedBlock.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,oBAAoB,EAAE,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AAEnG,MAAM,UAAU,8BAA8B,CAC5C,MAAuB,EACvB,aAAgD;IAEhD,OAAO,oBAAoB,CAAC,aAAa,CAAC;QACxC,CAAC,CAAC,UAAU;YACV,MAAM,CAAC,mBAAmB,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,aAAa,CAAC;QACxF,CAAC,CAAC,OAAO;YACP,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,oCAAoC,CAClD,MAAuB,EACvB,aAAgD;IAEhD,OAAO,oBAAoB,CAAC,aAAa,CAAC;QACxC,CAAC,CAAC,UAAU;YACV,MAAM,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,kBAAkB,CAAC,YAAY,CAAC,aAAa,CAAC;QAC7F,CAAC,CAAC,OAAO;YACP,MAAM,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,MAAuB,EACvB,aAAgD;IAEhD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,aAAa,CAAC;QAClD,CAAC,CAAC,UAAU;YACV,MAAM,CAAC,mBAAmB,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC;QACjG,CAAC,CAAC,OAAO;YACP,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAE7F,OAAO;QACL,IAAI,EAAE,aAAa,CAAC,IAAI;QACxB,aAAa,EAAE,aAAa,CAAC,aAAa;QAC1C,UAAU,EAAE,aAAa,CAAC,UAAU;QACpC,SAAS,EAAE,aAAa,CAAC,SAAS;QAClC,QAAQ;KACT,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"blindedBlock.js","sourceRoot":"","sources":["../../src/util/blindedBlock.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Epoch, ValidatorIndex } from "@lodestar/types";
1
+ import { Epoch, RootHex, ValidatorIndex } from "@lodestar/types";
2
2
  import { BeaconStateAllForks } from "../types.js";
3
3
  /**
4
4
  * Readonly interface for EpochShuffling.
@@ -36,4 +36,5 @@ export type EpochShuffling = {
36
36
  };
37
37
  export declare function computeCommitteeCount(activeValidatorCount: number): number;
38
38
  export declare function computeEpochShuffling(state: BeaconStateAllForks, activeIndices: ValidatorIndex[], epoch: Epoch): EpochShuffling;
39
+ export declare function getShufflingDecisionBlock(state: BeaconStateAllForks, epoch: Epoch): RootHex;
39
40
  //# sourceMappingURL=epochShuffling.d.ts.map
@@ -1,7 +1,10 @@
1
+ import { toHexString } from "@chainsafe/ssz";
1
2
  import { intDiv } from "@lodestar/utils";
2
3
  import { DOMAIN_BEACON_ATTESTER, MAX_COMMITTEES_PER_SLOT, SLOTS_PER_EPOCH, TARGET_COMMITTEE_SIZE, } from "@lodestar/params";
3
4
  import { getSeed } from "./seed.js";
4
5
  import { unshuffleList } from "./shuffle.js";
6
+ import { computeStartSlotAtEpoch } from "./epoch.js";
7
+ import { getBlockRootAtSlot } from "./blockRoot.js";
5
8
  export function computeCommitteeCount(activeValidatorCount) {
6
9
  const validatorsPerSlot = intDiv(activeValidatorCount, SLOTS_PER_EPOCH);
7
10
  const committeesPerSlot = intDiv(validatorsPerSlot, TARGET_COMMITTEE_SIZE);
@@ -37,4 +40,8 @@ export function computeEpochShuffling(state, activeIndices, epoch) {
37
40
  committeesPerSlot,
38
41
  };
39
42
  }
43
+ export function getShufflingDecisionBlock(state, epoch) {
44
+ const pivotSlot = computeStartSlotAtEpoch(epoch - 1) - 1;
45
+ return toHexString(getBlockRootAtSlot(state, pivotSlot));
46
+ }
40
47
  //# sourceMappingURL=epochShuffling.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"epochShuffling.js","sourceRoot":"","sources":["../../src/util/epochShuffling.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAC;AACvC,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;AA0C3C,MAAM,UAAU,qBAAqB,CAAC,oBAA4B;IAChE,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,EAAE,eAAe,CAAC,CAAC;IACxE,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAAC;IAC3E,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,uBAAuB,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,KAA0B,EAC1B,aAA+B,EAC/B,KAAY;IAEZ,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,sBAAsB,CAAC,CAAC;IAE3D,OAAO;IACP,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,EAAE,CAAC;IACxC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAE/B,MAAM,oBAAoB,GAAG,aAAa,CAAC,MAAM,CAAC;IAClD,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,oBAAoB,CAAC,CAAC;IAEtE,MAAM,cAAc,GAAG,iBAAiB,GAAG,eAAe,CAAC;IAE3D,MAAM,UAAU,GAAyB,EAAE,CAAC;IAC5C,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,eAAe,EAAE,IAAI,EAAE,EAAE;QACjD,MAAM,cAAc,GAAuB,EAAE,CAAC;QAC9C,KAAK,IAAI,cAAc,GAAG,CAAC,EAAE,cAAc,GAAG,iBAAiB,EAAE,cAAc,EAAE,EAAE;YACjF,MAAM,KAAK,GAAG,IAAI,GAAG,iBAAiB,GAAG,cAAc,CAAC;YACxD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,oBAAoB,GAAG,KAAK,CAAC,GAAG,cAAc,CAAC,CAAC;YAChF,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,oBAAoB,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;YACpF,IAAI,CAAC,CAAC,WAAW,IAAI,SAAS,CAAC,EAAE;gBAC/B,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,mCAAmC,SAAS,EAAE,CAAC,CAAC;aACtG;YACD,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;SAC9D;QACD,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;KACjC;IAED,OAAO;QACL,KAAK;QACL,aAAa;QACb,SAAS;QACT,UAAU;QACV,iBAAiB;KAClB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"epochShuffling.js","sourceRoot":"","sources":["../../src/util/epochShuffling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAC;AACvC,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAC,uBAAuB,EAAC,MAAM,YAAY,CAAC;AACnD,OAAO,EAAC,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AA0ClD,MAAM,UAAU,qBAAqB,CAAC,oBAA4B;IAChE,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,EAAE,eAAe,CAAC,CAAC;IACxE,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAAC;IAC3E,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,uBAAuB,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,KAA0B,EAC1B,aAA+B,EAC/B,KAAY;IAEZ,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,sBAAsB,CAAC,CAAC;IAE3D,OAAO;IACP,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,EAAE,CAAC;IACxC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAE/B,MAAM,oBAAoB,GAAG,aAAa,CAAC,MAAM,CAAC;IAClD,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,oBAAoB,CAAC,CAAC;IAEtE,MAAM,cAAc,GAAG,iBAAiB,GAAG,eAAe,CAAC;IAE3D,MAAM,UAAU,GAAyB,EAAE,CAAC;IAC5C,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,eAAe,EAAE,IAAI,EAAE,EAAE;QACjD,MAAM,cAAc,GAAuB,EAAE,CAAC;QAC9C,KAAK,IAAI,cAAc,GAAG,CAAC,EAAE,cAAc,GAAG,iBAAiB,EAAE,cAAc,EAAE,EAAE;YACjF,MAAM,KAAK,GAAG,IAAI,GAAG,iBAAiB,GAAG,cAAc,CAAC;YACxD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,oBAAoB,GAAG,KAAK,CAAC,GAAG,cAAc,CAAC,CAAC;YAChF,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,oBAAoB,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;YACpF,IAAI,CAAC,CAAC,WAAW,IAAI,SAAS,CAAC,EAAE;gBAC/B,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,mCAAmC,SAAS,EAAE,CAAC,CAAC;aACtG;YACD,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;SAC9D;QACD,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;KACjC;IAED,OAAO;QACL,KAAK;QACL,aAAa;QACb,SAAS;QACT,UAAU;QACV,iBAAiB;KAClB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,KAA0B,EAAE,KAAY;IAChF,MAAM,SAAS,GAAG,uBAAuB,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACzD,OAAO,WAAW,CAAC,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { allForks, bellatrix, capella } from "@lodestar/types";
2
+ import { ForkSeq } from "@lodestar/params";
2
3
  import { BeaconStateCapella, BeaconStateAllForks, BeaconStateExecutions, CachedBeaconStateAllForks, CachedBeaconStateExecutions } from "../types.js";
3
4
  /**
4
5
  * Execution enabled = merge is done.
@@ -28,4 +29,5 @@ export declare function getFullOrBlindedPayloadFromBody(body: allForks.FullOrBli
28
29
  export declare function isExecutionPayload(payload: allForks.FullOrBlindedExecutionPayload): payload is allForks.ExecutionPayload;
29
30
  export declare function isCapellaPayload(payload: allForks.FullOrBlindedExecutionPayload): payload is capella.FullOrBlindedExecutionPayload;
30
31
  export declare function isCapellaPayloadHeader(payload: capella.FullOrBlindedExecutionPayload): payload is capella.ExecutionPayloadHeader;
32
+ export declare function executionPayloadToPayloadHeader(fork: ForkSeq, payload: allForks.ExecutionPayload): allForks.ExecutionPayloadHeader;
31
33
  //# sourceMappingURL=execution.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import { isBlindedBeaconBlockBody, ssz } from "@lodestar/types";
2
+ import { ForkSeq } from "@lodestar/params";
2
3
  /**
3
4
  * Execution enabled = merge is done.
4
5
  * When (A) state has execution data OR (B) block has execution data
@@ -85,4 +86,32 @@ export function isCapellaPayload(payload) {
85
86
  export function isCapellaPayloadHeader(payload) {
86
87
  return payload.withdrawalsRoot !== undefined;
87
88
  }
89
+ export function executionPayloadToPayloadHeader(fork, payload) {
90
+ const transactionsRoot = ssz.bellatrix.Transactions.hashTreeRoot(payload.transactions);
91
+ const bellatrixPayloadFields = {
92
+ parentHash: payload.parentHash,
93
+ feeRecipient: payload.feeRecipient,
94
+ stateRoot: payload.stateRoot,
95
+ receiptsRoot: payload.receiptsRoot,
96
+ logsBloom: payload.logsBloom,
97
+ prevRandao: payload.prevRandao,
98
+ blockNumber: payload.blockNumber,
99
+ gasLimit: payload.gasLimit,
100
+ gasUsed: payload.gasUsed,
101
+ timestamp: payload.timestamp,
102
+ extraData: payload.extraData,
103
+ baseFeePerGas: payload.baseFeePerGas,
104
+ blockHash: payload.blockHash,
105
+ transactionsRoot,
106
+ };
107
+ if (fork >= ForkSeq.capella) {
108
+ bellatrixPayloadFields.withdrawalsRoot = ssz.capella.Withdrawals.hashTreeRoot(payload.withdrawals);
109
+ }
110
+ if (fork >= ForkSeq.deneb) {
111
+ // https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/beacon-chain.md#process_execution_payload
112
+ bellatrixPayloadFields.blobGasUsed = payload.blobGasUsed;
113
+ bellatrixPayloadFields.excessBlobGas = payload.excessBlobGas;
114
+ }
115
+ return bellatrixPayloadFields;
116
+ }
88
117
  //# sourceMappingURL=execution.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/util/execution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/util/execution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare const INACTIVITY_SCORE_SIZE = 8;
2
+ /**
3
+ * As monitored on mainnet, inactivityScores are not changed much and they are mostly 0
4
+ * Using Buffer.compare is the fastest way as noted in `./findModifiedValidators.ts`
5
+ * @returns output parameter modifiedValidators: validator indices that are modified
6
+ */
7
+ export declare function findModifiedInactivityScores(inactivityScoresBytes: Uint8Array, inactivityScoresBytes2: Uint8Array, modifiedValidators: number[], validatorOffset?: number): void;
8
+ //# sourceMappingURL=findModifiedInactivityScores.d.ts.map
@@ -0,0 +1,27 @@
1
+ // UintNum64 = 8 bytes
2
+ export const INACTIVITY_SCORE_SIZE = 8;
3
+ /**
4
+ * As monitored on mainnet, inactivityScores are not changed much and they are mostly 0
5
+ * Using Buffer.compare is the fastest way as noted in `./findModifiedValidators.ts`
6
+ * @returns output parameter modifiedValidators: validator indices that are modified
7
+ */
8
+ export function findModifiedInactivityScores(inactivityScoresBytes, inactivityScoresBytes2, modifiedValidators, validatorOffset = 0) {
9
+ if (inactivityScoresBytes.length !== inactivityScoresBytes2.length) {
10
+ throw new Error("inactivityScoresBytes.length !== inactivityScoresBytes2.length " +
11
+ inactivityScoresBytes.length +
12
+ " vs " +
13
+ inactivityScoresBytes2.length);
14
+ }
15
+ if (Buffer.compare(inactivityScoresBytes, inactivityScoresBytes2) === 0) {
16
+ return;
17
+ }
18
+ if (inactivityScoresBytes.length === INACTIVITY_SCORE_SIZE) {
19
+ modifiedValidators.push(validatorOffset);
20
+ return;
21
+ }
22
+ const numValidator = Math.floor(inactivityScoresBytes.length / INACTIVITY_SCORE_SIZE);
23
+ const halfValidator = Math.floor(numValidator / 2);
24
+ findModifiedInactivityScores(inactivityScoresBytes.subarray(0, halfValidator * INACTIVITY_SCORE_SIZE), inactivityScoresBytes2.subarray(0, halfValidator * INACTIVITY_SCORE_SIZE), modifiedValidators, validatorOffset);
25
+ findModifiedInactivityScores(inactivityScoresBytes.subarray(halfValidator * INACTIVITY_SCORE_SIZE), inactivityScoresBytes2.subarray(halfValidator * INACTIVITY_SCORE_SIZE), modifiedValidators, validatorOffset + halfValidator);
26
+ }
27
+ //# sourceMappingURL=findModifiedInactivityScores.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findModifiedInactivityScores.js","sourceRoot":"","sources":["../../../src/util/loadState/findModifiedInactivityScores.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEvC;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAC1C,qBAAiC,EACjC,sBAAkC,EAClC,kBAA4B,EAC5B,eAAe,GAAG,CAAC;IAEnB,IAAI,qBAAqB,CAAC,MAAM,KAAK,sBAAsB,CAAC,MAAM,EAAE;QAClE,MAAM,IAAI,KAAK,CACb,iEAAiE;YAC/D,qBAAqB,CAAC,MAAM;YAC5B,MAAM;YACN,sBAAsB,CAAC,MAAM,CAChC,CAAC;KACH;IAED,IAAI,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,sBAAsB,CAAC,KAAK,CAAC,EAAE;QACvE,OAAO;KACR;IAED,IAAI,qBAAqB,CAAC,MAAM,KAAK,qBAAqB,EAAE;QAC1D,kBAAkB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACzC,OAAO;KACR;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,MAAM,GAAG,qBAAqB,CAAC,CAAC;IACtF,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;IACnD,4BAA4B,CAC1B,qBAAqB,CAAC,QAAQ,CAAC,CAAC,EAAE,aAAa,GAAG,qBAAqB,CAAC,EACxE,sBAAsB,CAAC,QAAQ,CAAC,CAAC,EAAE,aAAa,GAAG,qBAAqB,CAAC,EACzE,kBAAkB,EAClB,eAAe,CAChB,CAAC;IACF,4BAA4B,CAC1B,qBAAqB,CAAC,QAAQ,CAAC,aAAa,GAAG,qBAAqB,CAAC,EACrE,sBAAsB,CAAC,QAAQ,CAAC,aAAa,GAAG,qBAAqB,CAAC,EACtE,kBAAkB,EAClB,eAAe,GAAG,aAAa,CAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Find modified validators by comparing two validators bytes using Buffer.compare() recursively
3
+ * - As noted in packages/state-transition/test/perf/util/loadState/findModifiedValidators.test.ts, serializing validators and compare Uint8Array is the fastest way
4
+ * - The performance is quite stable and can afford a lot of difference in validators (the benchmark tested up to 10k but it's not likely we have that difference in mainnet)
5
+ * - Also packages/state-transition/test/perf/misc/byteArrayEquals.test.ts shows that Buffer.compare() is very efficient for large Uint8Array
6
+ *
7
+ * @returns output parameter modifiedValidators: validator indices that are modified
8
+ */
9
+ export declare function findModifiedValidators(validatorsBytes: Uint8Array, validatorsBytes2: Uint8Array, modifiedValidators: number[], validatorOffset?: number): void;
10
+ //# sourceMappingURL=findModifiedValidators.d.ts.map
@@ -0,0 +1,26 @@
1
+ import { VALIDATOR_BYTES_SIZE } from "../sszBytes.js";
2
+ /**
3
+ * Find modified validators by comparing two validators bytes using Buffer.compare() recursively
4
+ * - As noted in packages/state-transition/test/perf/util/loadState/findModifiedValidators.test.ts, serializing validators and compare Uint8Array is the fastest way
5
+ * - The performance is quite stable and can afford a lot of difference in validators (the benchmark tested up to 10k but it's not likely we have that difference in mainnet)
6
+ * - Also packages/state-transition/test/perf/misc/byteArrayEquals.test.ts shows that Buffer.compare() is very efficient for large Uint8Array
7
+ *
8
+ * @returns output parameter modifiedValidators: validator indices that are modified
9
+ */
10
+ export function findModifiedValidators(validatorsBytes, validatorsBytes2, modifiedValidators, validatorOffset = 0) {
11
+ if (validatorsBytes.length !== validatorsBytes2.length) {
12
+ throw new Error("validatorsBytes.length !== validatorsBytes2.length " + validatorsBytes.length + " vs " + validatorsBytes2.length);
13
+ }
14
+ if (Buffer.compare(validatorsBytes, validatorsBytes2) === 0) {
15
+ return;
16
+ }
17
+ if (validatorsBytes.length === VALIDATOR_BYTES_SIZE) {
18
+ modifiedValidators.push(validatorOffset);
19
+ return;
20
+ }
21
+ const numValidator = Math.floor(validatorsBytes.length / VALIDATOR_BYTES_SIZE);
22
+ const halfValidator = Math.floor(numValidator / 2);
23
+ findModifiedValidators(validatorsBytes.subarray(0, halfValidator * VALIDATOR_BYTES_SIZE), validatorsBytes2.subarray(0, halfValidator * VALIDATOR_BYTES_SIZE), modifiedValidators, validatorOffset);
24
+ findModifiedValidators(validatorsBytes.subarray(halfValidator * VALIDATOR_BYTES_SIZE), validatorsBytes2.subarray(halfValidator * VALIDATOR_BYTES_SIZE), modifiedValidators, validatorOffset + halfValidator);
25
+ }
26
+ //# sourceMappingURL=findModifiedValidators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findModifiedValidators.js","sourceRoot":"","sources":["../../../src/util/loadState/findModifiedValidators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,gBAAgB,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CACpC,eAA2B,EAC3B,gBAA4B,EAC5B,kBAA4B,EAC5B,eAAe,GAAG,CAAC;IAEnB,IAAI,eAAe,CAAC,MAAM,KAAK,gBAAgB,CAAC,MAAM,EAAE;QACtD,MAAM,IAAI,KAAK,CACb,qDAAqD,GAAG,eAAe,CAAC,MAAM,GAAG,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAClH,CAAC;KACH;IAED,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE;QAC3D,OAAO;KACR;IAED,IAAI,eAAe,CAAC,MAAM,KAAK,oBAAoB,EAAE;QACnD,kBAAkB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACzC,OAAO;KACR;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,GAAG,oBAAoB,CAAC,CAAC;IAC/E,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;IACnD,sBAAsB,CACpB,eAAe,CAAC,QAAQ,CAAC,CAAC,EAAE,aAAa,GAAG,oBAAoB,CAAC,EACjE,gBAAgB,CAAC,QAAQ,CAAC,CAAC,EAAE,aAAa,GAAG,oBAAoB,CAAC,EAClE,kBAAkB,EAClB,eAAe,CAChB,CAAC;IACF,sBAAsB,CACpB,eAAe,CAAC,QAAQ,CAAC,aAAa,GAAG,oBAAoB,CAAC,EAC9D,gBAAgB,CAAC,QAAQ,CAAC,aAAa,GAAG,oBAAoB,CAAC,EAC/D,kBAAkB,EAClB,eAAe,GAAG,aAAa,CAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { ChainForkConfig } from "@lodestar/config";
2
+ import { BeaconStateAllForks } from "../../types.js";
3
+ type MigrateStateOutput = {
4
+ state: BeaconStateAllForks;
5
+ modifiedValidators: number[];
6
+ };
7
+ /**
8
+ * Load state from bytes given a seed state so that we share the same base tree. This gives some benefits:
9
+ * - Have single base tree across the application
10
+ * - Faster to load state
11
+ * - Less memory usage
12
+ * - Utilize the cached HashObjects in seed state due to a lot of validators are not changed, also the inactivity scores.
13
+ * @returns the new state and modified validators
14
+ */
15
+ export declare function loadState(config: ChainForkConfig, seedState: BeaconStateAllForks, stateBytes: Uint8Array): MigrateStateOutput;
16
+ export {};
17
+ //# sourceMappingURL=loadState.d.ts.map
@@ -0,0 +1,145 @@
1
+ import { deserializeContainerIgnoreFields, ssz } from "@lodestar/types";
2
+ import { ForkSeq } from "@lodestar/params";
3
+ import { VALIDATOR_BYTES_SIZE, getForkFromStateBytes, getStateTypeFromBytes } from "../sszBytes.js";
4
+ import { findModifiedValidators } from "./findModifiedValidators.js";
5
+ import { findModifiedInactivityScores } from "./findModifiedInactivityScores.js";
6
+ import { loadValidator } from "./loadValidator.js";
7
+ /**
8
+ * Load state from bytes given a seed state so that we share the same base tree. This gives some benefits:
9
+ * - Have single base tree across the application
10
+ * - Faster to load state
11
+ * - Less memory usage
12
+ * - Utilize the cached HashObjects in seed state due to a lot of validators are not changed, also the inactivity scores.
13
+ * @returns the new state and modified validators
14
+ */
15
+ export function loadState(config, seedState, stateBytes) {
16
+ // casting only to make typescript happy
17
+ const stateType = getStateTypeFromBytes(config, stateBytes);
18
+ const dataView = new DataView(stateBytes.buffer, stateBytes.byteOffset, stateBytes.byteLength);
19
+ const fieldRanges = stateType.getFieldRanges(dataView, 0, stateBytes.length);
20
+ const allFields = Object.keys(stateType.fields);
21
+ const validatorsFieldIndex = allFields.indexOf("validators");
22
+ // start with default view has the same performance to start with seed state
23
+ // and it is not fork dependent
24
+ const migratedState = deserializeContainerIgnoreFields(stateType, stateBytes, ["validators", "inactivityScores"], fieldRanges);
25
+ // validators are rarely changed
26
+ const validatorsRange = fieldRanges[validatorsFieldIndex];
27
+ const modifiedValidators = loadValidators(migratedState, seedState, stateBytes.subarray(validatorsRange.start, validatorsRange.end));
28
+ // inactivityScores are rarely changed
29
+ // this saves ~500ms of hashTreeRoot() time of state
30
+ const fork = getForkFromStateBytes(config, stateBytes);
31
+ const seedFork = config.getForkSeq(seedState.slot);
32
+ if (fork >= ForkSeq.altair && seedFork >= ForkSeq.altair) {
33
+ const inactivityScoresIndex = allFields.indexOf("inactivityScores");
34
+ const inactivityScoresRange = fieldRanges[inactivityScoresIndex];
35
+ loadInactivityScores(migratedState, seedState, stateBytes.subarray(inactivityScoresRange.start, inactivityScoresRange.end));
36
+ }
37
+ migratedState.commit();
38
+ return { state: migratedState, modifiedValidators };
39
+ }
40
+ /**
41
+ * This value is rarely changed as monitored 3 month state diffs on mainnet as of Sep 2023.
42
+ * Reusing this data helps save hashTreeRoot time of state ~500ms
43
+ *
44
+ * Given the below tree:
45
+ *
46
+ * seedState.inactivityScores ====> ROOT
47
+ * / \
48
+ * Hash01 Hash23
49
+ * / \ / \
50
+ * Sco0 Sco1 Sco2 Sco3
51
+ *
52
+ * if score 3 is modified, the new tree looks like this:
53
+ *
54
+ * migratedState.inactivityScores ====> ROOTa
55
+ * / \
56
+ * Hash01 Hash23a
57
+ * / \ / \
58
+ * Sco0 Sco1 Sco2 Sco3a
59
+ */
60
+ function loadInactivityScores(migratedState, seedState, inactivityScoresBytes) {
61
+ // migratedState starts with the same inactivityScores to seed state
62
+ migratedState.inactivityScores = seedState.inactivityScores.clone();
63
+ const oldValidator = migratedState.inactivityScores.length;
64
+ // UintNum64 = 8 bytes
65
+ const newValidator = inactivityScoresBytes.length / 8;
66
+ const minValidator = Math.min(oldValidator, newValidator);
67
+ const oldInactivityScores = migratedState.inactivityScores.serialize();
68
+ const isMoreValidator = newValidator >= oldValidator;
69
+ const modifiedValidators = [];
70
+ findModifiedInactivityScores(isMoreValidator ? oldInactivityScores : oldInactivityScores.subarray(0, minValidator * 8), isMoreValidator ? inactivityScoresBytes.subarray(0, minValidator * 8) : inactivityScoresBytes, modifiedValidators);
71
+ for (const validatorIndex of modifiedValidators) {
72
+ migratedState.inactivityScores.set(validatorIndex, ssz.UintNum64.deserialize(inactivityScoresBytes.subarray(validatorIndex * 8, (validatorIndex + 1) * 8)));
73
+ }
74
+ if (isMoreValidator) {
75
+ // add new inactivityScores
76
+ for (let validatorIndex = oldValidator; validatorIndex < newValidator; validatorIndex++) {
77
+ migratedState.inactivityScores.push(ssz.UintNum64.deserialize(inactivityScoresBytes.subarray(validatorIndex * 8, (validatorIndex + 1) * 8)));
78
+ }
79
+ }
80
+ else {
81
+ if (newValidator - 1 < 0) {
82
+ migratedState.inactivityScores = ssz.altair.InactivityScores.defaultViewDU();
83
+ }
84
+ else {
85
+ migratedState.inactivityScores = migratedState.inactivityScores.sliceTo(newValidator - 1);
86
+ }
87
+ }
88
+ }
89
+ /**
90
+ * As of Sep 2021, common validators of 2 mainnet states are rarely changed. However, the benchmark shows that
91
+ * 10k modified validators is not an issue. (see packages/state-transition/test/perf/util/loadState/findModifiedValidators.test.ts)
92
+ *
93
+ * This method loads validators from bytes given a seed state so that they share the same base tree. This gives some benefits:
94
+ * - Have single base tree across the application
95
+ * - Faster to load state
96
+ * - Less memory usage
97
+ * - Utilize the cached HashObjects in seed state due to a lot of validators are not changed
98
+ *
99
+ * Given the below tree:
100
+ *
101
+ * seedState.validators ====> ROOT
102
+ * / \
103
+ * Hash01 Hash23
104
+ * / \ / \
105
+ * Val0 Val1 Val2 Val3
106
+ *
107
+ * if validator 3 is modified, the new tree looks like this:
108
+ *
109
+ * migratedState.validators ====> ROOTa
110
+ * / \
111
+ * Hash01 Hash23a
112
+ * / \ / \
113
+ * Val0 Val1 Val2 Val3a
114
+ *
115
+ * @param migratedState state to be migrated, the validators are loaded to this state
116
+ * @returns modified validator indices
117
+ */
118
+ function loadValidators(migratedState, seedState, newValidatorsBytes) {
119
+ const seedValidatorCount = seedState.validators.length;
120
+ const newValidatorCount = Math.floor(newValidatorsBytes.length / VALIDATOR_BYTES_SIZE);
121
+ const isMoreValidator = newValidatorCount >= seedValidatorCount;
122
+ const minValidatorCount = Math.min(seedValidatorCount, newValidatorCount);
123
+ // migrated state starts with the same validators to seed state
124
+ migratedState.validators = seedState.validators.clone();
125
+ const seedValidatorsBytes = seedState.validators.serialize();
126
+ const modifiedValidators = [];
127
+ findModifiedValidators(isMoreValidator ? seedValidatorsBytes : seedValidatorsBytes.subarray(0, minValidatorCount * VALIDATOR_BYTES_SIZE), isMoreValidator ? newValidatorsBytes.subarray(0, minValidatorCount * VALIDATOR_BYTES_SIZE) : newValidatorsBytes, modifiedValidators);
128
+ for (const i of modifiedValidators) {
129
+ const seedValidator = seedState.validators.get(i);
130
+ const newValidatorBytes = newValidatorsBytes.subarray(i * VALIDATOR_BYTES_SIZE, (i + 1) * VALIDATOR_BYTES_SIZE);
131
+ migratedState.validators.set(i, loadValidator(seedValidator, newValidatorBytes));
132
+ }
133
+ if (newValidatorCount >= seedValidatorCount) {
134
+ // add new validators
135
+ for (let validatorIndex = seedValidatorCount; validatorIndex < newValidatorCount; validatorIndex++) {
136
+ migratedState.validators.push(ssz.phase0.Validator.deserializeToViewDU(newValidatorsBytes.subarray(validatorIndex * VALIDATOR_BYTES_SIZE, (validatorIndex + 1) * VALIDATOR_BYTES_SIZE)));
137
+ modifiedValidators.push(validatorIndex);
138
+ }
139
+ }
140
+ else {
141
+ migratedState.validators = migratedState.validators.sliceTo(newValidatorCount - 1);
142
+ }
143
+ return modifiedValidators;
144
+ }
145
+ //# sourceMappingURL=loadState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadState.js","sourceRoot":"","sources":["../../../src/util/loadState/loadState.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { CompositeViewDU } from "@chainsafe/ssz";
2
+ import { ssz } from "@lodestar/types";
3
+ /**
4
+ * Load validator from bytes given a seed validator.
5
+ * - Reuse pubkey and withdrawal credentials if possible to save memory
6
+ * - If it's a new validator, deserialize it
7
+ */
8
+ export declare function loadValidator(seedValidator: CompositeViewDU<typeof ssz.phase0.Validator>, newValidatorBytes: Uint8Array): CompositeViewDU<typeof ssz.phase0.Validator>;
9
+ //# sourceMappingURL=loadValidator.d.ts.map
@@ -0,0 +1,35 @@
1
+ import { deserializeContainerIgnoreFields, ssz } from "@lodestar/types";
2
+ /**
3
+ * Load validator from bytes given a seed validator.
4
+ * - Reuse pubkey and withdrawal credentials if possible to save memory
5
+ * - If it's a new validator, deserialize it
6
+ */
7
+ export function loadValidator(seedValidator, newValidatorBytes) {
8
+ const ignoredFields = getSameFields(seedValidator, newValidatorBytes);
9
+ if (ignoredFields.length > 0) {
10
+ const newValidatorValue = deserializeContainerIgnoreFields(ssz.phase0.Validator, newValidatorBytes, ignoredFields);
11
+ for (const field of ignoredFields) {
12
+ newValidatorValue[field] = seedValidator[field];
13
+ }
14
+ return ssz.phase0.Validator.toViewDU(newValidatorValue);
15
+ }
16
+ else {
17
+ return ssz.phase0.Validator.deserializeToViewDU(newValidatorBytes);
18
+ }
19
+ }
20
+ /**
21
+ * Return pubkey or withdrawalCredentials or both if they are the same.
22
+ */
23
+ function getSameFields(validator, validatorBytes) {
24
+ const ignoredFields = [];
25
+ const pubkey = validatorBytes.subarray(0, 48);
26
+ if (Buffer.compare(pubkey, validator.pubkey) === 0) {
27
+ ignoredFields.push("pubkey");
28
+ }
29
+ const withdrawalCredentials = validatorBytes.subarray(48, 80);
30
+ if (Buffer.compare(withdrawalCredentials, validator.withdrawalCredentials) === 0) {
31
+ ignoredFields.push("withdrawalCredentials");
32
+ }
33
+ return ignoredFields;
34
+ }
35
+ //# sourceMappingURL=loadValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadValidator.js","sourceRoot":"","sources":["../../../src/util/loadState/loadValidator.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,gCAAgC,EAAE,GAAG,EAAC,MAAM,iBAAiB,CAAC;AAEtE;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,aAA2D,EAC3D,iBAA6B;IAE7B,MAAM,aAAa,GAAG,aAAa,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;IACtE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;QAC5B,MAAM,iBAAiB,GAAG,gCAAgC,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;QACnH,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE;YACjC,iBAAiB,CAAC,KAAK,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;SACjD;QACD,OAAO,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;KACzD;SAAM;QACL,OAAO,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;KACpE;AACH,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,SAAuD,EACvD,cAA0B;IAE1B,MAAM,aAAa,GAA2C,EAAE,CAAC;IACjE,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9C,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QAClD,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;KAC9B;IAED,MAAM,qBAAqB,GAAG,cAAc,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9D,IAAI,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,SAAS,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE;QAChF,aAAa,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;KAC7C;IAED,OAAO,aAAa,CAAC;AACvB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /// <reference types="node" />
2
+ import { ChainForkConfig } from "@lodestar/config";
3
+ import { ForkSeq } from "@lodestar/params";
4
+ import { Slot, allForks } from "@lodestar/types";
5
+ /**
6
+ * 48 + 32 + 8 + 1 + 8 + 8 + 8 + 8 = 121
7
+ * ```
8
+ * class Validator(Container):
9
+ pubkey: BLSPubkey [fixed - 48 bytes]
10
+ withdrawal_credentials: Bytes32 [fixed - 32 bytes]
11
+ effective_balance: Gwei [fixed - 8 bytes]
12
+ slashed: boolean [fixed - 1 byte]
13
+ # Status epochs
14
+ activation_eligibility_epoch: Epoch [fixed - 8 bytes]
15
+ activation_epoch: Epoch [fixed - 8 bytes]
16
+ exit_epoch: Epoch [fixed - 8 bytes]
17
+ withdrawable_epoch: Epoch [fixed - 8 bytes]
18
+ ```
19
+ */
20
+ export declare const VALIDATOR_BYTES_SIZE = 121;
21
+ export declare function getForkFromStateBytes(config: ChainForkConfig, bytes: Buffer | Uint8Array): ForkSeq;
22
+ export declare function getStateTypeFromBytes(config: ChainForkConfig, bytes: Buffer | Uint8Array): allForks.AllForksSSZTypes["BeaconState"];
23
+ export declare function getStateSlotFromBytes(bytes: Uint8Array): Slot;
24
+ //# sourceMappingURL=sszBytes.d.ts.map
@@ -0,0 +1,44 @@
1
+ import { bytesToInt } from "@lodestar/utils";
2
+ /**
3
+ * Slot uint64
4
+ */
5
+ const SLOT_BYTE_COUNT = 8;
6
+ /**
7
+ * 48 + 32 + 8 + 1 + 8 + 8 + 8 + 8 = 121
8
+ * ```
9
+ * class Validator(Container):
10
+ pubkey: BLSPubkey [fixed - 48 bytes]
11
+ withdrawal_credentials: Bytes32 [fixed - 32 bytes]
12
+ effective_balance: Gwei [fixed - 8 bytes]
13
+ slashed: boolean [fixed - 1 byte]
14
+ # Status epochs
15
+ activation_eligibility_epoch: Epoch [fixed - 8 bytes]
16
+ activation_epoch: Epoch [fixed - 8 bytes]
17
+ exit_epoch: Epoch [fixed - 8 bytes]
18
+ withdrawable_epoch: Epoch [fixed - 8 bytes]
19
+ ```
20
+ */
21
+ export const VALIDATOR_BYTES_SIZE = 121;
22
+ /**
23
+ * 8 + 32 = 40
24
+ * ```
25
+ * class BeaconState(Container):
26
+ * genesis_time: uint64 [fixed - 8 bytes]
27
+ * genesis_validators_root: Root [fixed - 32 bytes]
28
+ * slot: Slot [fixed - 8 bytes]
29
+ * ...
30
+ * ```
31
+ */
32
+ const SLOT_BYTES_POSITION_IN_STATE = 40;
33
+ export function getForkFromStateBytes(config, bytes) {
34
+ const slot = bytesToInt(bytes.subarray(SLOT_BYTES_POSITION_IN_STATE, SLOT_BYTES_POSITION_IN_STATE + SLOT_BYTE_COUNT));
35
+ return config.getForkSeq(slot);
36
+ }
37
+ export function getStateTypeFromBytes(config, bytes) {
38
+ const slot = getStateSlotFromBytes(bytes);
39
+ return config.getForkTypes(slot).BeaconState;
40
+ }
41
+ export function getStateSlotFromBytes(bytes) {
42
+ return bytesToInt(bytes.subarray(SLOT_BYTES_POSITION_IN_STATE, SLOT_BYTES_POSITION_IN_STATE + SLOT_BYTE_COUNT));
43
+ }
44
+ //# sourceMappingURL=sszBytes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sszBytes.js","sourceRoot":"","sources":["../../src/util/sszBytes.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAE3C;;GAEG;AACH,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAExC;;;;;;;;;GASG;AACH,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAExC,MAAM,UAAU,qBAAqB,CAAC,MAAuB,EAAE,KAA0B;IACvF,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,4BAA4B,EAAE,4BAA4B,GAAG,eAAe,CAAC,CAAC,CAAC;IACtH,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,MAAuB,EACvB,KAA0B;IAE1B,MAAM,IAAI,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAiB;IACrD,OAAO,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,4BAA4B,EAAE,4BAA4B,GAAG,eAAe,CAAC,CAAC,CAAC;AAClH,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { Epoch, phase0, ValidatorIndex } from "@lodestar/types";
2
2
  import { ChainForkConfig } from "@lodestar/config";
3
+ import { ForkSeq } from "@lodestar/params";
3
4
  import { BeaconStateAllForks } from "../types.js";
4
5
  /**
5
6
  * Check if [[validator]] is active
@@ -15,5 +16,6 @@ export declare function isSlashableValidator(validator: phase0.Validator, epoch:
15
16
  * NAIVE - SLOW CODE 🐢
16
17
  */
17
18
  export declare function getActiveValidatorIndices(state: BeaconStateAllForks, epoch: Epoch): ValidatorIndex[];
19
+ export declare function getActivationChurnLimit(config: ChainForkConfig, fork: ForkSeq, activeValidatorCount: number): number;
18
20
  export declare function getChurnLimit(config: ChainForkConfig, activeValidatorCount: number): number;
19
21
  //# sourceMappingURL=validator.d.ts.map