@lodestar/state-transition 1.44.0-rc.2 → 1.44.0

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 (59) hide show
  1. package/lib/block/index.d.ts +2 -0
  2. package/lib/block/index.d.ts.map +1 -1
  3. package/lib/block/index.js +3 -1
  4. package/lib/block/index.js.map +1 -1
  5. package/lib/block/processBuilderDepositRequest.d.ts +10 -0
  6. package/lib/block/processBuilderDepositRequest.d.ts.map +1 -0
  7. package/lib/block/processBuilderDepositRequest.js +27 -0
  8. package/lib/block/processBuilderDepositRequest.js.map +1 -0
  9. package/lib/block/processBuilderExitRequest.d.ts +13 -0
  10. package/lib/block/processBuilderExitRequest.d.ts.map +1 -0
  11. package/lib/block/processBuilderExitRequest.js +29 -0
  12. package/lib/block/processBuilderExitRequest.js.map +1 -0
  13. package/lib/block/processDepositRequest.d.ts +2 -8
  14. package/lib/block/processDepositRequest.d.ts.map +1 -1
  15. package/lib/block/processDepositRequest.js +2 -98
  16. package/lib/block/processDepositRequest.js.map +1 -1
  17. package/lib/block/processExecutionPayloadBid.d.ts +2 -3
  18. package/lib/block/processExecutionPayloadBid.d.ts.map +1 -1
  19. package/lib/block/processExecutionPayloadBid.js +16 -8
  20. package/lib/block/processExecutionPayloadBid.js.map +1 -1
  21. package/lib/block/processParentExecutionPayload.d.ts +2 -2
  22. package/lib/block/processParentExecutionPayload.d.ts.map +1 -1
  23. package/lib/block/processParentExecutionPayload.js +16 -8
  24. package/lib/block/processParentExecutionPayload.js.map +1 -1
  25. package/lib/block/processProposerSlashing.d.ts.map +1 -1
  26. package/lib/block/processProposerSlashing.js +9 -1
  27. package/lib/block/processProposerSlashing.js.map +1 -1
  28. package/lib/block/processVoluntaryExit.d.ts +1 -1
  29. package/lib/block/processVoluntaryExit.d.ts.map +1 -1
  30. package/lib/block/processVoluntaryExit.js +1 -35
  31. package/lib/block/processVoluntaryExit.js.map +1 -1
  32. package/lib/slot/upgradeStateToGloas.js +34 -28
  33. package/lib/slot/upgradeStateToGloas.js.map +1 -1
  34. package/lib/stateView/beaconStateView.d.ts +1 -1
  35. package/lib/stateView/beaconStateView.d.ts.map +1 -1
  36. package/lib/stateView/beaconStateView.js.map +1 -1
  37. package/lib/stateView/interface.d.ts +1 -1
  38. package/lib/stateView/interface.d.ts.map +1 -1
  39. package/lib/stateView/nativeBeaconStateView.d.ts +1 -1
  40. package/lib/stateView/nativeBeaconStateView.d.ts.map +1 -1
  41. package/lib/stateView/nativeBeaconStateView.js.map +1 -1
  42. package/lib/util/gloas.d.ts +17 -0
  43. package/lib/util/gloas.d.ts.map +1 -1
  44. package/lib/util/gloas.js +59 -1
  45. package/lib/util/gloas.js.map +1 -1
  46. package/package.json +7 -7
  47. package/src/block/index.ts +6 -1
  48. package/src/block/processBuilderDepositRequest.ts +43 -0
  49. package/src/block/processBuilderExitRequest.ts +39 -0
  50. package/src/block/processDepositRequest.ts +3 -124
  51. package/src/block/processExecutionPayloadBid.ts +24 -9
  52. package/src/block/processParentExecutionPayload.ts +23 -11
  53. package/src/block/processProposerSlashing.ts +9 -4
  54. package/src/block/processVoluntaryExit.ts +2 -61
  55. package/src/slot/upgradeStateToGloas.ts +48 -32
  56. package/src/stateView/beaconStateView.ts +1 -1
  57. package/src/stateView/interface.ts +1 -1
  58. package/src/stateView/nativeBeaconStateView.ts +1 -1
  59. package/src/util/gloas.ts +76 -1
package/lib/util/gloas.js CHANGED
@@ -1,9 +1,14 @@
1
- import { BUILDER_INDEX_FLAG, BUILDER_PAYMENT_THRESHOLD_DENOMINATOR, BUILDER_PAYMENT_THRESHOLD_NUMERATOR, BUILDER_WITHDRAWAL_PREFIX, EFFECTIVE_BALANCE_INCREMENT, FAR_FUTURE_EPOCH, MIN_DEPOSIT_AMOUNT, MIN_SEED_LOOKAHEAD, PTC_SIZE, SLOTS_PER_EPOCH, } from "@lodestar/params";
1
+ import { PublicKey, Signature, verify } from "@chainsafe/blst";
2
+ import { BUILDER_INDEX_FLAG, BUILDER_PAYMENT_THRESHOLD_DENOMINATOR, BUILDER_PAYMENT_THRESHOLD_NUMERATOR, BUILDER_WITHDRAWAL_PREFIX, DOMAIN_BUILDER_DEPOSIT, EFFECTIVE_BALANCE_INCREMENT, FAR_FUTURE_EPOCH, MIN_DEPOSIT_AMOUNT, MIN_SEED_LOOKAHEAD, PTC_SIZE, SLOTS_PER_EPOCH, } from "@lodestar/params";
3
+ import { ssz } from "@lodestar/types";
2
4
  import { byteArrayEquals } from "@lodestar/utils";
5
+ import { ZERO_HASH } from "../constants/index.js";
3
6
  import { getBlockRootAtSlot } from "./blockRoot.js";
7
+ import { computeDomain } from "./domain.js";
4
8
  import { computeEpochAtSlot } from "./epoch.js";
5
9
  import { computeEpochShuffling } from "./epochShuffling.js";
6
10
  import { computePayloadTimelinessCommitteesForEpoch } from "./seed.js";
11
+ import { computeSigningRoot } from "./signingRoot.js";
7
12
  import { getActiveValidatorIndices } from "./validator.js";
8
13
  export function isBuilderWithdrawalCredential(withdrawalCredentials) {
9
14
  return withdrawalCredentials[0] === BUILDER_WITHDRAWAL_PREFIX;
@@ -171,4 +176,57 @@ export function getPtcWindowEpochCacheData(state) {
171
176
  nextPayloadTimelinessCommittees: toUint32Arrays(nextPtcWindow),
172
177
  };
173
178
  }
179
+ /**
180
+ * Add a new builder to the builders registry. Reuses slots from exited and fully withdrawn
181
+ * builders when available, otherwise appends.
182
+ *
183
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/beacon-chain.md#new-add_builder_to_registry
184
+ */
185
+ export function addBuilderToRegistry(state, pubkey, version, executionAddress, amount, slot) {
186
+ const currentEpoch = computeEpochAtSlot(state.slot);
187
+ const depositEpoch = computeEpochAtSlot(slot);
188
+ let builderIndex = state.builders.length;
189
+ for (let i = 0; i < state.builders.length; i++) {
190
+ const builder = state.builders.getReadonly(i);
191
+ if (builder.withdrawableEpoch <= currentEpoch && builder.balance === 0) {
192
+ builderIndex = i;
193
+ break;
194
+ }
195
+ }
196
+ const newBuilder = ssz.gloas.Builder.toViewDU({
197
+ pubkey,
198
+ version,
199
+ executionAddress,
200
+ balance: amount,
201
+ depositEpoch,
202
+ withdrawableEpoch: FAR_FUTURE_EPOCH,
203
+ });
204
+ if (builderIndex < state.builders.length) {
205
+ state.builders.set(builderIndex, newBuilder);
206
+ }
207
+ else {
208
+ state.builders.push(newBuilder);
209
+ }
210
+ }
211
+ /**
212
+ * Verify the proof of possession on a builder deposit request.
213
+ *
214
+ * The dedicated `DOMAIN_BUILDER_DEPOSIT` (vs the validator `DOMAIN_DEPOSIT`) prevents replay
215
+ * of validator deposit signatures against the builder deposit contract and vice versa.
216
+ *
217
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/beacon-chain.md#new-is_valid_builder_deposit_signature
218
+ */
219
+ export function isValidBuilderDepositSignature(config, pubkey, withdrawalCredentials, amount, signature) {
220
+ const depositMessage = { pubkey, withdrawalCredentials, amount };
221
+ const domain = computeDomain(DOMAIN_BUILDER_DEPOSIT, config.GENESIS_FORK_VERSION, ZERO_HASH);
222
+ const signingRoot = computeSigningRoot(ssz.phase0.DepositMessage, depositMessage, domain);
223
+ try {
224
+ const publicKey = PublicKey.fromBytes(pubkey, true);
225
+ const sig = Signature.fromBytes(signature, true);
226
+ return verify(signingRoot, publicKey, sig);
227
+ }
228
+ catch (_e) {
229
+ return false;
230
+ }
231
+ }
174
232
  //# sourceMappingURL=gloas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gloas.js","sourceRoot":"","sources":["../../src/util/gloas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gloas.js","sourceRoot":"","sources":["../../src/util/gloas.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/ChainSafe/lodestar/issues"
13
13
  },
14
- "version": "1.44.0-rc.2",
14
+ "version": "1.44.0",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
@@ -71,14 +71,14 @@
71
71
  "@chainsafe/pubkey-index-map": "^3.0.0",
72
72
  "@chainsafe/ssz": "^1.4.0",
73
73
  "@chainsafe/swap-or-not-shuffle": "^1.2.1",
74
- "@lodestar/config": "^1.44.0-rc.2",
75
- "@lodestar/params": "^1.44.0-rc.2",
76
- "@lodestar/types": "^1.44.0-rc.2",
77
- "@lodestar/utils": "^1.44.0-rc.2",
74
+ "@lodestar/config": "^1.44.0",
75
+ "@lodestar/params": "^1.44.0",
76
+ "@lodestar/types": "^1.44.0",
77
+ "@lodestar/utils": "^1.44.0",
78
78
  "@vekexasia/bigint-buffer2": "^1.1.1"
79
79
  },
80
80
  "devDependencies": {
81
- "@lodestar/api": "^1.44.0-rc.2"
81
+ "@lodestar/api": "^1.44.0"
82
82
  },
83
83
  "keywords": [
84
84
  "ethereum",
@@ -86,5 +86,5 @@
86
86
  "beacon",
87
87
  "blockchain"
88
88
  ],
89
- "gitHead": "fd39bbc0591f363398808776aab3192c03d782d9"
89
+ "gitHead": "e3d733b7b5107122ff90fc89021a9ab404198c39"
90
90
  }
@@ -38,6 +38,8 @@ export {
38
38
  export * from "./externalData.js";
39
39
  export * from "./initiateValidatorExit.js";
40
40
  export * from "./isValidIndexedAttestation.js";
41
+ export * from "./processBuilderDepositRequest.js";
42
+ export * from "./processBuilderExitRequest.js";
41
43
  export * from "./processDepositRequest.js";
42
44
  export * from "./processOperations.js";
43
45
 
@@ -85,7 +87,10 @@ export function processBlock(
85
87
  }
86
88
 
87
89
  if (fork >= ForkSeq.gloas) {
88
- processExecutionPayloadBid(state as CachedBeaconStateGloas, block as BeaconBlock<ForkPostGloas>);
90
+ processExecutionPayloadBid(
91
+ state as CachedBeaconStateGloas,
92
+ (block as BeaconBlock<ForkPostGloas>).body.signedExecutionPayloadBid
93
+ );
89
94
  }
90
95
 
91
96
  processRandao(state, block, verifySignatures);
@@ -0,0 +1,43 @@
1
+ import {FAR_FUTURE_EPOCH} from "@lodestar/params";
2
+ import {gloas} from "@lodestar/types";
3
+ import {CachedBeaconStateGloas} from "../types.js";
4
+ import {computeEpochAtSlot} from "../util/epoch.js";
5
+ import {addBuilderToRegistry, findBuilderIndexByPubkey, isValidBuilderDepositSignature} from "../util/gloas.js";
6
+
7
+ /**
8
+ * Process a builder deposit request from the execution layer: register a new builder
9
+ * (proof-of-possession gated) or top up an existing builder's balance.
10
+ *
11
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/beacon-chain.md#new-process_builder_deposit_request
12
+ */
13
+ export function processBuilderDepositRequest(
14
+ state: CachedBeaconStateGloas,
15
+ request: gloas.BuilderDepositRequest
16
+ ): void {
17
+ const {pubkey, withdrawalCredentials, amount, signature} = request;
18
+ const builderIndex = findBuilderIndexByPubkey(state, pubkey);
19
+
20
+ if (builderIndex === null) {
21
+ if (isValidBuilderDepositSignature(state.config, pubkey, withdrawalCredentials, amount, signature)) {
22
+ addBuilderToRegistry(
23
+ state,
24
+ pubkey,
25
+ withdrawalCredentials[0],
26
+ withdrawalCredentials.subarray(12),
27
+ amount,
28
+ state.slot
29
+ );
30
+ }
31
+ return;
32
+ }
33
+
34
+ const builder = state.builders.get(builderIndex);
35
+
36
+ // Increase balance by deposit amount
37
+ builder.balance += amount;
38
+
39
+ // If exited, reset the withdrawable epoch
40
+ if (builder.withdrawableEpoch !== FAR_FUTURE_EPOCH) {
41
+ builder.withdrawableEpoch = computeEpochAtSlot(state.slot) + state.config.MIN_BUILDER_WITHDRAWABILITY_DELAY;
42
+ }
43
+ }
@@ -0,0 +1,39 @@
1
+ import {gloas} from "@lodestar/types";
2
+ import {byteArrayEquals} from "@lodestar/utils";
3
+ import {CachedBeaconStateGloas} from "../types.js";
4
+ import {
5
+ findBuilderIndexByPubkey,
6
+ getPendingBalanceToWithdrawForBuilder,
7
+ initiateBuilderExit,
8
+ isActiveBuilder,
9
+ } from "../util/gloas.js";
10
+
11
+ /**
12
+ * Apply a builder exit request. Authorizes the exit via `source_address` (the builder's
13
+ * execution_address), not the BLS key — mirroring EIP-7002's 0x01 credential exit.
14
+ *
15
+ * Drops the request silently if any precondition fails; the EL has already dequeued it
16
+ * deterministically, so the fee is forfeited but `requests_hash` agreement is unaffected.
17
+ *
18
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/beacon-chain.md#new-process_builder_exit_request
19
+ */
20
+ export function processBuilderExitRequest(state: CachedBeaconStateGloas, request: gloas.BuilderExitRequest): void {
21
+ const builderIndex = findBuilderIndexByPubkey(state, request.pubkey);
22
+ if (builderIndex === null) {
23
+ return;
24
+ }
25
+
26
+ const builder = state.builders.getReadonly(builderIndex);
27
+
28
+ if (!isActiveBuilder(builder, state.finalizedCheckpoint.epoch)) {
29
+ return;
30
+ }
31
+ if (!byteArrayEquals(builder.executionAddress, request.sourceAddress)) {
32
+ return;
33
+ }
34
+ if (getPendingBalanceToWithdrawForBuilder(state, builderIndex) !== 0) {
35
+ return;
36
+ }
37
+
38
+ initiateBuilderExit(state, builderIndex);
39
+ }
@@ -1,135 +1,14 @@
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
- import {toPubkeyHex} from "@lodestar/utils";
1
+ import {ForkSeq, UNSET_DEPOSIT_REQUESTS_START_INDEX} from "@lodestar/params";
2
+ import {electra, ssz} from "@lodestar/types";
4
3
  import {CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
5
- import {findBuilderIndexByPubkey, isBuilderWithdrawalCredential} from "../util/gloas.js";
6
- import {computeEpochAtSlot, isValidatorKnown} from "../util/index.js";
7
- import {PendingDepositsLookup} from "../util/pendingDepositsLookup.js";
8
- import {isValidDepositSignature} from "./processDeposit.js";
9
4
 
10
- /**
11
- * Apply a deposit for a builder. Either increases balance for existing builder or adds new builder to registry.
12
- * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-apply_deposit_for_builder
13
- */
14
- export function applyDepositForBuilder(
15
- state: CachedBeaconStateGloas,
16
- pubkey: BLSPubkey,
17
- withdrawalCredentials: Bytes32,
18
- amount: UintNum64,
19
- signature: Bytes32,
20
- slot: UintNum64
21
- ): void {
22
- const builderIndex = findBuilderIndexByPubkey(state, pubkey);
23
-
24
- if (builderIndex !== null) {
25
- // Existing builder - increase balance
26
- const builder = state.builders.get(builderIndex);
27
- builder.balance += amount;
28
- } else {
29
- // New builder - verify signature and add to registry
30
- if (isValidDepositSignature(state.config, pubkey, withdrawalCredentials, amount, signature)) {
31
- addBuilderToRegistry(state, pubkey, withdrawalCredentials, amount, slot);
32
- }
33
- }
34
- }
35
-
36
- /**
37
- * Add a new builder to the builders registry.
38
- * Reuses slots from exited and fully withdrawn builders if available.
39
- */
40
- function addBuilderToRegistry(
41
- state: CachedBeaconStateGloas,
42
- pubkey: BLSPubkey,
43
- withdrawalCredentials: Bytes32,
44
- amount: UintNum64,
45
- slot: UintNum64
46
- ): void {
47
- const currentEpoch = computeEpochAtSlot(state.slot);
48
- const depositEpoch = computeEpochAtSlot(slot);
49
-
50
- // Try to find a reusable slot from an exited builder with zero balance
51
- let builderIndex = state.builders.length;
52
- for (let i = 0; i < state.builders.length; i++) {
53
- const builder = state.builders.getReadonly(i);
54
- if (builder.withdrawableEpoch <= currentEpoch && builder.balance === 0) {
55
- builderIndex = i;
56
- break;
57
- }
58
- }
59
-
60
- // Create new builder
61
- const newBuilder = ssz.gloas.Builder.toViewDU({
62
- pubkey,
63
- version: withdrawalCredentials[0],
64
- executionAddress: withdrawalCredentials.subarray(12),
65
- balance: amount,
66
- depositEpoch: depositEpoch,
67
- withdrawableEpoch: FAR_FUTURE_EPOCH,
68
- });
69
-
70
- if (builderIndex < state.builders.length) {
71
- // Reuse existing slot
72
- state.builders.set(builderIndex, newBuilder);
73
- } else {
74
- // Append to end
75
- state.builders.push(newBuilder);
76
- }
77
- }
78
-
79
- // TODO GLOAS: the PendingDepositsLookup is currently scoped to a single envelope of
80
- // deposit-requests. We can track it as ephemeral within EpochCache and transfer to the next block
81
- // transition to reuse cached signature verifications.
82
- // See https://github.com/ChainSafe/lodestar/issues/9181
83
5
  export function processDepositRequest(
84
6
  fork: ForkSeq,
85
7
  state: CachedBeaconStateElectra | CachedBeaconStateGloas,
86
- depositRequest: electra.DepositRequest,
87
- pendingDepositsLookup?: PendingDepositsLookup
8
+ depositRequest: electra.DepositRequest
88
9
  ): void {
89
10
  const {pubkey, withdrawalCredentials, amount, signature} = depositRequest;
90
11
 
91
- if (fork >= ForkSeq.gloas) {
92
- const stateGloas = state as CachedBeaconStateGloas;
93
- const lookup = pendingDepositsLookup ?? PendingDepositsLookup.build(stateGloas);
94
- const pubkeyHex = toPubkeyHex(pubkey);
95
- const builderIndex = findBuilderIndexByPubkey(stateGloas, pubkey);
96
- const validatorIndex = state.epochCtx.getValidatorIndex(pubkey);
97
-
98
- const isBuilder = builderIndex !== null;
99
- const isValidator = isValidatorKnown(state, validatorIndex);
100
-
101
- if (isBuilder) {
102
- // Top up an existing builder regardless of withdrawal credential prefix
103
- applyDepositForBuilder(stateGloas, pubkey, withdrawalCredentials, amount, signature, state.slot);
104
- return;
105
- }
106
-
107
- // Only check the (expensive) "pending validator" condition when needed
108
- if (
109
- isBuilderWithdrawalCredential(withdrawalCredentials) &&
110
- !isValidator &&
111
- !lookup.hasPendingValidator(state.config, pubkeyHex)
112
- ) {
113
- applyDepositForBuilder(stateGloas, pubkey, withdrawalCredentials, amount, signature, state.slot);
114
- return;
115
- }
116
-
117
- const pendingDeposit = ssz.electra.PendingDeposit.toViewDU({
118
- pubkey,
119
- withdrawalCredentials,
120
- amount,
121
- signature,
122
- slot: state.slot,
123
- });
124
- // Keep the lookup in sync with state.pendingDeposits so later deposit-requests
125
- // in the same envelope see this deposit
126
- lookup.add(pendingDeposit, pubkeyHex);
127
- state.pendingDeposits.push(pendingDeposit);
128
- return;
129
- }
130
-
131
- // Pre-Gloas (Electra) path
132
- // depositRequestsStartIndex is only set in Electra, from Fulu the eth1 bridge deposit mechanism was removed.
133
12
  if (fork === ForkSeq.electra && state.depositRequestsStartIndex === UNSET_DEPOSIT_REQUESTS_START_INDEX) {
134
13
  state.depositRequestsStartIndex = depositRequest.index;
135
14
  }
@@ -1,15 +1,17 @@
1
1
  import {PublicKey, Signature, verify} from "@chainsafe/blst";
2
- import {BUILDER_INDEX_SELF_BUILD, ForkPostGloas, SLOTS_PER_EPOCH} from "@lodestar/params";
3
- import {BeaconBlock, gloas, ssz} from "@lodestar/types";
2
+ import {BUILDER_INDEX_SELF_BUILD, GENESIS_SLOT, PAYLOAD_BUILDER_VERSION, SLOTS_PER_EPOCH} from "@lodestar/params";
3
+ import {gloas, ssz} from "@lodestar/types";
4
4
  import {byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
5
5
  import {G2_POINT_AT_INFINITY} from "../constants/constants.js";
6
6
  import {getExecutionPayloadBidSigningRoot} from "../signatureSets/executionPayloadBid.js";
7
7
  import {CachedBeaconStateGloas} from "../types.js";
8
8
  import {canBuilderCoverBid, isActiveBuilder} from "../util/gloas.js";
9
- import {getCurrentEpoch, getRandaoMix} from "../util/index.js";
9
+ import {getBlockRootAtSlot, getCurrentEpoch, getRandaoMix} from "../util/index.js";
10
10
 
11
- export function processExecutionPayloadBid(state: CachedBeaconStateGloas, block: BeaconBlock<ForkPostGloas>): void {
12
- const signedBid = block.body.signedExecutionPayloadBid;
11
+ export function processExecutionPayloadBid(
12
+ state: CachedBeaconStateGloas,
13
+ signedBid: gloas.SignedExecutionPayloadBid
14
+ ): void {
13
15
  const bid = signedBid.message;
14
16
  const {builderIndex, value: amount} = bid;
15
17
 
@@ -31,6 +33,13 @@ export function processExecutionPayloadBid(state: CachedBeaconStateGloas, block:
31
33
  throw Error(`Invalid execution payload bid: builder ${builderIndex} is not active`);
32
34
  }
33
35
 
36
+ // Verify that the builder is a payload builder
37
+ if (builder.version !== PAYLOAD_BUILDER_VERSION) {
38
+ throw Error(
39
+ `Invalid execution payload bid: builder ${builderIndex} version ${builder.version} != ${PAYLOAD_BUILDER_VERSION}`
40
+ );
41
+ }
42
+
34
43
  // Verify that the builder has funds to cover the bid
35
44
  if (!canBuilderCoverBid(state, builderIndex, amount)) {
36
45
  throw Error(`Invalid execution payload bid: builder ${builderIndex} has insufficient balance`);
@@ -42,8 +51,12 @@ export function processExecutionPayloadBid(state: CachedBeaconStateGloas, block:
42
51
  }
43
52
  }
44
53
 
45
- if (bid.slot !== block.slot) {
46
- throw Error(`Bid slot ${bid.slot} does not match block slot ${block.slot}`);
54
+ if (bid.slot !== state.slot) {
55
+ throw Error(`Bid slot ${bid.slot} does not match state slot ${state.slot}`);
56
+ }
57
+
58
+ if (state.slot <= GENESIS_SLOT) {
59
+ throw Error(`Execution payload bid not allowed at genesis slot ${state.slot}`);
47
60
  }
48
61
 
49
62
  if (!byteArrayEquals(bid.parentBlockHash, state.latestBlockHash)) {
@@ -52,9 +65,10 @@ export function processExecutionPayloadBid(state: CachedBeaconStateGloas, block:
52
65
  );
53
66
  }
54
67
 
55
- if (!byteArrayEquals(bid.parentBlockRoot, block.parentRoot)) {
68
+ const parentBlockRoot = getBlockRootAtSlot(state, state.slot - 1);
69
+ if (!byteArrayEquals(bid.parentBlockRoot, parentBlockRoot)) {
56
70
  throw Error(
57
- `Parent block root ${toRootHex(bid.parentBlockRoot)} of bid does not match block's parent root ${toRootHex(block.parentRoot)}`
71
+ `Parent block root ${toRootHex(bid.parentBlockRoot)} of bid does not match state's parent block root ${toRootHex(parentBlockRoot)}`
58
72
  );
59
73
  }
60
74
 
@@ -79,6 +93,7 @@ export function processExecutionPayloadBid(state: CachedBeaconStateGloas, block:
79
93
  amount,
80
94
  builderIndex,
81
95
  }),
96
+ proposerIndex: state.epochCtx.getBeaconProposer(state.slot),
82
97
  });
83
98
 
84
99
  state.builderPendingPayments.set(SLOTS_PER_EPOCH + (bid.slot % SLOTS_PER_EPOCH), pendingPaymentView);
@@ -1,9 +1,10 @@
1
1
  import {ForkPostGloas, SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
2
- import {BeaconBlock, electra, ssz} from "@lodestar/types";
2
+ import {BeaconBlock, gloas, ssz} from "@lodestar/types";
3
3
  import {byteArrayEquals, toRootHex} from "@lodestar/utils";
4
4
  import {CachedBeaconStateGloas} from "../types.js";
5
5
  import {computeEpochAtSlot} from "../util/epoch.js";
6
- import {PendingDepositsLookup} from "../util/pendingDepositsLookup.js";
6
+ import {processBuilderDepositRequest} from "./processBuilderDepositRequest.js";
7
+ import {processBuilderExitRequest} from "./processBuilderExitRequest.js";
7
8
  import {processConsolidationRequest} from "./processConsolidationRequest.js";
8
9
  import {processDepositRequest} from "./processDepositRequest.js";
9
10
  import {processWithdrawalRequest} from "./processWithdrawalRequest.js";
@@ -26,7 +27,7 @@ export function processParentExecutionPayload(state: CachedBeaconStateGloas, blo
26
27
  }
27
28
 
28
29
  // Parent was FULL -- verify the bid commitment and apply the payload
29
- const requestsRoot = ssz.electra.ExecutionRequests.hashTreeRoot(requests);
30
+ const requestsRoot = ssz.gloas.ExecutionRequests.hashTreeRoot(requests);
30
31
  if (!byteArrayEquals(requestsRoot, parentBid.executionRequestsRoot)) {
31
32
  throw new Error(
32
33
  `Parent execution requests root mismatch actual=${toRootHex(requestsRoot)} expected=${toRootHex(parentBid.executionRequestsRoot)}`
@@ -45,7 +46,7 @@ export function processParentExecutionPayload(state: CachedBeaconStateGloas, blo
45
46
  *
46
47
  * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.6/specs/gloas/beacon-chain.md#new-apply_parent_execution_payload
47
48
  */
48
- export function applyParentExecutionPayload(state: CachedBeaconStateGloas, requests: electra.ExecutionRequests): void {
49
+ export function applyParentExecutionPayload(state: CachedBeaconStateGloas, requests: gloas.ExecutionRequests): void {
49
50
  const fork = state.config.getForkSeq(state.slot);
50
51
  const parentBid = state.latestExecutionPayloadBid;
51
52
  const parentSlot = parentBid.slot;
@@ -54,11 +55,8 @@ export function applyParentExecutionPayload(state: CachedBeaconStateGloas, reque
54
55
 
55
56
  // Process execution requests from parent's payload. The execution
56
57
  // requests are processed at state.slot (child's slot), not the parent's slot.
57
- if (requests.deposits.length > 0) {
58
- const pendingDepositsLookup = PendingDepositsLookup.build(state);
59
- for (const deposit of requests.deposits) {
60
- processDepositRequest(fork, state, deposit, pendingDepositsLookup);
61
- }
58
+ for (const deposit of requests.deposits) {
59
+ processDepositRequest(fork, state, deposit);
62
60
  }
63
61
 
64
62
  for (const withdrawal of requests.withdrawals) {
@@ -69,6 +67,14 @@ export function applyParentExecutionPayload(state: CachedBeaconStateGloas, reque
69
67
  processConsolidationRequest(state, consolidation);
70
68
  }
71
69
 
70
+ for (const builderDeposit of requests.builderDeposits) {
71
+ processBuilderDepositRequest(state, builderDeposit);
72
+ }
73
+
74
+ for (const builderExit of requests.builderExits) {
75
+ processBuilderExitRequest(state, builderExit);
76
+ }
77
+
72
78
  // Settle the builder payment
73
79
  if (parentEpoch === currentEpoch) {
74
80
  settleBuilderPayment(state, SLOTS_PER_EPOCH + (parentSlot % SLOTS_PER_EPOCH));
@@ -110,8 +116,14 @@ function settleBuilderPayment(state: CachedBeaconStateGloas, paymentIndex: numbe
110
116
  state.builderPendingPayments.set(paymentIndex, ssz.gloas.BuilderPendingPayment.defaultViewDU());
111
117
  }
112
118
 
113
- function assertEmptyExecutionRequests(requests: electra.ExecutionRequests): void {
114
- if (requests.deposits.length !== 0 || requests.withdrawals.length !== 0 || requests.consolidations.length !== 0) {
119
+ function assertEmptyExecutionRequests(requests: gloas.ExecutionRequests): void {
120
+ if (
121
+ requests.deposits.length !== 0 ||
122
+ requests.withdrawals.length !== 0 ||
123
+ requests.consolidations.length !== 0 ||
124
+ requests.builderDeposits.length !== 0 ||
125
+ requests.builderExits.length !== 0
126
+ ) {
115
127
  throw new Error("Parent execution requests must be empty when parent block is EMPTY");
116
128
  }
117
129
  }
@@ -32,6 +32,10 @@ export function processProposerSlashing(
32
32
  );
33
33
 
34
34
  if (fork >= ForkSeq.gloas) {
35
+ // Remove the BuilderPendingPayment corresponding to this proposal if it is still in the
36
+ // 2-epoch window. Only clear it when the slashed validator is the proposer associated with
37
+ // the payment; otherwise an unrelated same-slot equivocation could grief an honest proposer's
38
+ // payment.
35
39
  const slot = Number(proposerSlashing.signedHeader1.message.slot);
36
40
  const proposalEpoch = computeEpochAtSlot(slot);
37
41
  const currentEpoch = state.epochCtx.epoch;
@@ -45,10 +49,11 @@ export function processProposerSlashing(
45
49
  : undefined;
46
50
 
47
51
  if (paymentIndex !== undefined) {
48
- (state as CachedBeaconStateGloas).builderPendingPayments.set(
49
- paymentIndex,
50
- ssz.gloas.BuilderPendingPayment.defaultViewDU()
51
- );
52
+ const builderPendingPayments = (state as CachedBeaconStateGloas).builderPendingPayments;
53
+ const payment = builderPendingPayments.get(paymentIndex);
54
+ if (payment.proposerIndex === proposerSlashing.signedHeader1.message.proposerIndex) {
55
+ builderPendingPayments.set(paymentIndex, ssz.gloas.BuilderPendingPayment.defaultViewDU());
56
+ }
52
57
  }
53
58
  }
54
59
 
@@ -2,14 +2,7 @@ import {FAR_FUTURE_EPOCH, ForkSeq} from "@lodestar/params";
2
2
  import {phase0} from "@lodestar/types";
3
3
  import {verifyVoluntaryExitSignature} from "../signatureSets/index.js";
4
4
  import {BeaconStateView} from "../stateView/beaconStateView.js";
5
- import {CachedBeaconStateAllForks, CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
6
- import {
7
- convertValidatorIndexToBuilderIndex,
8
- getPendingBalanceToWithdrawForBuilder,
9
- initiateBuilderExit,
10
- isActiveBuilder,
11
- isBuilderIndex,
12
- } from "../util/gloas.js";
5
+ import {CachedBeaconStateAllForks, CachedBeaconStateElectra} from "../types.js";
13
6
  import {getPendingBalanceToWithdraw, isActiveValidator} from "../util/index.js";
14
7
  import {initiateValidatorExit} from "./index.js";
15
8
 
@@ -24,7 +17,7 @@ export enum VoluntaryExitValidity {
24
17
  }
25
18
 
26
19
  /**
27
- * Process a VoluntaryExit operation. Initiates the exit of a validator or builder.
20
+ * Process a VoluntaryExit operation. Initiates the exit of a validator.
28
21
  *
29
22
  * PERF: Work depends on number of VoluntaryExit per block. On regular networks the average is 0 / block.
30
23
  */
@@ -34,21 +27,11 @@ export function processVoluntaryExit(
34
27
  signedVoluntaryExit: phase0.SignedVoluntaryExit,
35
28
  verifySignature = true
36
29
  ): void {
37
- const voluntaryExit = signedVoluntaryExit.message;
38
-
39
30
  const validity = getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature);
40
31
  if (validity !== VoluntaryExitValidity.valid) {
41
32
  throw Error(`Invalid voluntary exit at forkSeq=${fork} reason=${validity}`);
42
33
  }
43
34
 
44
- if (fork >= ForkSeq.gloas && isBuilderIndex(voluntaryExit.validatorIndex)) {
45
- initiateBuilderExit(
46
- state as CachedBeaconStateGloas,
47
- convertValidatorIndexToBuilderIndex(voluntaryExit.validatorIndex)
48
- );
49
- return;
50
- }
51
-
52
35
  const validator = state.validators.get(signedVoluntaryExit.message.validatorIndex);
53
36
  initiateValidatorExit(fork, state, validator);
54
37
  }
@@ -67,51 +50,9 @@ export function getVoluntaryExitValidity(
67
50
  return VoluntaryExitValidity.earlyEpoch;
68
51
  }
69
52
 
70
- // Check if this is a builder exit
71
- if (fork >= ForkSeq.gloas && isBuilderIndex(voluntaryExit.validatorIndex)) {
72
- return getBuilderVoluntaryExitValidity(state as CachedBeaconStateGloas, signedVoluntaryExit, verifySignature);
73
- }
74
-
75
53
  return getValidatorVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature);
76
54
  }
77
55
 
78
- function getBuilderVoluntaryExitValidity(
79
- state: CachedBeaconStateGloas,
80
- signedVoluntaryExit: phase0.SignedVoluntaryExit,
81
- verifySignature: boolean
82
- ): VoluntaryExitValidity {
83
- const {config, epochCtx} = state;
84
- const builderIndex = convertValidatorIndexToBuilderIndex(signedVoluntaryExit.message.validatorIndex);
85
-
86
- if (builderIndex >= state.builders.length) {
87
- return VoluntaryExitValidity.inactive;
88
- }
89
-
90
- const builder = state.builders.getReadonly(builderIndex);
91
-
92
- // Verify the builder is active
93
- if (!isActiveBuilder(builder, state.finalizedCheckpoint.epoch)) {
94
- return builder.withdrawableEpoch !== FAR_FUTURE_EPOCH
95
- ? VoluntaryExitValidity.alreadyExited
96
- : VoluntaryExitValidity.inactive;
97
- }
98
-
99
- // Only exit builder if it has no pending withdrawals in the queue
100
- if (getPendingBalanceToWithdrawForBuilder(state, builderIndex) !== 0) {
101
- return VoluntaryExitValidity.pendingWithdrawals;
102
- }
103
-
104
- // Verify signature
105
- if (
106
- verifySignature &&
107
- !verifyVoluntaryExitSignature(config, epochCtx.pubkeyCache, new BeaconStateView(state), signedVoluntaryExit)
108
- ) {
109
- return VoluntaryExitValidity.invalidSignature;
110
- }
111
-
112
- return VoluntaryExitValidity.valid;
113
- }
114
-
115
56
  function getValidatorVoluntaryExitValidity(
116
57
  fork: ForkSeq,
117
58
  state: CachedBeaconStateAllForks,