@lodestar/state-transition 1.22.0-dev.9c62011986 → 1.22.0-dev.9f4bf50408

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 (146) hide show
  1. package/LICENSE +201 -165
  2. package/lib/block/index.js +1 -1
  3. package/lib/block/index.js.map +1 -1
  4. package/lib/block/initiateValidatorExit.d.ts +2 -1
  5. package/lib/block/initiateValidatorExit.js +21 -13
  6. package/lib/block/initiateValidatorExit.js.map +1 -1
  7. package/lib/block/isValidIndexedAttestation.js +5 -2
  8. package/lib/block/isValidIndexedAttestation.js.map +1 -1
  9. package/lib/block/processAttestationPhase0.d.ts +2 -2
  10. package/lib/block/processAttestationPhase0.js +33 -11
  11. package/lib/block/processAttestationPhase0.js.map +1 -1
  12. package/lib/block/processAttestations.d.ts +2 -2
  13. package/lib/block/processAttestations.js.map +1 -1
  14. package/lib/block/processAttestationsAltair.d.ts +2 -2
  15. package/lib/block/processAttestationsAltair.js +3 -3
  16. package/lib/block/processAttestationsAltair.js.map +1 -1
  17. package/lib/block/processBlockHeader.js +3 -2
  18. package/lib/block/processBlockHeader.js.map +1 -1
  19. package/lib/block/processBlsToExecutionChange.js +3 -2
  20. package/lib/block/processBlsToExecutionChange.js.map +1 -1
  21. package/lib/block/processConsolidationRequest.d.ts +4 -0
  22. package/lib/block/processConsolidationRequest.js +55 -0
  23. package/lib/block/processConsolidationRequest.js.map +1 -0
  24. package/lib/block/processDeposit.d.ts +8 -0
  25. package/lib/block/processDeposit.js +94 -54
  26. package/lib/block/processDeposit.js.map +1 -1
  27. package/lib/block/processDepositRequest.d.ts +5 -0
  28. package/lib/block/processDepositRequest.js +9 -0
  29. package/lib/block/processDepositRequest.js.map +1 -0
  30. package/lib/block/processExecutionPayload.js +4 -3
  31. package/lib/block/processExecutionPayload.js.map +1 -1
  32. package/lib/block/processOperations.d.ts +4 -1
  33. package/lib/block/processOperations.js +21 -4
  34. package/lib/block/processOperations.js.map +1 -1
  35. package/lib/block/processVoluntaryExit.d.ts +2 -1
  36. package/lib/block/processVoluntaryExit.js +16 -6
  37. package/lib/block/processVoluntaryExit.js.map +1 -1
  38. package/lib/block/processWithdrawalRequest.d.ts +5 -0
  39. package/lib/block/processWithdrawalRequest.js +67 -0
  40. package/lib/block/processWithdrawalRequest.js.map +1 -0
  41. package/lib/block/processWithdrawals.d.ts +5 -3
  42. package/lib/block/processWithdrawals.js +70 -17
  43. package/lib/block/processWithdrawals.js.map +1 -1
  44. package/lib/block/slashValidator.js +9 -5
  45. package/lib/block/slashValidator.js.map +1 -1
  46. package/lib/cache/effectiveBalanceIncrements.d.ts +3 -4
  47. package/lib/cache/effectiveBalanceIncrements.js +5 -5
  48. package/lib/cache/effectiveBalanceIncrements.js.map +1 -1
  49. package/lib/cache/epochCache.d.ts +66 -8
  50. package/lib/cache/epochCache.js +185 -22
  51. package/lib/cache/epochCache.js.map +1 -1
  52. package/lib/cache/epochTransitionCache.d.ts +12 -2
  53. package/lib/cache/epochTransitionCache.js +6 -3
  54. package/lib/cache/epochTransitionCache.js.map +1 -1
  55. package/lib/cache/pubkeyCache.d.ts +23 -3
  56. package/lib/cache/pubkeyCache.js +8 -1
  57. package/lib/cache/pubkeyCache.js.map +1 -1
  58. package/lib/cache/stateCache.d.ts +4 -2
  59. package/lib/cache/stateCache.js +2 -1
  60. package/lib/cache/stateCache.js.map +1 -1
  61. package/lib/cache/syncCommitteeCache.js +2 -2
  62. package/lib/cache/syncCommitteeCache.js.map +1 -1
  63. package/lib/cache/types.d.ts +1 -0
  64. package/lib/epoch/index.d.ts +6 -2
  65. package/lib/epoch/index.js +27 -5
  66. package/lib/epoch/index.js.map +1 -1
  67. package/lib/epoch/processEffectiveBalanceUpdates.d.ts +4 -1
  68. package/lib/epoch/processEffectiveBalanceUpdates.js +25 -6
  69. package/lib/epoch/processEffectiveBalanceUpdates.js.map +1 -1
  70. package/lib/epoch/processPendingBalanceDeposits.d.ts +12 -0
  71. package/lib/epoch/processPendingBalanceDeposits.js +68 -0
  72. package/lib/epoch/processPendingBalanceDeposits.js.map +1 -0
  73. package/lib/epoch/processPendingConsolidations.d.ts +16 -0
  74. package/lib/epoch/processPendingConsolidations.js +49 -0
  75. package/lib/epoch/processPendingConsolidations.js.map +1 -0
  76. package/lib/epoch/processRegistryUpdates.d.ts +2 -1
  77. package/lib/epoch/processRegistryUpdates.js +6 -3
  78. package/lib/epoch/processRegistryUpdates.js.map +1 -1
  79. package/lib/epoch/processRewardsAndPenalties.js +2 -1
  80. package/lib/epoch/processRewardsAndPenalties.js.map +1 -1
  81. package/lib/epoch/processSyncCommitteeUpdates.d.ts +2 -1
  82. package/lib/epoch/processSyncCommitteeUpdates.js +4 -3
  83. package/lib/epoch/processSyncCommitteeUpdates.js.map +1 -1
  84. package/lib/index.d.ts +2 -2
  85. package/lib/index.js +1 -1
  86. package/lib/index.js.map +1 -1
  87. package/lib/metrics.d.ts +5 -0
  88. package/lib/metrics.js.map +1 -1
  89. package/lib/signatureSets/attesterSlashings.d.ts +3 -3
  90. package/lib/signatureSets/attesterSlashings.js +1 -2
  91. package/lib/signatureSets/attesterSlashings.js.map +1 -1
  92. package/lib/signatureSets/index.js +2 -2
  93. package/lib/signatureSets/index.js.map +1 -1
  94. package/lib/signatureSets/indexedAttestation.js +2 -1
  95. package/lib/signatureSets/indexedAttestation.js.map +1 -1
  96. package/lib/slot/index.d.ts +1 -0
  97. package/lib/slot/index.js +1 -0
  98. package/lib/slot/index.js.map +1 -1
  99. package/lib/slot/upgradeStateToAltair.js +1 -1
  100. package/lib/slot/upgradeStateToAltair.js.map +1 -1
  101. package/lib/slot/upgradeStateToElectra.d.ts +8 -0
  102. package/lib/slot/upgradeStateToElectra.js +138 -0
  103. package/lib/slot/upgradeStateToElectra.js.map +1 -0
  104. package/lib/stateTransition.d.ts +1 -0
  105. package/lib/stateTransition.js +12 -8
  106. package/lib/stateTransition.js.map +1 -1
  107. package/lib/types.d.ts +2 -2
  108. package/lib/util/balance.js +2 -2
  109. package/lib/util/balance.js.map +1 -1
  110. package/lib/util/deposit.d.ts +4 -0
  111. package/lib/util/deposit.js +22 -0
  112. package/lib/util/deposit.js.map +1 -0
  113. package/lib/util/electra.d.ts +8 -0
  114. package/lib/util/electra.js +47 -0
  115. package/lib/util/electra.js.map +1 -0
  116. package/lib/util/epoch.d.ts +4 -1
  117. package/lib/util/epoch.js +37 -0
  118. package/lib/util/epoch.js.map +1 -1
  119. package/lib/util/epochShuffling.js +2 -3
  120. package/lib/util/epochShuffling.js.map +1 -1
  121. package/lib/util/execution.js +8 -0
  122. package/lib/util/execution.js.map +1 -1
  123. package/lib/util/genesis.d.ts +1 -1
  124. package/lib/util/genesis.js +30 -9
  125. package/lib/util/genesis.js.map +1 -1
  126. package/lib/util/index.d.ts +3 -0
  127. package/lib/util/index.js +3 -0
  128. package/lib/util/index.js.map +1 -1
  129. package/lib/util/loadState/index.d.ts +1 -1
  130. package/lib/util/loadState/index.js +1 -1
  131. package/lib/util/loadState/index.js.map +1 -1
  132. package/lib/util/loadState/loadState.d.ts +7 -0
  133. package/lib/util/loadState/loadState.js +15 -0
  134. package/lib/util/loadState/loadState.js.map +1 -1
  135. package/lib/util/seed.d.ts +4 -3
  136. package/lib/util/seed.js +11 -10
  137. package/lib/util/seed.js.map +1 -1
  138. package/lib/util/syncCommittee.d.ts +2 -1
  139. package/lib/util/syncCommittee.js +2 -2
  140. package/lib/util/syncCommittee.js.map +1 -1
  141. package/lib/util/validator.d.ts +10 -1
  142. package/lib/util/validator.js +35 -1
  143. package/lib/util/validator.js.map +1 -1
  144. package/lib/util/weakSubjectivity.js +2 -2
  145. package/lib/util/weakSubjectivity.js.map +1 -1
  146. package/package.json +9 -8
@@ -1,5 +1,5 @@
1
- import { FAR_FUTURE_EPOCH } from "@lodestar/params";
2
- import { isActiveValidator } from "../util/index.js";
1
+ import { FAR_FUTURE_EPOCH, ForkSeq } from "@lodestar/params";
2
+ import { getPendingBalanceToWithdraw, isActiveValidator } from "../util/index.js";
3
3
  import { verifyVoluntaryExitSignature } from "../signatureSets/index.js";
4
4
  import { initiateValidatorExit } from "./index.js";
5
5
  /**
@@ -7,12 +7,15 @@ import { initiateValidatorExit } from "./index.js";
7
7
  *
8
8
  * PERF: Work depends on number of VoluntaryExit per block. On regular networks the average is 0 / block.
9
9
  */
10
- export function processVoluntaryExit(state, signedVoluntaryExit, verifySignature = true) {
11
- if (!isValidVoluntaryExit(state, signedVoluntaryExit, verifySignature)) {
12
- throw Error("Invalid voluntary exit");
10
+ export function processVoluntaryExit(fork, state, signedVoluntaryExit, verifySignature = true) {
11
+ const isValidExit = fork >= ForkSeq.electra
12
+ ? isValidVoluntaryExitElectra(state, signedVoluntaryExit, verifySignature)
13
+ : isValidVoluntaryExit(state, signedVoluntaryExit, verifySignature);
14
+ if (!isValidExit) {
15
+ throw Error(`Invalid voluntary exit at forkSeq=${fork}`);
13
16
  }
14
17
  const validator = state.validators.get(signedVoluntaryExit.message.validatorIndex);
15
- initiateValidatorExit(state, validator);
18
+ initiateValidatorExit(fork, state, validator);
16
19
  }
17
20
  export function isValidVoluntaryExit(state, signedVoluntaryExit, verifySignature = true) {
18
21
  const { config, epochCtx } = state;
@@ -31,4 +34,11 @@ export function isValidVoluntaryExit(state, signedVoluntaryExit, verifySignature
31
34
  // verify signature
32
35
  (!verifySignature || verifyVoluntaryExitSignature(state, signedVoluntaryExit)));
33
36
  }
37
+ function isValidVoluntaryExitElectra(state, signedVoluntaryExit, verifySignature = true) {
38
+ // only exit validator if it has no pending withdrawals in the queue (post-Electra only)
39
+ if (getPendingBalanceToWithdraw(state, signedVoluntaryExit.message.validatorIndex) === 0) {
40
+ return isValidVoluntaryExit(state, signedVoluntaryExit, verifySignature);
41
+ }
42
+ return false;
43
+ }
34
44
  //# sourceMappingURL=processVoluntaryExit.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"processVoluntaryExit.js","sourceRoot":"","sources":["../../src/block/processVoluntaryExit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAC,4BAA4B,EAAC,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAC,qBAAqB,EAAC,MAAM,YAAY,CAAC;AAEjD;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAgC,EAChC,mBAA+C,EAC/C,eAAe,GAAG,IAAI;IAEtB,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,EAAE,eAAe,CAAC,EAAE,CAAC;QACvE,MAAM,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACnF,qBAAqB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAgC,EAChC,mBAA+C,EAC/C,eAAe,GAAG,IAAI;IAEtB,MAAM,EAAC,MAAM,EAAE,QAAQ,EAAC,GAAG,KAAK,CAAC;IACjC,MAAM,aAAa,GAAG,mBAAmB,CAAC,OAAO,CAAC;IAClD,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IACrE,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC;IAEpC,OAAO;IACL,iCAAiC;IACjC,iBAAiB,CAAC,SAAS,EAAE,YAAY,CAAC;QAC1C,qCAAqC;QACrC,SAAS,CAAC,SAAS,KAAK,gBAAgB;QACxC,qFAAqF;QACrF,YAAY,IAAI,aAAa,CAAC,KAAK;QACnC,mDAAmD;QACnD,YAAY,IAAI,SAAS,CAAC,eAAe,GAAG,MAAM,CAAC,sBAAsB;QACzE,mBAAmB;QACnB,CAAC,CAAC,eAAe,IAAI,4BAA4B,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAC/E,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"processVoluntaryExit.js","sourceRoot":"","sources":["../../src/block/processVoluntaryExit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAE,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAC,2BAA2B,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAEhF,OAAO,EAAC,4BAA4B,EAAC,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAC,qBAAqB,EAAC,MAAM,YAAY,CAAC;AAEjD;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAa,EACb,KAAgC,EAChC,mBAA+C,EAC/C,eAAe,GAAG,IAAI;IAEtB,MAAM,WAAW,GACf,IAAI,IAAI,OAAO,CAAC,OAAO;QACrB,CAAC,CAAC,2BAA2B,CAAC,KAAiC,EAAE,mBAAmB,EAAE,eAAe,CAAC;QACtG,CAAC,CAAC,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,EAAE,eAAe,CAAC,CAAC;IACxE,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,KAAK,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACnF,qBAAqB,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAgC,EAChC,mBAA+C,EAC/C,eAAe,GAAG,IAAI;IAEtB,MAAM,EAAC,MAAM,EAAE,QAAQ,EAAC,GAAG,KAAK,CAAC;IACjC,MAAM,aAAa,GAAG,mBAAmB,CAAC,OAAO,CAAC;IAClD,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IACrE,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC;IAEpC,OAAO;IACL,iCAAiC;IACjC,iBAAiB,CAAC,SAAS,EAAE,YAAY,CAAC;QAC1C,qCAAqC;QACrC,SAAS,CAAC,SAAS,KAAK,gBAAgB;QACxC,qFAAqF;QACrF,YAAY,IAAI,aAAa,CAAC,KAAK;QACnC,mDAAmD;QACnD,YAAY,IAAI,SAAS,CAAC,eAAe,GAAG,MAAM,CAAC,sBAAsB;QACzE,mBAAmB;QACnB,CAAC,CAAC,eAAe,IAAI,4BAA4B,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAC/E,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B,CAClC,KAA+B,EAC/B,mBAA+C,EAC/C,eAAe,GAAG,IAAI;IAEtB,wFAAwF;IACxF,IAAI,2BAA2B,CAAC,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QACzF,OAAO,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,EAAE,eAAe,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { electra } from "@lodestar/types";
2
+ import { ForkSeq } from "@lodestar/params";
3
+ import { CachedBeaconStateElectra } from "../types.js";
4
+ export declare function processWithdrawalRequest(fork: ForkSeq, state: CachedBeaconStateElectra, withdrawalRequest: electra.WithdrawalRequest): void;
5
+ //# sourceMappingURL=processWithdrawalRequest.d.ts.map
@@ -0,0 +1,67 @@
1
+ import { ssz } from "@lodestar/types";
2
+ import { FAR_FUTURE_EPOCH, MIN_ACTIVATION_BALANCE, PENDING_PARTIAL_WITHDRAWALS_LIMIT, FULL_EXIT_REQUEST_AMOUNT, } from "@lodestar/params";
3
+ import { toHex } from "@lodestar/utils";
4
+ import { hasCompoundingWithdrawalCredential, hasExecutionWithdrawalCredential } from "../util/electra.js";
5
+ import { getPendingBalanceToWithdraw, isActiveValidator } from "../util/validator.js";
6
+ import { computeExitEpochAndUpdateChurn } from "../util/epoch.js";
7
+ import { initiateValidatorExit } from "./initiateValidatorExit.js";
8
+ export function processWithdrawalRequest(fork, state, withdrawalRequest) {
9
+ const amount = Number(withdrawalRequest.amount);
10
+ const { pendingPartialWithdrawals, validators, epochCtx } = state;
11
+ // no need to use unfinalized pubkey cache from 6110 as validator won't be active anyway
12
+ const { pubkey2index, config } = epochCtx;
13
+ const isFullExitRequest = amount === FULL_EXIT_REQUEST_AMOUNT;
14
+ // If partial withdrawal queue is full, only full exits are processed
15
+ if (pendingPartialWithdrawals.length >= PENDING_PARTIAL_WITHDRAWALS_LIMIT && !isFullExitRequest) {
16
+ return;
17
+ }
18
+ // bail out if validator is not in beacon state
19
+ // note that we don't need to check for 6110 unfinalized vals as they won't be eligible for withdraw/exit anyway
20
+ const validatorIndex = pubkey2index.get(withdrawalRequest.validatorPubkey);
21
+ if (validatorIndex === undefined) {
22
+ return;
23
+ }
24
+ const validator = validators.get(validatorIndex);
25
+ if (!isValidatorEligibleForWithdrawOrExit(validator, withdrawalRequest.sourceAddress, state)) {
26
+ return;
27
+ }
28
+ // TODO Electra: Consider caching pendingPartialWithdrawals
29
+ const pendingBalanceToWithdraw = getPendingBalanceToWithdraw(state, validatorIndex);
30
+ const validatorBalance = state.balances.get(validatorIndex);
31
+ if (isFullExitRequest) {
32
+ // only exit validator if it has no pending withdrawals in the queue
33
+ if (pendingBalanceToWithdraw === 0) {
34
+ initiateValidatorExit(fork, state, validator);
35
+ }
36
+ return;
37
+ }
38
+ // partial withdrawal request
39
+ const hasSufficientEffectiveBalance = validator.effectiveBalance >= MIN_ACTIVATION_BALANCE;
40
+ const hasExcessBalance = validatorBalance > MIN_ACTIVATION_BALANCE + pendingBalanceToWithdraw;
41
+ // Only allow partial withdrawals with compounding withdrawal credentials
42
+ if (hasCompoundingWithdrawalCredential(validator.withdrawalCredentials) &&
43
+ hasSufficientEffectiveBalance &&
44
+ hasExcessBalance) {
45
+ const amountToWithdraw = BigInt(Math.min(validatorBalance - MIN_ACTIVATION_BALANCE - pendingBalanceToWithdraw, amount));
46
+ const exitQueueEpoch = computeExitEpochAndUpdateChurn(state, amountToWithdraw);
47
+ const withdrawableEpoch = exitQueueEpoch + config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY;
48
+ const pendingPartialWithdrawal = ssz.electra.PendingPartialWithdrawal.toViewDU({
49
+ index: validatorIndex,
50
+ amount: amountToWithdraw,
51
+ withdrawableEpoch,
52
+ });
53
+ state.pendingPartialWithdrawals.push(pendingPartialWithdrawal);
54
+ }
55
+ }
56
+ function isValidatorEligibleForWithdrawOrExit(validator, sourceAddress, state) {
57
+ const { withdrawalCredentials } = validator;
58
+ const addressStr = toHex(withdrawalCredentials.subarray(12));
59
+ const sourceAddressStr = toHex(sourceAddress);
60
+ const { epoch: currentEpoch, config } = state.epochCtx;
61
+ return (hasExecutionWithdrawalCredential(withdrawalCredentials) &&
62
+ addressStr === sourceAddressStr &&
63
+ isActiveValidator(validator, currentEpoch) &&
64
+ validator.exitEpoch === FAR_FUTURE_EPOCH &&
65
+ currentEpoch >= validator.activationEpoch + config.SHARD_COMMITTEE_PERIOD);
66
+ }
67
+ //# sourceMappingURL=processWithdrawalRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processWithdrawalRequest.js","sourceRoot":"","sources":["../../src/block/processWithdrawalRequest.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,10 @@
1
1
  import { capella } from "@lodestar/types";
2
- import { CachedBeaconStateCapella } from "../types.js";
3
- export declare function processWithdrawals(state: CachedBeaconStateCapella, payload: capella.FullOrBlindedExecutionPayload): void;
4
- export declare function getExpectedWithdrawals(state: CachedBeaconStateCapella): {
2
+ import { ForkSeq } from "@lodestar/params";
3
+ import { CachedBeaconStateCapella, CachedBeaconStateElectra } from "../types.js";
4
+ export declare function processWithdrawals(fork: ForkSeq, state: CachedBeaconStateCapella | CachedBeaconStateElectra, payload: capella.FullOrBlindedExecutionPayload): void;
5
+ export declare function getExpectedWithdrawals(fork: ForkSeq, state: CachedBeaconStateCapella | CachedBeaconStateElectra): {
5
6
  withdrawals: capella.Withdrawal[];
6
7
  sampledValidators: number;
8
+ partialWithdrawalsCount: number;
7
9
  };
8
10
  //# sourceMappingURL=processWithdrawals.d.ts.map
@@ -1,15 +1,18 @@
1
- import { byteArrayEquals, toHexString } from "@chainsafe/ssz";
1
+ import { byteArrayEquals } from "@chainsafe/ssz";
2
2
  import { ssz } from "@lodestar/types";
3
- import { MAX_EFFECTIVE_BALANCE, MAX_WITHDRAWALS_PER_PAYLOAD, MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP, } from "@lodestar/params";
4
- import { decreaseBalance, hasEth1WithdrawalCredential, isCapellaPayloadHeader } from "../util/index.js";
5
- export function processWithdrawals(state, payload) {
6
- const { withdrawals: expectedWithdrawals } = getExpectedWithdrawals(state);
3
+ import { MAX_WITHDRAWALS_PER_PAYLOAD, MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP, ForkSeq, MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP, FAR_FUTURE_EPOCH, MIN_ACTIVATION_BALANCE, MAX_EFFECTIVE_BALANCE, } from "@lodestar/params";
4
+ import { toRootHex } from "@lodestar/utils";
5
+ import { decreaseBalance, getMaxEffectiveBalance, hasEth1WithdrawalCredential, hasExecutionWithdrawalCredential, isCapellaPayloadHeader, } from "../util/index.js";
6
+ export function processWithdrawals(fork, state, payload) {
7
+ // partialWithdrawalsCount is withdrawals coming from EL since electra (EIP-7002)
8
+ // TODO - electra: may switch to executionWithdrawalsCount
9
+ const { withdrawals: expectedWithdrawals, partialWithdrawalsCount } = getExpectedWithdrawals(fork, state);
7
10
  const numWithdrawals = expectedWithdrawals.length;
8
11
  if (isCapellaPayloadHeader(payload)) {
9
12
  const expectedWithdrawalsRoot = ssz.capella.Withdrawals.hashTreeRoot(expectedWithdrawals);
10
13
  const actualWithdrawalsRoot = payload.withdrawalsRoot;
11
14
  if (!byteArrayEquals(expectedWithdrawalsRoot, actualWithdrawalsRoot)) {
12
- throw Error(`Invalid withdrawalsRoot of executionPayloadHeader, expected=${toHexString(expectedWithdrawalsRoot)}, actual=${toHexString(actualWithdrawalsRoot)}`);
15
+ throw Error(`Invalid withdrawalsRoot of executionPayloadHeader, expected=${toRootHex(expectedWithdrawalsRoot)}, actual=${toRootHex(actualWithdrawalsRoot)}`);
13
16
  }
14
17
  }
15
18
  else {
@@ -27,6 +30,10 @@ export function processWithdrawals(state, payload) {
27
30
  const withdrawal = expectedWithdrawals[i];
28
31
  decreaseBalance(state, withdrawal.validatorIndex, Number(withdrawal.amount));
29
32
  }
33
+ if (fork >= ForkSeq.electra) {
34
+ const stateElectra = state;
35
+ stateElectra.pendingPartialWithdrawals = stateElectra.pendingPartialWithdrawals.sliceFrom(partialWithdrawalsCount);
36
+ }
30
37
  // Update the nextWithdrawalIndex
31
38
  if (expectedWithdrawals.length > 0) {
32
39
  const latestWithdrawal = expectedWithdrawals[expectedWithdrawals.length - 1];
@@ -45,39 +52,85 @@ export function processWithdrawals(state, payload) {
45
52
  (state.nextWithdrawalValidatorIndex + MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP) % state.validators.length;
46
53
  }
47
54
  }
48
- export function getExpectedWithdrawals(state) {
55
+ export function getExpectedWithdrawals(fork, state) {
56
+ if (fork < ForkSeq.capella) {
57
+ throw new Error(`getExpectedWithdrawals not supported at forkSeq=${fork} < ForkSeq.capella`);
58
+ }
49
59
  const epoch = state.epochCtx.epoch;
50
60
  let withdrawalIndex = state.nextWithdrawalIndex;
51
61
  const { validators, balances, nextWithdrawalValidatorIndex } = state;
62
+ const withdrawals = [];
63
+ const isPostElectra = fork >= ForkSeq.electra;
64
+ if (isPostElectra) {
65
+ const stateElectra = state;
66
+ // MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP = 8, PENDING_PARTIAL_WITHDRAWALS_LIMIT: 134217728 so we should only call getAllReadonly() if it makes sense
67
+ // pendingPartialWithdrawals comes from EIP-7002 smart contract where it takes fee so it's more likely than not validator is in correct condition to withdraw
68
+ // also we may break early if withdrawableEpoch > epoch
69
+ const allPendingPartialWithdrawals = stateElectra.pendingPartialWithdrawals.length <= MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP
70
+ ? stateElectra.pendingPartialWithdrawals.getAllReadonly()
71
+ : null;
72
+ // EIP-7002: Execution layer triggerable withdrawals
73
+ for (let i = 0; i < stateElectra.pendingPartialWithdrawals.length; i++) {
74
+ const withdrawal = allPendingPartialWithdrawals
75
+ ? allPendingPartialWithdrawals[i]
76
+ : stateElectra.pendingPartialWithdrawals.getReadonly(i);
77
+ if (withdrawal.withdrawableEpoch > epoch || withdrawals.length === MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP) {
78
+ break;
79
+ }
80
+ const validator = validators.getReadonly(withdrawal.index);
81
+ if (validator.exitEpoch === FAR_FUTURE_EPOCH &&
82
+ validator.effectiveBalance >= MIN_ACTIVATION_BALANCE &&
83
+ balances.get(withdrawal.index) > MIN_ACTIVATION_BALANCE) {
84
+ const balanceOverMinActivationBalance = BigInt(balances.get(withdrawal.index) - MIN_ACTIVATION_BALANCE);
85
+ const withdrawableBalance = balanceOverMinActivationBalance < withdrawal.amount ? balanceOverMinActivationBalance : withdrawal.amount;
86
+ withdrawals.push({
87
+ index: withdrawalIndex,
88
+ validatorIndex: withdrawal.index,
89
+ address: validator.withdrawalCredentials.subarray(12),
90
+ amount: withdrawableBalance,
91
+ });
92
+ withdrawalIndex++;
93
+ }
94
+ }
95
+ }
96
+ // partialWithdrawalsCount is withdrawals coming from EL since electra (EIP-7002)
97
+ const partialWithdrawalsCount = withdrawals.length;
52
98
  const bound = Math.min(validators.length, MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP);
53
99
  let n = 0;
54
- const withdrawals = [];
55
100
  // Just run a bounded loop max iterating over all withdrawals
56
101
  // however breaks out once we have MAX_WITHDRAWALS_PER_PAYLOAD
57
102
  for (n = 0; n < bound; n++) {
58
103
  // Get next validator in turn
59
104
  const validatorIndex = (nextWithdrawalValidatorIndex + n) % validators.length;
60
- // It's most likely for validators to not have set eth1 credentials, than having 0 balance
61
105
  const validator = validators.getReadonly(validatorIndex);
62
- if (!hasEth1WithdrawalCredential(validator.withdrawalCredentials)) {
106
+ const balance = balances.get(validatorIndex);
107
+ const { withdrawableEpoch, withdrawalCredentials, effectiveBalance } = validator;
108
+ const hasWithdrawableCredentials = isPostElectra
109
+ ? hasExecutionWithdrawalCredential(withdrawalCredentials)
110
+ : hasEth1WithdrawalCredential(withdrawalCredentials);
111
+ // early skip for balance = 0 as its now more likely that validator has exited/slahed with
112
+ // balance zero than not have withdrawal credentials set
113
+ if (balance === 0 || !hasWithdrawableCredentials) {
63
114
  continue;
64
115
  }
65
- const balance = balances.get(validatorIndex);
66
- if (balance > 0 && validator.withdrawableEpoch <= epoch) {
116
+ // capella full withdrawal
117
+ if (withdrawableEpoch <= epoch) {
67
118
  withdrawals.push({
68
119
  index: withdrawalIndex,
69
120
  validatorIndex,
70
- address: validator.withdrawalCredentials.slice(12),
121
+ address: validator.withdrawalCredentials.subarray(12),
71
122
  amount: BigInt(balance),
72
123
  });
73
124
  withdrawalIndex++;
74
125
  }
75
- else if (validator.effectiveBalance === MAX_EFFECTIVE_BALANCE && balance > MAX_EFFECTIVE_BALANCE) {
126
+ else if (effectiveBalance === (isPostElectra ? getMaxEffectiveBalance(withdrawalCredentials) : MAX_EFFECTIVE_BALANCE) &&
127
+ balance > effectiveBalance) {
128
+ // capella partial withdrawal
76
129
  withdrawals.push({
77
130
  index: withdrawalIndex,
78
131
  validatorIndex,
79
- address: validator.withdrawalCredentials.slice(12),
80
- amount: BigInt(balance - MAX_EFFECTIVE_BALANCE),
132
+ address: validator.withdrawalCredentials.subarray(12),
133
+ amount: BigInt(balance - effectiveBalance),
81
134
  });
82
135
  withdrawalIndex++;
83
136
  }
@@ -86,6 +139,6 @@ export function getExpectedWithdrawals(state) {
86
139
  break;
87
140
  }
88
141
  }
89
- return { withdrawals, sampledValidators: n };
142
+ return { withdrawals, sampledValidators: n, partialWithdrawalsCount };
90
143
  }
91
144
  //# sourceMappingURL=processWithdrawals.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"processWithdrawals.js","sourceRoot":"","sources":["../../src/block/processWithdrawals.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"processWithdrawals.js","sourceRoot":"","sources":["../../src/block/processWithdrawals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAC,GAAG,EAAU,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,2BAA2B,EAC3B,oCAAoC,EACpC,OAAO,EACP,0CAA0C,EAC1C,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,2BAA2B,EAC3B,gCAAgC,EAChC,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,UAAU,kBAAkB,CAChC,IAAa,EACb,KAA0D,EAC1D,OAA8C;IAE9C,iFAAiF;IACjF,0DAA0D;IAC1D,MAAM,EAAC,WAAW,EAAE,mBAAmB,EAAE,uBAAuB,EAAC,GAAG,sBAAsB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACxG,MAAM,cAAc,GAAG,mBAAmB,CAAC,MAAM,CAAC;IAElD,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,MAAM,uBAAuB,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC;QAC1F,MAAM,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC;QACtD,IAAI,CAAC,eAAe,CAAC,uBAAuB,EAAE,qBAAqB,CAAC,EAAE,CAAC;YACrE,MAAM,KAAK,CACT,+DAA+D,SAAS,CACtE,uBAAuB,CACxB,YAAY,SAAS,CAAC,qBAAqB,CAAC,EAAE,CAChD,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,mBAAmB,CAAC,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;YAC9D,MAAM,KAAK,CAAC,uCAAuC,cAAc,WAAW,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5G,CAAC;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvE,MAAM,KAAK,CAAC,gCAAgC,CAAC,EAAE,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC1C,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,cAAc,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5B,MAAM,YAAY,GAAG,KAAiC,CAAC;QACvD,YAAY,CAAC,yBAAyB,GAAG,YAAY,CAAC,yBAAyB,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IACrH,CAAC;IAED,iCAAiC;IACjC,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7E,KAAK,CAAC,mBAAmB,GAAG,gBAAgB,CAAC,KAAK,GAAG,CAAC,CAAC;IACzD,CAAC;IAED,0CAA0C;IAC1C,IAAI,mBAAmB,CAAC,MAAM,KAAK,2BAA2B,EAAE,CAAC;QAC/D,2FAA2F;QAC3F,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7E,KAAK,CAAC,4BAA4B,GAAG,CAAC,gBAAgB,CAAC,cAAc,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;IACvG,CAAC;SAAM,CAAC;QACN,8FAA8F;QAC9F,0BAA0B;QAC1B,KAAK,CAAC,4BAA4B;YAChC,CAAC,KAAK,CAAC,4BAA4B,GAAG,oCAAoC,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;IAC1G,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,IAAa,EACb,KAA0D;IAM1D,IAAI,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,mDAAmD,IAAI,oBAAoB,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;IACnC,IAAI,eAAe,GAAG,KAAK,CAAC,mBAAmB,CAAC;IAChD,MAAM,EAAC,UAAU,EAAE,QAAQ,EAAE,4BAA4B,EAAC,GAAG,KAAK,CAAC;IAEnE,MAAM,WAAW,GAAyB,EAAE,CAAC;IAC7C,MAAM,aAAa,GAAG,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAE9C,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,YAAY,GAAG,KAAiC,CAAC;QAEvD,yJAAyJ;QACzJ,6JAA6J;QAC7J,uDAAuD;QACvD,MAAM,4BAA4B,GAChC,YAAY,CAAC,yBAAyB,CAAC,MAAM,IAAI,0CAA0C;YACzF,CAAC,CAAC,YAAY,CAAC,yBAAyB,CAAC,cAAc,EAAE;YACzD,CAAC,CAAC,IAAI,CAAC;QAEX,oDAAoD;QACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,yBAAyB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvE,MAAM,UAAU,GAAG,4BAA4B;gBAC7C,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC;gBACjC,CAAC,CAAC,YAAY,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAC1D,IAAI,UAAU,CAAC,iBAAiB,GAAG,KAAK,IAAI,WAAW,CAAC,MAAM,KAAK,0CAA0C,EAAE,CAAC;gBAC9G,MAAM;YACR,CAAC;YAED,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAE3D,IACE,SAAS,CAAC,SAAS,KAAK,gBAAgB;gBACxC,SAAS,CAAC,gBAAgB,IAAI,sBAAsB;gBACpD,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,sBAAsB,EACvD,CAAC;gBACD,MAAM,+BAA+B,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,sBAAsB,CAAC,CAAC;gBACxG,MAAM,mBAAmB,GACvB,+BAA+B,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;gBAC5G,WAAW,CAAC,IAAI,CAAC;oBACf,KAAK,EAAE,eAAe;oBACtB,cAAc,EAAE,UAAU,CAAC,KAAK;oBAChC,OAAO,EAAE,SAAS,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACrD,MAAM,EAAE,mBAAmB;iBAC5B,CAAC,CAAC;gBACH,eAAe,EAAE,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAED,iFAAiF;IACjF,MAAM,uBAAuB,GAAG,WAAW,CAAC,MAAM,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,oCAAoC,CAAC,CAAC;IAChF,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,6DAA6D;IAC7D,8DAA8D;IAC9D,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,6BAA6B;QAC7B,MAAM,cAAc,GAAG,CAAC,4BAA4B,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;QAE9E,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC7C,MAAM,EAAC,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB,EAAC,GAAG,SAAS,CAAC;QAC/E,MAAM,0BAA0B,GAAG,aAAa;YAC9C,CAAC,CAAC,gCAAgC,CAAC,qBAAqB,CAAC;YACzD,CAAC,CAAC,2BAA2B,CAAC,qBAAqB,CAAC,CAAC;QACvD,0FAA0F;QAC1F,wDAAwD;QACxD,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC;YACjD,SAAS;QACX,CAAC;QAED,0BAA0B;QAC1B,IAAI,iBAAiB,IAAI,KAAK,EAAE,CAAC;YAC/B,WAAW,CAAC,IAAI,CAAC;gBACf,KAAK,EAAE,eAAe;gBACtB,cAAc;gBACd,OAAO,EAAE,SAAS,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACrD,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC;aACxB,CAAC,CAAC;YACH,eAAe,EAAE,CAAC;QACpB,CAAC;aAAM,IACL,gBAAgB,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC;YAC5G,OAAO,GAAG,gBAAgB,EAC1B,CAAC;YACD,6BAA6B;YAC7B,WAAW,CAAC,IAAI,CAAC;gBACf,KAAK,EAAE,eAAe;gBACtB,cAAc;gBACd,OAAO,EAAE,SAAS,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACrD,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,gBAAgB,CAAC;aAC3C,CAAC,CAAC;YACH,eAAe,EAAE,CAAC;QACpB,CAAC;QAED,4CAA4C;QAC5C,IAAI,WAAW,CAAC,MAAM,IAAI,2BAA2B,EAAE,CAAC;YACtD,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,EAAC,WAAW,EAAE,iBAAiB,EAAE,CAAC,EAAE,uBAAuB,EAAC,CAAC;AACtE,CAAC"}
@@ -1,4 +1,4 @@
1
- import { EFFECTIVE_BALANCE_INCREMENT, EPOCHS_PER_SLASHINGS_VECTOR, ForkSeq, MIN_SLASHING_PENALTY_QUOTIENT, MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR, MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX, PROPOSER_REWARD_QUOTIENT, PROPOSER_WEIGHT, TIMELY_TARGET_FLAG_INDEX, WEIGHT_DENOMINATOR, WHISTLEBLOWER_REWARD_QUOTIENT, } from "@lodestar/params";
1
+ import { EFFECTIVE_BALANCE_INCREMENT, EPOCHS_PER_SLASHINGS_VECTOR, ForkSeq, MIN_SLASHING_PENALTY_QUOTIENT, MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR, MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX, MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA, PROPOSER_REWARD_QUOTIENT, PROPOSER_WEIGHT, TIMELY_TARGET_FLAG_INDEX, WEIGHT_DENOMINATOR, WHISTLEBLOWER_REWARD_QUOTIENT, WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA, } from "@lodestar/params";
2
2
  import { decreaseBalance, increaseBalance } from "../util/index.js";
3
3
  import { initiateValidatorExit } from "./initiateValidatorExit.js";
4
4
  /** Same to https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.5/specs/altair/beacon-chain.md#has_flag */
@@ -8,14 +8,14 @@ export function slashValidator(fork, state, slashedIndex, whistleblowerIndex) {
8
8
  const { epoch, effectiveBalanceIncrements } = epochCtx;
9
9
  const validator = state.validators.get(slashedIndex);
10
10
  // TODO: Bellatrix initiateValidatorExit validators.update() with the one below
11
- initiateValidatorExit(state, validator);
11
+ initiateValidatorExit(fork, state, validator);
12
12
  validator.slashed = true;
13
13
  validator.withdrawableEpoch = Math.max(validator.withdrawableEpoch, epoch + EPOCHS_PER_SLASHINGS_VECTOR);
14
14
  const { effectiveBalance } = validator;
15
15
  // state.slashings is initially a Gwei (BigInt) vector, however since Nov 2023 it's converted to UintNum64 (number) vector in the state transition because:
16
16
  // - state.slashings[nextEpoch % EPOCHS_PER_SLASHINGS_VECTOR] is reset per epoch in processSlashingsReset()
17
17
  // - max slashed validators per epoch is SLOTS_PER_EPOCH * MAX_ATTESTER_SLASHINGS * MAX_VALIDATORS_PER_COMMITTEE which is 32 * 2 * 2048 = 131072 on mainnet
18
- // - with that and 32_000_000_000 MAX_EFFECTIVE_BALANCE, it still fits in a number given that Math.floor(Number.MAX_SAFE_INTEGER / 32_000_000_000) = 281474
18
+ // - with that and 32_000_000_000 MAX_EFFECTIVE_BALANCE or 2048_000_000_000 MAX_EFFECTIVE_BALANCE_ELECTRA, it still fits in a number given that Math.floor(Number.MAX_SAFE_INTEGER / 32_000_000_000) = 281474
19
19
  // - we don't need to compute the total slashings from state.slashings, it's handled by totalSlashingsByIncrement in EpochCache
20
20
  const slashingIndex = epoch % EPOCHS_PER_SLASHINGS_VECTOR;
21
21
  state.slashings.set(slashingIndex, (state.slashings.get(slashingIndex) ?? 0) + effectiveBalance);
@@ -24,10 +24,14 @@ export function slashValidator(fork, state, slashedIndex, whistleblowerIndex) {
24
24
  ? MIN_SLASHING_PENALTY_QUOTIENT
25
25
  : fork === ForkSeq.altair
26
26
  ? MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR
27
- : MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX;
27
+ : fork < ForkSeq.electra // no change from bellatrix to deneb
28
+ ? MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX
29
+ : MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA;
28
30
  decreaseBalance(state, slashedIndex, Math.floor(effectiveBalance / minSlashingPenaltyQuotient));
29
31
  // apply proposer and whistleblower rewards
30
- const whistleblowerReward = Math.floor(effectiveBalance / WHISTLEBLOWER_REWARD_QUOTIENT);
32
+ const whistleblowerReward = fork < ForkSeq.electra
33
+ ? Math.floor(effectiveBalance / WHISTLEBLOWER_REWARD_QUOTIENT)
34
+ : Math.floor(effectiveBalance / WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA);
31
35
  const proposerReward = fork === ForkSeq.phase0
32
36
  ? Math.floor(whistleblowerReward / PROPOSER_REWARD_QUOTIENT)
33
37
  : Math.floor((whistleblowerReward * PROPOSER_WEIGHT) / WEIGHT_DENOMINATOR);
@@ -1 +1 @@
1
- {"version":3,"file":"slashValidator.js","sourceRoot":"","sources":["../../src/block/slashValidator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slashValidator.js","sourceRoot":"","sources":["../../src/block/slashValidator.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,13 @@
1
1
  import { BeaconStateAllForks } from "../types.js";
2
2
  /**
3
3
  * Alias to allow easier refactoring.
4
- * TODO: Estimate the risk of future proof of MAX_EFFECTIVE_BALANCE_INCREMENT < 255
5
4
  */
6
- export type EffectiveBalanceIncrements = Uint8Array;
7
- /** Helper to prevent re-writting tests downstream if we change Uint8Array to number[] */
5
+ export type EffectiveBalanceIncrements = Uint16Array;
6
+ /** Helper to prevent re-writting tests downstream if we change Uint16Array to number[] */
8
7
  export declare function getEffectiveBalanceIncrementsZeroed(len: number): EffectiveBalanceIncrements;
9
8
  /**
10
9
  * effectiveBalanceIncrements length will always be equal or greater than validatorCount. The
11
- * getEffectiveBalanceIncrementsByteLen() modulo is used to reduce the frequency at which its Uint8Array is recreated.
10
+ * getEffectiveBalanceIncrementsByteLen() modulo is used to reduce the frequency at which its Uint16Array is recreated.
12
11
  * if effectiveBalanceIncrements has length greater than validatorCount it's not a problem since those values would
13
12
  * never be accessed.
14
13
  */
@@ -1,18 +1,18 @@
1
1
  import { EFFECTIVE_BALANCE_INCREMENT } from "@lodestar/params";
2
- /** Helper to prevent re-writting tests downstream if we change Uint8Array to number[] */
2
+ /** Helper to prevent re-writting tests downstream if we change Uint16Array to number[] */
3
3
  export function getEffectiveBalanceIncrementsZeroed(len) {
4
- return new Uint8Array(len);
4
+ return new Uint16Array(len);
5
5
  }
6
6
  /**
7
7
  * effectiveBalanceIncrements length will always be equal or greater than validatorCount. The
8
- * getEffectiveBalanceIncrementsByteLen() modulo is used to reduce the frequency at which its Uint8Array is recreated.
8
+ * getEffectiveBalanceIncrementsByteLen() modulo is used to reduce the frequency at which its Uint16Array is recreated.
9
9
  * if effectiveBalanceIncrements has length greater than validatorCount it's not a problem since those values would
10
10
  * never be accessed.
11
11
  */
12
12
  export function getEffectiveBalanceIncrementsWithLen(validatorCount) {
13
13
  // TODO: Research what's the best number to minimize both memory cost and copy costs
14
14
  const byteLen = 1024 * Math.ceil(validatorCount / 1024);
15
- return new Uint8Array(byteLen);
15
+ return new Uint16Array(byteLen);
16
16
  }
17
17
  /**
18
18
  * Shows how EffectiveBalanceIncrements is meant to be populated.
@@ -21,7 +21,7 @@ export function getEffectiveBalanceIncrementsWithLen(validatorCount) {
21
21
  */
22
22
  export function getEffectiveBalanceIncrements(state) {
23
23
  const validatorsArr = state.validators.getAllReadonlyValues();
24
- const effectiveBalanceIncrements = new Uint8Array(validatorsArr.length);
24
+ const effectiveBalanceIncrements = new Uint16Array(validatorsArr.length);
25
25
  for (let i = 0; i < validatorsArr.length; i++) {
26
26
  effectiveBalanceIncrements[i] = Math.floor(validatorsArr[i].effectiveBalance / EFFECTIVE_BALANCE_INCREMENT);
27
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"effectiveBalanceIncrements.js","sourceRoot":"","sources":["../../src/cache/effectiveBalanceIncrements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,2BAA2B,EAAC,MAAM,kBAAkB,CAAC;AAS7D,yFAAyF;AACzF,MAAM,UAAU,mCAAmC,CAAC,GAAW;IAC7D,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oCAAoC,CAAC,cAAsB;IACzE,oFAAoF;IACpF,MAAM,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAExD,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,6BAA6B,CAAC,KAA0B;IACtE,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC;IAC9D,MAAM,0BAA0B,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,0BAA0B,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,gBAAgB,GAAG,2BAA2B,CAAC,CAAC;IAC9G,CAAC;IACD,OAAO,0BAA0B,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"effectiveBalanceIncrements.js","sourceRoot":"","sources":["../../src/cache/effectiveBalanceIncrements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,2BAA2B,EAAC,MAAM,kBAAkB,CAAC;AAQ7D,0FAA0F;AAC1F,MAAM,UAAU,mCAAmC,CAAC,GAAW;IAC7D,OAAO,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oCAAoC,CAAC,cAAsB;IACzE,oFAAoF;IACpF,MAAM,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAExD,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,6BAA6B,CAAC,KAA0B;IACtE,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC;IAC9D,MAAM,0BAA0B,GAAG,IAAI,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACzE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,0BAA0B,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,gBAAgB,GAAG,2BAA2B,CAAC,CAAC;IAC9G,CAAC;IACD,OAAO,0BAA0B,CAAC;AACpC,CAAC"}
@@ -1,9 +1,13 @@
1
- import { BLSSignature, CommitteeIndex, Epoch, Slot, ValidatorIndex, phase0, SyncPeriod } from "@lodestar/types";
1
+ import { PublicKey } from "@chainsafe/blst";
2
+ import * as immutable from "immutable";
3
+ import { BLSSignature, CommitteeIndex, Epoch, Slot, ValidatorIndex, phase0, SyncPeriod, Attestation, IndexedAttestation } from "@lodestar/types";
2
4
  import { BeaconConfig, ChainConfig } from "@lodestar/config";
5
+ import { ForkSeq } from "@lodestar/params";
3
6
  import { LodestarError } from "@lodestar/utils";
4
7
  import { EpochShuffling } from "../util/epochShuffling.js";
8
+ import { EpochCacheMetrics } from "../metrics.js";
5
9
  import { EffectiveBalanceIncrements } from "./effectiveBalanceIncrements.js";
6
- import { Index2PubkeyCache, PubkeyIndexMap } from "./pubkeyCache.js";
10
+ import { Index2PubkeyCache, PubkeyIndexMap, UnfinalizedPubkeyIndexMap, PubkeyHex } from "./pubkeyCache.js";
7
11
  import { BeaconStateAllForks, ShufflingGetter } from "./types.js";
8
12
  import { SyncCommitteeCache } from "./syncCommitteeCache.js";
9
13
  /** `= PROPOSER_WEIGHT / (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT)` */
@@ -51,23 +55,30 @@ type ProposersDeferred = {
51
55
  export declare class EpochCache {
52
56
  config: BeaconConfig;
53
57
  /**
54
- * Unique globally shared pubkey registry. There should only exist one for the entire application.
58
+ * Unique globally shared finalized pubkey registry. There should only exist one for the entire application.
55
59
  *
56
60
  * TODO: this is a hack, we need a safety mechanism in case a bad eth1 majority vote is in,
57
61
  * or handle non finalized data differently, or use an immutable.js structure for cheap copies
58
- * Warning: may contain pubkeys that do not yet exist in the current state, but do in a later processed state.
62
+ *
63
+ * New: This would include only validators whose activation_eligibility_epoch != FAR_FUTURE_EPOCH and hence it is
64
+ * insert only. Validators could be 1) Active 2) In the activation queue 3) Initialized but pending queued
59
65
  *
60
66
  * $VALIDATOR_COUNT x 192 char String -> Number Map
61
67
  */
62
68
  pubkey2index: PubkeyIndexMap;
63
69
  /**
64
- * Unique globally shared pubkey registry. There should only exist one for the entire application.
70
+ * Unique globally shared finalized pubkey registry. There should only exist one for the entire application.
65
71
  *
66
- * Warning: may contain indices that do not yet exist in the current state, but do in a later processed state.
72
+ * New: This would include only validators whose activation_eligibility_epoch != FAR_FUTURE_EPOCH and hence it is
73
+ * insert only. Validators could be 1) Active 2) In the activation queue 3) Initialized but pending queued
67
74
  *
68
75
  * $VALIDATOR_COUNT x BLST deserialized pubkey (Jacobian coordinates)
69
76
  */
70
77
  index2pubkey: Index2PubkeyCache;
78
+ /**
79
+ * Unique pubkey registry shared in the same fork. There should only exist one for the fork.
80
+ */
81
+ unfinalizedPubkey2index: UnfinalizedPubkeyIndexMap;
71
82
  /**
72
83
  * Indexes of the block proposers for the current epoch.
73
84
  *
@@ -125,6 +136,7 @@ export declare class EpochCache {
125
136
  * initiateValidatorExit(). This value may vary on each fork of the state.
126
137
  *
127
138
  * NOTE: Changes block to block
139
+ * NOTE: No longer used by initiateValidatorExit post-electra
128
140
  */
129
141
  exitQueueEpoch: Epoch;
130
142
  /**
@@ -132,6 +144,7 @@ export declare class EpochCache {
132
144
  * initiateValidatorExit(). This value may vary on each fork of the state.
133
145
  *
134
146
  * NOTE: Changes block to block
147
+ * NOTE: No longer used by initiateValidatorExit post-electra
135
148
  */
136
149
  exitQueueChurn: number;
137
150
  /**
@@ -158,10 +171,20 @@ export declare class EpochCache {
158
171
  nextSyncCommitteeIndexed: SyncCommitteeCache;
159
172
  epoch: Epoch;
160
173
  syncPeriod: SyncPeriod;
174
+ /**
175
+ * state.validators.length of every state at epoch boundary
176
+ * They are saved in increasing order of epoch.
177
+ * The first validator length in the list corresponds to the state AFTER the latest finalized checkpoint state. ie. state.finalizedCheckpoint.epoch - 1
178
+ * The last validator length corresponds to the latest epoch state ie. this.epoch
179
+ * eg. latest epoch = 105, latest finalized cp state epoch = 102
180
+ * then the list will be (in terms of epoch) [103, 104, 105]
181
+ */
182
+ historicalValidatorLengths: immutable.List<number>;
161
183
  constructor(data: {
162
184
  config: BeaconConfig;
163
185
  pubkey2index: PubkeyIndexMap;
164
186
  index2pubkey: Index2PubkeyCache;
187
+ unfinalizedPubkey2index: UnfinalizedPubkeyIndexMap;
165
188
  proposers: number[];
166
189
  proposersPrevEpoch: number[] | null;
167
190
  proposersNextEpoch: ProposersDeferred;
@@ -184,10 +207,11 @@ export declare class EpochCache {
184
207
  nextSyncCommitteeIndexed: SyncCommitteeCache;
185
208
  epoch: Epoch;
186
209
  syncPeriod: SyncPeriod;
210
+ historialValidatorLengths: immutable.List<number>;
187
211
  });
188
212
  /**
189
213
  * Create an epoch cache
190
- * @param validators cached validators that matches `state.validators`
214
+ * @param state a finalized beacon state. Passing in unfinalized state may cause unexpected behaviour eg. empty unfinalized cache
191
215
  *
192
216
  * SLOW CODE - 🐢
193
217
  */
@@ -201,6 +225,7 @@ export declare class EpochCache {
201
225
  * new epoch.
202
226
  */
203
227
  afterProcessEpoch(state: BeaconStateAllForks, epochTransitionCache: {
228
+ indicesEligibleForActivationQueue: ValidatorIndex[];
204
229
  nextEpochShufflingActiveValidatorIndices: ValidatorIndex[];
205
230
  nextEpochShufflingActiveIndicesLength: number;
206
231
  nextEpochTotalActiveBalanceByIncrement: number;
@@ -210,6 +235,10 @@ export declare class EpochCache {
210
235
  * Return the beacon committee at slot for index.
211
236
  */
212
237
  getBeaconCommittee(slot: Slot, index: CommitteeIndex): Uint32Array;
238
+ /**
239
+ * Return a single Uint32Array representing concatted committees of indices
240
+ */
241
+ getBeaconCommittees(slot: Slot, indices: CommitteeIndex[]): Uint32Array;
213
242
  getCommitteeCountPerSlot(epoch: Epoch): number;
214
243
  /**
215
244
  * Compute the correct subnet for a slot/committee index
@@ -258,7 +287,11 @@ export declare class EpochCache {
258
287
  /**
259
288
  * Return the indexed attestation corresponding to ``attestation``.
260
289
  */
261
- getIndexedAttestation(attestation: phase0.Attestation): phase0.IndexedAttestation;
290
+ getIndexedAttestation(fork: ForkSeq, attestation: Attestation): IndexedAttestation;
291
+ /**
292
+ * Return indices of validators who attestested in `attestation`
293
+ */
294
+ getAttestingIndices(fork: ForkSeq, attestation: Attestation): number[];
262
295
  getCommitteeAssignments(epoch: Epoch, requestedValidatorIndices: ValidatorIndex[]): Map<ValidatorIndex, AttesterDuty>;
263
296
  /**
264
297
  * Return the committee assignment in the ``epoch`` for ``validator_index``.
@@ -270,7 +303,30 @@ export declare class EpochCache {
270
303
  */
271
304
  getCommitteeAssignment(epoch: Epoch, validatorIndex: ValidatorIndex): phase0.CommitteeAssignment | null;
272
305
  isAggregator(slot: Slot, index: CommitteeIndex, slotSignature: BLSSignature): boolean;
306
+ /**
307
+ * Return finalized pubkey given the validator index.
308
+ * Only finalized pubkey as we do not store unfinalized pubkey because no where in the spec has a
309
+ * need to make such enquiry
310
+ */
311
+ getPubkey(index: ValidatorIndex): PublicKey | undefined;
312
+ getValidatorIndex(pubkey: Uint8Array | PubkeyHex): ValidatorIndex | undefined;
313
+ /**
314
+ *
315
+ * Add unfinalized pubkeys
316
+ *
317
+ */
273
318
  addPubkey(index: ValidatorIndex, pubkey: Uint8Array): void;
319
+ addUnFinalizedPubkey(index: ValidatorIndex, pubkey: PubkeyHex | Uint8Array, metrics?: EpochCacheMetrics): void;
320
+ addFinalizedPubkeys(pubkeyMap: UnfinalizedPubkeyIndexMap, metrics?: EpochCacheMetrics): void;
321
+ /**
322
+ * Add finalized validator index and pubkey into finalized cache.
323
+ * Since addFinalizedPubkey() primarily takes pubkeys from unfinalized cache, it can take pubkey hex string directly
324
+ */
325
+ addFinalizedPubkey(index: ValidatorIndex, pubkey: PubkeyHex | Uint8Array, metrics?: EpochCacheMetrics): void;
326
+ /**
327
+ * Delete pubkeys from unfinalized cache
328
+ */
329
+ deleteUnfinalizedPubkeys(pubkeys: Iterable<PubkeyHex>): void;
274
330
  getShufflingAtSlot(slot: Slot): EpochShuffling;
275
331
  getShufflingAtSlotOrNull(slot: Slot): EpochShuffling | null;
276
332
  getShufflingAtEpoch(epoch: Epoch): EpochShuffling;
@@ -292,6 +348,8 @@ export declare class EpochCache {
292
348
  /** On phase0 -> altair fork, set both current and nextSyncCommitteeIndexed */
293
349
  setSyncCommitteesIndexed(nextSyncCommitteeIndices: number[]): void;
294
350
  effectiveBalanceIncrementsSet(index: number, effectiveBalance: number): void;
351
+ isPostElectra(): boolean;
352
+ getValidatorCountAtEpoch(targetEpoch: Epoch): number | undefined;
295
353
  }
296
354
  type AttesterDuty = {
297
355
  validatorIndex: ValidatorIndex;