@lodestar/beacon-node 1.48.0-dev.262a9c1d16 → 1.48.0-dev.293e560a59
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/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +39 -39
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +13 -0
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/chain.d.ts +0 -5
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +38 -67
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +1 -1
- package/lib/chain/emitter.js +1 -1
- package/lib/chain/errors/blockError.d.ts +5 -3
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +2 -2
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +11 -0
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js +2 -0
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/prepareNextSlot.js +13 -13
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +64 -46
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +50 -9
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +29 -0
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/network/reqresp/rateLimit.js +1 -2
- package/lib/network/reqresp/rateLimit.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/validator/index.ts +43 -44
- package/src/chain/blocks/importBlock.ts +13 -0
- package/src/chain/chain.ts +46 -74
- package/src/chain/emitter.ts +1 -1
- package/src/chain/errors/blockError.ts +3 -3
- package/src/chain/errors/executionPayloadEnvelope.ts +9 -0
- package/src/chain/prepareNextSlot.ts +16 -16
- package/src/chain/produceBlock/produceBlockBody.ts +71 -50
- package/src/chain/validation/block.ts +66 -9
- package/src/chain/validation/executionPayloadEnvelope.ts +37 -0
- package/src/network/reqresp/rateLimit.ts +1 -2
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {ExecutionStatus} from "@lodestar/fork-choice";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ForkName,
|
|
5
|
+
MAX_ATTESTATIONS_ELECTRA,
|
|
6
|
+
MAX_ATTESTER_SLASHINGS_ELECTRA,
|
|
7
|
+
MAX_BLS_TO_EXECUTION_CHANGES,
|
|
8
|
+
MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD,
|
|
9
|
+
MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD,
|
|
10
|
+
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD,
|
|
11
|
+
MAX_PAYLOAD_ATTESTATIONS,
|
|
12
|
+
MAX_PROPOSER_SLASHINGS,
|
|
13
|
+
MAX_VOLUNTARY_EXITS,
|
|
14
|
+
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD,
|
|
15
|
+
MIN_SEED_LOOKAHEAD,
|
|
16
|
+
isForkPostBellatrix,
|
|
17
|
+
isForkPostDeneb,
|
|
18
|
+
isForkPostGloas,
|
|
19
|
+
} from "@lodestar/params";
|
|
4
20
|
import {
|
|
5
21
|
computeEpochAtSlot,
|
|
6
22
|
computeStartSlotAtEpoch,
|
|
@@ -157,8 +173,7 @@ export async function validateGossipBlock(
|
|
|
157
173
|
}
|
|
158
174
|
|
|
159
175
|
if (isForkPostGloas(fork)) {
|
|
160
|
-
const
|
|
161
|
-
const bid = body.signedExecutionPayloadBid.message;
|
|
176
|
+
const bid = (block as gloas.BeaconBlock).body.signedExecutionPayloadBid.message;
|
|
162
177
|
|
|
163
178
|
// [REJECT] The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer
|
|
164
179
|
// -- i.e. validate that len(bid.blob_kzg_commitments) <= max_blobs_per_block
|
|
@@ -181,12 +196,54 @@ export async function validateGossipBlock(
|
|
|
181
196
|
});
|
|
182
197
|
}
|
|
183
198
|
|
|
184
|
-
// [REJECT] The block
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
199
|
+
// [REJECT] The counts of `block.body.parent_execution_requests` are within
|
|
200
|
+
// their respective limits -- i.e. validate that
|
|
201
|
+
// `len(block.body.parent_execution_requests.withdrawals) <= MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD`,
|
|
202
|
+
// `len(block.body.parent_execution_requests.consolidations) <= MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD`,
|
|
203
|
+
// `len(block.body.parent_execution_requests.builder_deposits) <= MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD`,
|
|
204
|
+
// and
|
|
205
|
+
// `len(block.body.parent_execution_requests.builder_exits) <= MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD`.
|
|
206
|
+
// [REJECT] The counts of the block body operations are within their respective
|
|
207
|
+
// limits -- i.e. validate that
|
|
208
|
+
// `len(block.body.proposer_slashings) <= MAX_PROPOSER_SLASHINGS`,
|
|
209
|
+
// `len(block.body.attester_slashings) <= MAX_ATTESTER_SLASHINGS_ELECTRA`,
|
|
210
|
+
// `len(block.body.attestations) <= MAX_ATTESTATIONS_ELECTRA`,
|
|
211
|
+
// `len(block.body.deposits) == 0`,
|
|
212
|
+
// `len(block.body.voluntary_exits) <= MAX_VOLUNTARY_EXITS`,
|
|
213
|
+
// `len(block.body.bls_to_execution_changes) <= MAX_BLS_TO_EXECUTION_CHANGES`,
|
|
214
|
+
// and `len(block.body.payload_attestations) <= MAX_PAYLOAD_ATTESTATIONS`.
|
|
215
|
+
const body = (block as gloas.BeaconBlock).body;
|
|
216
|
+
const requests = body.parentExecutionRequests;
|
|
217
|
+
const countLimits: [string, number, number][] = [
|
|
218
|
+
["parentExecutionRequests.withdrawals", requests.withdrawals.length, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD],
|
|
219
|
+
[
|
|
220
|
+
"parentExecutionRequests.consolidations",
|
|
221
|
+
requests.consolidations.length,
|
|
222
|
+
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD,
|
|
223
|
+
],
|
|
224
|
+
[
|
|
225
|
+
"parentExecutionRequests.builderDeposits",
|
|
226
|
+
requests.builderDeposits.length,
|
|
227
|
+
MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD,
|
|
228
|
+
],
|
|
229
|
+
["parentExecutionRequests.builderExits", requests.builderExits.length, MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD],
|
|
230
|
+
["proposerSlashings", body.proposerSlashings.length, MAX_PROPOSER_SLASHINGS],
|
|
231
|
+
["attesterSlashings", body.attesterSlashings.length, MAX_ATTESTER_SLASHINGS_ELECTRA],
|
|
232
|
+
["attestations", body.attestations.length, MAX_ATTESTATIONS_ELECTRA],
|
|
233
|
+
["deposits", body.deposits.length, 0],
|
|
234
|
+
["voluntaryExits", body.voluntaryExits.length, MAX_VOLUNTARY_EXITS],
|
|
235
|
+
["blsToExecutionChanges", body.blsToExecutionChanges.length, MAX_BLS_TO_EXECUTION_CHANGES],
|
|
236
|
+
["payloadAttestations", body.payloadAttestations.length, MAX_PAYLOAD_ATTESTATIONS],
|
|
237
|
+
];
|
|
238
|
+
for (const [name, count, limit] of countLimits) {
|
|
239
|
+
if (count > limit) {
|
|
240
|
+
throw new BlockGossipError(GossipAction.REJECT, {
|
|
241
|
+
code: BlockErrorCode.TOO_MANY_BLOCK_OPERATIONS,
|
|
242
|
+
name,
|
|
243
|
+
count,
|
|
244
|
+
limit,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
190
247
|
}
|
|
191
248
|
|
|
192
249
|
// TODO GLOAS: [REJECT] The block's execution payload parent (defined by bid.parent_block_hash) passes all validation
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import {PayloadStatus} from "@lodestar/fork-choice";
|
|
2
|
+
import {
|
|
3
|
+
MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD,
|
|
4
|
+
MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD,
|
|
5
|
+
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD,
|
|
6
|
+
MAX_WITHDRAWALS_PER_PAYLOAD,
|
|
7
|
+
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD,
|
|
8
|
+
} from "@lodestar/params";
|
|
2
9
|
import {
|
|
3
10
|
computeStartSlotAtEpoch,
|
|
4
11
|
getExecutionPayloadEnvelopeSignatureSet,
|
|
@@ -115,6 +122,36 @@ async function validateExecutionPayloadEnvelope(
|
|
|
115
122
|
});
|
|
116
123
|
}
|
|
117
124
|
|
|
125
|
+
// [REJECT] The counts of `execution_requests` are within their respective limits.
|
|
126
|
+
// New in Gloas:EIP7688 — progressive lists are unbounded at the type level, so bounds
|
|
127
|
+
// are enforced here in gossip validation.
|
|
128
|
+
const {executionRequests} = envelope;
|
|
129
|
+
const requestCountLimits: [string, number, number][] = [
|
|
130
|
+
["withdrawals", executionRequests.withdrawals.length, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD],
|
|
131
|
+
["consolidations", executionRequests.consolidations.length, MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD],
|
|
132
|
+
["builderDeposits", executionRequests.builderDeposits.length, MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD],
|
|
133
|
+
["builderExits", executionRequests.builderExits.length, MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD],
|
|
134
|
+
];
|
|
135
|
+
for (const [name, count, limit] of requestCountLimits) {
|
|
136
|
+
if (count > limit) {
|
|
137
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
|
|
138
|
+
code: ExecutionPayloadEnvelopeErrorCode.EXECUTION_REQUESTS_COUNT_EXCEEDED,
|
|
139
|
+
name,
|
|
140
|
+
count,
|
|
141
|
+
limit,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// [REJECT] The number of withdrawals is within the limit.
|
|
147
|
+
if (payload.withdrawals.length > MAX_WITHDRAWALS_PER_PAYLOAD) {
|
|
148
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
|
|
149
|
+
code: ExecutionPayloadEnvelopeErrorCode.WITHDRAWALS_COUNT_EXCEEDED,
|
|
150
|
+
count: payload.withdrawals.length,
|
|
151
|
+
limit: MAX_WITHDRAWALS_PER_PAYLOAD,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
118
155
|
// Get the block state to verify the builder's signature.
|
|
119
156
|
const blockState = await chain.regen
|
|
120
157
|
.getState(block.stateRoot, RegenCaller.validateGossipPayloadEnvelope)
|
|
@@ -126,8 +126,7 @@ function getRequestCountFn<T extends ReqRespMethod>(
|
|
|
126
126
|
const type = requestSszTypeByMethod(fork, config)[method];
|
|
127
127
|
return (reqData: Uint8Array) => {
|
|
128
128
|
try {
|
|
129
|
-
|
|
130
|
-
return Math.max(1, (type && fn(type.deserialize(reqData))) ?? 1);
|
|
129
|
+
return (type && fn(type.deserialize(reqData))) ?? 1;
|
|
131
130
|
} catch (_e) {
|
|
132
131
|
return 1;
|
|
133
132
|
}
|