@lodestar/state-transition 1.40.0-dev.0ae7a89ead → 1.40.0-dev.193b2e2047
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.
- package/lib/block/index.d.ts +1 -0
- package/lib/block/index.d.ts.map +1 -1
- package/lib/block/index.js +1 -0
- package/lib/block/index.js.map +1 -1
- package/lib/block/isValidIndexedAttestation.d.ts.map +1 -1
- package/lib/block/isValidIndexedAttestation.js +2 -2
- package/lib/block/isValidIndexedAttestation.js.map +1 -1
- package/lib/block/isValidIndexedPayloadAttestation.d.ts.map +1 -1
- package/lib/block/isValidIndexedPayloadAttestation.js +1 -1
- package/lib/block/isValidIndexedPayloadAttestation.js.map +1 -1
- package/lib/block/processAttestationsAltair.d.ts.map +1 -1
- package/lib/block/processAttestationsAltair.js +2 -2
- package/lib/block/processAttestationsAltair.js.map +1 -1
- package/lib/block/processConsolidationRequest.d.ts +1 -2
- package/lib/block/processConsolidationRequest.d.ts.map +1 -1
- package/lib/block/processConsolidationRequest.js +2 -2
- package/lib/block/processConsolidationRequest.js.map +1 -1
- package/lib/block/processDepositRequest.d.ts +8 -2
- package/lib/block/processDepositRequest.d.ts.map +1 -1
- package/lib/block/processDepositRequest.js +81 -8
- package/lib/block/processDepositRequest.js.map +1 -1
- package/lib/block/processExecutionPayloadBid.d.ts.map +1 -1
- package/lib/block/processExecutionPayloadBid.js +16 -29
- package/lib/block/processExecutionPayloadBid.js.map +1 -1
- package/lib/block/processExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/block/processExecutionPayloadEnvelope.js +26 -25
- package/lib/block/processExecutionPayloadEnvelope.js.map +1 -1
- package/lib/block/processOperations.js +2 -2
- package/lib/block/processOperations.js.map +1 -1
- package/lib/block/processProposerSlashing.js +2 -2
- package/lib/block/processProposerSlashing.js.map +1 -1
- package/lib/block/processSyncCommittee.d.ts +1 -2
- package/lib/block/processSyncCommittee.d.ts.map +1 -1
- package/lib/block/processSyncCommittee.js +5 -5
- package/lib/block/processSyncCommittee.js.map +1 -1
- package/lib/block/processVoluntaryExit.d.ts +1 -1
- package/lib/block/processVoluntaryExit.d.ts.map +1 -1
- package/lib/block/processVoluntaryExit.js +45 -3
- package/lib/block/processVoluntaryExit.js.map +1 -1
- package/lib/block/processWithdrawalRequest.js +1 -1
- package/lib/block/processWithdrawalRequest.js.map +1 -1
- package/lib/block/processWithdrawals.d.ts +1 -0
- package/lib/block/processWithdrawals.d.ts.map +1 -1
- package/lib/block/processWithdrawals.js +121 -66
- package/lib/block/processWithdrawals.js.map +1 -1
- package/lib/epoch/processBuilderPendingPayments.d.ts.map +1 -1
- package/lib/epoch/processBuilderPendingPayments.js +1 -4
- package/lib/epoch/processBuilderPendingPayments.js.map +1 -1
- package/lib/signatureSets/attesterSlashings.d.ts +3 -4
- package/lib/signatureSets/attesterSlashings.d.ts.map +1 -1
- package/lib/signatureSets/attesterSlashings.js +6 -6
- package/lib/signatureSets/attesterSlashings.js.map +1 -1
- package/lib/signatureSets/blsToExecutionChange.d.ts +3 -3
- package/lib/signatureSets/blsToExecutionChange.d.ts.map +1 -1
- package/lib/signatureSets/blsToExecutionChange.js.map +1 -1
- package/lib/signatureSets/executionPayloadBid.d.ts +4 -0
- package/lib/signatureSets/executionPayloadBid.d.ts.map +1 -0
- package/lib/signatureSets/executionPayloadBid.js +8 -0
- package/lib/signatureSets/executionPayloadBid.js.map +1 -0
- package/lib/signatureSets/executionPayloadEnvelope.d.ts +4 -0
- package/lib/signatureSets/executionPayloadEnvelope.d.ts.map +1 -0
- package/lib/signatureSets/executionPayloadEnvelope.js +8 -0
- package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -0
- package/lib/signatureSets/index.d.ts +3 -2
- package/lib/signatureSets/index.d.ts.map +1 -1
- package/lib/signatureSets/index.js +10 -8
- package/lib/signatureSets/index.js.map +1 -1
- package/lib/signatureSets/indexedAttestation.d.ts +3 -4
- package/lib/signatureSets/indexedAttestation.d.ts.map +1 -1
- package/lib/signatureSets/indexedAttestation.js +6 -6
- package/lib/signatureSets/indexedAttestation.js.map +1 -1
- package/lib/signatureSets/indexedPayloadAttestation.d.ts +5 -4
- package/lib/signatureSets/indexedPayloadAttestation.d.ts.map +1 -1
- package/lib/signatureSets/indexedPayloadAttestation.js +3 -3
- package/lib/signatureSets/indexedPayloadAttestation.js.map +1 -1
- package/lib/signatureSets/proposer.d.ts +3 -3
- package/lib/signatureSets/proposer.d.ts.map +1 -1
- package/lib/signatureSets/proposer.js +12 -12
- package/lib/signatureSets/proposer.js.map +1 -1
- package/lib/signatureSets/proposerSlashings.d.ts +2 -3
- package/lib/signatureSets/proposerSlashings.d.ts.map +1 -1
- package/lib/signatureSets/proposerSlashings.js +6 -6
- package/lib/signatureSets/proposerSlashings.js.map +1 -1
- package/lib/signatureSets/randao.d.ts +1 -1
- package/lib/signatureSets/randao.d.ts.map +1 -1
- package/lib/signatureSets/randao.js +4 -4
- package/lib/signatureSets/randao.js.map +1 -1
- package/lib/signatureSets/voluntaryExits.d.ts +2 -2
- package/lib/signatureSets/voluntaryExits.d.ts.map +1 -1
- package/lib/signatureSets/voluntaryExits.js +6 -6
- package/lib/signatureSets/voluntaryExits.js.map +1 -1
- package/lib/util/electra.d.ts.map +1 -1
- package/lib/util/electra.js +1 -2
- package/lib/util/electra.js.map +1 -1
- package/lib/util/gloas.d.ts +46 -5
- package/lib/util/gloas.d.ts.map +1 -1
- package/lib/util/gloas.js +91 -5
- package/lib/util/gloas.js.map +1 -1
- package/lib/util/index.d.ts +1 -0
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +1 -0
- package/lib/util/index.js.map +1 -1
- package/lib/util/signatureSets.d.ts +38 -5
- package/lib/util/signatureSets.d.ts.map +1 -1
- package/lib/util/signatureSets.js +48 -6
- package/lib/util/signatureSets.js.map +1 -1
- package/lib/util/validator.d.ts +6 -1
- package/lib/util/validator.d.ts.map +1 -1
- package/lib/util/validator.js +26 -16
- package/lib/util/validator.js.map +1 -1
- package/package.json +7 -7
- package/src/block/index.ts +1 -0
- package/src/block/isValidIndexedAttestation.ts +3 -2
- package/src/block/isValidIndexedPayloadAttestation.ts +4 -1
- package/src/block/processAttestationsAltair.ts +2 -8
- package/src/block/processConsolidationRequest.ts +2 -3
- package/src/block/processDepositRequest.ts +101 -8
- package/src/block/processExecutionPayloadBid.ts +20 -42
- package/src/block/processExecutionPayloadEnvelope.ts +34 -30
- package/src/block/processOperations.ts +2 -2
- package/src/block/processProposerSlashing.ts +2 -2
- package/src/block/processSyncCommittee.ts +3 -6
- package/src/block/processVoluntaryExit.ts +60 -5
- package/src/block/processWithdrawalRequest.ts +1 -1
- package/src/block/processWithdrawals.ts +168 -70
- package/src/epoch/processBuilderPendingPayments.ts +1 -5
- package/src/signatureSets/attesterSlashings.ts +3 -7
- package/src/signatureSets/blsToExecutionChange.ts +3 -3
- package/src/signatureSets/executionPayloadBid.ts +14 -0
- package/src/signatureSets/executionPayloadEnvelope.ts +13 -0
- package/src/signatureSets/index.ts +8 -9
- package/src/signatureSets/indexedAttestation.ts +2 -7
- package/src/signatureSets/indexedPayloadAttestation.ts +9 -7
- package/src/signatureSets/proposer.ts +8 -12
- package/src/signatureSets/proposerSlashings.ts +4 -7
- package/src/signatureSets/randao.ts +4 -8
- package/src/signatureSets/voluntaryExits.ts +5 -10
- package/src/util/electra.ts +1 -4
- package/src/util/gloas.ts +116 -10
- package/src/util/index.ts +1 -0
- package/src/util/signatureSets.ts +84 -8
- package/src/util/validator.ts +31 -16
|
@@ -2,22 +2,29 @@ import {byteArrayEquals} from "@chainsafe/ssz";
|
|
|
2
2
|
import {
|
|
3
3
|
FAR_FUTURE_EPOCH,
|
|
4
4
|
ForkSeq,
|
|
5
|
+
MAX_BUILDERS_PER_WITHDRAWALS_SWEEP,
|
|
5
6
|
MAX_EFFECTIVE_BALANCE,
|
|
6
7
|
MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP,
|
|
7
8
|
MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP,
|
|
8
9
|
MAX_WITHDRAWALS_PER_PAYLOAD,
|
|
9
10
|
MIN_ACTIVATION_BALANCE,
|
|
10
11
|
} from "@lodestar/params";
|
|
11
|
-
import {ValidatorIndex, capella, ssz} from "@lodestar/types";
|
|
12
|
+
import {BuilderIndex, ValidatorIndex, capella, ssz} from "@lodestar/types";
|
|
12
13
|
import {toRootHex} from "@lodestar/utils";
|
|
13
14
|
import {CachedBeaconStateCapella, CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
|
|
14
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
convertBuilderIndexToValidatorIndex,
|
|
17
|
+
convertValidatorIndexToBuilderIndex,
|
|
18
|
+
isBuilderIndex,
|
|
19
|
+
isParentBlockFull,
|
|
20
|
+
} from "../util/gloas.ts";
|
|
15
21
|
import {
|
|
16
22
|
decreaseBalance,
|
|
17
23
|
getMaxEffectiveBalance,
|
|
18
24
|
hasEth1WithdrawalCredential,
|
|
19
25
|
hasExecutionWithdrawalCredential,
|
|
20
26
|
isCapellaPayloadHeader,
|
|
27
|
+
isPartiallyWithdrawableValidator,
|
|
21
28
|
} from "../util/index.js";
|
|
22
29
|
|
|
23
30
|
export function processWithdrawals(
|
|
@@ -32,9 +39,14 @@ export function processWithdrawals(
|
|
|
32
39
|
|
|
33
40
|
// processedBuilderWithdrawalsCount is withdrawals coming from builder payment since gloas (EIP-7732)
|
|
34
41
|
// processedPartialWithdrawalsCount is withdrawals coming from EL since electra (EIP-7002)
|
|
42
|
+
// processedBuildersSweepCount is withdrawals from builder sweep since gloas (EIP-7732)
|
|
35
43
|
// processedValidatorSweepCount is withdrawals coming from validator sweep
|
|
36
|
-
const {
|
|
37
|
-
|
|
44
|
+
const {
|
|
45
|
+
expectedWithdrawals,
|
|
46
|
+
processedBuilderWithdrawalsCount,
|
|
47
|
+
processedPartialWithdrawalsCount,
|
|
48
|
+
processedBuildersSweepCount,
|
|
49
|
+
} = getExpectedWithdrawals(fork, state);
|
|
38
50
|
const numWithdrawals = expectedWithdrawals.length;
|
|
39
51
|
|
|
40
52
|
// After gloas, withdrawals are verified later in processExecutionPayloadEnvelope
|
|
@@ -78,20 +90,20 @@ export function processWithdrawals(
|
|
|
78
90
|
|
|
79
91
|
if (fork >= ForkSeq.gloas) {
|
|
80
92
|
const stateGloas = state as CachedBeaconStateGloas;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
stateGloas.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
|
|
94
|
+
// Store expected withdrawals for verification
|
|
95
|
+
stateGloas.payloadExpectedWithdrawals = ssz.capella.Withdrawals.toViewDU(expectedWithdrawals);
|
|
96
|
+
|
|
97
|
+
// Update builder pending withdrawals queue
|
|
98
|
+
stateGloas.builderPendingWithdrawals = stateGloas.builderPendingWithdrawals.sliceFrom(
|
|
99
|
+
processedBuilderWithdrawalsCount
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// Update next builder index for sweep
|
|
103
|
+
if (stateGloas.builders.length > 0) {
|
|
104
|
+
const nextIndex = stateGloas.nextWithdrawalBuilderIndex + processedBuildersSweepCount;
|
|
105
|
+
stateGloas.nextWithdrawalBuilderIndex = nextIndex % stateGloas.builders.length;
|
|
106
|
+
}
|
|
95
107
|
}
|
|
96
108
|
// Update the nextWithdrawalIndex
|
|
97
109
|
// https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.0/specs/capella/beacon-chain.md#new-update_next_withdrawal_index
|
|
@@ -116,10 +128,14 @@ export function processWithdrawals(
|
|
|
116
128
|
function getBuilderWithdrawals(
|
|
117
129
|
state: CachedBeaconStateGloas,
|
|
118
130
|
withdrawalIndex: number,
|
|
119
|
-
|
|
131
|
+
priorWithdrawals: capella.Withdrawal[],
|
|
132
|
+
builderBalanceAfterWithdrawals: Map<number, number>
|
|
120
133
|
): {builderWithdrawals: capella.Withdrawal[]; withdrawalIndex: number; processedCount: number} {
|
|
134
|
+
const withdrawalsLimit = MAX_WITHDRAWALS_PER_PAYLOAD - 1;
|
|
135
|
+
if (priorWithdrawals.length > withdrawalsLimit) {
|
|
136
|
+
throw Error(`Prior withdrawals exceed limit: ${priorWithdrawals.length} > ${withdrawalsLimit}`);
|
|
137
|
+
}
|
|
121
138
|
const builderWithdrawals: capella.Withdrawal[] = [];
|
|
122
|
-
const epoch = state.epochCtx.epoch;
|
|
123
139
|
const allBuilderPendingWithdrawals =
|
|
124
140
|
state.builderPendingWithdrawals.length <= MAX_WITHDRAWALS_PER_PAYLOAD
|
|
125
141
|
? state.builderPendingWithdrawals.getAllReadonly()
|
|
@@ -127,55 +143,103 @@ function getBuilderWithdrawals(
|
|
|
127
143
|
|
|
128
144
|
let processedCount = 0;
|
|
129
145
|
for (let i = 0; i < state.builderPendingWithdrawals.length; i++) {
|
|
146
|
+
// Check combined length against limit
|
|
147
|
+
const allWithdrawals = priorWithdrawals.length + builderWithdrawals.length;
|
|
148
|
+
if (allWithdrawals >= withdrawalsLimit) {
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
|
|
130
152
|
const withdrawal = allBuilderPendingWithdrawals
|
|
131
153
|
? allBuilderPendingWithdrawals[i]
|
|
132
154
|
: state.builderPendingWithdrawals.getReadonly(i);
|
|
133
155
|
|
|
134
|
-
|
|
135
|
-
|
|
156
|
+
const builderIndex = withdrawal.builderIndex;
|
|
157
|
+
|
|
158
|
+
// Get builder balance (from builder.balance, not state.balances)
|
|
159
|
+
let balance = builderBalanceAfterWithdrawals.get(builderIndex);
|
|
160
|
+
if (balance === undefined) {
|
|
161
|
+
balance = state.builders.getReadonly(builderIndex).balance;
|
|
162
|
+
builderBalanceAfterWithdrawals.set(builderIndex, balance);
|
|
136
163
|
}
|
|
137
164
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
165
|
+
// Use the withdrawal amount directly as specified in the spec
|
|
166
|
+
builderWithdrawals.push({
|
|
167
|
+
index: withdrawalIndex,
|
|
168
|
+
validatorIndex: convertBuilderIndexToValidatorIndex(builderIndex),
|
|
169
|
+
address: withdrawal.feeRecipient,
|
|
170
|
+
amount: BigInt(withdrawal.amount),
|
|
171
|
+
});
|
|
172
|
+
withdrawalIndex++;
|
|
173
|
+
builderBalanceAfterWithdrawals.set(builderIndex, balance - withdrawal.amount);
|
|
141
174
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
balance = state.balances.get(builderIndex);
|
|
145
|
-
balanceAfterWithdrawals.set(builderIndex, balance);
|
|
146
|
-
}
|
|
175
|
+
processedCount++;
|
|
176
|
+
}
|
|
147
177
|
|
|
148
|
-
|
|
178
|
+
return {builderWithdrawals, withdrawalIndex, processedCount};
|
|
179
|
+
}
|
|
149
180
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
181
|
+
function getBuildersSweepWithdrawals(
|
|
182
|
+
state: CachedBeaconStateGloas,
|
|
183
|
+
withdrawalIndex: number,
|
|
184
|
+
numPriorWithdrawal: number,
|
|
185
|
+
builderBalanceAfterWithdrawals: Map<number, number>
|
|
186
|
+
): {buildersSweepWithdrawals: capella.Withdrawal[]; withdrawalIndex: number; processedCount: number} {
|
|
187
|
+
const withdrawalsLimit = MAX_WITHDRAWALS_PER_PAYLOAD - 1;
|
|
188
|
+
if (numPriorWithdrawal > withdrawalsLimit) {
|
|
189
|
+
throw Error(`Prior withdrawals exceed limit: ${numPriorWithdrawal} > ${withdrawalsLimit}`);
|
|
190
|
+
}
|
|
191
|
+
const buildersSweepWithdrawals: capella.Withdrawal[] = [];
|
|
192
|
+
const epoch = state.epochCtx.epoch;
|
|
193
|
+
const builders = state.builders;
|
|
156
194
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
195
|
+
// Return early if no builders
|
|
196
|
+
if (builders.length === 0) {
|
|
197
|
+
return {buildersSweepWithdrawals, withdrawalIndex, processedCount: 0};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const buildersLimit = Math.min(builders.length, MAX_BUILDERS_PER_WITHDRAWALS_SWEEP);
|
|
201
|
+
let processedCount = 0;
|
|
202
|
+
|
|
203
|
+
for (let n = 0; n < buildersLimit; n++) {
|
|
204
|
+
if (buildersSweepWithdrawals.length + numPriorWithdrawal >= withdrawalsLimit) {
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Get next builder in turn
|
|
209
|
+
const builderIndex = (state.nextWithdrawalBuilderIndex + n) % builders.length;
|
|
210
|
+
const builder = builders.getReadonly(builderIndex);
|
|
211
|
+
|
|
212
|
+
// Get builder balance
|
|
213
|
+
let balance = builderBalanceAfterWithdrawals.get(builderIndex);
|
|
214
|
+
if (balance === undefined) {
|
|
215
|
+
balance = builder.balance;
|
|
216
|
+
builderBalanceAfterWithdrawals.set(builderIndex, balance);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Check if builder is withdrawable and has balance
|
|
220
|
+
if (builder.withdrawableEpoch <= epoch && balance > 0) {
|
|
221
|
+
// Withdraw full balance to builder's execution address
|
|
222
|
+
buildersSweepWithdrawals.push({
|
|
223
|
+
index: withdrawalIndex,
|
|
224
|
+
validatorIndex: convertBuilderIndexToValidatorIndex(builderIndex),
|
|
225
|
+
address: builder.executionAddress,
|
|
226
|
+
amount: BigInt(balance),
|
|
227
|
+
});
|
|
228
|
+
withdrawalIndex++;
|
|
229
|
+
builderBalanceAfterWithdrawals.set(builderIndex, 0);
|
|
167
230
|
}
|
|
231
|
+
|
|
168
232
|
processedCount++;
|
|
169
233
|
}
|
|
170
234
|
|
|
171
|
-
return {
|
|
235
|
+
return {buildersSweepWithdrawals, withdrawalIndex, processedCount};
|
|
172
236
|
}
|
|
173
237
|
|
|
174
238
|
function getPendingPartialWithdrawals(
|
|
175
239
|
state: CachedBeaconStateElectra,
|
|
176
240
|
withdrawalIndex: number,
|
|
177
241
|
numPriorWithdrawal: number,
|
|
178
|
-
|
|
242
|
+
validatorBalanceAfterWithdrawals: Map<ValidatorIndex, number>
|
|
179
243
|
): {pendingPartialWithdrawals: capella.Withdrawal[]; withdrawalIndex: number; processedCount: number} {
|
|
180
244
|
const epoch = state.epochCtx.epoch;
|
|
181
245
|
const pendingPartialWithdrawals: capella.Withdrawal[] = [];
|
|
@@ -203,17 +267,17 @@ function getPendingPartialWithdrawals(
|
|
|
203
267
|
: state.pendingPartialWithdrawals.getReadonly(i);
|
|
204
268
|
if (
|
|
205
269
|
withdrawal.withdrawableEpoch > epoch ||
|
|
206
|
-
pendingPartialWithdrawals.length + numPriorWithdrawal
|
|
270
|
+
pendingPartialWithdrawals.length + numPriorWithdrawal >= partialWithdrawalBound
|
|
207
271
|
) {
|
|
208
272
|
break;
|
|
209
273
|
}
|
|
210
274
|
|
|
211
275
|
const validatorIndex = withdrawal.validatorIndex;
|
|
212
276
|
const validator = validators.getReadonly(validatorIndex);
|
|
213
|
-
let balance =
|
|
277
|
+
let balance = validatorBalanceAfterWithdrawals.get(validatorIndex);
|
|
214
278
|
if (balance === undefined) {
|
|
215
279
|
balance = state.balances.get(validatorIndex);
|
|
216
|
-
|
|
280
|
+
validatorBalanceAfterWithdrawals.set(validatorIndex, balance);
|
|
217
281
|
}
|
|
218
282
|
|
|
219
283
|
if (
|
|
@@ -231,7 +295,7 @@ function getPendingPartialWithdrawals(
|
|
|
231
295
|
amount: withdrawableBalance,
|
|
232
296
|
});
|
|
233
297
|
withdrawalIndex++;
|
|
234
|
-
|
|
298
|
+
validatorBalanceAfterWithdrawals.set(validatorIndex, balance - Number(withdrawableBalance));
|
|
235
299
|
}
|
|
236
300
|
processedCount++;
|
|
237
301
|
}
|
|
@@ -244,7 +308,7 @@ function getValidatorsSweepWithdrawals(
|
|
|
244
308
|
state: CachedBeaconStateCapella | CachedBeaconStateElectra | CachedBeaconStateGloas,
|
|
245
309
|
withdrawalIndex: number,
|
|
246
310
|
numPriorWithdrawal: number,
|
|
247
|
-
|
|
311
|
+
validatorBalanceAfterWithdrawals: Map<ValidatorIndex, number>
|
|
248
312
|
): {sweepWithdrawals: capella.Withdrawal[]; processedCount: number} {
|
|
249
313
|
const sweepWithdrawals: capella.Withdrawal[] = [];
|
|
250
314
|
const epoch = state.epochCtx.epoch;
|
|
@@ -264,13 +328,13 @@ function getValidatorsSweepWithdrawals(
|
|
|
264
328
|
const validatorIndex = (nextWithdrawalValidatorIndex + n) % validators.length;
|
|
265
329
|
|
|
266
330
|
const validator = validators.getReadonly(validatorIndex);
|
|
267
|
-
let balance =
|
|
331
|
+
let balance = validatorBalanceAfterWithdrawals.get(validatorIndex);
|
|
268
332
|
if (balance === undefined) {
|
|
269
333
|
balance = balances.get(validatorIndex);
|
|
270
|
-
|
|
334
|
+
validatorBalanceAfterWithdrawals.set(validatorIndex, balance);
|
|
271
335
|
}
|
|
272
336
|
|
|
273
|
-
const {withdrawableEpoch, withdrawalCredentials
|
|
337
|
+
const {withdrawableEpoch, withdrawalCredentials} = validator;
|
|
274
338
|
const hasWithdrawableCredentials = isPostElectra
|
|
275
339
|
? hasExecutionWithdrawalCredential(withdrawalCredentials)
|
|
276
340
|
: hasEth1WithdrawalCredential(withdrawalCredentials);
|
|
@@ -290,13 +354,11 @@ function getValidatorsSweepWithdrawals(
|
|
|
290
354
|
amount: BigInt(balance),
|
|
291
355
|
});
|
|
292
356
|
withdrawalIndex++;
|
|
293
|
-
|
|
294
|
-
} else if (
|
|
295
|
-
effectiveBalance === (isPostElectra ? getMaxEffectiveBalance(withdrawalCredentials) : MAX_EFFECTIVE_BALANCE) &&
|
|
296
|
-
balance > effectiveBalance
|
|
297
|
-
) {
|
|
357
|
+
validatorBalanceAfterWithdrawals.set(validatorIndex, 0);
|
|
358
|
+
} else if (isPartiallyWithdrawableValidator(fork, validator, balance)) {
|
|
298
359
|
// capella partial withdrawal
|
|
299
|
-
const
|
|
360
|
+
const maxEffectiveBalance = isPostElectra ? getMaxEffectiveBalance(withdrawalCredentials) : MAX_EFFECTIVE_BALANCE;
|
|
361
|
+
const partialAmount = balance - maxEffectiveBalance;
|
|
300
362
|
sweepWithdrawals.push({
|
|
301
363
|
index: withdrawalIndex,
|
|
302
364
|
validatorIndex,
|
|
@@ -304,7 +366,7 @@ function getValidatorsSweepWithdrawals(
|
|
|
304
366
|
amount: BigInt(partialAmount),
|
|
305
367
|
});
|
|
306
368
|
withdrawalIndex++;
|
|
307
|
-
|
|
369
|
+
validatorBalanceAfterWithdrawals.set(validatorIndex, balance - partialAmount);
|
|
308
370
|
}
|
|
309
371
|
processedCount++;
|
|
310
372
|
}
|
|
@@ -317,7 +379,16 @@ function applyWithdrawals(
|
|
|
317
379
|
withdrawals: capella.Withdrawal[]
|
|
318
380
|
): void {
|
|
319
381
|
for (const withdrawal of withdrawals) {
|
|
320
|
-
|
|
382
|
+
if (isBuilderIndex(withdrawal.validatorIndex)) {
|
|
383
|
+
// Handle builder withdrawal
|
|
384
|
+
const builderIndex = convertValidatorIndexToBuilderIndex(withdrawal.validatorIndex);
|
|
385
|
+
const builder = (state as CachedBeaconStateGloas).builders.get(builderIndex);
|
|
386
|
+
const withdrawalAmount = Number(withdrawal.amount);
|
|
387
|
+
builder.balance -= Math.min(withdrawalAmount, builder.balance);
|
|
388
|
+
} else {
|
|
389
|
+
// Handle validator withdrawal
|
|
390
|
+
decreaseBalance(state, withdrawal.validatorIndex, Number(withdrawal.amount));
|
|
391
|
+
}
|
|
321
392
|
}
|
|
322
393
|
}
|
|
323
394
|
|
|
@@ -328,6 +399,7 @@ export function getExpectedWithdrawals(
|
|
|
328
399
|
expectedWithdrawals: capella.Withdrawal[];
|
|
329
400
|
processedBuilderWithdrawalsCount: number;
|
|
330
401
|
processedPartialWithdrawalsCount: number;
|
|
402
|
+
processedBuildersSweepCount: number;
|
|
331
403
|
processedValidatorSweepCount: number;
|
|
332
404
|
} {
|
|
333
405
|
if (fork < ForkSeq.capella) {
|
|
@@ -337,20 +409,28 @@ export function getExpectedWithdrawals(
|
|
|
337
409
|
let withdrawalIndex = state.nextWithdrawalIndex;
|
|
338
410
|
|
|
339
411
|
const expectedWithdrawals: capella.Withdrawal[] = [];
|
|
340
|
-
//
|
|
412
|
+
// Separate maps to track balances after applying withdrawals
|
|
341
413
|
// https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.0/specs/capella/beacon-chain.md#new-get_balance_after_withdrawals
|
|
342
|
-
const
|
|
414
|
+
const builderBalanceAfterWithdrawals = new Map<BuilderIndex, number>();
|
|
415
|
+
const validatorBalanceAfterWithdrawals = new Map<ValidatorIndex, number>();
|
|
343
416
|
// partialWithdrawalsCount is withdrawals coming from EL since electra (EIP-7002)
|
|
344
417
|
let processedPartialWithdrawalsCount = 0;
|
|
345
418
|
// builderWithdrawalsCount is withdrawals coming from builder payments since Gloas (EIP-7732)
|
|
346
419
|
let processedBuilderWithdrawalsCount = 0;
|
|
420
|
+
// buildersSweepCount is withdrawals from builder sweep since Gloas (EIP-7732)
|
|
421
|
+
let processedBuildersSweepCount = 0;
|
|
347
422
|
|
|
348
423
|
if (fork >= ForkSeq.gloas) {
|
|
349
424
|
const {
|
|
350
425
|
builderWithdrawals,
|
|
351
426
|
withdrawalIndex: newWithdrawalIndex,
|
|
352
427
|
processedCount,
|
|
353
|
-
} = getBuilderWithdrawals(
|
|
428
|
+
} = getBuilderWithdrawals(
|
|
429
|
+
state as CachedBeaconStateGloas,
|
|
430
|
+
withdrawalIndex,
|
|
431
|
+
expectedWithdrawals,
|
|
432
|
+
builderBalanceAfterWithdrawals
|
|
433
|
+
);
|
|
354
434
|
|
|
355
435
|
expectedWithdrawals.push(...builderWithdrawals);
|
|
356
436
|
withdrawalIndex = newWithdrawalIndex;
|
|
@@ -366,7 +446,7 @@ export function getExpectedWithdrawals(
|
|
|
366
446
|
state as CachedBeaconStateElectra,
|
|
367
447
|
withdrawalIndex,
|
|
368
448
|
expectedWithdrawals.length,
|
|
369
|
-
|
|
449
|
+
validatorBalanceAfterWithdrawals
|
|
370
450
|
);
|
|
371
451
|
|
|
372
452
|
expectedWithdrawals.push(...pendingPartialWithdrawals);
|
|
@@ -374,12 +454,29 @@ export function getExpectedWithdrawals(
|
|
|
374
454
|
processedPartialWithdrawalsCount = processedCount;
|
|
375
455
|
}
|
|
376
456
|
|
|
457
|
+
if (fork >= ForkSeq.gloas) {
|
|
458
|
+
const {
|
|
459
|
+
buildersSweepWithdrawals,
|
|
460
|
+
withdrawalIndex: newWithdrawalIndex,
|
|
461
|
+
processedCount,
|
|
462
|
+
} = getBuildersSweepWithdrawals(
|
|
463
|
+
state as CachedBeaconStateGloas,
|
|
464
|
+
withdrawalIndex,
|
|
465
|
+
expectedWithdrawals.length,
|
|
466
|
+
builderBalanceAfterWithdrawals
|
|
467
|
+
);
|
|
468
|
+
|
|
469
|
+
expectedWithdrawals.push(...buildersSweepWithdrawals);
|
|
470
|
+
withdrawalIndex = newWithdrawalIndex;
|
|
471
|
+
processedBuildersSweepCount = processedCount;
|
|
472
|
+
}
|
|
473
|
+
|
|
377
474
|
const {sweepWithdrawals, processedCount: processedValidatorSweepCount} = getValidatorsSweepWithdrawals(
|
|
378
475
|
fork,
|
|
379
476
|
state,
|
|
380
477
|
withdrawalIndex,
|
|
381
478
|
expectedWithdrawals.length,
|
|
382
|
-
|
|
479
|
+
validatorBalanceAfterWithdrawals
|
|
383
480
|
);
|
|
384
481
|
|
|
385
482
|
expectedWithdrawals.push(...sweepWithdrawals);
|
|
@@ -388,6 +485,7 @@ export function getExpectedWithdrawals(
|
|
|
388
485
|
expectedWithdrawals,
|
|
389
486
|
processedBuilderWithdrawalsCount,
|
|
390
487
|
processedPartialWithdrawalsCount,
|
|
488
|
+
processedBuildersSweepCount,
|
|
391
489
|
processedValidatorSweepCount,
|
|
392
490
|
};
|
|
393
491
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
2
2
|
import {ssz} from "@lodestar/types";
|
|
3
3
|
import {CachedBeaconStateGloas} from "../types.ts";
|
|
4
|
-
import {computeExitEpochAndUpdateChurn} from "../util/epoch.ts";
|
|
5
4
|
import {getBuilderPaymentQuorumThreshold} from "../util/gloas.ts";
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -12,10 +11,7 @@ export function processBuilderPendingPayments(state: CachedBeaconStateGloas): vo
|
|
|
12
11
|
|
|
13
12
|
for (let i = 0; i < SLOTS_PER_EPOCH; i++) {
|
|
14
13
|
const payment = state.builderPendingPayments.get(i);
|
|
15
|
-
if (payment.weight
|
|
16
|
-
const exitQueueEpoch = computeExitEpochAndUpdateChurn(state, BigInt(payment.withdrawal.amount));
|
|
17
|
-
payment.withdrawal.withdrawableEpoch = exitQueueEpoch + state.config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY;
|
|
18
|
-
|
|
14
|
+
if (payment.weight >= quorum) {
|
|
19
15
|
state.builderPendingWithdrawals.push(payment.withdrawal);
|
|
20
16
|
}
|
|
21
17
|
}
|
|
@@ -1,38 +1,34 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
2
|
import {DOMAIN_BEACON_ATTESTER} from "@lodestar/params";
|
|
3
3
|
import {AttesterSlashing, IndexedAttestationBigint, SignedBeaconBlock, Slot, ssz} from "@lodestar/types";
|
|
4
|
-
import {Index2PubkeyCache} from "../cache/pubkeyCache.js";
|
|
5
4
|
import {ISignatureSet, SignatureSetType, computeSigningRoot, computeStartSlotAtEpoch} from "../util/index.js";
|
|
6
5
|
|
|
7
6
|
/** Get signature sets from all AttesterSlashing objects in a block */
|
|
8
7
|
export function getAttesterSlashingsSignatureSets(
|
|
9
8
|
config: BeaconConfig,
|
|
10
|
-
index2pubkey: Index2PubkeyCache,
|
|
11
9
|
signedBlock: SignedBeaconBlock
|
|
12
10
|
): ISignatureSet[] {
|
|
13
11
|
// the getDomain() api requires the state slot as 1st param, however it's the same to block.slot in state-transition
|
|
14
12
|
// and the same epoch when we verify blocks in batch in beacon-node. So we can safely use block.slot here.
|
|
15
13
|
const blockSlot = signedBlock.message.slot;
|
|
16
14
|
return signedBlock.message.body.attesterSlashings.flatMap((attesterSlashing) =>
|
|
17
|
-
getAttesterSlashingSignatureSets(config,
|
|
15
|
+
getAttesterSlashingSignatureSets(config, blockSlot, attesterSlashing)
|
|
18
16
|
);
|
|
19
17
|
}
|
|
20
18
|
|
|
21
19
|
/** Get signature sets from a single AttesterSlashing object */
|
|
22
20
|
export function getAttesterSlashingSignatureSets(
|
|
23
21
|
config: BeaconConfig,
|
|
24
|
-
index2pubkey: Index2PubkeyCache,
|
|
25
22
|
stateSlot: Slot,
|
|
26
23
|
attesterSlashing: AttesterSlashing
|
|
27
24
|
): ISignatureSet[] {
|
|
28
25
|
return [attesterSlashing.attestation1, attesterSlashing.attestation2].map((attestation) =>
|
|
29
|
-
getIndexedAttestationBigintSignatureSet(config,
|
|
26
|
+
getIndexedAttestationBigintSignatureSet(config, stateSlot, attestation)
|
|
30
27
|
);
|
|
31
28
|
}
|
|
32
29
|
|
|
33
30
|
export function getIndexedAttestationBigintSignatureSet(
|
|
34
31
|
config: BeaconConfig,
|
|
35
|
-
index2pubkey: Index2PubkeyCache,
|
|
36
32
|
stateSlot: Slot,
|
|
37
33
|
indexedAttestation: IndexedAttestationBigint
|
|
38
34
|
): ISignatureSet {
|
|
@@ -41,7 +37,7 @@ export function getIndexedAttestationBigintSignatureSet(
|
|
|
41
37
|
|
|
42
38
|
return {
|
|
43
39
|
type: SignatureSetType.aggregate,
|
|
44
|
-
|
|
40
|
+
indices: indexedAttestation.attestingIndices.map((i) => Number(i)),
|
|
45
41
|
signingRoot: computeSigningRoot(ssz.phase0.AttestationDataBigint, indexedAttestation.data, domain),
|
|
46
42
|
signature: indexedAttestation.signature,
|
|
47
43
|
};
|
|
@@ -2,7 +2,7 @@ import {PublicKey} from "@chainsafe/blst";
|
|
|
2
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
3
|
import {DOMAIN_BLS_TO_EXECUTION_CHANGE, ForkName} from "@lodestar/params";
|
|
4
4
|
import {capella, ssz} from "@lodestar/types";
|
|
5
|
-
import {
|
|
5
|
+
import {SignatureSetType, SingleSignatureSet, computeSigningRoot, verifySignatureSet} from "../util/index.js";
|
|
6
6
|
|
|
7
7
|
export function verifyBlsToExecutionChangeSignature(
|
|
8
8
|
config: BeaconConfig,
|
|
@@ -17,7 +17,7 @@ export function verifyBlsToExecutionChangeSignature(
|
|
|
17
17
|
export function getBlsToExecutionChangeSignatureSet(
|
|
18
18
|
config: BeaconConfig,
|
|
19
19
|
signedBLSToExecutionChange: capella.SignedBLSToExecutionChange
|
|
20
|
-
):
|
|
20
|
+
): SingleSignatureSet {
|
|
21
21
|
// signatureFork for signing domain is fixed
|
|
22
22
|
const signatureFork = ForkName.phase0;
|
|
23
23
|
const domain = config.getDomainAtFork(signatureFork, DOMAIN_BLS_TO_EXECUTION_CHANGE);
|
|
@@ -35,7 +35,7 @@ export function getBlsToExecutionChangeSignatureSet(
|
|
|
35
35
|
export function getBlsToExecutionChangeSignatureSets(
|
|
36
36
|
config: BeaconConfig,
|
|
37
37
|
signedBlock: capella.SignedBeaconBlock
|
|
38
|
-
):
|
|
38
|
+
): SingleSignatureSet[] {
|
|
39
39
|
return signedBlock.message.body.blsToExecutionChanges.map((blsToExecutionChange) =>
|
|
40
40
|
getBlsToExecutionChangeSignatureSet(config, blsToExecutionChange)
|
|
41
41
|
);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
2
|
+
import {DOMAIN_BEACON_BUILDER} from "@lodestar/params";
|
|
3
|
+
import {Slot, gloas, ssz} from "@lodestar/types";
|
|
4
|
+
import {computeSigningRoot} from "../util/index.js";
|
|
5
|
+
|
|
6
|
+
export function getExecutionPayloadBidSigningRoot(
|
|
7
|
+
config: BeaconConfig,
|
|
8
|
+
stateSlot: Slot,
|
|
9
|
+
bid: gloas.ExecutionPayloadBid
|
|
10
|
+
): Uint8Array {
|
|
11
|
+
const domain = config.getDomain(stateSlot, DOMAIN_BEACON_BUILDER);
|
|
12
|
+
|
|
13
|
+
return computeSigningRoot(ssz.gloas.ExecutionPayloadBid, bid, domain);
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
2
|
+
import {DOMAIN_BEACON_BUILDER} from "@lodestar/params";
|
|
3
|
+
import {gloas, ssz} from "@lodestar/types";
|
|
4
|
+
import {computeSigningRoot} from "../util/index.js";
|
|
5
|
+
|
|
6
|
+
export function getExecutionPayloadEnvelopeSigningRoot(
|
|
7
|
+
config: BeaconConfig,
|
|
8
|
+
envelope: gloas.ExecutionPayloadEnvelope
|
|
9
|
+
): Uint8Array {
|
|
10
|
+
const domain = config.getDomain(envelope.slot, DOMAIN_BEACON_BUILDER);
|
|
11
|
+
|
|
12
|
+
return computeSigningRoot(ssz.gloas.ExecutionPayloadEnvelope, envelope, domain);
|
|
13
|
+
}
|
|
@@ -2,7 +2,6 @@ import {BeaconConfig} from "@lodestar/config";
|
|
|
2
2
|
import {ForkSeq} from "@lodestar/params";
|
|
3
3
|
import {IndexedAttestation, SignedBeaconBlock, altair, capella} from "@lodestar/types";
|
|
4
4
|
import {getSyncCommitteeSignatureSet} from "../block/processSyncCommittee.js";
|
|
5
|
-
import {Index2PubkeyCache} from "../cache/pubkeyCache.js";
|
|
6
5
|
import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
|
|
7
6
|
import {ISignatureSet} from "../util/index.js";
|
|
8
7
|
import {getAttesterSlashingsSignatureSets} from "./attesterSlashings.js";
|
|
@@ -15,6 +14,8 @@ import {getVoluntaryExitsSignatureSets} from "./voluntaryExits.js";
|
|
|
15
14
|
|
|
16
15
|
export * from "./attesterSlashings.js";
|
|
17
16
|
export * from "./blsToExecutionChange.js";
|
|
17
|
+
export * from "./executionPayloadBid.js";
|
|
18
|
+
export * from "./executionPayloadEnvelope.js";
|
|
18
19
|
export * from "./indexedAttestation.js";
|
|
19
20
|
export * from "./indexedPayloadAttestation.js";
|
|
20
21
|
export * from "./proposer.js";
|
|
@@ -28,7 +29,6 @@ export * from "./voluntaryExits.js";
|
|
|
28
29
|
*/
|
|
29
30
|
export function getBlockSignatureSets(
|
|
30
31
|
config: BeaconConfig,
|
|
31
|
-
index2pubkey: Index2PubkeyCache,
|
|
32
32
|
currentSyncCommitteeIndexed: SyncCommitteeCache,
|
|
33
33
|
signedBlock: SignedBeaconBlock,
|
|
34
34
|
indexedAttestations: IndexedAttestation[],
|
|
@@ -41,22 +41,21 @@ export function getBlockSignatureSets(
|
|
|
41
41
|
const fork = config.getForkSeq(signedBlock.message.slot);
|
|
42
42
|
|
|
43
43
|
const signatureSets = [
|
|
44
|
-
getRandaoRevealSignatureSet(config,
|
|
45
|
-
...getProposerSlashingsSignatureSets(config,
|
|
46
|
-
...getAttesterSlashingsSignatureSets(config,
|
|
47
|
-
...getAttestationsSignatureSets(config,
|
|
48
|
-
...getVoluntaryExitsSignatureSets(config,
|
|
44
|
+
getRandaoRevealSignatureSet(config, signedBlock.message),
|
|
45
|
+
...getProposerSlashingsSignatureSets(config, signedBlock),
|
|
46
|
+
...getAttesterSlashingsSignatureSets(config, signedBlock),
|
|
47
|
+
...getAttestationsSignatureSets(config, signedBlock, indexedAttestations),
|
|
48
|
+
...getVoluntaryExitsSignatureSets(config, signedBlock),
|
|
49
49
|
];
|
|
50
50
|
|
|
51
51
|
if (!opts?.skipProposerSignature) {
|
|
52
|
-
signatureSets.push(getBlockProposerSignatureSet(config,
|
|
52
|
+
signatureSets.push(getBlockProposerSignatureSet(config, signedBlock));
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// Only after altair fork, validate tSyncCommitteeSignature
|
|
56
56
|
if (fork >= ForkSeq.altair) {
|
|
57
57
|
const syncCommitteeSignatureSet = getSyncCommitteeSignatureSet(
|
|
58
58
|
config,
|
|
59
|
-
index2pubkey,
|
|
60
59
|
currentSyncCommitteeIndexed,
|
|
61
60
|
(signedBlock as altair.SignedBeaconBlock).message
|
|
62
61
|
);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
2
|
import {DOMAIN_BEACON_ATTESTER} from "@lodestar/params";
|
|
3
3
|
import {IndexedAttestation, SignedBeaconBlock, Slot, phase0, ssz} from "@lodestar/types";
|
|
4
|
-
import {Index2PubkeyCache} from "../cache/pubkeyCache.js";
|
|
5
4
|
import {
|
|
6
5
|
ISignatureSet,
|
|
7
6
|
computeSigningRoot,
|
|
@@ -22,13 +21,12 @@ export function getAttestationDataSigningRoot(
|
|
|
22
21
|
|
|
23
22
|
export function getAttestationWithIndicesSignatureSet(
|
|
24
23
|
config: BeaconConfig,
|
|
25
|
-
index2pubkey: Index2PubkeyCache,
|
|
26
24
|
stateSlot: Slot,
|
|
27
25
|
attestation: Pick<phase0.Attestation, "data" | "signature">,
|
|
28
26
|
attestingIndices: number[]
|
|
29
27
|
): ISignatureSet {
|
|
30
28
|
return createAggregateSignatureSetFromComponents(
|
|
31
|
-
attestingIndices
|
|
29
|
+
attestingIndices,
|
|
32
30
|
getAttestationDataSigningRoot(config, stateSlot, attestation.data),
|
|
33
31
|
attestation.signature
|
|
34
32
|
);
|
|
@@ -36,13 +34,11 @@ export function getAttestationWithIndicesSignatureSet(
|
|
|
36
34
|
|
|
37
35
|
export function getIndexedAttestationSignatureSet(
|
|
38
36
|
config: BeaconConfig,
|
|
39
|
-
index2pubkey: Index2PubkeyCache,
|
|
40
37
|
stateSlot: Slot,
|
|
41
38
|
indexedAttestation: IndexedAttestation
|
|
42
39
|
): ISignatureSet {
|
|
43
40
|
return getAttestationWithIndicesSignatureSet(
|
|
44
41
|
config,
|
|
45
|
-
index2pubkey,
|
|
46
42
|
stateSlot,
|
|
47
43
|
indexedAttestation,
|
|
48
44
|
indexedAttestation.attestingIndices
|
|
@@ -51,7 +47,6 @@ export function getIndexedAttestationSignatureSet(
|
|
|
51
47
|
|
|
52
48
|
export function getAttestationsSignatureSets(
|
|
53
49
|
config: BeaconConfig,
|
|
54
|
-
index2pubkey: Index2PubkeyCache,
|
|
55
50
|
signedBlock: SignedBeaconBlock,
|
|
56
51
|
indexedAttestations: IndexedAttestation[]
|
|
57
52
|
): ISignatureSet[] {
|
|
@@ -64,6 +59,6 @@ export function getAttestationsSignatureSets(
|
|
|
64
59
|
// and the same epoch when we verify blocks in batch in beacon-node. So we can safely use block.slot here.
|
|
65
60
|
const blockSlot = signedBlock.message.slot;
|
|
66
61
|
return indexedAttestations.map((indexedAttestation) =>
|
|
67
|
-
getIndexedAttestationSignatureSet(config,
|
|
62
|
+
getIndexedAttestationSignatureSet(config, blockSlot, indexedAttestation)
|
|
68
63
|
);
|
|
69
64
|
}
|