@lodestar/beacon-node 1.50.0 → 1.51.0-dev.02c5a19f35
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 +7 -2
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/index.js +8 -2
- package/lib/api/impl/beacon/state/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -1
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js +17 -9
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +3 -0
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +133 -27
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.d.ts +11 -13
- package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.js +49 -44
- package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +4 -5
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/blockInput/utils.js +2 -2
- package/lib/chain/blocks/blockInput/utils.js.map +1 -1
- package/lib/chain/blocks/importBlock.js +10 -6
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +50 -2
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +4 -0
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/types.js +5 -0
- package/lib/chain/blocks/types.js.map +1 -1
- package/lib/chain/chain.d.ts +2 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +8 -3
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +11 -1
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadBid.js +2 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -1
- package/lib/chain/errors/inclusionList.d.ts +60 -0
- package/lib/chain/errors/inclusionList.d.ts.map +1 -0
- package/lib/chain/errors/inclusionList.js +19 -0
- package/lib/chain/errors/inclusionList.js.map +1 -0
- package/lib/chain/errors/index.d.ts +1 -0
- package/lib/chain/errors/index.d.ts.map +1 -1
- package/lib/chain/errors/index.js +1 -0
- package/lib/chain/errors/index.js.map +1 -1
- package/lib/chain/interface.d.ts +3 -2
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/inclusionListStore.d.ts +63 -0
- package/lib/chain/opPools/inclusionListStore.d.ts.map +1 -0
- package/lib/chain/opPools/inclusionListStore.js +171 -0
- package/lib/chain/opPools/inclusionListStore.js.map +1 -0
- package/lib/chain/opPools/index.d.ts +1 -0
- package/lib/chain/opPools/index.d.ts.map +1 -1
- package/lib/chain/opPools/index.js +1 -0
- package/lib/chain/opPools/index.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +4 -3
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +37 -15
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +1 -0
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +1 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/reprocess.d.ts +2 -1
- package/lib/chain/reprocess.d.ts.map +1 -1
- package/lib/chain/reprocess.js +2 -1
- package/lib/chain/reprocess.js.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +33 -1
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/inclusionList.d.ts +14 -0
- package/lib/chain/validation/inclusionList.d.ts.map +1 -0
- package/lib/chain/validation/inclusionList.js +150 -0
- package/lib/chain/validation/inclusionList.js.map +1 -0
- package/lib/chain/validation/index.d.ts +1 -0
- package/lib/chain/validation/index.d.ts.map +1 -1
- package/lib/chain/validation/index.js +1 -0
- package/lib/chain/validation/index.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +6 -4
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/constants/constants.d.ts +1 -0
- package/lib/constants/constants.d.ts.map +1 -1
- package/lib/constants/constants.js +1 -0
- package/lib/constants/constants.js.map +1 -1
- package/lib/db/repositories/blockArchive.js +2 -2
- package/lib/db/repositories/blockArchive.js.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.js +1 -2
- package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
- package/lib/execution/builder/validateBid.d.ts.map +1 -1
- package/lib/execution/builder/validateBid.js +14 -1
- package/lib/execution/builder/validateBid.js.map +1 -1
- package/lib/execution/engine/blobVersionedHashes.d.ts +1 -1
- package/lib/execution/engine/blobVersionedHashes.d.ts.map +1 -1
- package/lib/execution/engine/blobVersionedHashes.js.map +1 -1
- package/lib/execution/engine/disabled.d.ts +1 -0
- package/lib/execution/engine/disabled.d.ts.map +1 -1
- package/lib/execution/engine/disabled.js +3 -0
- package/lib/execution/engine/disabled.js.map +1 -1
- package/lib/execution/engine/http.d.ts +8 -2
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +27 -4
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/index.d.ts.map +1 -1
- package/lib/execution/engine/index.js +1 -1
- package/lib/execution/engine/index.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +11 -2
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/interface.js.map +1 -1
- package/lib/execution/engine/jsonRpcHttpClient.d.ts.map +1 -1
- package/lib/execution/engine/jsonRpcHttpClient.js +14 -4
- package/lib/execution/engine/jsonRpcHttpClient.js.map +1 -1
- package/lib/execution/engine/jsonRpcTransport.d.ts +3 -2
- package/lib/execution/engine/jsonRpcTransport.d.ts.map +1 -1
- package/lib/execution/engine/jsonRpcTransport.js +33 -9
- package/lib/execution/engine/jsonRpcTransport.js.map +1 -1
- package/lib/execution/engine/mock.d.ts +1 -0
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +31 -7
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/payloadIdCache.d.ts +5 -3
- package/lib/execution/engine/payloadIdCache.d.ts.map +1 -1
- package/lib/execution/engine/payloadIdCache.js +15 -4
- package/lib/execution/engine/payloadIdCache.js.map +1 -1
- package/lib/execution/engine/restTransport.d.ts +5 -2
- package/lib/execution/engine/restTransport.d.ts.map +1 -1
- package/lib/execution/engine/restTransport.js +36 -21
- package/lib/execution/engine/restTransport.js.map +1 -1
- package/lib/execution/engine/sszTypes.d.ts +38 -38
- package/lib/execution/engine/transport.d.ts +5 -2
- package/lib/execution/engine/transport.d.ts.map +1 -1
- package/lib/execution/engine/transportMetrics.d.ts +5 -1
- package/lib/execution/engine/transportMetrics.d.ts.map +1 -1
- package/lib/execution/engine/types.d.ts +25 -1
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +29 -15
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/metrics/metrics/beacon.d.ts +16 -0
- package/lib/metrics/metrics/beacon.d.ts.map +1 -1
- package/lib/metrics/metrics/beacon.js +35 -0
- package/lib/metrics/metrics/beacon.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +20 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +51 -1
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/gossipsub.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.js +3 -1
- package/lib/network/gossip/gossipsub.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +8 -2
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/interface.js +1 -0
- package/lib/network/gossip/interface.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +13 -19
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +13 -1
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/interface.d.ts +2 -1
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +2 -1
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +5 -0
- package/lib/network/network.js.map +1 -1
- package/lib/network/peers/utils/enrSubnetsDeserialize.d.ts.map +1 -1
- package/lib/network/peers/utils/enrSubnetsDeserialize.js +5 -2
- package/lib/network/peers/utils/enrSubnetsDeserialize.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +63 -17
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
- package/lib/network/processor/gossipQueues/index.js +6 -0
- package/lib/network/processor/gossipQueues/index.js.map +1 -1
- package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
- package/lib/network/processor/gossipValidatorFn.js +5 -1
- package/lib/network/processor/gossipValidatorFn.js.map +1 -1
- package/lib/network/processor/index.d.ts +5 -0
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +40 -29
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js +6 -0
- package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +4 -4
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +3 -3
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/inclusionListsByIndices.d.ts +10 -0
- package/lib/network/reqresp/handlers/inclusionListsByIndices.d.ts.map +1 -0
- package/lib/network/reqresp/handlers/inclusionListsByIndices.js +30 -0
- package/lib/network/reqresp/handlers/inclusionListsByIndices.js.map +1 -0
- package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/index.js +5 -0
- package/lib/network/reqresp/handlers/index.js.map +1 -1
- package/lib/network/reqresp/protocols.d.ts +1 -0
- package/lib/network/reqresp/protocols.d.ts.map +1 -1
- package/lib/network/reqresp/protocols.js +5 -0
- package/lib/network/reqresp/protocols.js.map +1 -1
- package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
- package/lib/network/reqresp/rateLimit.js +6 -2
- package/lib/network/reqresp/rateLimit.js.map +1 -1
- package/lib/network/reqresp/types.d.ts +5 -2
- package/lib/network/reqresp/types.d.ts.map +1 -1
- package/lib/network/reqresp/types.js +3 -0
- package/lib/network/reqresp/types.js.map +1 -1
- package/lib/network/subnets/attnetsService.d.ts.map +1 -1
- package/lib/network/subnets/attnetsService.js +3 -1
- package/lib/network/subnets/attnetsService.js.map +1 -1
- package/lib/node/notifier.d.ts.map +1 -1
- package/lib/node/notifier.js +12 -13
- package/lib/node/notifier.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +45 -20
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/util/clock.d.ts.map +1 -1
- package/lib/util/clock.js +3 -4
- package/lib/util/clock.js.map +1 -1
- package/lib/util/sszBytes.d.ts +2 -2
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +22 -14
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +30 -30
- package/src/api/impl/beacon/blocks/index.ts +10 -3
- package/src/api/impl/beacon/state/index.ts +10 -1
- package/src/api/impl/beacon/state/utils.ts +19 -9
- package/src/api/impl/debug/index.ts +4 -0
- package/src/api/impl/validator/index.ts +173 -29
- package/src/chain/ColumnReconstructionTracker.ts +63 -46
- package/src/chain/archiveStore/utils/archiveBlocks.ts +6 -7
- package/src/chain/blocks/blockInput/blockInput.ts +1 -1
- package/src/chain/blocks/blockInput/utils.ts +2 -2
- package/src/chain/blocks/importBlock.ts +11 -11
- package/src/chain/blocks/importExecutionPayload.ts +68 -2
- package/src/chain/blocks/types.ts +5 -0
- package/src/chain/chain.ts +8 -2
- package/src/chain/errors/executionPayloadBid.ts +12 -0
- package/src/chain/errors/inclusionList.ts +38 -0
- package/src/chain/errors/index.ts +1 -0
- package/src/chain/interface.ts +4 -1
- package/src/chain/opPools/inclusionListStore.ts +208 -0
- package/src/chain/opPools/index.ts +1 -0
- package/src/chain/prepareNextSlot.ts +7 -3
- package/src/chain/produceBlock/computeNewStateRoot.ts +9 -2
- package/src/chain/produceBlock/produceBlockBody.ts +70 -24
- package/src/chain/regen/interface.ts +1 -0
- package/src/chain/reprocess.ts +2 -1
- package/src/chain/seenCache/seenGossipBlockInput.ts +2 -1
- package/src/chain/stateCache/persistentCheckpointsCache.ts +4 -1
- package/src/chain/validation/executionPayloadBid.ts +52 -2
- package/src/chain/validation/inclusionList.ts +192 -0
- package/src/chain/validation/index.ts +1 -0
- package/src/chain/validatorMonitor.ts +7 -4
- package/src/constants/constants.ts +1 -0
- package/src/db/repositories/blockArchive.ts +2 -2
- package/src/db/repositories/blockArchiveIndex.ts +2 -3
- package/src/execution/builder/validateBid.ts +23 -2
- package/src/execution/engine/blobVersionedHashes.ts +1 -1
- package/src/execution/engine/disabled.ts +4 -0
- package/src/execution/engine/http.ts +40 -5
- package/src/execution/engine/index.ts +2 -1
- package/src/execution/engine/interface.ts +27 -3
- package/src/execution/engine/jsonRpcHttpClient.ts +12 -5
- package/src/execution/engine/jsonRpcTransport.ts +46 -9
- package/src/execution/engine/mock.ts +32 -7
- package/src/execution/engine/payloadIdCache.ts +24 -6
- package/src/execution/engine/restTransport.ts +68 -23
- package/src/execution/engine/transport.ts +7 -2
- package/src/execution/engine/transportMetrics.ts +2 -1
- package/src/execution/engine/types.ts +53 -16
- package/src/metrics/metrics/beacon.ts +37 -0
- package/src/metrics/metrics/lodestar.ts +53 -1
- package/src/network/gossip/gossipsub.ts +3 -1
- package/src/network/gossip/interface.ts +5 -0
- package/src/network/gossip/topic.ts +14 -0
- package/src/network/interface.ts +2 -0
- package/src/network/network.ts +11 -0
- package/src/network/peers/utils/enrSubnetsDeserialize.ts +5 -2
- package/src/network/processor/gossipHandlers.ts +80 -20
- package/src/network/processor/gossipQueues/index.ts +6 -0
- package/src/network/processor/gossipValidatorFn.ts +5 -0
- package/src/network/processor/index.ts +36 -27
- package/src/network/processor/types.ts +1 -1
- package/src/network/reqresp/ReqRespBeaconNode.ts +7 -0
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +4 -10
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +3 -3
- package/src/network/reqresp/handlers/inclusionListsByIndices.ts +44 -0
- package/src/network/reqresp/handlers/index.ts +5 -0
- package/src/network/reqresp/protocols.ts +6 -0
- package/src/network/reqresp/rateLimit.ts +6 -2
- package/src/network/reqresp/types.ts +6 -0
- package/src/network/subnets/attnetsService.ts +8 -3
- package/src/node/notifier.ts +14 -13
- package/src/sync/unknownBlock.ts +50 -30
- package/src/util/clock.ts +3 -4
- package/src/util/sszBytes.ts +25 -12
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {NUMBER_OF_COLUMNS} from "@lodestar/params";
|
|
3
|
+
import {RootHex} from "@lodestar/types";
|
|
2
4
|
import {Logger, sleep} from "@lodestar/utils";
|
|
3
5
|
import {Metrics} from "../metrics/metrics.js";
|
|
4
6
|
import {DataColumnReconstructionCode, recoverDataColumnSidecars} from "../util/dataColumns.js";
|
|
7
|
+
import {JobItemQueue} from "../util/queue/index.js";
|
|
5
8
|
import {BlockInputColumns} from "./blocks/blockInput/index.js";
|
|
6
9
|
import {PayloadEnvelopeInput} from "./blocks/payloadEnvelopeInput/index.js";
|
|
7
10
|
import {ChainEventEmitter} from "./emitter.js";
|
|
@@ -16,15 +19,22 @@ const RECONSTRUCTION_DELAY_MIN_BPS = 667;
|
|
|
16
19
|
*/
|
|
17
20
|
const RECONSTRUCTION_DELAY_MAX_BPS = 1000;
|
|
18
21
|
|
|
22
|
+
const QUEUE_MAX_LENGTH = 16;
|
|
23
|
+
|
|
24
|
+
export type ColumnReconstructionInput = BlockInputColumns | PayloadEnvelopeInput;
|
|
25
|
+
|
|
19
26
|
export type ColumnReconstructionTrackerInit = {
|
|
20
27
|
logger: Logger;
|
|
21
28
|
emitter: ChainEventEmitter;
|
|
22
29
|
metrics: Metrics | null;
|
|
23
30
|
config: ChainForkConfig;
|
|
31
|
+
signal: AbortSignal;
|
|
24
32
|
};
|
|
25
33
|
|
|
26
34
|
/**
|
|
27
|
-
*
|
|
35
|
+
* Runs column reconstruction one block root at a time, in trigger order. A trigger for a root that is
|
|
36
|
+
* queued or in flight is a no-op. A root is removed once its attempt finishes so a later column can
|
|
37
|
+
* retry a failed attempt.
|
|
28
38
|
*/
|
|
29
39
|
export class ColumnReconstructionTracker {
|
|
30
40
|
logger: Logger;
|
|
@@ -32,64 +42,71 @@ export class ColumnReconstructionTracker {
|
|
|
32
42
|
metrics: Metrics | null;
|
|
33
43
|
config: ChainForkConfig;
|
|
34
44
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* This is sufficient to avoid duplicate calls since we only call this
|
|
39
|
-
* function when we see a new data column sidecar from gossip.
|
|
40
|
-
*/
|
|
41
|
-
lastBlockRootHex: string | null = null;
|
|
42
|
-
/** Track if a reconstruction attempt is in-flight */
|
|
43
|
-
running = false;
|
|
44
|
-
|
|
45
|
-
private readonly minDelayMs: number;
|
|
46
|
-
private readonly maxDelayMs: number;
|
|
45
|
+
private readonly signal: AbortSignal;
|
|
46
|
+
private readonly pending = new Set<RootHex>();
|
|
47
|
+
private readonly queue: JobItemQueue<[ColumnReconstructionInput, number], void>;
|
|
47
48
|
|
|
48
49
|
constructor(init: ColumnReconstructionTrackerInit) {
|
|
49
50
|
this.logger = init.logger;
|
|
50
51
|
this.emitter = init.emitter;
|
|
51
52
|
this.metrics = init.metrics;
|
|
52
53
|
this.config = init.config;
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
54
|
+
this.signal = init.signal;
|
|
55
|
+
this.queue = new JobItemQueue(
|
|
56
|
+
this.reconstruct,
|
|
57
|
+
{maxLength: QUEUE_MAX_LENGTH, signal: init.signal},
|
|
58
|
+
init.metrics?.columnReconstructionQueue
|
|
59
|
+
);
|
|
55
60
|
}
|
|
56
61
|
|
|
57
|
-
triggerColumnReconstruction(input:
|
|
58
|
-
if (this.
|
|
62
|
+
triggerColumnReconstruction(input: ColumnReconstructionInput): void {
|
|
63
|
+
if (this.pending.has(input.blockRootHex)) {
|
|
59
64
|
return;
|
|
60
65
|
}
|
|
61
66
|
|
|
62
|
-
if (
|
|
67
|
+
if (input.getAllColumns().length < NUMBER_OF_COLUMNS / 2) {
|
|
63
68
|
return;
|
|
64
69
|
}
|
|
65
70
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
result: DataColumnReconstructionCode.Failed,
|
|
83
|
-
});
|
|
84
|
-
this.logger.debug("Error during data column sidecar reconstruction", logCtx, e as Error);
|
|
85
|
-
})
|
|
86
|
-
.finally(() => {
|
|
87
|
-
this.logger.debug("Data column sidecar reconstruction attempt finished", logCtx);
|
|
88
|
-
this.running = false;
|
|
89
|
-
});
|
|
90
|
-
})
|
|
91
|
-
.catch((err) => {
|
|
92
|
-
this.logger.debug("ColumnReconstructionTracker unreachable error", {}, err);
|
|
93
|
-
});
|
|
71
|
+
this.pending.add(input.blockRootHex);
|
|
72
|
+
void this.enqueue(input);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private async enqueue(input: ColumnReconstructionInput): Promise<void> {
|
|
76
|
+
try {
|
|
77
|
+
await this.queue.push(input, Date.now());
|
|
78
|
+
} catch (e) {
|
|
79
|
+
this.logger.debug(
|
|
80
|
+
"Data column sidecar reconstruction dropped",
|
|
81
|
+
{slot: input.slot, root: input.blockRootHex},
|
|
82
|
+
e as Error
|
|
83
|
+
);
|
|
84
|
+
} finally {
|
|
85
|
+
this.pending.delete(input.blockRootHex);
|
|
86
|
+
}
|
|
94
87
|
}
|
|
88
|
+
|
|
89
|
+
private reconstruct = async (input: ColumnReconstructionInput, queuedAtMs: number): Promise<void> => {
|
|
90
|
+
const fork = this.config.getForkName(input.slot);
|
|
91
|
+
const minDelayMs = this.config.getSlotComponentDurationMs(fork, RECONSTRUCTION_DELAY_MIN_BPS);
|
|
92
|
+
const maxDelayMs = this.config.getSlotComponentDurationMs(fork, RECONSTRUCTION_DELAY_MAX_BPS);
|
|
93
|
+
const delay = minDelayMs + Math.random() * (maxDelayMs - minDelayMs);
|
|
94
|
+
|
|
95
|
+
// The delay gives gossip a chance to deliver the remaining columns, so time already spent in the
|
|
96
|
+
// queue behind another root counts towards it
|
|
97
|
+
await sleep(delay - (Date.now() - queuedAtMs), this.signal);
|
|
98
|
+
|
|
99
|
+
const logCtx = {slot: input.slot, root: input.blockRootHex};
|
|
100
|
+
this.logger.debug("Attempting data column sidecar reconstruction", logCtx);
|
|
101
|
+
try {
|
|
102
|
+
const result = await recoverDataColumnSidecars(input, this.emitter, this.metrics);
|
|
103
|
+
this.metrics?.recoverDataColumnSidecars.reconstructionResult.inc({result});
|
|
104
|
+
this.logger.debug("Data column sidecar reconstruction complete", {...logCtx, result});
|
|
105
|
+
} catch (e) {
|
|
106
|
+
this.metrics?.recoverDataColumnSidecars.reconstructionResult.inc({result: DataColumnReconstructionCode.Failed});
|
|
107
|
+
this.logger.debug("Error during data column sidecar reconstruction", logCtx, e as Error);
|
|
108
|
+
} finally {
|
|
109
|
+
this.logger.debug("Data column sidecar reconstruction attempt finished", logCtx);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
95
112
|
}
|
|
@@ -3,7 +3,7 @@ import {ChainForkConfig} from "@lodestar/config";
|
|
|
3
3
|
import {KeyValue} from "@lodestar/db";
|
|
4
4
|
import {CheckpointWithHex, ExecutionStatus, IForkChoice, PayloadStatus, ProtoBlock} from "@lodestar/fork-choice";
|
|
5
5
|
import {ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
6
|
-
import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
6
|
+
import {computeEpochAtSlot, computeStartSlotAtEpoch, getBlobDataRetentionStartEpoch} from "@lodestar/state-transition";
|
|
7
7
|
import {Epoch, Slot} from "@lodestar/types";
|
|
8
8
|
import {Logger, fromAsync, fromHex, prettyPrintIndices, toRootHex} from "@lodestar/utils";
|
|
9
9
|
import {IBeaconDb} from "../../../db/index.js";
|
|
@@ -253,14 +253,13 @@ export async function archiveBlocks(
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
// Delete expired data column sidecars
|
|
256
|
-
// Keep only `[current_epoch -
|
|
256
|
+
// Keep only `[min(compute_blob_data_retention_start_epoch(current_epoch), current_epoch - archiveDataEpochs)]`
|
|
257
257
|
if (finalizedPostFulu) {
|
|
258
258
|
if (archiveDataEpochs !== Infinity) {
|
|
259
|
-
const
|
|
260
|
-
config
|
|
261
|
-
archiveDataEpochs ?? 0
|
|
259
|
+
const dataColumnSidecarsMinEpoch = Math.min(
|
|
260
|
+
getBlobDataRetentionStartEpoch(config, currentEpoch),
|
|
261
|
+
currentEpoch - (archiveDataEpochs ?? 0)
|
|
262
262
|
);
|
|
263
|
-
const dataColumnSidecarsMinEpoch = currentEpoch - dataColumnSidecarsArchiveWindow;
|
|
264
263
|
if (dataColumnSidecarsMinEpoch >= config.FULU_FORK_EPOCH) {
|
|
265
264
|
const columnsPruneSlot = computeStartSlotAtEpoch(dataColumnSidecarsMinEpoch);
|
|
266
265
|
const prunedColumnSlots = await db.dataColumns.pruneBefore(columnsPruneSlot);
|
|
@@ -439,7 +438,7 @@ async function migrateDataColumnSidecarsFromHotToColdDb(
|
|
|
439
438
|
const blockEpoch = computeEpochAtSlot(block.slot);
|
|
440
439
|
if (
|
|
441
440
|
config.getForkSeq(block.slot) < ForkSeq.fulu ||
|
|
442
|
-
blockEpoch < currentEpoch
|
|
441
|
+
blockEpoch < getBlobDataRetentionStartEpoch(config, currentEpoch)
|
|
443
442
|
) {
|
|
444
443
|
continue;
|
|
445
444
|
}
|
|
@@ -210,7 +210,7 @@ export class BlockInputPreData extends AbstractBlockInput<ForkPreDeneb, null> {
|
|
|
210
210
|
this.blockPromise.resolve(state.block);
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
static createFromBlock(props: AddBlock & CreateBlockInputMeta): BlockInputPreData {
|
|
213
|
+
static createFromBlock(props: AddBlock<ForkPreDeneb> & CreateBlockInputMeta): BlockInputPreData {
|
|
214
214
|
const init: BlockInputInit = {
|
|
215
215
|
daOutOfRange: props.daOutOfRange,
|
|
216
216
|
timeCreated: props.seenTimestampSec,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {ForkName, isForkPostDeneb, isForkPostFulu} from "@lodestar/params";
|
|
3
|
-
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
3
|
+
import {computeEpochAtSlot, getBlobDataRetentionStartEpoch} from "@lodestar/state-transition";
|
|
4
4
|
import {Epoch, Slot} from "@lodestar/types";
|
|
5
5
|
|
|
6
6
|
export function isDaOutOfRange(
|
|
@@ -10,7 +10,7 @@ export function isDaOutOfRange(
|
|
|
10
10
|
currentEpoch: Epoch
|
|
11
11
|
): boolean {
|
|
12
12
|
if (isForkPostFulu(forkName)) {
|
|
13
|
-
return computeEpochAtSlot(blockSlot) < currentEpoch
|
|
13
|
+
return computeEpochAtSlot(blockSlot) < getBlobDataRetentionStartEpoch(config, currentEpoch);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
if (isForkPostDeneb(forkName)) {
|
|
@@ -45,7 +45,7 @@ import {isQueueErrorAborted} from "../../util/queue/index.js";
|
|
|
45
45
|
import type {BeaconChain} from "../chain.js";
|
|
46
46
|
import {ChainEvent, ReorgEventData} from "../emitter.js";
|
|
47
47
|
import {ForkchoiceCaller} from "../forkChoice/index.js";
|
|
48
|
-
import {
|
|
48
|
+
import {REPROCESS_MIN_TIME_TO_NEXT_SLOT_BPS} from "../reprocess.js";
|
|
49
49
|
import {toCheckpointHex} from "../stateCache/persistentCheckpointsCache.js";
|
|
50
50
|
import {isBlockInputBlobs, isBlockInputColumns} from "./blockInput/blockInput.js";
|
|
51
51
|
import {AttestationImportOpt, FullyVerifiedBlock, ImportBlockOpts} from "./types.js";
|
|
@@ -335,7 +335,8 @@ export async function importBlock(
|
|
|
335
335
|
this.metrics.headSlot.set(newHead.slot);
|
|
336
336
|
// Only track "recent" blocks. Otherwise sync can distort this metrics heavily.
|
|
337
337
|
// We want to track recent blocks coming from gossip, unknown block sync, and API.
|
|
338
|
-
|
|
338
|
+
const headFork = this.config.getForkName(newHead.slot);
|
|
339
|
+
if (delaySec < (SLOTS_PER_EPOCH * this.config.getSlotDurationMs(headFork)) / 1000) {
|
|
339
340
|
this.metrics.importBlock.elapsedTimeTillBecomeHead.observe(delaySec);
|
|
340
341
|
const cutOffSec = this.config.getAttestationDueMs(this.config.getForkName(blockSlot)) / 1000;
|
|
341
342
|
if (delaySec > cutOffSec) {
|
|
@@ -457,7 +458,8 @@ export async function importBlock(
|
|
|
457
458
|
* - `headBlockHash !== null` -> Pre BELLATRIX_EPOCH
|
|
458
459
|
* - `headBlockHash !== ZERO_HASH` -> Pre TTD
|
|
459
460
|
*/
|
|
460
|
-
const
|
|
461
|
+
const fcuHead = this.forkChoice.getHead();
|
|
462
|
+
const headBlockHash = fcuHead.executionPayloadBlockHash ?? ZERO_HASH_HEX;
|
|
461
463
|
/**
|
|
462
464
|
* After BELLATRIX_EPOCH and TTD it's okay to send a zero hash block hash for the finalized block. This will happen if
|
|
463
465
|
* the current finalized block does not contain any execution payload at all (pre MERGE_EPOCH) or if it contains a
|
|
@@ -467,12 +469,7 @@ export async function importBlock(
|
|
|
467
469
|
const finalizedBlockHash = getFinalizedExecutionBlockHash(this.forkChoice);
|
|
468
470
|
if (headBlockHash !== ZERO_HASH_HEX) {
|
|
469
471
|
this.executionEngine
|
|
470
|
-
.notifyForkchoiceUpdate(
|
|
471
|
-
this.config.getForkName(this.forkChoice.getHead().slot),
|
|
472
|
-
headBlockHash,
|
|
473
|
-
safeBlockHash,
|
|
474
|
-
finalizedBlockHash
|
|
475
|
-
)
|
|
472
|
+
.notifyForkchoiceUpdate(this.config.getForkName(fcuHead.slot), headBlockHash, safeBlockHash, finalizedBlockHash)
|
|
476
473
|
.catch((e) => {
|
|
477
474
|
if (!isErrorAborted(e) && !isQueueErrorAborted(e)) {
|
|
478
475
|
this.logger.error("Error pushing notifyForkchoiceUpdate()", {headBlockHash, finalizedBlockHash}, e);
|
|
@@ -586,7 +583,7 @@ export async function importBlock(
|
|
|
586
583
|
this.validatorMonitor?.registerSyncAggregateInBlock(
|
|
587
584
|
blockEpoch,
|
|
588
585
|
(block as altair.SignedBeaconBlock).message.body.syncAggregate,
|
|
589
|
-
fullyVerifiedBlock.postState.
|
|
586
|
+
fullyVerifiedBlock.postState.currentSyncCommitteeValidatorIndices
|
|
590
587
|
);
|
|
591
588
|
}
|
|
592
589
|
|
|
@@ -600,7 +597,10 @@ export async function importBlock(
|
|
|
600
597
|
}
|
|
601
598
|
}
|
|
602
599
|
|
|
603
|
-
const
|
|
600
|
+
const reprocessGuardSec =
|
|
601
|
+
this.config.getSlotComponentDurationMs(this.config.getForkName(blockSlot), REPROCESS_MIN_TIME_TO_NEXT_SLOT_BPS) /
|
|
602
|
+
1000;
|
|
603
|
+
const advancedSlot = this.clock.slotWithFutureTolerance(reprocessGuardSec);
|
|
604
604
|
|
|
605
605
|
// Gossip blocks need to be imported as soon as possible, waiting attestations could be processed
|
|
606
606
|
// in the next event loop. See https://github.com/ChainSafe/lodestar/issues/4789
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {SerializedList} from "@chainsafe/ssz";
|
|
1
2
|
import {routes} from "@lodestar/api";
|
|
2
3
|
import {
|
|
3
4
|
ExecutionStatus,
|
|
@@ -5,9 +6,16 @@ import {
|
|
|
5
6
|
getFinalizedExecutionBlockHash,
|
|
6
7
|
getSafeExecutionBlockHash,
|
|
7
8
|
} from "@lodestar/fork-choice";
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
DataAvailabilityStatus,
|
|
11
|
+
computeEpochAtSlot,
|
|
12
|
+
isStatePostGloas,
|
|
13
|
+
isStatePostHeze,
|
|
14
|
+
} from "@lodestar/state-transition";
|
|
15
|
+
import {RootHex, bellatrix} from "@lodestar/types";
|
|
9
16
|
import {isErrorAborted} from "@lodestar/utils";
|
|
10
17
|
import {ExecutionPayloadStatus} from "../../execution/index.js";
|
|
18
|
+
import {getShufflingDependentRoot} from "../../util/dependentRoot.js";
|
|
11
19
|
import {isQueueErrorAborted} from "../../util/queue/index.js";
|
|
12
20
|
import {BeaconChain} from "../chain.js";
|
|
13
21
|
import {RegenCaller} from "../regen/interface.js";
|
|
@@ -172,6 +180,37 @@ export async function importExecutionPayload(
|
|
|
172
180
|
);
|
|
173
181
|
}
|
|
174
182
|
|
|
183
|
+
// Timely inclusion lists of the preceding slot, keyed by that slot's dependent root on the block's branch and
|
|
184
|
+
// resolved from the parent, which is at or before that slot. Gossip validation only accepts lists whose dependent
|
|
185
|
+
// block is in fork choice, so a dependent root fork choice cannot resolve (below the anchor after checkpoint sync)
|
|
186
|
+
// keys no stored list
|
|
187
|
+
let inclusionListTransactions: bellatrix.Transactions | undefined;
|
|
188
|
+
if (isStatePostHeze(blockState)) {
|
|
189
|
+
const inclusionListSlot = protoBlock.slot - 1;
|
|
190
|
+
let dependentRoot: RootHex | null = null;
|
|
191
|
+
const parentBlock = this.forkChoice.getBlockHexDefaultStatus(protoBlock.parentRoot);
|
|
192
|
+
if (parentBlock !== null) {
|
|
193
|
+
try {
|
|
194
|
+
dependentRoot = getShufflingDependentRoot(
|
|
195
|
+
this.forkChoice,
|
|
196
|
+
computeEpochAtSlot(inclusionListSlot),
|
|
197
|
+
computeEpochAtSlot(parentBlock.slot),
|
|
198
|
+
parentBlock
|
|
199
|
+
);
|
|
200
|
+
} catch (e) {
|
|
201
|
+
this.logger.debug(
|
|
202
|
+
"Inclusion list dependent root not in fork choice, importing payload without lists",
|
|
203
|
+
{slot, root: blockRootHex},
|
|
204
|
+
e as Error
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
inclusionListTransactions =
|
|
209
|
+
dependentRoot === null
|
|
210
|
+
? SerializedList.empty()
|
|
211
|
+
: this.inclusionListStore.getInclusionListTransactions(inclusionListSlot, dependentRoot, true);
|
|
212
|
+
}
|
|
213
|
+
|
|
175
214
|
// 4a. Run EL and signature verification in parallel
|
|
176
215
|
const logCtx = {slot, root: blockRootHex, executionBlock: envelope.payload.blockNumber};
|
|
177
216
|
this.logger.debug("Call engine api newPayload", logCtx);
|
|
@@ -182,7 +221,8 @@ export async function importExecutionPayload(
|
|
|
182
221
|
envelope.payload,
|
|
183
222
|
payloadInput.getVersionedHashes(),
|
|
184
223
|
envelope.parentBeaconBlockRoot,
|
|
185
|
-
envelope.executionRequests
|
|
224
|
+
envelope.executionRequests,
|
|
225
|
+
inclusionListTransactions
|
|
186
226
|
),
|
|
187
227
|
|
|
188
228
|
opts.validSignature === true
|
|
@@ -250,6 +290,32 @@ export async function importExecutionPayload(
|
|
|
250
290
|
}
|
|
251
291
|
});
|
|
252
292
|
|
|
293
|
+
// A VALID payload that does not satisfy the inclusion list constraints is still imported, fork choice
|
|
294
|
+
// only records the verdict so should_extend_payload moves the head to the EMPTY variant, which the next
|
|
295
|
+
// proposer builds on.
|
|
296
|
+
// Recorded before the payload enters fork choice. A VALID response must carry a verdict, an
|
|
297
|
+
// optimistically imported payload counts as satisfied until the engine validates it, anything else as
|
|
298
|
+
// unsatisfied. A VALID response without a verdict violates the engine API, it is logged and treated as
|
|
299
|
+
// satisfied so a non-compliant engine does not orphan every payload
|
|
300
|
+
if (inclusionListTransactions !== undefined) {
|
|
301
|
+
if (execResult.status === ExecutionPayloadStatus.VALID && execResult.inclusionListSatisfied == null) {
|
|
302
|
+
this.logger.warn("Execution engine reported no inclusion list verdict, not enforcing inclusion lists", logCtx);
|
|
303
|
+
}
|
|
304
|
+
const satisfied =
|
|
305
|
+
execResult.status === ExecutionPayloadStatus.VALID
|
|
306
|
+
? (execResult.inclusionListSatisfied ?? true)
|
|
307
|
+
: execResult.status === ExecutionPayloadStatus.SYNCING || execResult.status === ExecutionPayloadStatus.ACCEPTED;
|
|
308
|
+
this.forkChoice.recordPayloadInclusionListSatisfaction(blockRootHex, satisfied);
|
|
309
|
+
if (!satisfied) {
|
|
310
|
+
this.logger.verbose("Payload did not satisfy inclusion list constraints", {
|
|
311
|
+
...logCtx,
|
|
312
|
+
blockHash: blockHashHex,
|
|
313
|
+
status: execResult.status,
|
|
314
|
+
inclusionListTransactions: inclusionListTransactions.length,
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
253
319
|
// 6. Update fork choice, transitions the block's PENDING variant to FULL
|
|
254
320
|
const execStatus = toForkChoiceExecutionStatus(execResult.status);
|
|
255
321
|
this.forkChoice.onExecutionPayload(
|
|
@@ -12,6 +12,11 @@ export enum GossipedInputType {
|
|
|
12
12
|
dataColumn = "data_column",
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
export enum InclusionListSource {
|
|
16
|
+
gossip = "gossip",
|
|
17
|
+
api = "api",
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
type DataColumnData = {
|
|
16
21
|
dataColumn: fulu.DataColumnSidecar;
|
|
17
22
|
dataColumnBytes: Uint8Array | null;
|
package/src/chain/chain.ts
CHANGED
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
} from "@lodestar/types";
|
|
59
59
|
import {Logger, fromHex, gweiToWei, isErrorAborted, pruneSetToMax, sleep, toRootHex} from "@lodestar/utils";
|
|
60
60
|
import {ProcessShutdownCallback} from "@lodestar/validator";
|
|
61
|
-
import {GENESIS_EPOCH, ZERO_HASH} from "../constants/index.js";
|
|
61
|
+
import {GENESIS_EPOCH, HALF_SLOT_BPS, ZERO_HASH} from "../constants/index.js";
|
|
62
62
|
import {IBeaconDb} from "../db/index.js";
|
|
63
63
|
import {BLOB_SIDECARS_IN_WRAPPER_INDEX} from "../db/repositories/blobSidecars.js";
|
|
64
64
|
import {decodeArchivedEnvelope} from "../db/repositories/index.js";
|
|
@@ -100,6 +100,7 @@ import {
|
|
|
100
100
|
AttestationPool,
|
|
101
101
|
DeferredVoluntaryExitPool,
|
|
102
102
|
ExecutionPayloadBidPool,
|
|
103
|
+
InclusionListStore,
|
|
103
104
|
OpPool,
|
|
104
105
|
PayloadAttestationPool,
|
|
105
106
|
ProposerPreferencesPool,
|
|
@@ -198,6 +199,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
198
199
|
readonly executionPayloadBidPool: ExecutionPayloadBidPool;
|
|
199
200
|
readonly payloadAttestationPool: PayloadAttestationPool;
|
|
200
201
|
readonly proposerPreferencesPool = new ProposerPreferencesPool();
|
|
202
|
+
readonly inclusionListStore: InclusionListStore;
|
|
201
203
|
readonly opPool: OpPool;
|
|
202
204
|
readonly deferredVoluntaryExitPool: DeferredVoluntaryExitPool;
|
|
203
205
|
|
|
@@ -335,6 +337,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
335
337
|
this.payloadAttestationPool = new PayloadAttestationPool(config, clock, metrics);
|
|
336
338
|
this.opPool = new OpPool(config);
|
|
337
339
|
this.deferredVoluntaryExitPool = new DeferredVoluntaryExitPool(logger);
|
|
340
|
+
this.inclusionListStore = new InclusionListStore(config);
|
|
338
341
|
|
|
339
342
|
this.seenAggregatedAttestations = new SeenAggregatedAttestations(metrics);
|
|
340
343
|
this.seenContributionAndProof = new SeenContributionAndProof(metrics);
|
|
@@ -509,6 +512,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
509
512
|
emitter,
|
|
510
513
|
metrics,
|
|
511
514
|
config,
|
|
515
|
+
signal,
|
|
512
516
|
});
|
|
513
517
|
|
|
514
518
|
this.archiveStore = new ArchiveStore(
|
|
@@ -1831,6 +1835,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1831
1835
|
this.executionPayloadBidPool.prune(slot);
|
|
1832
1836
|
this.seenExecutionPayloadBids.prune(slot);
|
|
1833
1837
|
this.proposerPreferencesPool.prune(slot);
|
|
1838
|
+
this.inclusionListStore.prune(slot);
|
|
1834
1839
|
this.seenAttestationDatas.onSlot(slot);
|
|
1835
1840
|
this.reprocessController.onSlot(slot);
|
|
1836
1841
|
|
|
@@ -1841,7 +1846,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1841
1846
|
const metrics = this.metrics;
|
|
1842
1847
|
if (metrics && (slot + 1) % SLOTS_PER_EPOCH === 0) {
|
|
1843
1848
|
// On the last slot of the epoch
|
|
1844
|
-
|
|
1849
|
+
const fork = this.config.getForkName(slot);
|
|
1850
|
+
sleep(this.config.getSlotComponentDurationMs(fork, HALF_SLOT_BPS))
|
|
1845
1851
|
.then(() => this.validatorMonitor?.onceEveryEndOfEpoch(this.getHeadState()))
|
|
1846
1852
|
.catch((e) => {
|
|
1847
1853
|
if (!isErrorAborted(e)) this.logger.error("Error on validator monitor onceEveryEndOfEpoch", {slot}, e);
|
|
@@ -21,6 +21,8 @@ export enum ExecutionPayloadBidErrorCode {
|
|
|
21
21
|
NO_MATCHING_PROPOSER_PREFERENCES = "EXECUTION_PAYLOAD_BID_ERROR_NO_MATCHING_PROPOSER_PREFERENCES",
|
|
22
22
|
PROPOSER_PREFERENCES_FEE_RECIPIENT_MISMATCH = "EXECUTION_PAYLOAD_BID_ERROR_PROPOSER_PREFERENCES_FEE_RECIPIENT_MISMATCH",
|
|
23
23
|
PROPOSER_PREFERENCES_GAS_LIMIT_MISMATCH = "EXECUTION_PAYLOAD_BID_ERROR_PROPOSER_PREFERENCES_GAS_LIMIT_MISMATCH",
|
|
24
|
+
INCLUSION_LIST_BITS_NOT_INCLUSIVE = "EXECUTION_PAYLOAD_BID_ERROR_INCLUSION_LIST_BITS_NOT_INCLUSIVE",
|
|
25
|
+
BEFORE_INCLUSION_LIST_DEADLINE = "EXECUTION_PAYLOAD_BID_ERROR_BEFORE_INCLUSION_LIST_DEADLINE",
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export type ExecutionPayloadBidErrorType =
|
|
@@ -86,6 +88,16 @@ export type ExecutionPayloadBidErrorType =
|
|
|
86
88
|
bidFeeRecipient: string;
|
|
87
89
|
expectedFeeRecipient: string;
|
|
88
90
|
}
|
|
91
|
+
| {
|
|
92
|
+
code: ExecutionPayloadBidErrorCode.INCLUSION_LIST_BITS_NOT_INCLUSIVE;
|
|
93
|
+
builderIndex: BuilderIndex;
|
|
94
|
+
slot: Slot;
|
|
95
|
+
}
|
|
96
|
+
| {
|
|
97
|
+
code: ExecutionPayloadBidErrorCode.BEFORE_INCLUSION_LIST_DEADLINE;
|
|
98
|
+
builderIndex: BuilderIndex;
|
|
99
|
+
slot: Slot;
|
|
100
|
+
}
|
|
89
101
|
| {
|
|
90
102
|
code: ExecutionPayloadBidErrorCode.PROPOSER_PREFERENCES_GAS_LIMIT_MISMATCH;
|
|
91
103
|
builderIndex: BuilderIndex;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {Epoch, RootHex, Slot, ValidatorIndex} from "@lodestar/types";
|
|
2
|
+
import {GossipActionError} from "./gossipValidation.js";
|
|
3
|
+
|
|
4
|
+
export enum InclusionListErrorCode {
|
|
5
|
+
EMPTY_TRANSACTIONS = "INCLUSION_LIST_ERROR_EMPTY_TRANSACTIONS",
|
|
6
|
+
MAXIMUM_SIZE_EXCEEDED = "INCLUSION_LIST_ERROR_MAXIMUM_SIZE_EXCEEDED",
|
|
7
|
+
EMPTY_TRANSACTION = "INCLUSION_LIST_ERROR_EMPTY_TRANSACTION",
|
|
8
|
+
INVALID_SLOT = "INCLUSION_LIST_ERROR_INVALID_SLOT",
|
|
9
|
+
MORE_THAN_TWO = "INCLUSION_LIST_ERROR_MORE_THAN_TWO",
|
|
10
|
+
VALIDATOR_NOT_IN_COMMITTEE = "INCLUSION_LIST_ERROR_VALIDATOR_NOT_IN_COMMITTEE",
|
|
11
|
+
UNKNOWN_DEPENDENT_ROOT = "INCLUSION_LIST_ERROR_UNKNOWN_DEPENDENT_ROOT",
|
|
12
|
+
INVALID_DEPENDENT_ROOT_SLOT = "INCLUSION_LIST_ERROR_INVALID_DEPENDENT_ROOT_SLOT",
|
|
13
|
+
INVALID_DEPENDENT_ROOT = "INCLUSION_LIST_ERROR_INVALID_DEPENDENT_ROOT",
|
|
14
|
+
MISSING_SHUFFLING = "INCLUSION_LIST_ERROR_MISSING_SHUFFLING",
|
|
15
|
+
INVALID_SIGNATURE = "INCLUSION_LIST_ERROR_INVALID_SIGNATURE",
|
|
16
|
+
PRE_HEZE_SLOT = "INCLUSION_LIST_ERROR_PRE_HEZE_SLOT",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type InclusionListErrorType =
|
|
20
|
+
| {code: InclusionListErrorCode.EMPTY_TRANSACTIONS}
|
|
21
|
+
| {code: InclusionListErrorCode.MAXIMUM_SIZE_EXCEEDED; totalBytes: number; maxBytes: number}
|
|
22
|
+
| {code: InclusionListErrorCode.EMPTY_TRANSACTION; transactionIndex: number}
|
|
23
|
+
| {code: InclusionListErrorCode.INVALID_SLOT; inclusionListSlot: Slot; currentSlot: Slot}
|
|
24
|
+
| {code: InclusionListErrorCode.MORE_THAN_TWO; validatorIndex: ValidatorIndex}
|
|
25
|
+
| {code: InclusionListErrorCode.VALIDATOR_NOT_IN_COMMITTEE; validatorIndex: ValidatorIndex}
|
|
26
|
+
| {code: InclusionListErrorCode.UNKNOWN_DEPENDENT_ROOT; dependentRoot: RootHex}
|
|
27
|
+
| {
|
|
28
|
+
code: InclusionListErrorCode.INVALID_DEPENDENT_ROOT_SLOT;
|
|
29
|
+
dependentRoot: RootHex;
|
|
30
|
+
dependentSlot: Slot;
|
|
31
|
+
maxSlot: Slot;
|
|
32
|
+
}
|
|
33
|
+
| {code: InclusionListErrorCode.INVALID_DEPENDENT_ROOT; dependentRoot: RootHex; epoch: Epoch}
|
|
34
|
+
| {code: InclusionListErrorCode.MISSING_SHUFFLING; dependentRoot: RootHex; epoch: Epoch}
|
|
35
|
+
| {code: InclusionListErrorCode.INVALID_SIGNATURE}
|
|
36
|
+
| {code: InclusionListErrorCode.PRE_HEZE_SLOT; inclusionListSlot: Slot};
|
|
37
|
+
|
|
38
|
+
export class InclusionListError extends GossipActionError<InclusionListErrorType> {}
|
|
@@ -8,6 +8,7 @@ export * from "./envelopeReconstructionError.js";
|
|
|
8
8
|
export * from "./executionPayloadBid.js";
|
|
9
9
|
export * from "./executionPayloadEnvelope.js";
|
|
10
10
|
export * from "./gossipValidation.js";
|
|
11
|
+
export * from "./inclusionList.js";
|
|
11
12
|
export * from "./payloadAttestation.js";
|
|
12
13
|
export * from "./proposerPreferences.js";
|
|
13
14
|
export * from "./proposerSlashingError.js";
|
package/src/chain/interface.ts
CHANGED
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
AttestationPool,
|
|
50
50
|
DeferredVoluntaryExitPool,
|
|
51
51
|
ExecutionPayloadBidPool,
|
|
52
|
+
InclusionListStore,
|
|
52
53
|
OpPool,
|
|
53
54
|
PayloadAttestationPool,
|
|
54
55
|
ProposerPreferencesPool,
|
|
@@ -131,6 +132,7 @@ export interface IBeaconChain {
|
|
|
131
132
|
readonly executionPayloadBidPool: ExecutionPayloadBidPool;
|
|
132
133
|
readonly payloadAttestationPool: PayloadAttestationPool;
|
|
133
134
|
readonly proposerPreferencesPool: ProposerPreferencesPool;
|
|
135
|
+
readonly inclusionListStore: InclusionListStore;
|
|
134
136
|
readonly opPool: OpPool;
|
|
135
137
|
readonly deferredVoluntaryExitPool: DeferredVoluntaryExitPool;
|
|
136
138
|
|
|
@@ -331,6 +333,7 @@ export type SSZObjectType =
|
|
|
331
333
|
| "syncCommittee"
|
|
332
334
|
| "contributionAndProof";
|
|
333
335
|
|
|
334
|
-
export type CommonBlockBody = phase0.BeaconBlockBody &
|
|
336
|
+
export type CommonBlockBody = Omit<phase0.BeaconBlockBody, "eth1Data" | "deposits"> &
|
|
337
|
+
Partial<Pick<phase0.BeaconBlockBody, "eth1Data" | "deposits">> &
|
|
335
338
|
Pick<capella.BeaconBlockBody, "blsToExecutionChanges"> &
|
|
336
339
|
Pick<altair.BeaconBlockBody, "syncAggregate">;
|