@lodestar/state-transition 1.40.0-dev.0ae7a89ead → 1.40.0-dev.1cab20c166

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 (58) hide show
  1. package/lib/block/index.d.ts +1 -0
  2. package/lib/block/index.d.ts.map +1 -1
  3. package/lib/block/index.js +1 -0
  4. package/lib/block/index.js.map +1 -1
  5. package/lib/block/processConsolidationRequest.d.ts +1 -2
  6. package/lib/block/processConsolidationRequest.d.ts.map +1 -1
  7. package/lib/block/processConsolidationRequest.js +2 -2
  8. package/lib/block/processConsolidationRequest.js.map +1 -1
  9. package/lib/block/processDepositRequest.d.ts +8 -2
  10. package/lib/block/processDepositRequest.d.ts.map +1 -1
  11. package/lib/block/processDepositRequest.js +81 -8
  12. package/lib/block/processDepositRequest.js.map +1 -1
  13. package/lib/block/processExecutionPayloadBid.d.ts.map +1 -1
  14. package/lib/block/processExecutionPayloadBid.js +14 -27
  15. package/lib/block/processExecutionPayloadBid.js.map +1 -1
  16. package/lib/block/processExecutionPayloadEnvelope.d.ts.map +1 -1
  17. package/lib/block/processExecutionPayloadEnvelope.js +26 -25
  18. package/lib/block/processExecutionPayloadEnvelope.js.map +1 -1
  19. package/lib/block/processOperations.js +2 -2
  20. package/lib/block/processOperations.js.map +1 -1
  21. package/lib/block/processVoluntaryExit.d.ts +1 -1
  22. package/lib/block/processVoluntaryExit.d.ts.map +1 -1
  23. package/lib/block/processVoluntaryExit.js +45 -3
  24. package/lib/block/processVoluntaryExit.js.map +1 -1
  25. package/lib/block/processWithdrawalRequest.js +1 -1
  26. package/lib/block/processWithdrawalRequest.js.map +1 -1
  27. package/lib/block/processWithdrawals.d.ts +1 -0
  28. package/lib/block/processWithdrawals.d.ts.map +1 -1
  29. package/lib/block/processWithdrawals.js +121 -66
  30. package/lib/block/processWithdrawals.js.map +1 -1
  31. package/lib/epoch/processBuilderPendingPayments.d.ts.map +1 -1
  32. package/lib/epoch/processBuilderPendingPayments.js +1 -4
  33. package/lib/epoch/processBuilderPendingPayments.js.map +1 -1
  34. package/lib/util/electra.d.ts.map +1 -1
  35. package/lib/util/electra.js +1 -2
  36. package/lib/util/electra.js.map +1 -1
  37. package/lib/util/gloas.d.ts +43 -3
  38. package/lib/util/gloas.d.ts.map +1 -1
  39. package/lib/util/gloas.js +93 -5
  40. package/lib/util/gloas.js.map +1 -1
  41. package/lib/util/validator.d.ts +6 -1
  42. package/lib/util/validator.d.ts.map +1 -1
  43. package/lib/util/validator.js +26 -16
  44. package/lib/util/validator.js.map +1 -1
  45. package/package.json +7 -7
  46. package/src/block/index.ts +1 -0
  47. package/src/block/processConsolidationRequest.ts +2 -3
  48. package/src/block/processDepositRequest.ts +101 -8
  49. package/src/block/processExecutionPayloadBid.ts +18 -40
  50. package/src/block/processExecutionPayloadEnvelope.ts +34 -30
  51. package/src/block/processOperations.ts +2 -2
  52. package/src/block/processVoluntaryExit.ts +60 -5
  53. package/src/block/processWithdrawalRequest.ts +1 -1
  54. package/src/block/processWithdrawals.ts +168 -70
  55. package/src/epoch/processBuilderPendingPayments.ts +1 -5
  56. package/src/util/electra.ts +1 -4
  57. package/src/util/gloas.ts +109 -8
  58. package/src/util/validator.ts +31 -16
@@ -1 +1 @@
1
- {"version":3,"file":"gloas.d.ts","sourceRoot":"","sources":["../../src/util/gloas.ts"],"names":[],"mappings":"AAQA,OAAO,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAC,eAAe,EAAC,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAC,sBAAsB,EAAC,MAAM,aAAa,CAAC;AAGnD,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAEzC,wBAAgB,8BAA8B,CAAC,qBAAqB,EAAE,UAAU,GAAG,OAAO,CAEzF;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAMtF;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,sBAAsB,EAC7B,UAAU,EAAE,KAAK,CAAC,wBAAwB,GACzC,OAAO,CAKT;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAOnG;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAOnG;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAExE"}
1
+ {"version":3,"file":"gloas.d.ts","sourceRoot":"","sources":["../../src/util/gloas.ts"],"names":[],"mappings":"AAWA,OAAO,EAAC,eAAe,EAAC,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAC,sBAAsB,EAAC,MAAM,aAAa,CAAC;AAGnD,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAEzC,wBAAgB,6BAA6B,CAAC,qBAAqB,EAAE,UAAU,GAAG,OAAO,CAExF;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAMtF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAElF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAK5F;AAED;;;GAGG;AACH,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAoBjH;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAUlH;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAW7F;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAOzG;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAOnG;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAOnG;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAExE"}
package/lib/util/gloas.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { byteArrayEquals } from "@chainsafe/ssz";
2
- import { BUILDER_PAYMENT_THRESHOLD_DENOMINATOR, BUILDER_PAYMENT_THRESHOLD_NUMERATOR, BUILDER_WITHDRAWAL_PREFIX, EFFECTIVE_BALANCE_INCREMENT, SLOTS_PER_EPOCH, } from "@lodestar/params";
2
+ import { BUILDER_INDEX_FLAG, BUILDER_PAYMENT_THRESHOLD_DENOMINATOR, BUILDER_PAYMENT_THRESHOLD_NUMERATOR, BUILDER_WITHDRAWAL_PREFIX, EFFECTIVE_BALANCE_INCREMENT, FAR_FUTURE_EPOCH, MIN_DEPOSIT_AMOUNT, SLOTS_PER_EPOCH, } from "@lodestar/params";
3
3
  import { getBlockRootAtSlot } from "./blockRoot.js";
4
4
  import { computeEpochAtSlot } from "./epoch.js";
5
- export function hasBuilderWithdrawalCredential(withdrawalCredentials) {
5
+ export function isBuilderWithdrawalCredential(withdrawalCredentials) {
6
6
  return withdrawalCredentials[0] === BUILDER_WITHDRAWAL_PREFIX;
7
7
  }
8
8
  export function getBuilderPaymentQuorumThreshold(state) {
@@ -10,10 +10,98 @@ export function getBuilderPaymentQuorumThreshold(state) {
10
10
  BUILDER_PAYMENT_THRESHOLD_NUMERATOR;
11
11
  return Math.floor(quorum / BUILDER_PAYMENT_THRESHOLD_DENOMINATOR);
12
12
  }
13
- export function isBuilderPaymentWithdrawable(state, withdrawal) {
14
- const builder = state.validators.getReadonly(withdrawal.builderIndex);
13
+ /**
14
+ * Check if a validator index represents a builder (has the builder flag set).
15
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-is_builder_index
16
+ */
17
+ export function isBuilderIndex(validatorIndex) {
18
+ return (validatorIndex & BUILDER_INDEX_FLAG) !== 0;
19
+ }
20
+ /**
21
+ * Convert a builder index to a flagged validator index for use in Withdrawal containers.
22
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-convert_builder_index_to_validator_index
23
+ */
24
+ export function convertBuilderIndexToValidatorIndex(builderIndex) {
25
+ return builderIndex | BUILDER_INDEX_FLAG;
26
+ }
27
+ /**
28
+ * Convert a flagged validator index back to a builder index.
29
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-convert_validator_index_to_builder_index
30
+ */
31
+ export function convertValidatorIndexToBuilderIndex(validatorIndex) {
32
+ return validatorIndex & ~BUILDER_INDEX_FLAG;
33
+ }
34
+ /**
35
+ * Check if a builder is active (deposited and not yet withdrawable).
36
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#isactivebuilder
37
+ */
38
+ export function isActiveBuilder(state, builderIndex) {
39
+ const builder = state.builders.getReadonly(builderIndex);
40
+ const finalizedEpoch = state.finalizedCheckpoint.epoch;
41
+ return builder.depositEpoch < finalizedEpoch && builder.withdrawableEpoch === FAR_FUTURE_EPOCH;
42
+ }
43
+ /**
44
+ * Get the total pending balance to withdraw for a builder (from withdrawals + payments).
45
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-get_pending_balance_to_withdraw_for_builder
46
+ */
47
+ export function getPendingBalanceToWithdrawForBuilder(state, builderIndex) {
48
+ let pendingBalance = 0;
49
+ // Sum pending withdrawals
50
+ for (let i = 0; i < state.builderPendingWithdrawals.length; i++) {
51
+ const withdrawal = state.builderPendingWithdrawals.getReadonly(i);
52
+ if (withdrawal.builderIndex === builderIndex) {
53
+ pendingBalance += withdrawal.amount;
54
+ }
55
+ }
56
+ // Sum pending payments
57
+ for (let i = 0; i < state.builderPendingPayments.length; i++) {
58
+ const payment = state.builderPendingPayments.getReadonly(i);
59
+ if (payment.withdrawal.builderIndex === builderIndex) {
60
+ pendingBalance += payment.withdrawal.amount;
61
+ }
62
+ }
63
+ return pendingBalance;
64
+ }
65
+ /**
66
+ * Check if a builder has sufficient balance to cover a bid amount.
67
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-can_builder_cover_bid
68
+ */
69
+ export function canBuilderCoverBid(state, builderIndex, bidAmount) {
70
+ const builder = state.builders.getReadonly(builderIndex);
71
+ const pendingBalance = getPendingBalanceToWithdrawForBuilder(state, builderIndex);
72
+ const minBalance = MIN_DEPOSIT_AMOUNT + pendingBalance;
73
+ if (builder.balance < minBalance) {
74
+ return false;
75
+ }
76
+ return builder.balance - minBalance >= bidAmount;
77
+ }
78
+ /**
79
+ * Initiate a builder exit by setting their withdrawable epoch.
80
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-initiate_builder_exit
81
+ */
82
+ export function initiateBuilderExit(state, builderIndex) {
83
+ const builder = state.builders.get(builderIndex);
84
+ // Return if builder already initiated exit
85
+ if (builder.withdrawableEpoch !== FAR_FUTURE_EPOCH) {
86
+ return;
87
+ }
88
+ // Set builder exit epoch
15
89
  const currentEpoch = computeEpochAtSlot(state.slot);
16
- return builder.withdrawableEpoch >= currentEpoch || !builder.slashed;
90
+ builder.withdrawableEpoch = currentEpoch + state.config.MIN_BUILDER_WITHDRAWABILITY_DELAY;
91
+ }
92
+ /**
93
+ * Find the index of a builder by their public key.
94
+ * Returns null if not found.
95
+ *
96
+ * May consider builder pubkey cache if performance becomes an issue.
97
+ */
98
+ export function findBuilderIndexByPubkey(state, pubkey) {
99
+ for (let i = 0; i < state.builders.length; i++) {
100
+ if (byteArrayEquals(state.builders.getReadonly(i).pubkey, pubkey)) {
101
+ return i;
102
+ }
103
+ }
104
+ return null;
17
105
  }
18
106
  export function isAttestationSameSlot(state, data) {
19
107
  if (data.slot === 0)
@@ -1 +1 @@
1
- {"version":3,"file":"gloas.js","sourceRoot":"","sources":["../../src/util/gloas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,qCAAqC,EACrC,mCAAmC,EACnC,yBAAyB,EACzB,2BAA2B,EAC3B,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAC,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAC,kBAAkB,EAAC,MAAM,YAAY,CAAC;AAG9C,MAAM,UAAU,8BAA8B,CAAC,qBAAiC;IAC9E,OAAO,qBAAqB,CAAC,CAAC,CAAC,KAAK,yBAAyB,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,KAA6B;IAC5E,MAAM,MAAM,GACV,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,4BAA4B,GAAG,2BAA2B,CAAC,GAAG,eAAe,CAAC;QACzG,mCAAmC,CAAC;IAEtC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,qCAAqC,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,KAA6B,EAC7B,UAA0C;IAE1C,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IACtE,MAAM,YAAY,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEpD,OAAO,OAAO,CAAC,iBAAiB,IAAI,YAAY,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAA6B,EAAE,IAAqB;IACxF,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjC,MAAM,mBAAmB,GAAG,eAAe,CAAC,IAAI,CAAC,eAAe,EAAE,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACxG,MAAM,kBAAkB,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,EAAE,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;IAE5G,OAAO,mBAAmB,IAAI,kBAAkB,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,SAAoB,EAAE,IAAqB;IACxF,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjC,MAAM,mBAAmB,GAAG,eAAe,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3G,MAAM,kBAAkB,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;IAE/G,OAAO,mBAAmB,IAAI,kBAAkB,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,OAAO,eAAe,CAAC,KAAK,CAAC,yBAAyB,CAAC,SAAS,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;AAC3F,CAAC"}
1
+ {"version":3,"file":"gloas.js","sourceRoot":"","sources":["../../src/util/gloas.ts"],"names":[],"mappings":"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"}
@@ -26,5 +26,10 @@ export declare function getBalanceChurnLimitFromCache(epochCtx: EpochCache): num
26
26
  export declare function getActivationExitChurnLimit(epochCtx: EpochCache): number;
27
27
  export declare function getConsolidationChurnLimit(epochCtx: EpochCache): number;
28
28
  export declare function getMaxEffectiveBalance(withdrawalCredentials: Uint8Array): number;
29
- export declare function getPendingBalanceToWithdraw(fork: ForkSeq, state: CachedBeaconStateElectra | CachedBeaconStateGloas, validatorIndex: ValidatorIndex): number;
29
+ /**
30
+ * Check if validator is partially withdrawable.
31
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/electra/beacon-chain.md#modified-is_partially_withdrawable_validator
32
+ */
33
+ export declare function isPartiallyWithdrawableValidator(fork: ForkSeq, validator: phase0.Validator, balance: number): boolean;
34
+ export declare function getPendingBalanceToWithdraw(state: CachedBeaconStateElectra | CachedBeaconStateGloas, validatorIndex: ValidatorIndex): number;
30
35
  //# sourceMappingURL=validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/util/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAEL,OAAO,EAGR,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAC,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EAAC,mBAAmB,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,UAAU,EAAC,MAAM,aAAa,CAAC;AAG9G;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAEpF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAEvF;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,KAAK,GAAG,WAAW,CAW/F;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAKpH;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAE3F;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,4BAA4B,EAAE,MAAM,EACpC,kBAAkB,EAAE,MAAM,EAC1B,qBAAqB,EAAE,MAAM,GAC5B,MAAM,CAQR;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAM1E;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAExE;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAEvE;AAED,wBAAgB,sBAAsB,CAAC,qBAAqB,EAAE,UAAU,GAAG,MAAM,CAMhF;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,wBAAwB,GAAG,sBAAsB,EACxD,cAAc,EAAE,cAAc,GAC7B,MAAM,CAuBR"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/util/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAEL,OAAO,EAIR,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAC,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EAAC,mBAAmB,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,UAAU,EAAC,MAAM,aAAa,CAAC;AAI9G;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAEpF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAEvF;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,KAAK,GAAG,WAAW,CAW/F;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAKpH;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAE3F;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,4BAA4B,EAAE,MAAM,EACpC,kBAAkB,EAAE,MAAM,EAC1B,qBAAqB,EAAE,MAAM,GAC5B,MAAM,CAQR;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAM1E;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAExE;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAEvE;AAED,wBAAgB,sBAAsB,CAAC,qBAAqB,EAAE,UAAU,GAAG,MAAM,CAMhF;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAsBrH;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,wBAAwB,GAAG,sBAAsB,EACxD,cAAc,EAAE,cAAc,GAC7B,MAAM,CASR"}
@@ -1,6 +1,7 @@
1
- import { EFFECTIVE_BALANCE_INCREMENT, ForkSeq, MAX_EFFECTIVE_BALANCE_ELECTRA, MIN_ACTIVATION_BALANCE, } from "@lodestar/params";
1
+ import { EFFECTIVE_BALANCE_INCREMENT, ForkSeq, MAX_EFFECTIVE_BALANCE, MAX_EFFECTIVE_BALANCE_ELECTRA, MIN_ACTIVATION_BALANCE, } from "@lodestar/params";
2
2
  import { intDiv } from "@lodestar/utils";
3
- import { hasCompoundingWithdrawalCredential } from "./electra.js";
3
+ import { hasEth1WithdrawalCredential } from "./capella.js";
4
+ import { hasCompoundingWithdrawalCredential, hasExecutionWithdrawalCredential } from "./electra.js";
4
5
  /**
5
6
  * Check if [[validator]] is active
6
7
  */
@@ -61,26 +62,35 @@ export function getMaxEffectiveBalance(withdrawalCredentials) {
61
62
  }
62
63
  return MIN_ACTIVATION_BALANCE;
63
64
  }
64
- export function getPendingBalanceToWithdraw(fork, state, validatorIndex) {
65
+ /**
66
+ * Check if validator is partially withdrawable.
67
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/electra/beacon-chain.md#modified-is_partially_withdrawable_validator
68
+ */
69
+ export function isPartiallyWithdrawableValidator(fork, validator, balance) {
70
+ const isPostElectra = fork >= ForkSeq.electra;
71
+ // Check withdrawal credentials
72
+ const hasWithdrawableCredentials = isPostElectra
73
+ ? hasExecutionWithdrawalCredential(validator.withdrawalCredentials)
74
+ : hasEth1WithdrawalCredential(validator.withdrawalCredentials);
75
+ if (!hasWithdrawableCredentials) {
76
+ return false;
77
+ }
78
+ // Get max effective balance based on fork
79
+ const maxEffectiveBalance = isPostElectra
80
+ ? getMaxEffectiveBalance(validator.withdrawalCredentials)
81
+ : MAX_EFFECTIVE_BALANCE;
82
+ // Check if at max effective balance and has excess balance
83
+ const hasMaxEffectiveBalance = validator.effectiveBalance === maxEffectiveBalance;
84
+ const hasExcessBalance = balance > maxEffectiveBalance;
85
+ return hasMaxEffectiveBalance && hasExcessBalance;
86
+ }
87
+ export function getPendingBalanceToWithdraw(state, validatorIndex) {
65
88
  let total = 0;
66
89
  for (const item of state.pendingPartialWithdrawals.getAllReadonly()) {
67
90
  if (item.validatorIndex === validatorIndex) {
68
91
  total += Number(item.amount);
69
92
  }
70
93
  }
71
- if (fork >= ForkSeq.gloas) {
72
- const stateGloas = state;
73
- for (const item of stateGloas.builderPendingWithdrawals.getAllReadonly()) {
74
- if (item.builderIndex === validatorIndex) {
75
- total += item.amount;
76
- }
77
- }
78
- for (const item of stateGloas.builderPendingPayments.getAllReadonly()) {
79
- if (item.withdrawal.builderIndex === validatorIndex) {
80
- total += item.withdrawal.amount;
81
- }
82
- }
83
- }
84
94
  return total;
85
95
  }
86
96
  //# sourceMappingURL=validator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/util/validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/util/validator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,2BAA2B,EAC3B,OAAO,EACP,qBAAqB,EACrB,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAC;AAEvC,OAAO,EAAC,2BAA2B,EAAC,MAAM,cAAc,CAAC;AACzD,OAAO,EAAC,kCAAkC,EAAE,gCAAgC,EAAC,MAAM,cAAc,CAAC;AAElG;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAA2B,EAAE,KAAY;IACzE,OAAO,SAAS,CAAC,eAAe,IAAI,KAAK,IAAI,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC;AAC3E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAA2B,EAAE,KAAY;IAC5E,OAAO,CAAC,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,eAAe,IAAI,KAAK,IAAI,KAAK,GAAG,SAAS,CAAC,iBAAiB,CAAC;AACzG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAA0B,EAAE,KAAY;IAChF,MAAM,OAAO,GAAqB,EAAE,CAAC;IAErC,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC;IAC9D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,IAAI,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAuB,EAAE,IAAa,EAAE,oBAA4B;IAC1G,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,oCAAoC,EAAE,aAAa,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAC5G,CAAC;IACD,OAAO,aAAa,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAuB,EAAE,oBAA4B;IACjF,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,yBAAyB,EAAE,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC;AAC/G,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,4BAAoC,EACpC,kBAA0B,EAC1B,qBAA6B;IAE7B,MAAM,8BAA8B,GAAG,IAAI,CAAC,KAAK,CAC/C,CAAC,4BAA4B,GAAG,kBAAkB,CAAC,GAAG,2BAA2B,CAClF,CAAC;IAEF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,8BAA8B,EAAE,qBAAqB,CAAC,CAAC;IAE9E,OAAO,KAAK,GAAG,CAAC,KAAK,GAAG,2BAA2B,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,QAAoB;IAChE,OAAO,oBAAoB,CACzB,QAAQ,CAAC,4BAA4B,EACrC,QAAQ,CAAC,MAAM,CAAC,oBAAoB,EACpC,QAAQ,CAAC,MAAM,CAAC,iCAAiC,CAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,QAAoB;IAC9D,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,yCAAyC,EAAE,6BAA6B,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtH,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,QAAoB;IAC7D,OAAO,6BAA6B,CAAC,QAAQ,CAAC,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,qBAAiC;IACtE,iEAAiE;IACjE,IAAI,kCAAkC,CAAC,qBAAqB,CAAC,EAAE,CAAC;QAC9D,OAAO,6BAA6B,CAAC;IACvC,CAAC;IACD,OAAO,sBAAsB,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gCAAgC,CAAC,IAAa,EAAE,SAA2B,EAAE,OAAe;IAC1G,MAAM,aAAa,GAAG,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAE9C,+BAA+B;IAC/B,MAAM,0BAA0B,GAAG,aAAa;QAC9C,CAAC,CAAC,gCAAgC,CAAC,SAAS,CAAC,qBAAqB,CAAC;QACnE,CAAC,CAAC,2BAA2B,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;IAEjE,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0CAA0C;IAC1C,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,sBAAsB,CAAC,SAAS,CAAC,qBAAqB,CAAC;QACzD,CAAC,CAAC,qBAAqB,CAAC;IAE1B,2DAA2D;IAC3D,MAAM,sBAAsB,GAAG,SAAS,CAAC,gBAAgB,KAAK,mBAAmB,CAAC;IAClF,MAAM,gBAAgB,GAAG,OAAO,GAAG,mBAAmB,CAAC;IAEvD,OAAO,sBAAsB,IAAI,gBAAgB,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,KAAwD,EACxD,cAA8B;IAE9B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,yBAAyB,CAAC,cAAc,EAAE,EAAE,CAAC;QACpE,IAAI,IAAI,CAAC,cAAc,KAAK,cAAc,EAAE,CAAC;YAC3C,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/ChainSafe/lodestar/issues"
13
13
  },
14
- "version": "1.40.0-dev.0ae7a89ead",
14
+ "version": "1.40.0-dev.1cab20c166",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
@@ -62,14 +62,14 @@
62
62
  "@chainsafe/pubkey-index-map": "^3.0.0",
63
63
  "@chainsafe/ssz": "^1.2.2",
64
64
  "@chainsafe/swap-or-not-shuffle": "^1.2.1",
65
- "@lodestar/config": "^1.40.0-dev.0ae7a89ead",
66
- "@lodestar/params": "^1.40.0-dev.0ae7a89ead",
67
- "@lodestar/types": "^1.40.0-dev.0ae7a89ead",
68
- "@lodestar/utils": "^1.40.0-dev.0ae7a89ead",
65
+ "@lodestar/config": "^1.40.0-dev.1cab20c166",
66
+ "@lodestar/params": "^1.40.0-dev.1cab20c166",
67
+ "@lodestar/types": "^1.40.0-dev.1cab20c166",
68
+ "@lodestar/utils": "^1.40.0-dev.1cab20c166",
69
69
  "bigint-buffer": "^1.1.5"
70
70
  },
71
71
  "devDependencies": {
72
- "@lodestar/api": "^1.40.0-dev.0ae7a89ead"
72
+ "@lodestar/api": "^1.40.0-dev.1cab20c166"
73
73
  },
74
74
  "keywords": [
75
75
  "ethereum",
@@ -77,5 +77,5 @@
77
77
  "beacon",
78
78
  "blockchain"
79
79
  ],
80
- "gitHead": "757f82afe00660128b35e96d623c226d22ad9444"
80
+ "gitHead": "c76f6cb3dc8cc7c4b0a631c4fd2761f8211e39e1"
81
81
  }
@@ -38,6 +38,7 @@ export {
38
38
  export * from "./externalData.js";
39
39
  export * from "./initiateValidatorExit.js";
40
40
  export * from "./isValidIndexedAttestation.js";
41
+ export * from "./processDepositRequest.js";
41
42
  export * from "./processOperations.js";
42
43
 
43
44
  export function processBlock(
@@ -1,4 +1,4 @@
1
- import {FAR_FUTURE_EPOCH, ForkSeq, MIN_ACTIVATION_BALANCE, PENDING_CONSOLIDATIONS_LIMIT} from "@lodestar/params";
1
+ import {FAR_FUTURE_EPOCH, MIN_ACTIVATION_BALANCE, PENDING_CONSOLIDATIONS_LIMIT} from "@lodestar/params";
2
2
  import {electra, ssz} from "@lodestar/types";
3
3
  import {CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
4
4
  import {hasEth1WithdrawalCredential} from "../util/capella.js";
@@ -13,7 +13,6 @@ import {getConsolidationChurnLimit, getPendingBalanceToWithdraw, isActiveValidat
13
13
 
14
14
  // TODO Electra: Clean up necessary as there is a lot of overlap with isValidSwitchToCompoundRequest
15
15
  export function processConsolidationRequest(
16
- fork: ForkSeq,
17
16
  state: CachedBeaconStateElectra | CachedBeaconStateGloas,
18
17
  consolidationRequest: electra.ConsolidationRequest
19
18
  ): void {
@@ -83,7 +82,7 @@ export function processConsolidationRequest(
83
82
  }
84
83
 
85
84
  // Verify the source has no pending withdrawals in the queue
86
- if (getPendingBalanceToWithdraw(fork, state, sourceIndex) > 0) {
85
+ if (getPendingBalanceToWithdraw(state, sourceIndex) > 0) {
87
86
  return;
88
87
  }
89
88
 
@@ -1,21 +1,114 @@
1
- import {UNSET_DEPOSIT_REQUESTS_START_INDEX} from "@lodestar/params";
2
- import {electra, ssz} from "@lodestar/types";
1
+ import {FAR_FUTURE_EPOCH, ForkSeq, UNSET_DEPOSIT_REQUESTS_START_INDEX} from "@lodestar/params";
2
+ import {BLSPubkey, Bytes32, UintNum64, electra, ssz} from "@lodestar/types";
3
3
  import {CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
4
+ import {findBuilderIndexByPubkey, isBuilderWithdrawalCredential} from "../util/gloas.js";
5
+ import {computeEpochAtSlot, isValidatorKnown} from "../util/index.js";
6
+ import {isValidDepositSignature} from "./processDeposit.js";
7
+
8
+ /**
9
+ * Apply a deposit for a builder. Either increases balance for existing builder or adds new builder to registry.
10
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-apply_deposit_for_builder
11
+ */
12
+ export function applyDepositForBuilder(
13
+ state: CachedBeaconStateGloas,
14
+ pubkey: BLSPubkey,
15
+ withdrawalCredentials: Bytes32,
16
+ amount: UintNum64,
17
+ signature: Bytes32
18
+ ): void {
19
+ const builderIndex = findBuilderIndexByPubkey(state, pubkey);
20
+
21
+ if (builderIndex !== null) {
22
+ // Existing builder - increase balance
23
+ const builder = state.builders.get(builderIndex);
24
+ builder.balance += amount;
25
+ } else {
26
+ // New builder - verify signature and add to registry
27
+ if (isValidDepositSignature(state.config, pubkey, withdrawalCredentials, amount, signature)) {
28
+ addBuilderToRegistry(state, pubkey, withdrawalCredentials, amount);
29
+ }
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Add a new builder to the builders registry.
35
+ * Reuses slots from exited and fully withdrawn builders if available.
36
+ */
37
+ function addBuilderToRegistry(
38
+ state: CachedBeaconStateGloas,
39
+ pubkey: BLSPubkey,
40
+ withdrawalCredentials: Bytes32,
41
+ amount: UintNum64
42
+ ): void {
43
+ const currentEpoch = computeEpochAtSlot(state.slot);
44
+
45
+ // Try to find a reusable slot from an exited builder with zero balance
46
+ let builderIndex = state.builders.length;
47
+ for (let i = 0; i < state.builders.length; i++) {
48
+ const builder = state.builders.getReadonly(i);
49
+ if (builder.withdrawableEpoch <= currentEpoch && builder.balance === 0) {
50
+ builderIndex = i;
51
+ break;
52
+ }
53
+ }
54
+
55
+ // Create new builder
56
+ const newBuilder = ssz.gloas.Builder.toViewDU({
57
+ pubkey,
58
+ version: withdrawalCredentials[0],
59
+ executionAddress: withdrawalCredentials.subarray(12),
60
+ balance: amount,
61
+ depositEpoch: currentEpoch,
62
+ withdrawableEpoch: FAR_FUTURE_EPOCH,
63
+ });
64
+
65
+ if (builderIndex < state.builders.length) {
66
+ // Reuse existing slot
67
+ state.builders.set(builderIndex, newBuilder);
68
+ } else {
69
+ // Append to end
70
+ state.builders.push(newBuilder);
71
+ }
72
+ }
4
73
 
5
74
  export function processDepositRequest(
75
+ fork: ForkSeq,
6
76
  state: CachedBeaconStateElectra | CachedBeaconStateGloas,
7
77
  depositRequest: electra.DepositRequest
8
78
  ): void {
9
- if (state.depositRequestsStartIndex === UNSET_DEPOSIT_REQUESTS_START_INDEX) {
79
+ const {pubkey, withdrawalCredentials, amount, signature} = depositRequest;
80
+
81
+ // Check if this is a builder or validator deposit
82
+ if (fork >= ForkSeq.gloas) {
83
+ const stateGloas = state as CachedBeaconStateGloas;
84
+ const builderIndex = findBuilderIndexByPubkey(stateGloas, pubkey);
85
+ const validatorIndex = state.epochCtx.getValidatorIndex(pubkey);
86
+
87
+ // Regardless of the withdrawal credentials prefix, if a builder/validator
88
+ // already exists with this pubkey, apply the deposit to their balance
89
+ const isBuilder = builderIndex !== null;
90
+ const isValidator = isValidatorKnown(state, validatorIndex);
91
+ const isBuilderPrefix = isBuilderWithdrawalCredential(withdrawalCredentials);
92
+
93
+ // Route to builder if it's an existing builder OR has builder prefix and is not a validator
94
+ if (isBuilder || (isBuilderPrefix && !isValidator)) {
95
+ // Apply builder deposits immediately
96
+ applyDepositForBuilder(stateGloas, pubkey, withdrawalCredentials, amount, signature);
97
+ return;
98
+ }
99
+ }
100
+
101
+ // Only set deposit_requests_start_index in Electra fork, not Gloas
102
+ if (fork < ForkSeq.gloas && state.depositRequestsStartIndex === UNSET_DEPOSIT_REQUESTS_START_INDEX) {
10
103
  state.depositRequestsStartIndex = depositRequest.index;
11
104
  }
12
105
 
13
- // Create pending deposit
106
+ // Add validator deposits to the queue
14
107
  const pendingDeposit = ssz.electra.PendingDeposit.toViewDU({
15
- pubkey: depositRequest.pubkey,
16
- withdrawalCredentials: depositRequest.withdrawalCredentials,
17
- amount: depositRequest.amount,
18
- signature: depositRequest.signature,
108
+ pubkey,
109
+ withdrawalCredentials,
110
+ amount,
111
+ signature,
19
112
  slot: state.slot,
20
113
  });
21
114
  state.pendingDeposits.push(pendingDeposit);
@@ -1,68 +1,47 @@
1
1
  import {PublicKey, Signature, verify} from "@chainsafe/blst";
2
2
  import {byteArrayEquals} from "@chainsafe/ssz";
3
- import {
4
- DOMAIN_BEACON_BUILDER,
5
- FAR_FUTURE_EPOCH,
6
- ForkPostGloas,
7
- MIN_ACTIVATION_BALANCE,
8
- SLOTS_PER_EPOCH,
9
- } from "@lodestar/params";
3
+ import {BUILDER_INDEX_SELF_BUILD, DOMAIN_BEACON_BUILDER, ForkPostGloas, SLOTS_PER_EPOCH} from "@lodestar/params";
10
4
  import {BeaconBlock, gloas, ssz} from "@lodestar/types";
11
5
  import {toHex, toRootHex} from "@lodestar/utils";
12
6
  import {G2_POINT_AT_INFINITY} from "../constants/constants.ts";
13
7
  import {CachedBeaconStateGloas} from "../types.ts";
14
- import {hasBuilderWithdrawalCredential} from "../util/gloas.ts";
15
- import {computeSigningRoot, getCurrentEpoch, getRandaoMix, isActiveValidator} from "../util/index.ts";
8
+ import {canBuilderCoverBid, isActiveBuilder} from "../util/gloas.ts";
9
+ import {computeSigningRoot, getCurrentEpoch, getRandaoMix} from "../util/index.ts";
16
10
 
17
11
  export function processExecutionPayloadBid(state: CachedBeaconStateGloas, block: BeaconBlock<ForkPostGloas>): void {
18
12
  const signedBid = block.body.signedExecutionPayloadBid;
19
13
  const bid = signedBid.message;
20
14
  const {builderIndex, value: amount} = bid;
21
- const builder = state.validators.getReadonly(builderIndex);
22
15
 
23
16
  // For self-builds, amount must be zero regardless of withdrawal credential prefix
24
- if (builderIndex === block.proposerIndex) {
17
+ if (builderIndex === BUILDER_INDEX_SELF_BUILD) {
25
18
  if (amount !== 0) {
26
19
  throw Error(`Invalid execution payload bid: self-build with non-zero amount ${amount}`);
27
20
  }
28
21
  if (!byteArrayEquals(signedBid.signature, G2_POINT_AT_INFINITY)) {
29
22
  throw Error("Invalid execution payload bid: self-build with non-zero signature");
30
23
  }
31
- // Non-self builds require builder withdrawal credential
32
- } else {
33
- if (!hasBuilderWithdrawalCredential(builder.withdrawalCredentials)) {
34
- throw Error(`Invalid execution payload bid: builder ${builderIndex} does not have builder withdrawal credential`);
24
+ }
25
+ // Non-self builds require active builder with valid signature
26
+ else {
27
+ const builder = state.builders.getReadonly(builderIndex);
28
+
29
+ // Verify that the builder is active
30
+ if (!isActiveBuilder(state, builderIndex)) {
31
+ throw Error(`Invalid execution payload bid: builder ${builderIndex} is not active`);
32
+ }
33
+
34
+ // Verify that the builder has funds to cover the bid
35
+ if (!canBuilderCoverBid(state, builderIndex, amount)) {
36
+ throw Error(`Invalid execution payload bid: builder ${builderIndex} has insufficient balance`);
35
37
  }
36
38
 
39
+ // Verify that the bid signature is valid
37
40
  if (!verifyExecutionPayloadBidSignature(state, builder.pubkey, signedBid)) {
38
41
  throw Error(`Invalid execution payload bid: invalid signature for builder ${builderIndex}`);
39
42
  }
40
43
  }
41
44
 
42
- if (!isActiveValidator(builder, getCurrentEpoch(state))) {
43
- throw Error(`Invalid execution payload bid: builder ${builderIndex} is not active`);
44
- }
45
-
46
- if (builder.slashed) {
47
- throw Error(`Invalid execution payload bid: builder ${builderIndex} is slashed`);
48
- }
49
-
50
- const pendingPayments = state.builderPendingPayments
51
- .getAllReadonly()
52
- .filter((payment) => payment.withdrawal.builderIndex === builderIndex)
53
- .reduce((acc, payment) => acc + payment.withdrawal.amount, 0);
54
- const pendingWithdrawals = state.builderPendingWithdrawals
55
- .getAllReadonly()
56
- .filter((withdrawal) => withdrawal.builderIndex === builderIndex)
57
- .reduce((acc, withdrawal) => acc + withdrawal.amount, 0);
58
-
59
- if (
60
- amount !== 0 &&
61
- state.balances.get(builderIndex) < amount + pendingPayments + pendingWithdrawals + MIN_ACTIVATION_BALANCE
62
- ) {
63
- throw Error("Insufficient builder balance");
64
- }
65
-
66
45
  if (bid.slot !== block.slot) {
67
46
  throw Error(`Bid slot ${bid.slot} does not match block slot ${block.slot}`);
68
47
  }
@@ -91,7 +70,6 @@ export function processExecutionPayloadBid(state: CachedBeaconStateGloas, block:
91
70
  feeRecipient: bid.feeRecipient,
92
71
  amount,
93
72
  builderIndex,
94
- withdrawableEpoch: FAR_FUTURE_EPOCH,
95
73
  }),
96
74
  });
97
75