@lodestar/beacon-node 1.40.0 → 1.41.0-dev.0393d54ddd
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/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +121 -3
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +5 -2
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/lightclient/index.d.ts.map +1 -1
- package/lib/api/impl/lightclient/index.js +19 -2
- package/lib/api/impl/lightclient/index.js.map +1 -1
- package/lib/api/impl/node/index.d.ts +1 -1
- package/lib/api/impl/node/index.d.ts.map +1 -1
- package/lib/api/impl/node/index.js +18 -1
- package/lib/api/impl/node/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +101 -1
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +9 -0
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/utils/archivePayloads.d.ts +7 -0
- package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +1 -0
- package/lib/chain/archiveStore/utils/archivePayloads.js +10 -0
- package/lib/chain/archiveStore/utils/archivePayloads.js.map +1 -0
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +0 -2
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +2 -1
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +3 -0
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/chain.d.ts +2 -2
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +24 -6
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +2 -2
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/errors/blockError.d.ts +7 -1
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +2 -0
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/interface.d.ts +2 -2
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/lightClient/index.d.ts.map +1 -1
- package/lib/chain/lightClient/index.js +1 -1
- package/lib/chain/lightClient/index.js.map +1 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/prepareNextSlot.js +3 -3
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts +10 -2
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +24 -2
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +22 -7
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +102 -9
- 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 +27 -3
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts +2 -2
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +2 -1
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/db/beacon.d.ts +3 -1
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +5 -1
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/buckets.d.ts +3 -1
- package/lib/db/buckets.d.ts.map +1 -1
- package/lib/db/buckets.js +2 -0
- package/lib/db/buckets.js.map +1 -1
- package/lib/db/interface.d.ts +3 -1
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecar.d.ts +5 -3
- package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecar.js +14 -1
- package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
- package/lib/db/repositories/dataColumnSidecarArchive.d.ts +5 -3
- package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecarArchive.js +14 -1
- package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
- package/lib/db/repositories/executionPayloadEnvelope.d.ts +19 -0
- package/lib/db/repositories/executionPayloadEnvelope.d.ts.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelope.js +22 -0
- package/lib/db/repositories/executionPayloadEnvelope.js.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts +18 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js +28 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -0
- package/lib/db/repositories/index.d.ts +2 -0
- package/lib/db/repositories/index.d.ts.map +1 -1
- package/lib/db/repositories/index.js +2 -0
- package/lib/db/repositories/index.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +3 -25
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/interface.js +2 -20
- package/lib/execution/engine/interface.js.map +1 -1
- package/lib/metrics/metrics/beacon.d.ts +1 -0
- package/lib/metrics/metrics/beacon.d.ts.map +1 -1
- package/lib/metrics/metrics/beacon.js +5 -0
- package/lib/metrics/metrics/beacon.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +5 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +9 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/metrics/metrics.d.ts.map +1 -1
- package/lib/metrics/metrics.js +8 -3
- package/lib/metrics/metrics.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +3 -3
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/topic.d.ts +114 -65
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +2 -2
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/interface.d.ts +3 -2
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +3 -2
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +10 -1
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +5 -1
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/reqresp/handlers/lightClientUpdatesByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/lightClientUpdatesByRange.js +7 -1
- package/lib/network/reqresp/handlers/lightClientUpdatesByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +3 -9
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +4 -4
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/lib/util/blobs.d.ts +2 -2
- package/lib/util/blobs.d.ts.map +1 -1
- package/lib/util/blobs.js.map +1 -1
- package/lib/util/dataColumns.d.ts +15 -2
- package/lib/util/dataColumns.d.ts.map +1 -1
- package/lib/util/dataColumns.js +40 -5
- package/lib/util/dataColumns.js.map +1 -1
- package/lib/util/multifork.d.ts +8 -0
- package/lib/util/multifork.d.ts.map +1 -1
- package/lib/util/multifork.js +37 -0
- package/lib/util/multifork.js.map +1 -1
- package/lib/util/serializedCache.d.ts +5 -0
- package/lib/util/serializedCache.d.ts.map +1 -1
- package/lib/util/serializedCache.js +5 -0
- package/lib/util/serializedCache.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +145 -2
- package/src/api/impl/debug/index.ts +8 -5
- package/src/api/impl/lightclient/index.ts +19 -2
- package/src/api/impl/node/index.ts +22 -1
- package/src/api/impl/validator/index.ts +124 -1
- package/src/chain/archiveStore/archiveStore.ts +10 -0
- package/src/chain/archiveStore/utils/archivePayloads.ts +15 -0
- package/src/chain/blocks/importBlock.ts +0 -3
- package/src/chain/blocks/index.ts +2 -1
- package/src/chain/blocks/writeBlockInputToDb.ts +3 -0
- package/src/chain/chain.ts +41 -11
- package/src/chain/emitter.ts +2 -2
- package/src/chain/errors/blockError.ts +4 -1
- package/src/chain/interface.ts +2 -2
- package/src/chain/lightClient/index.ts +4 -1
- package/src/chain/options.ts +1 -0
- package/src/chain/prepareNextSlot.ts +5 -5
- package/src/chain/produceBlock/computeNewStateRoot.ts +35 -3
- package/src/chain/produceBlock/produceBlockBody.ts +154 -11
- package/src/chain/validation/block.ts +32 -4
- package/src/chain/validation/dataColumnSidecar.ts +2 -5
- package/src/chain/validation/executionPayloadEnvelope.ts +2 -1
- package/src/chain/validation/payloadAttestationMessage.ts +1 -1
- package/src/db/beacon.ts +8 -0
- package/src/db/buckets.ts +3 -0
- package/src/db/interface.ts +5 -0
- package/src/db/repositories/dataColumnSidecar.ts +18 -3
- package/src/db/repositories/dataColumnSidecarArchive.ts +18 -3
- package/src/db/repositories/executionPayloadEnvelope.ts +26 -0
- package/src/db/repositories/executionPayloadEnvelopeArchive.ts +32 -0
- package/src/db/repositories/index.ts +2 -0
- package/src/execution/engine/interface.ts +3 -27
- package/src/metrics/metrics/beacon.ts +5 -0
- package/src/metrics/metrics/lodestar.ts +9 -0
- package/src/metrics/metrics.ts +8 -3
- package/src/network/gossip/interface.ts +3 -3
- package/src/network/gossip/topic.ts +2 -1
- package/src/network/interface.ts +4 -1
- package/src/network/network.ts +21 -3
- package/src/network/processor/gossipHandlers.ts +7 -1
- package/src/network/reqresp/handlers/lightClientUpdatesByRange.ts +6 -1
- package/src/sync/utils/downloadByRange.ts +3 -15
- package/src/sync/utils/downloadByRoot.ts +5 -11
- package/src/util/blobs.ts +3 -3
- package/src/util/dataColumns.ts +54 -5
- package/src/util/multifork.ts +45 -0
- package/src/util/serializedCache.ts +5 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {ProtoBlock, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
2
|
+
import {IForkChoice, ProtoBlock, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
3
3
|
import {
|
|
4
|
+
BUILDER_INDEX_SELF_BUILD,
|
|
4
5
|
ForkName,
|
|
5
6
|
ForkPostBellatrix,
|
|
6
7
|
ForkPostDeneb,
|
|
7
8
|
ForkPostFulu,
|
|
9
|
+
ForkPostGloas,
|
|
8
10
|
ForkPreGloas,
|
|
9
11
|
ForkSeq,
|
|
10
12
|
isForkPostAltair,
|
|
@@ -16,6 +18,8 @@ import {
|
|
|
16
18
|
CachedBeaconStateBellatrix,
|
|
17
19
|
CachedBeaconStateCapella,
|
|
18
20
|
CachedBeaconStateExecutions,
|
|
21
|
+
CachedBeaconStateGloas,
|
|
22
|
+
G2_POINT_AT_INFINITY,
|
|
19
23
|
computeTimeAtSlot,
|
|
20
24
|
getExpectedWithdrawals,
|
|
21
25
|
getRandaoMix,
|
|
@@ -42,6 +46,7 @@ import {
|
|
|
42
46
|
deneb,
|
|
43
47
|
electra,
|
|
44
48
|
fulu,
|
|
49
|
+
gloas,
|
|
45
50
|
} from "@lodestar/types";
|
|
46
51
|
import {Logger, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
47
52
|
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
@@ -99,6 +104,20 @@ export type AssembledBodyType<T extends BlockType> = T extends BlockType.Full
|
|
|
99
104
|
: BlindedBeaconBlockBody;
|
|
100
105
|
export type AssembledBlockType<T extends BlockType> = T extends BlockType.Full ? BeaconBlock : BlindedBeaconBlock;
|
|
101
106
|
|
|
107
|
+
export type ProduceFullGloas = {
|
|
108
|
+
type: BlockType.Full;
|
|
109
|
+
fork: ForkPostGloas;
|
|
110
|
+
executionPayload: ExecutionPayload<ForkPostGloas>;
|
|
111
|
+
executionRequests: electra.ExecutionRequests;
|
|
112
|
+
blobsBundle: BlobsBundle<ForkPostGloas>;
|
|
113
|
+
cells: fulu.Cell[][];
|
|
114
|
+
/**
|
|
115
|
+
* Cached envelope state root computed during block production.
|
|
116
|
+
* This is the state root after running `processExecutionPayloadEnvelope` on the
|
|
117
|
+
* post-block state, and later used to construct the `ExecutionPayloadEnvelope`.
|
|
118
|
+
*/
|
|
119
|
+
envelopeStateRoot: Root;
|
|
120
|
+
};
|
|
102
121
|
export type ProduceFullFulu = {
|
|
103
122
|
type: BlockType.Full;
|
|
104
123
|
fork: ForkPostFulu;
|
|
@@ -131,6 +150,7 @@ export type ProduceBlinded = {
|
|
|
131
150
|
|
|
132
151
|
/** The result of local block production, everything that's not the block itself */
|
|
133
152
|
export type ProduceResult =
|
|
153
|
+
| ProduceFullGloas
|
|
134
154
|
| ProduceFullFulu
|
|
135
155
|
| ProduceFullDeneb
|
|
136
156
|
| ProduceFullBellatrix
|
|
@@ -180,12 +200,112 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
180
200
|
this.logger.verbose("Producing beacon block body", logMeta);
|
|
181
201
|
|
|
182
202
|
if (isForkPostGloas(fork)) {
|
|
183
|
-
// TODO GLOAS:
|
|
203
|
+
// TODO GLOAS: support non self-building here, the block type differentiation between
|
|
204
|
+
// full and blinded no longer makes sense in gloas, it might be a good idea to move
|
|
205
|
+
// this into a completely separate function and have pre/post gloas more separated
|
|
206
|
+
const gloasState = currentState as CachedBeaconStateGloas;
|
|
207
|
+
const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice);
|
|
208
|
+
const finalizedBlockHash = this.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
|
|
209
|
+
const feeRecipient = requestedFeeRecipient ?? this.beaconProposerCache.getOrDefault(proposerIndex);
|
|
210
|
+
|
|
211
|
+
const endExecutionPayload = this.metrics?.executionBlockProductionTimeSteps.startTimer();
|
|
212
|
+
|
|
213
|
+
this.logger.verbose("Preparing execution payload from engine", {
|
|
214
|
+
slot: blockSlot,
|
|
215
|
+
parentBlockRoot: toRootHex(parentBlockRoot),
|
|
216
|
+
feeRecipient,
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Get execution payload from EL
|
|
220
|
+
const prepareRes = await prepareExecutionPayload(
|
|
221
|
+
this,
|
|
222
|
+
this.logger,
|
|
223
|
+
fork,
|
|
224
|
+
parentBlockRoot,
|
|
225
|
+
safeBlockHash,
|
|
226
|
+
finalizedBlockHash ?? ZERO_HASH_HEX,
|
|
227
|
+
gloasState,
|
|
228
|
+
feeRecipient
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
const {prepType, payloadId} = prepareRes;
|
|
232
|
+
Object.assign(logMeta, {executionPayloadPrepType: prepType});
|
|
233
|
+
|
|
234
|
+
if (prepType !== PayloadPreparationType.Cached) {
|
|
235
|
+
await sleep(PAYLOAD_GENERATION_TIME_MS);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
this.logger.verbose("Fetching execution payload from engine", {slot: blockSlot, payloadId});
|
|
239
|
+
const payloadRes = await this.executionEngine.getPayload(fork, payloadId);
|
|
240
|
+
|
|
241
|
+
endExecutionPayload?.({step: BlockProductionStep.executionPayload});
|
|
242
|
+
|
|
243
|
+
const {executionPayload, blobsBundle, executionRequests} = payloadRes;
|
|
244
|
+
executionPayloadValue = payloadRes.executionPayloadValue;
|
|
245
|
+
shouldOverrideBuilder = payloadRes.shouldOverrideBuilder;
|
|
246
|
+
|
|
247
|
+
if (blobsBundle === undefined) {
|
|
248
|
+
throw Error(`Missing blobsBundle response from getPayload at fork=${fork}`);
|
|
249
|
+
}
|
|
250
|
+
if (executionRequests === undefined) {
|
|
251
|
+
throw Error(`Missing executionRequests response from getPayload at fork=${fork}`);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const cells = blobsBundle.blobs.map((blob) => kzg.computeCells(blob));
|
|
255
|
+
if (this.opts.sanityCheckExecutionEngineBlobs) {
|
|
256
|
+
await validateCellsAndKzgCommitments(blobsBundle.commitments, blobsBundle.proofs, cells);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Create self-build execution payload bid
|
|
260
|
+
const bid: gloas.ExecutionPayloadBid = {
|
|
261
|
+
parentBlockHash: gloasState.latestBlockHash,
|
|
262
|
+
parentBlockRoot: parentBlockRoot,
|
|
263
|
+
blockHash: executionPayload.blockHash,
|
|
264
|
+
prevRandao: getRandaoMix(gloasState, gloasState.epochCtx.epoch),
|
|
265
|
+
feeRecipient: executionPayload.feeRecipient,
|
|
266
|
+
gasLimit: BigInt(executionPayload.gasLimit),
|
|
267
|
+
builderIndex: BUILDER_INDEX_SELF_BUILD,
|
|
268
|
+
slot: blockSlot,
|
|
269
|
+
value: 0,
|
|
270
|
+
executionPayment: 0,
|
|
271
|
+
blobKzgCommitments: blobsBundle.commitments,
|
|
272
|
+
};
|
|
273
|
+
const signedBid: gloas.SignedExecutionPayloadBid = {
|
|
274
|
+
message: bid,
|
|
275
|
+
signature: G2_POINT_AT_INFINITY,
|
|
276
|
+
};
|
|
277
|
+
|
|
184
278
|
const commonBlockBody = await commonBlockBodyPromise;
|
|
185
|
-
|
|
186
|
-
|
|
279
|
+
const gloasBody = Object.assign({}, commonBlockBody) as gloas.BeaconBlockBody;
|
|
280
|
+
gloasBody.signedExecutionPayloadBid = signedBid;
|
|
281
|
+
// TODO GLOAS: Get payload attestations from pool for previous slot
|
|
282
|
+
gloasBody.payloadAttestations = [];
|
|
283
|
+
blockBody = gloasBody as AssembledBodyType<T>;
|
|
284
|
+
|
|
285
|
+
// Store execution payload data required to construct execution payload envelope later
|
|
286
|
+
const gloasResult = produceResult as ProduceFullGloas;
|
|
287
|
+
gloasResult.executionPayload = executionPayload as ExecutionPayload<ForkPostGloas>;
|
|
288
|
+
gloasResult.executionRequests = executionRequests;
|
|
289
|
+
gloasResult.blobsBundle = blobsBundle;
|
|
290
|
+
gloasResult.cells = cells;
|
|
291
|
+
|
|
292
|
+
const fetchedTime = Date.now() / 1000 - computeTimeAtSlot(this.config, blockSlot, this.genesisTime);
|
|
293
|
+
this.metrics?.blockPayload.payloadFetchedTime.observe({prepType}, fetchedTime);
|
|
294
|
+
this.logger.verbose("Produced block with self-build bid", {
|
|
295
|
+
slot: blockSlot,
|
|
296
|
+
executionPayloadValue,
|
|
297
|
+
prepType,
|
|
298
|
+
payloadId,
|
|
299
|
+
fetchedTime,
|
|
300
|
+
executionBlockHash: toRootHex(executionPayload.blockHash),
|
|
301
|
+
blobs: blobsBundle.commitments.length,
|
|
302
|
+
});
|
|
187
303
|
|
|
188
|
-
|
|
304
|
+
Object.assign(logMeta, {
|
|
305
|
+
transactions: executionPayload.transactions.length,
|
|
306
|
+
blobs: blobsBundle.commitments.length,
|
|
307
|
+
shouldOverrideBuilder,
|
|
308
|
+
});
|
|
189
309
|
} else if (isForkPostBellatrix(fork)) {
|
|
190
310
|
const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice);
|
|
191
311
|
const finalizedBlockHash = this.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
|
|
@@ -480,10 +600,12 @@ export async function prepareExecutionPayload(
|
|
|
480
600
|
parentBlockRoot: Root,
|
|
481
601
|
safeBlockHash: RootHex,
|
|
482
602
|
finalizedBlockHash: RootHex,
|
|
483
|
-
state: CachedBeaconStateExecutions,
|
|
603
|
+
state: CachedBeaconStateExecutions | CachedBeaconStateGloas,
|
|
484
604
|
suggestedFeeRecipient: string
|
|
485
605
|
): Promise<{prepType: PayloadPreparationType; payloadId: PayloadId}> {
|
|
486
|
-
const parentHash =
|
|
606
|
+
const parentHash = isForkPostGloas(fork)
|
|
607
|
+
? (state as CachedBeaconStateGloas).latestBlockHash
|
|
608
|
+
: (state as CachedBeaconStateExecutions).latestExecutionPayloadHeader.blockHash;
|
|
487
609
|
const timestamp = computeTimeAtSlot(chain.config, state.slot, state.genesisTime);
|
|
488
610
|
const prevRandao = getRandaoMix(state, state.epochCtx.epoch);
|
|
489
611
|
|
|
@@ -568,25 +690,46 @@ export function getPayloadAttributesForSSE(
|
|
|
568
690
|
fork: ForkPostBellatrix,
|
|
569
691
|
chain: {
|
|
570
692
|
config: ChainForkConfig;
|
|
693
|
+
forkChoice: IForkChoice;
|
|
571
694
|
},
|
|
572
695
|
{
|
|
573
696
|
prepareState,
|
|
574
697
|
prepareSlot,
|
|
575
698
|
parentBlockRoot,
|
|
576
699
|
feeRecipient,
|
|
577
|
-
}: {
|
|
700
|
+
}: {
|
|
701
|
+
prepareState: CachedBeaconStateExecutions | CachedBeaconStateGloas;
|
|
702
|
+
prepareSlot: Slot;
|
|
703
|
+
parentBlockRoot: Root;
|
|
704
|
+
feeRecipient: string;
|
|
705
|
+
}
|
|
578
706
|
): SSEPayloadAttributes {
|
|
579
|
-
const parentHash =
|
|
707
|
+
const parentHash = isForkPostGloas(fork)
|
|
708
|
+
? (prepareState as CachedBeaconStateGloas).latestBlockHash
|
|
709
|
+
: (prepareState as CachedBeaconStateExecutions).latestExecutionPayloadHeader.blockHash;
|
|
580
710
|
const payloadAttributes = preparePayloadAttributes(fork, chain, {
|
|
581
711
|
prepareState,
|
|
582
712
|
prepareSlot,
|
|
583
713
|
parentBlockRoot,
|
|
584
714
|
feeRecipient,
|
|
585
715
|
});
|
|
716
|
+
|
|
717
|
+
let parentBlockNumber: number;
|
|
718
|
+
if (isForkPostGloas(fork)) {
|
|
719
|
+
// TODO GLOAS: revisit this after fork choice changes are merged
|
|
720
|
+
const parentBlock = chain.forkChoice.getBlock(parentBlockRoot);
|
|
721
|
+
if (parentBlock?.executionPayloadBlockHash == null) {
|
|
722
|
+
throw Error(`Parent block not found in fork choice root=${toRootHex(parentBlockRoot)}`);
|
|
723
|
+
}
|
|
724
|
+
parentBlockNumber = parentBlock.executionPayloadNumber;
|
|
725
|
+
} else {
|
|
726
|
+
parentBlockNumber = (prepareState as CachedBeaconStateExecutions).latestExecutionPayloadHeader.blockNumber;
|
|
727
|
+
}
|
|
728
|
+
|
|
586
729
|
const ssePayloadAttributes: SSEPayloadAttributes = {
|
|
587
730
|
proposerIndex: prepareState.epochCtx.getBeaconProposer(prepareSlot),
|
|
588
731
|
proposalSlot: prepareSlot,
|
|
589
|
-
parentBlockNumber
|
|
732
|
+
parentBlockNumber,
|
|
590
733
|
parentBlockRoot,
|
|
591
734
|
parentBlockHash: parentHash,
|
|
592
735
|
payloadAttributes,
|
|
@@ -605,7 +748,7 @@ function preparePayloadAttributes(
|
|
|
605
748
|
parentBlockRoot,
|
|
606
749
|
feeRecipient,
|
|
607
750
|
}: {
|
|
608
|
-
prepareState: CachedBeaconStateExecutions;
|
|
751
|
+
prepareState: CachedBeaconStateExecutions | CachedBeaconStateGloas;
|
|
609
752
|
prepareSlot: Slot;
|
|
610
753
|
parentBlockRoot: Root;
|
|
611
754
|
feeRecipient: string;
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
isExecutionEnabled,
|
|
10
10
|
isExecutionStateType,
|
|
11
11
|
} from "@lodestar/state-transition";
|
|
12
|
-
import {SignedBeaconBlock, deneb} from "@lodestar/types";
|
|
13
|
-
import {sleep, toRootHex} from "@lodestar/utils";
|
|
12
|
+
import {SignedBeaconBlock, deneb, gloas} from "@lodestar/types";
|
|
13
|
+
import {byteArrayEquals, sleep, toRootHex} from "@lodestar/utils";
|
|
14
14
|
import {BlockErrorCode, BlockGossipError, GossipAction} from "../errors/index.js";
|
|
15
15
|
import {IBeaconChain} from "../interface.js";
|
|
16
16
|
import {RegenCaller} from "../regen/index.js";
|
|
@@ -23,6 +23,7 @@ export async function validateGossipBlock(
|
|
|
23
23
|
): Promise<void> {
|
|
24
24
|
const block = signedBlock.message;
|
|
25
25
|
const blockSlot = block.slot;
|
|
26
|
+
const blockEpoch = computeEpochAtSlot(blockSlot);
|
|
26
27
|
|
|
27
28
|
// [IGNORE] The block is not from a future slot (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e.validate
|
|
28
29
|
// that signed_beacon_block.message.slot <= current_slot (a client MAY queue future blocks for processing at the
|
|
@@ -113,7 +114,7 @@ export async function validateGossipBlock(
|
|
|
113
114
|
// [REJECT] The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer -- i.e. validate that len(body.signed_beacon_block.message.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK
|
|
114
115
|
if (isForkPostDeneb(fork) && !isForkPostGloas(fork)) {
|
|
115
116
|
const blobKzgCommitmentsLen = (block as deneb.BeaconBlock).body.blobKzgCommitments.length;
|
|
116
|
-
const maxBlobsPerBlock = config.getMaxBlobsPerBlock(
|
|
117
|
+
const maxBlobsPerBlock = config.getMaxBlobsPerBlock(blockEpoch);
|
|
117
118
|
if (blobKzgCommitmentsLen > maxBlobsPerBlock) {
|
|
118
119
|
throw new BlockGossipError(GossipAction.REJECT, {
|
|
119
120
|
code: BlockErrorCode.TOO_MANY_KZG_COMMITMENTS,
|
|
@@ -123,12 +124,39 @@ export async function validateGossipBlock(
|
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
|
|
127
|
+
if (isForkPostGloas(fork)) {
|
|
128
|
+
const bid = (block as gloas.BeaconBlock).body.signedExecutionPayloadBid.message;
|
|
129
|
+
|
|
130
|
+
// [REJECT] The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer
|
|
131
|
+
// -- i.e. validate that len(bid.blob_kzg_commitments) <= max_blobs_per_block
|
|
132
|
+
const blobKzgCommitmentsLen = bid.blobKzgCommitments.length;
|
|
133
|
+
const maxBlobsPerBlock = config.getMaxBlobsPerBlock(blockEpoch);
|
|
134
|
+
if (blobKzgCommitmentsLen > maxBlobsPerBlock) {
|
|
135
|
+
throw new BlockGossipError(GossipAction.REJECT, {
|
|
136
|
+
code: BlockErrorCode.TOO_MANY_KZG_COMMITMENTS,
|
|
137
|
+
blobKzgCommitmentsLen,
|
|
138
|
+
commitmentLimit: maxBlobsPerBlock,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// [REJECT] The bid's parent (defined by bid.parent_block_root) equals the block's parent (defined by block.parent_root)
|
|
143
|
+
if (!byteArrayEquals(bid.parentBlockRoot, block.parentRoot)) {
|
|
144
|
+
throw new BlockGossipError(GossipAction.REJECT, {
|
|
145
|
+
code: BlockErrorCode.BID_PARENT_ROOT_MISMATCH,
|
|
146
|
+
bidParentRoot: toRootHex(bid.parentBlockRoot),
|
|
147
|
+
blockParentRoot: parentRoot,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// TODO GLOAS: [REJECT] The block's execution payload parent (defined by bid.parent_block_hash) passes all validation
|
|
152
|
+
// This requires execution engine integration to verify the parent block hash
|
|
153
|
+
}
|
|
154
|
+
|
|
126
155
|
// use getPreState to reload state if needed. It also checks for whether the current finalized checkpoint is an ancestor of the block.
|
|
127
156
|
// As a result, we throw an IGNORE (whereas the spec says we should REJECT for this scenario).
|
|
128
157
|
// this is something we should change this in the future to make the code airtight to the spec.
|
|
129
158
|
// [IGNORE] The block's parent (defined by block.parent_root) has been seen (via both gossip and non-gossip sources) (a client MAY queue blocks for processing once the parent block is retrieved).
|
|
130
159
|
// [REJECT] The block's parent (defined by block.parent_root) passes validation.
|
|
131
|
-
// TODO GLOAS: post-gloas, we check the validity of bid's parent payload, not the entire beacon block
|
|
132
160
|
const blockState = await chain.regen
|
|
133
161
|
.getPreState(block, {dontTransferCache: true}, RegenCaller.validateGossipBlock)
|
|
134
162
|
.catch(() => {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
getBlockHeaderProposerSignatureSetByHeaderSlot,
|
|
11
11
|
getBlockHeaderProposerSignatureSetByParentStateSlot,
|
|
12
12
|
} from "@lodestar/state-transition";
|
|
13
|
-
import {Root, Slot, SubnetID, fulu, ssz} from "@lodestar/types";
|
|
13
|
+
import {DataColumnSidecar, Root, Slot, SubnetID, fulu, ssz} from "@lodestar/types";
|
|
14
14
|
import {byteArrayEquals, toRootHex, verifyMerkleBranch} from "@lodestar/utils";
|
|
15
15
|
import {Metrics} from "../../metrics/metrics.js";
|
|
16
16
|
import {kzg} from "../../util/kzg.js";
|
|
@@ -457,9 +457,6 @@ export async function validateBlockDataColumnSidecars(
|
|
|
457
457
|
* SPEC FUNCTION
|
|
458
458
|
* https://github.com/ethereum/consensus-specs/blob/v1.6.0-alpha.4/specs/fulu/p2p-interface.md#compute_subnet_for_data_column_sidecar
|
|
459
459
|
*/
|
|
460
|
-
export function computeSubnetForDataColumnSidecar(
|
|
461
|
-
config: ChainConfig,
|
|
462
|
-
columnSidecar: fulu.DataColumnSidecar
|
|
463
|
-
): SubnetID {
|
|
460
|
+
export function computeSubnetForDataColumnSidecar(config: ChainConfig, columnSidecar: DataColumnSidecar): SubnetID {
|
|
464
461
|
return columnSidecar.index % config.DATA_COLUMN_SIDECAR_SUBNET_COUNT;
|
|
465
462
|
}
|
|
@@ -35,7 +35,8 @@ async function validateExecutionPayloadEnvelope(
|
|
|
35
35
|
// [IGNORE] The envelope's block root `envelope.block_root` has been seen (via
|
|
36
36
|
// gossip or non-gossip sources) (a client MAY queue payload for processing once
|
|
37
37
|
// the block is retrieved).
|
|
38
|
-
// TODO GLOAS: Need to review this
|
|
38
|
+
// TODO GLOAS: Need to review this, we should queue the envelope for later
|
|
39
|
+
// processing if the block is not yet known, otherwise we would ignore it here
|
|
39
40
|
const block = chain.forkChoice.getBlock(envelope.beaconBlockRoot);
|
|
40
41
|
if (block === null) {
|
|
41
42
|
throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
|
|
@@ -89,7 +89,7 @@ async function validatePayloadAttestationMessage(
|
|
|
89
89
|
// [REJECT] `payload_attestation_message.signature` is valid with respect to the validator's public key.
|
|
90
90
|
const signatureSet = createSingleSignatureSetFromComponents(
|
|
91
91
|
chain.index2pubkey[validatorIndex],
|
|
92
|
-
getPayloadAttestationDataSigningRoot(chain.config,
|
|
92
|
+
getPayloadAttestationDataSigningRoot(chain.config, data),
|
|
93
93
|
payloadAttestationMessage.signature
|
|
94
94
|
);
|
|
95
95
|
|
package/src/db/beacon.ts
CHANGED
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
CheckpointHeaderRepository,
|
|
16
16
|
DataColumnSidecarArchiveRepository,
|
|
17
17
|
DataColumnSidecarRepository,
|
|
18
|
+
ExecutionPayloadEnvelopeArchiveRepository,
|
|
19
|
+
ExecutionPayloadEnvelopeRepository,
|
|
18
20
|
ProposerSlashingRepository,
|
|
19
21
|
StateArchiveRepository,
|
|
20
22
|
SyncCommitteeRepository,
|
|
@@ -36,6 +38,9 @@ export class BeaconDb implements IBeaconDb {
|
|
|
36
38
|
dataColumnSidecar: DataColumnSidecarRepository;
|
|
37
39
|
dataColumnSidecarArchive: DataColumnSidecarArchiveRepository;
|
|
38
40
|
|
|
41
|
+
executionPayloadEnvelope: ExecutionPayloadEnvelopeRepository;
|
|
42
|
+
executionPayloadEnvelopeArchive: ExecutionPayloadEnvelopeArchiveRepository;
|
|
43
|
+
|
|
39
44
|
stateArchive: StateArchiveRepository;
|
|
40
45
|
checkpointState: CheckpointStateRepository;
|
|
41
46
|
|
|
@@ -65,6 +70,9 @@ export class BeaconDb implements IBeaconDb {
|
|
|
65
70
|
this.dataColumnSidecar = new DataColumnSidecarRepository(config, db);
|
|
66
71
|
this.dataColumnSidecarArchive = new DataColumnSidecarArchiveRepository(config, db);
|
|
67
72
|
|
|
73
|
+
this.executionPayloadEnvelope = new ExecutionPayloadEnvelopeRepository(config, db);
|
|
74
|
+
this.executionPayloadEnvelopeArchive = new ExecutionPayloadEnvelopeArchiveRepository(config, db);
|
|
75
|
+
|
|
68
76
|
this.stateArchive = new StateArchiveRepository(config, db);
|
|
69
77
|
this.checkpointState = new CheckpointStateRepository(config, db);
|
|
70
78
|
this.voluntaryExit = new VoluntaryExitRepository(config, db);
|
package/src/db/buckets.ts
CHANGED
|
@@ -69,6 +69,9 @@ export enum Bucket {
|
|
|
69
69
|
|
|
70
70
|
fulu_dataColumnSidecars = 57, // FULU BeaconBlockRoot -> DataColumnSidecars
|
|
71
71
|
fulu_dataColumnSidecarsArchive = 58, // FULU BeaconBlockSlot -> DataColumnSidecars
|
|
72
|
+
|
|
73
|
+
gloas_executionPayloadEnvelope = 59, // GLOAS BeaconBlockRoot -> SignedExecutionPayloadEnvelope
|
|
74
|
+
gloas_executionPayloadEnvelopeArchive = 60, // GLOAS Slot -> SignedExecutionPayloadEnvelope
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
export function getBucketNameByValue<T extends Bucket>(enumValue: T): keyof typeof Bucket {
|
package/src/db/interface.ts
CHANGED
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
CheckpointHeaderRepository,
|
|
13
13
|
DataColumnSidecarArchiveRepository,
|
|
14
14
|
DataColumnSidecarRepository,
|
|
15
|
+
ExecutionPayloadEnvelopeArchiveRepository,
|
|
16
|
+
ExecutionPayloadEnvelopeRepository,
|
|
15
17
|
ProposerSlashingRepository,
|
|
16
18
|
StateArchiveRepository,
|
|
17
19
|
SyncCommitteeRepository,
|
|
@@ -35,6 +37,9 @@ export interface IBeaconDb {
|
|
|
35
37
|
dataColumnSidecar: DataColumnSidecarRepository;
|
|
36
38
|
dataColumnSidecarArchive: DataColumnSidecarArchiveRepository;
|
|
37
39
|
|
|
40
|
+
executionPayloadEnvelope: ExecutionPayloadEnvelopeRepository;
|
|
41
|
+
executionPayloadEnvelopeArchive: ExecutionPayloadEnvelopeArchiveRepository;
|
|
42
|
+
|
|
38
43
|
// finalized states
|
|
39
44
|
stateArchive: StateArchiveRepository;
|
|
40
45
|
// checkpoint states
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {Db, PrefixedRepository, decodeNumberForDbKey, encodeNumberForDbKey} from "@lodestar/db";
|
|
3
3
|
import {NUMBER_OF_COLUMNS} from "@lodestar/params";
|
|
4
|
-
import {ColumnIndex, Root,
|
|
4
|
+
import {ColumnIndex, DataColumnSidecar, Root, isGloasDataColumnSidecar, ssz} from "@lodestar/types";
|
|
5
|
+
import {isGloasDataColumnSidecarBytes} from "../../util/multifork.js";
|
|
5
6
|
import {Bucket, getBucketNameByValue} from "../buckets.js";
|
|
6
7
|
|
|
7
8
|
const COLUMN_INDEX_BYTE_SIZE = 2;
|
|
@@ -15,7 +16,7 @@ type BlockRoot = Root;
|
|
|
15
16
|
*
|
|
16
17
|
* Indexed data by `blockRoot` + `columnIndex`
|
|
17
18
|
*/
|
|
18
|
-
export class DataColumnSidecarRepository extends PrefixedRepository<BlockRoot, ColumnIndex,
|
|
19
|
+
export class DataColumnSidecarRepository extends PrefixedRepository<BlockRoot, ColumnIndex, DataColumnSidecar> {
|
|
19
20
|
constructor(config: ChainForkConfig, db: Db) {
|
|
20
21
|
const bucket = Bucket.fulu_dataColumnSidecars;
|
|
21
22
|
super(config, db, bucket, ssz.fulu.DataColumnSidecar, getBucketNameByValue(bucket));
|
|
@@ -24,10 +25,24 @@ export class DataColumnSidecarRepository extends PrefixedRepository<BlockRoot, C
|
|
|
24
25
|
/**
|
|
25
26
|
* Id is hashTreeRoot of unsigned BeaconBlock
|
|
26
27
|
*/
|
|
27
|
-
getId(value:
|
|
28
|
+
getId(value: DataColumnSidecar): ColumnIndex {
|
|
28
29
|
return value.index;
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
encodeValue(value: DataColumnSidecar): Uint8Array {
|
|
33
|
+
if (isGloasDataColumnSidecar(value)) {
|
|
34
|
+
return ssz.gloas.DataColumnSidecar.serialize(value);
|
|
35
|
+
}
|
|
36
|
+
return ssz.fulu.DataColumnSidecar.serialize(value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
decodeValue(data: Uint8Array): DataColumnSidecar {
|
|
40
|
+
if (isGloasDataColumnSidecarBytes(data)) {
|
|
41
|
+
return ssz.gloas.DataColumnSidecar.deserialize(data);
|
|
42
|
+
}
|
|
43
|
+
return ssz.fulu.DataColumnSidecar.deserialize(data);
|
|
44
|
+
}
|
|
45
|
+
|
|
31
46
|
encodeKeyRaw(prefix: BlockRoot, id: ColumnIndex): Uint8Array {
|
|
32
47
|
return Buffer.concat([prefix, encodeNumberForDbKey(id, COLUMN_INDEX_BYTE_SIZE)]);
|
|
33
48
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {Db, PrefixedRepository, decodeNumberForDbKey, encodeNumberForDbKey} from "@lodestar/db";
|
|
3
3
|
import {NUMBER_OF_COLUMNS} from "@lodestar/params";
|
|
4
|
-
import {ColumnIndex, Slot,
|
|
4
|
+
import {ColumnIndex, DataColumnSidecar, Slot, isGloasDataColumnSidecar, ssz} from "@lodestar/types";
|
|
5
|
+
import {isGloasDataColumnSidecarBytes} from "../../util/multifork.js";
|
|
5
6
|
import {Bucket, getBucketNameByValue} from "../buckets.js";
|
|
6
7
|
|
|
7
8
|
const COLUMN_INDEX_BYTE_SIZE = 2;
|
|
@@ -13,7 +14,7 @@ const SLOT_BYTE_SIZE = 8;
|
|
|
13
14
|
*
|
|
14
15
|
* Indexed data by `slot` + `columnIndex`
|
|
15
16
|
*/
|
|
16
|
-
export class DataColumnSidecarArchiveRepository extends PrefixedRepository<Slot, ColumnIndex,
|
|
17
|
+
export class DataColumnSidecarArchiveRepository extends PrefixedRepository<Slot, ColumnIndex, DataColumnSidecar> {
|
|
17
18
|
constructor(config: ChainForkConfig, db: Db) {
|
|
18
19
|
const bucket = Bucket.fulu_dataColumnSidecarsArchive;
|
|
19
20
|
super(config, db, bucket, ssz.fulu.DataColumnSidecar, getBucketNameByValue(bucket));
|
|
@@ -22,10 +23,24 @@ export class DataColumnSidecarArchiveRepository extends PrefixedRepository<Slot,
|
|
|
22
23
|
/**
|
|
23
24
|
* Id is hashTreeRoot of unsigned BeaconBlock
|
|
24
25
|
*/
|
|
25
|
-
getId(value:
|
|
26
|
+
getId(value: DataColumnSidecar): ColumnIndex {
|
|
26
27
|
return value.index;
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
encodeValue(value: DataColumnSidecar): Uint8Array {
|
|
31
|
+
if (isGloasDataColumnSidecar(value)) {
|
|
32
|
+
return ssz.gloas.DataColumnSidecar.serialize(value);
|
|
33
|
+
}
|
|
34
|
+
return ssz.fulu.DataColumnSidecar.serialize(value);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
decodeValue(data: Uint8Array): DataColumnSidecar {
|
|
38
|
+
if (isGloasDataColumnSidecarBytes(data)) {
|
|
39
|
+
return ssz.gloas.DataColumnSidecar.deserialize(data);
|
|
40
|
+
}
|
|
41
|
+
return ssz.fulu.DataColumnSidecar.deserialize(data);
|
|
42
|
+
}
|
|
43
|
+
|
|
29
44
|
encodeKeyRaw(prefix: Slot, id: ColumnIndex): Uint8Array {
|
|
30
45
|
return Buffer.concat([
|
|
31
46
|
encodeNumberForDbKey(prefix, SLOT_BYTE_SIZE),
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {Db, Repository} from "@lodestar/db";
|
|
3
|
+
import {Root, gloas, ssz} from "@lodestar/types";
|
|
4
|
+
import {Bucket, getBucketNameByValue} from "../buckets.js";
|
|
5
|
+
|
|
6
|
+
type BlockRoot = Root;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Used to store unfinalized `SignedExecutionPayloadEnvelope`
|
|
10
|
+
*
|
|
11
|
+
* Indexed by beacon block root (root of the beacon block that contains the bid)
|
|
12
|
+
*/
|
|
13
|
+
export class ExecutionPayloadEnvelopeRepository extends Repository<BlockRoot, gloas.SignedExecutionPayloadEnvelope> {
|
|
14
|
+
constructor(config: ChainForkConfig, db: Db) {
|
|
15
|
+
const bucket = Bucket.gloas_executionPayloadEnvelope;
|
|
16
|
+
super(config, db, bucket, ssz.gloas.SignedExecutionPayloadEnvelope, getBucketNameByValue(bucket));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Id is the beacon block root (not execution payload hash)
|
|
21
|
+
* This allows correlation with the block that contains the bid
|
|
22
|
+
*/
|
|
23
|
+
getId(value: gloas.SignedExecutionPayloadEnvelope): BlockRoot {
|
|
24
|
+
return value.message.beaconBlockRoot;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {BUCKET_LENGTH, Db, Repository, encodeKey as encodeDbKey} from "@lodestar/db";
|
|
3
|
+
import {Slot, gloas, ssz} from "@lodestar/types";
|
|
4
|
+
import {bytesToInt} from "@lodestar/utils";
|
|
5
|
+
import {Bucket, getBucketNameByValue} from "../buckets.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Used to store finalized `SignedExecutionPayloadEnvelope`
|
|
9
|
+
*
|
|
10
|
+
* Indexed by slot for chronological archival
|
|
11
|
+
*/
|
|
12
|
+
export class ExecutionPayloadEnvelopeArchiveRepository extends Repository<Slot, gloas.SignedExecutionPayloadEnvelope> {
|
|
13
|
+
constructor(config: ChainForkConfig, db: Db) {
|
|
14
|
+
const bucket = Bucket.gloas_executionPayloadEnvelopeArchive;
|
|
15
|
+
super(config, db, bucket, ssz.gloas.SignedExecutionPayloadEnvelope, getBucketNameByValue(bucket));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Id is the slot from the envelope
|
|
20
|
+
*/
|
|
21
|
+
getId(value: gloas.SignedExecutionPayloadEnvelope): Slot {
|
|
22
|
+
return value.message.slot;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
encodeKey(id: Slot): Uint8Array {
|
|
26
|
+
return encodeDbKey(this.bucket, id);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
decodeKey(data: Uint8Array): number {
|
|
30
|
+
return bytesToInt(data.subarray(BUCKET_LENGTH), "be");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -8,6 +8,8 @@ export {BlockArchiveRepository} from "./blockArchive.js";
|
|
|
8
8
|
export {BLSToExecutionChangeRepository} from "./blsToExecutionChange.js";
|
|
9
9
|
export {DataColumnSidecarRepository} from "./dataColumnSidecar.js";
|
|
10
10
|
export {DataColumnSidecarArchiveRepository} from "./dataColumnSidecarArchive.js";
|
|
11
|
+
export {ExecutionPayloadEnvelopeRepository} from "./executionPayloadEnvelope.js";
|
|
12
|
+
export {ExecutionPayloadEnvelopeArchiveRepository} from "./executionPayloadEnvelopeArchive.js";
|
|
11
13
|
export {BestLightClientUpdateRepository} from "./lightclientBestUpdate.js";
|
|
12
14
|
export {CheckpointHeaderRepository} from "./lightclientCheckpointHeader.js";
|
|
13
15
|
export {SyncCommitteeRepository} from "./lightclientSyncCommittee.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {routes} from "@lodestar/api";
|
|
1
2
|
import {
|
|
2
3
|
CONSOLIDATION_REQUEST_TYPE,
|
|
3
4
|
DEPOSIT_REQUEST_TYPE,
|
|
@@ -14,6 +15,8 @@ import {ExecutionPayloadBody} from "./types.js";
|
|
|
14
15
|
import {DATA} from "./utils.js";
|
|
15
16
|
|
|
16
17
|
export {PayloadIdCache, type PayloadId, type WithdrawalV1};
|
|
18
|
+
export type ClientVersion = routes.node.ClientVersion;
|
|
19
|
+
export const ClientCode = routes.node.ClientCode;
|
|
17
20
|
|
|
18
21
|
export enum ExecutionPayloadStatus {
|
|
19
22
|
/** given payload is valid */
|
|
@@ -45,26 +48,6 @@ export enum ExecutionEngineState {
|
|
|
45
48
|
AUTH_FAILED = "AUTH_FAILED",
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
/**
|
|
49
|
-
* Client code as defined in https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.4/src/engine/identification.md#clientcode
|
|
50
|
-
* ClientCode.XX is dedicated to other clients which do not have their own code
|
|
51
|
-
*/
|
|
52
|
-
export enum ClientCode {
|
|
53
|
-
BU = "BU", // besu
|
|
54
|
-
EJ = "EJ", // ethereumJS
|
|
55
|
-
EG = "EG", // erigon
|
|
56
|
-
GE = "GE", // go-ethereum
|
|
57
|
-
GR = "GR", // grandine
|
|
58
|
-
LH = "LH", // lighthouse
|
|
59
|
-
LS = "LS", // lodestar
|
|
60
|
-
NM = "NM", // nethermind
|
|
61
|
-
NB = "NB", // nimbus
|
|
62
|
-
TK = "TK", // teku
|
|
63
|
-
PM = "PM", // prysm
|
|
64
|
-
RH = "RH", // reth
|
|
65
|
-
XX = "XX", // unknown
|
|
66
|
-
}
|
|
67
|
-
|
|
68
51
|
export type ExecutionRequestType =
|
|
69
52
|
| typeof DEPOSIT_REQUEST_TYPE
|
|
70
53
|
| typeof WITHDRAWAL_REQUEST_TYPE
|
|
@@ -106,13 +89,6 @@ export type PayloadAttributes = {
|
|
|
106
89
|
parentBeaconBlockRoot?: Uint8Array;
|
|
107
90
|
};
|
|
108
91
|
|
|
109
|
-
export type ClientVersion = {
|
|
110
|
-
code: ClientCode;
|
|
111
|
-
name: string;
|
|
112
|
-
version: string;
|
|
113
|
-
commit: string;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
92
|
export type VersionedHashes = Uint8Array[];
|
|
117
93
|
|
|
118
94
|
/**
|
|
@@ -144,6 +144,11 @@ export function createBeaconMetrics(register: RegistryMetricCreator) {
|
|
|
144
144
|
help: "Time for preparing payload in advance",
|
|
145
145
|
buckets: [0.1, 1, 3, 5, 10],
|
|
146
146
|
}),
|
|
147
|
+
executionPayloadEnvelopeProcessingTime: register.histogram({
|
|
148
|
+
name: "beacon_block_payload_envelope_processing_seconds",
|
|
149
|
+
help: "Time to process execution payload envelope during block production",
|
|
150
|
+
buckets: [0.005, 0.01, 0.05, 0.1, 0.2, 0.5, 1],
|
|
151
|
+
}),
|
|
147
152
|
payloadFetchedTime: register.histogram<{prepType: PayloadPreparationType}>({
|
|
148
153
|
name: "beacon_block_payload_fetched_time",
|
|
149
154
|
help: "Time to fetch the payload from EL",
|
|
@@ -827,6 +827,15 @@ export function createLodestarMetrics(
|
|
|
827
827
|
help: "Total number of blobs retrieved from execution engine and published to gossip",
|
|
828
828
|
}),
|
|
829
829
|
},
|
|
830
|
+
// Gossip execution payload envelope
|
|
831
|
+
gossipExecutionPayloadEnvelope: {
|
|
832
|
+
elapsedTimeTillReceived: register.histogram<{source: OpSource}>({
|
|
833
|
+
name: "lodestar_gossip_execution_payload_envelope_elapsed_time_till_received",
|
|
834
|
+
help: "Time elapsed between slot time and the time execution payload envelope received",
|
|
835
|
+
labelNames: ["source"],
|
|
836
|
+
buckets: [0.5, 1, 2, 4, 6, 12],
|
|
837
|
+
}),
|
|
838
|
+
},
|
|
830
839
|
recoverDataColumnSidecars: {
|
|
831
840
|
recoverTime: register.histogram({
|
|
832
841
|
name: "lodestar_recover_data_column_sidecar_recover_time_seconds",
|