@lodestar/beacon-node 1.50.0 → 1.51.0-dev.7d2ef8139c
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/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +31 -17
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.d.ts +0 -2
- package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.js +4 -5
- 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.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +7 -4
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +3 -2
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/interface.d.ts +1 -1
- package/lib/chain/interface.d.ts.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.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +8 -6
- package/lib/chain/produceBlock/produceBlockBody.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/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/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/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/restTransport.d.ts +3 -1
- package/lib/execution/engine/restTransport.d.ts.map +1 -1
- package/lib/execution/engine/restTransport.js +33 -21
- package/lib/execution/engine/restTransport.js.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.map +1 -1
- package/lib/execution/engine/types.js +12 -11
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +4 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +7 -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/topic.d.ts +0 -14
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/processor/index.js +3 -3
- package/lib/network/processor/index.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/rateLimit.js +2 -2
- package/lib/network/reqresp/rateLimit.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 +3 -2
- 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 +15 -15
- package/src/api/impl/beacon/blocks/index.ts +10 -3
- package/src/api/impl/validator/index.ts +41 -19
- package/src/chain/ColumnReconstructionTracker.ts +4 -6
- 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 +8 -4
- package/src/chain/chain.ts +3 -2
- package/src/chain/interface.ts +2 -1
- package/src/chain/prepareNextSlot.ts +7 -3
- package/src/chain/produceBlock/computeNewStateRoot.ts +9 -2
- package/src/chain/produceBlock/produceBlockBody.ts +10 -5
- 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/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/engine/index.ts +2 -1
- package/src/execution/engine/jsonRpcHttpClient.ts +12 -5
- package/src/execution/engine/restTransport.ts +53 -22
- package/src/execution/engine/transportMetrics.ts +2 -1
- package/src/execution/engine/types.ts +13 -11
- package/src/metrics/metrics/lodestar.ts +7 -1
- package/src/network/gossip/gossipsub.ts +3 -1
- package/src/network/processor/index.ts +3 -3
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +4 -10
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +3 -3
- package/src/network/reqresp/rateLimit.ts +2 -2
- package/src/network/subnets/attnetsService.ts +8 -3
- package/src/node/notifier.ts +14 -13
- package/src/sync/unknownBlock.ts +3 -2
- package/src/util/clock.ts +3 -4
- package/src/util/sszBytes.ts +25 -12
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/ChainSafe/lodestar/issues"
|
|
13
13
|
},
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.51.0-dev.7d2ef8139c",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -127,17 +127,17 @@
|
|
|
127
127
|
"@libp2p/prometheus-metrics": "^5.0.28",
|
|
128
128
|
"@libp2p/tcp": "^11.0.27",
|
|
129
129
|
"@libp2p/utils": "^7.4.0",
|
|
130
|
-
"@lodestar/api": "^1.
|
|
131
|
-
"@lodestar/config": "^1.
|
|
132
|
-
"@lodestar/db": "^1.
|
|
133
|
-
"@lodestar/fork-choice": "^1.
|
|
134
|
-
"@lodestar/logger": "^1.
|
|
135
|
-
"@lodestar/params": "^1.
|
|
136
|
-
"@lodestar/reqresp": "^1.
|
|
137
|
-
"@lodestar/state-transition": "^1.
|
|
138
|
-
"@lodestar/types": "^1.
|
|
139
|
-
"@lodestar/utils": "^1.
|
|
140
|
-
"@lodestar/validator": "^1.
|
|
130
|
+
"@lodestar/api": "^1.51.0-dev.7d2ef8139c",
|
|
131
|
+
"@lodestar/config": "^1.51.0-dev.7d2ef8139c",
|
|
132
|
+
"@lodestar/db": "^1.51.0-dev.7d2ef8139c",
|
|
133
|
+
"@lodestar/fork-choice": "^1.51.0-dev.7d2ef8139c",
|
|
134
|
+
"@lodestar/logger": "^1.51.0-dev.7d2ef8139c",
|
|
135
|
+
"@lodestar/params": "^1.51.0-dev.7d2ef8139c",
|
|
136
|
+
"@lodestar/reqresp": "^1.51.0-dev.7d2ef8139c",
|
|
137
|
+
"@lodestar/state-transition": "^1.51.0-dev.7d2ef8139c",
|
|
138
|
+
"@lodestar/types": "^1.51.0-dev.7d2ef8139c",
|
|
139
|
+
"@lodestar/utils": "^1.51.0-dev.7d2ef8139c",
|
|
140
|
+
"@lodestar/validator": "^1.51.0-dev.7d2ef8139c",
|
|
141
141
|
"@multiformats/multiaddr": "^13.0.1",
|
|
142
142
|
"datastore-core": "^12.0.1",
|
|
143
143
|
"datastore-level": "^13.0.1",
|
|
@@ -159,8 +159,8 @@
|
|
|
159
159
|
"@ethereumjs/rlp": "^4.0.1",
|
|
160
160
|
"@libp2p/interface-internal": "^3.1.12",
|
|
161
161
|
"@libp2p/logger": "^6.2.13",
|
|
162
|
-
"@lodestar/spec-test-util": "^1.
|
|
163
|
-
"@lodestar/test-utils": "^1.
|
|
162
|
+
"@lodestar/spec-test-util": "^1.51.0-dev.7d2ef8139c",
|
|
163
|
+
"@lodestar/test-utils": "^1.51.0-dev.7d2ef8139c",
|
|
164
164
|
"@types/js-yaml": "^4.0.5",
|
|
165
165
|
"@types/qs": "^6.9.7",
|
|
166
166
|
"@types/tmp": "^0.2.3",
|
|
@@ -175,5 +175,5 @@
|
|
|
175
175
|
"beacon",
|
|
176
176
|
"blockchain"
|
|
177
177
|
],
|
|
178
|
-
"gitHead": "
|
|
178
|
+
"gitHead": "247d6fb7a7be86a876b60f2d48aa962ddd36ead0"
|
|
179
179
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
ForkPostBellatrix,
|
|
7
7
|
ForkPostFulu,
|
|
8
8
|
ForkPostGloas,
|
|
9
|
+
ForkPreBellatrix,
|
|
9
10
|
ForkPreGloas,
|
|
10
11
|
NUMBER_OF_COLUMNS,
|
|
11
12
|
SLOTS_PER_HISTORICAL_ROOT,
|
|
@@ -674,7 +675,7 @@ export function getBeaconBlockApi({
|
|
|
674
675
|
return {
|
|
675
676
|
data: isForkPostBellatrix(fork)
|
|
676
677
|
? signedBeaconBlockToBlinded(config, block as SignedBeaconBlock<ForkPostBellatrix & ForkPreGloas>)
|
|
677
|
-
: block,
|
|
678
|
+
: (block as SignedBeaconBlock<ForkPreBellatrix>),
|
|
678
679
|
meta: {
|
|
679
680
|
executionOptimistic,
|
|
680
681
|
finalized,
|
|
@@ -692,8 +693,14 @@ export function getBeaconBlockApi({
|
|
|
692
693
|
},
|
|
693
694
|
|
|
694
695
|
async getBlockRoot({blockId}) {
|
|
695
|
-
// Fast path: From head state already available in memory get historical blockRoot
|
|
696
|
-
|
|
696
|
+
// Fast path: From head state already available in memory get historical blockRoot.
|
|
697
|
+
// A 0x id is a root. parseInt() accepts that prefix as hex and can return a slot.
|
|
698
|
+
const slot =
|
|
699
|
+
typeof blockId === "number"
|
|
700
|
+
? blockId
|
|
701
|
+
: blockId.toLowerCase().startsWith("0x")
|
|
702
|
+
? Number.NaN
|
|
703
|
+
: parseInt(blockId, 10);
|
|
697
704
|
if (!Number.isNaN(slot)) {
|
|
698
705
|
const head = chain.forkChoice.getHead();
|
|
699
706
|
|
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
BUILDER_INDEX_SELF_BUILD,
|
|
6
6
|
ForkName,
|
|
7
7
|
ForkPostBellatrix,
|
|
8
|
+
ForkPostDeneb,
|
|
9
|
+
ForkPreDeneb,
|
|
8
10
|
ForkPreGloas,
|
|
9
11
|
ForkSeq,
|
|
10
12
|
GENESIS_SLOT,
|
|
@@ -111,14 +113,13 @@ import {
|
|
|
111
113
|
* Post this time, race execution and builder to pick whatever resolves first.
|
|
112
114
|
*
|
|
113
115
|
* Empirically the builder block resolves in ~1 second, and execution block resolves in <500 ms.
|
|
114
|
-
* A cutoff of 2 seconds gives enough time and if there are unexpected delays
|
|
115
|
-
* in time as proposals
|
|
116
|
+
* A cutoff of 1667 BPS (2 seconds for 12s slots) gives enough time and if there are unexpected delays
|
|
117
|
+
* it ensures we publish in time as proposals after the attestation deadline will likely be orphaned
|
|
118
|
+
* due to proposer boost reorg.
|
|
116
119
|
*
|
|
117
120
|
* TODO GLOAS: re-evaluate cutoff timing due to attestation deadline changes in gloas
|
|
118
121
|
*/
|
|
119
|
-
const
|
|
120
|
-
/** Overall timeout for execution and block production apis */
|
|
121
|
-
const BLOCK_PRODUCTION_RACE_TIMEOUT_MS = 12_000;
|
|
122
|
+
const BLOCK_PRODUCTION_RACE_CUTOFF_BPS = 1667;
|
|
122
123
|
/** Rejection message of the bid block branch when there is no viable bid to commit to */
|
|
123
124
|
const NO_BID_AVAILABLE = "No builder bid available";
|
|
124
125
|
|
|
@@ -167,8 +168,8 @@ function compareBidCandidates(a: BidCandidate, b: BidCandidate): number {
|
|
|
167
168
|
}
|
|
168
169
|
|
|
169
170
|
type ProduceBlockContentsRes = {executionPayloadValue: Wei; consensusBlockValue: Wei} & {
|
|
170
|
-
data: BlockContents
|
|
171
|
-
version:
|
|
171
|
+
data: BlockContents<ForkPreGloas>;
|
|
172
|
+
version: ForkPreGloas;
|
|
172
173
|
};
|
|
173
174
|
type ProduceBlindedBlockRes = {executionPayloadValue: Wei; consensusBlockValue: Wei} & {
|
|
174
175
|
data: BlindedBeaconBlock;
|
|
@@ -301,8 +302,8 @@ export function getValidatorApi(
|
|
|
301
302
|
*/
|
|
302
303
|
function msToNextEpoch(): number {
|
|
303
304
|
const nextEpoch = chain.clock.currentEpoch + 1;
|
|
304
|
-
const
|
|
305
|
-
const nextEpochStartSec = chain.genesisTime
|
|
305
|
+
const nextEpochSlot = computeStartSlotAtEpoch(nextEpoch);
|
|
306
|
+
const nextEpochStartSec = computeTimeAtSlot(config, nextEpochSlot, chain.genesisTime);
|
|
306
307
|
return nextEpochStartSec * 1000 - Date.now();
|
|
307
308
|
}
|
|
308
309
|
|
|
@@ -511,6 +512,10 @@ export function getValidatorApi(
|
|
|
511
512
|
parentBlock: ProtoBlock;
|
|
512
513
|
}
|
|
513
514
|
): Promise<ProduceBlockContentsRes & {shouldOverrideBuilder?: boolean}> {
|
|
515
|
+
const version = config.getForkName(slot);
|
|
516
|
+
if (isForkPostGloas(version)) {
|
|
517
|
+
throw Error(`produceEngineBlockContents called for post-gloas fork=${version}`);
|
|
518
|
+
}
|
|
514
519
|
const source = ProducedBlockSource.engine;
|
|
515
520
|
metrics?.blockProductionRequests.inc({source});
|
|
516
521
|
|
|
@@ -525,7 +530,6 @@ export function getValidatorApi(
|
|
|
525
530
|
feeRecipient,
|
|
526
531
|
commonBlockBodyPromise,
|
|
527
532
|
});
|
|
528
|
-
const version = config.getForkName(block.slot);
|
|
529
533
|
if (strictFeeRecipientCheck && feeRecipient && isForkPostBellatrix(version)) {
|
|
530
534
|
const blockFeeRecipient = toHex((block as bellatrix.BeaconBlock).body.executionPayload.feeRecipient);
|
|
531
535
|
if (blockFeeRecipient !== feeRecipient) {
|
|
@@ -563,7 +567,7 @@ export function getValidatorApi(
|
|
|
563
567
|
|
|
564
568
|
return {
|
|
565
569
|
data: {
|
|
566
|
-
block
|
|
570
|
+
block: block as BeaconBlock<ForkPostDeneb & ForkPreGloas>,
|
|
567
571
|
blobs: blobsBundle.blobs,
|
|
568
572
|
kzgProofs: blobsBundle.proofs,
|
|
569
573
|
},
|
|
@@ -574,7 +578,13 @@ export function getValidatorApi(
|
|
|
574
578
|
};
|
|
575
579
|
}
|
|
576
580
|
|
|
577
|
-
return {
|
|
581
|
+
return {
|
|
582
|
+
data: {block: block as BeaconBlock<ForkPreDeneb>},
|
|
583
|
+
version,
|
|
584
|
+
executionPayloadValue,
|
|
585
|
+
consensusBlockValue,
|
|
586
|
+
shouldOverrideBuilder,
|
|
587
|
+
};
|
|
578
588
|
} finally {
|
|
579
589
|
if (timer) timer({source});
|
|
580
590
|
}
|
|
@@ -680,17 +690,21 @@ export function getValidatorApi(
|
|
|
680
690
|
});
|
|
681
691
|
|
|
682
692
|
// Calculate cutoff time based on start of the slot
|
|
683
|
-
const cutoffMs = Math.max(
|
|
693
|
+
const cutoffMs = Math.max(
|
|
694
|
+
0,
|
|
695
|
+
config.getSlotComponentDurationMs(fork, BLOCK_PRODUCTION_RACE_CUTOFF_BPS) - chain.clock.msFromSlot(slot)
|
|
696
|
+
);
|
|
697
|
+
const blockProductionTimeoutMs = config.getSlotDurationMs(fork);
|
|
684
698
|
|
|
685
699
|
logger.verbose("Block production race (builder vs execution) starting", {
|
|
686
700
|
...loggerContext,
|
|
687
701
|
cutoffMs,
|
|
688
|
-
timeoutMs:
|
|
702
|
+
timeoutMs: blockProductionTimeoutMs,
|
|
689
703
|
});
|
|
690
704
|
|
|
691
705
|
const blockProductionRacePromise = resolveOrRacePromises([builderPromise, enginePromise], {
|
|
692
706
|
resolveTimeoutMs: cutoffMs,
|
|
693
|
-
raceTimeoutMs:
|
|
707
|
+
raceTimeoutMs: blockProductionTimeoutMs,
|
|
694
708
|
signal: controller.signal,
|
|
695
709
|
});
|
|
696
710
|
|
|
@@ -878,6 +892,10 @@ export function getValidatorApi(
|
|
|
878
892
|
|
|
879
893
|
return {
|
|
880
894
|
async produceBlockV3({slot, randaoReveal, graffiti, skipRandaoVerification, builderBoostFactor, ...opts}) {
|
|
895
|
+
const forkName = config.getForkName(slot);
|
|
896
|
+
if (isForkPostGloas(forkName)) {
|
|
897
|
+
throw new ApiError(400, `produceBlockV3 not supported for post-gloas fork=${forkName}, use produceBlockV4`);
|
|
898
|
+
}
|
|
881
899
|
const {data, ...meta} = await produceEngineOrBuilderBlock(
|
|
882
900
|
slot,
|
|
883
901
|
randaoReveal,
|
|
@@ -1095,7 +1113,10 @@ export function getValidatorApi(
|
|
|
1095
1113
|
|
|
1096
1114
|
// Calculate cutoff time based on start of the slot, ensures a slow local payload build does
|
|
1097
1115
|
// not delay the proposal when a builder bid block is available (and vice versa)
|
|
1098
|
-
const cutoffMs = Math.max(
|
|
1116
|
+
const cutoffMs = Math.max(
|
|
1117
|
+
0,
|
|
1118
|
+
config.getSlotComponentDurationMs(fork, BLOCK_PRODUCTION_RACE_CUTOFF_BPS) - chain.clock.msFromSlot(slot)
|
|
1119
|
+
);
|
|
1099
1120
|
|
|
1100
1121
|
// use abort controller to stop waiting for the bid block if the engine block will be selected
|
|
1101
1122
|
const controller = new AbortController();
|
|
@@ -1123,7 +1144,7 @@ export function getValidatorApi(
|
|
|
1123
1144
|
|
|
1124
1145
|
const [engineResult, bidBlockResult] = await resolveOrRacePromises([enginePromise, bidBlockPromise], {
|
|
1125
1146
|
resolveTimeoutMs: cutoffMs,
|
|
1126
|
-
raceTimeoutMs:
|
|
1147
|
+
raceTimeoutMs: config.getSlotDurationMs(fork),
|
|
1127
1148
|
signal: controller.signal,
|
|
1128
1149
|
});
|
|
1129
1150
|
|
|
@@ -1417,7 +1438,7 @@ export function getValidatorApi(
|
|
|
1417
1438
|
// Spec: set payload_present only if the envelope was seen before get_payload_due_ms()
|
|
1418
1439
|
// into the slot. Use the envelope's own arrival time (getPayloadEnvelopeSource), not
|
|
1419
1440
|
// the input's creation time.
|
|
1420
|
-
const payloadDueSec = config.getPayloadDueMs() / 1000;
|
|
1441
|
+
const payloadDueSec = config.getPayloadDueMs(fork) / 1000;
|
|
1421
1442
|
const payloadSeenSec =
|
|
1422
1443
|
payloadInput?.hasPayloadEnvelope() === true
|
|
1423
1444
|
? chain.clock.secFromSlot(slot, payloadInput.getPayloadEnvelopeSource().seenTimestampSec)
|
|
@@ -1494,8 +1515,9 @@ export function getValidatorApi(
|
|
|
1494
1515
|
const currentEpoch = currentEpochWithDisparity();
|
|
1495
1516
|
const nextEpoch = currentEpoch + 1;
|
|
1496
1517
|
const startSlot = computeStartSlotAtEpoch(epoch);
|
|
1518
|
+
const prepareFork = config.getForkName(computeStartSlotAtEpoch(nextEpoch) - 1);
|
|
1497
1519
|
const prepareNextSlotLookAheadMs =
|
|
1498
|
-
config.
|
|
1520
|
+
config.getSlotDurationMs(prepareFork) - config.getSlotComponentDurationMs(prepareFork, PREPARE_NEXT_SLOT_BPS);
|
|
1499
1521
|
const toNextEpochMs = msToNextEpoch();
|
|
1500
1522
|
const nearNextEpoch = toNextEpochMs < prepareNextSlotLookAheadMs;
|
|
1501
1523
|
// Post-Fulu the proposer lookahead is deterministic and known a full epoch ahead, so
|
|
@@ -42,16 +42,11 @@ export class ColumnReconstructionTracker {
|
|
|
42
42
|
/** Track if a reconstruction attempt is in-flight */
|
|
43
43
|
running = false;
|
|
44
44
|
|
|
45
|
-
private readonly minDelayMs: number;
|
|
46
|
-
private readonly maxDelayMs: number;
|
|
47
|
-
|
|
48
45
|
constructor(init: ColumnReconstructionTrackerInit) {
|
|
49
46
|
this.logger = init.logger;
|
|
50
47
|
this.emitter = init.emitter;
|
|
51
48
|
this.metrics = init.metrics;
|
|
52
49
|
this.config = init.config;
|
|
53
|
-
this.minDelayMs = this.config.getSlotComponentDurationMs(RECONSTRUCTION_DELAY_MIN_BPS);
|
|
54
|
-
this.maxDelayMs = this.config.getSlotComponentDurationMs(RECONSTRUCTION_DELAY_MAX_BPS);
|
|
55
50
|
}
|
|
56
51
|
|
|
57
52
|
triggerColumnReconstruction(input: BlockInputColumns | PayloadEnvelopeInput): void {
|
|
@@ -67,7 +62,10 @@ export class ColumnReconstructionTracker {
|
|
|
67
62
|
// just that it has been triggered for this block root.
|
|
68
63
|
this.running = true;
|
|
69
64
|
this.lastBlockRootHex = input.blockRootHex;
|
|
70
|
-
const
|
|
65
|
+
const fork = this.config.getForkName(input.slot);
|
|
66
|
+
const minDelayMs = this.config.getSlotComponentDurationMs(fork, RECONSTRUCTION_DELAY_MIN_BPS);
|
|
67
|
+
const maxDelayMs = this.config.getSlotComponentDurationMs(fork, RECONSTRUCTION_DELAY_MAX_BPS);
|
|
68
|
+
const delay = minDelayMs + Math.random() * (maxDelayMs - minDelayMs);
|
|
71
69
|
sleep(delay)
|
|
72
70
|
.then(() => {
|
|
73
71
|
const logCtx = {slot: input.slot, root: input.blockRootHex};
|
|
@@ -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) {
|
|
@@ -586,7 +587,7 @@ export async function importBlock(
|
|
|
586
587
|
this.validatorMonitor?.registerSyncAggregateInBlock(
|
|
587
588
|
blockEpoch,
|
|
588
589
|
(block as altair.SignedBeaconBlock).message.body.syncAggregate,
|
|
589
|
-
fullyVerifiedBlock.postState.
|
|
590
|
+
fullyVerifiedBlock.postState.currentSyncCommitteeValidatorIndices
|
|
590
591
|
);
|
|
591
592
|
}
|
|
592
593
|
|
|
@@ -600,7 +601,10 @@ export async function importBlock(
|
|
|
600
601
|
}
|
|
601
602
|
}
|
|
602
603
|
|
|
603
|
-
const
|
|
604
|
+
const reprocessGuardSec =
|
|
605
|
+
this.config.getSlotComponentDurationMs(this.config.getForkName(blockSlot), REPROCESS_MIN_TIME_TO_NEXT_SLOT_BPS) /
|
|
606
|
+
1000;
|
|
607
|
+
const advancedSlot = this.clock.slotWithFutureTolerance(reprocessGuardSec);
|
|
604
608
|
|
|
605
609
|
// Gossip blocks need to be imported as soon as possible, waiting attestations could be processed
|
|
606
610
|
// in the next event loop. See https://github.com/ChainSafe/lodestar/issues/4789
|
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";
|
|
@@ -1841,7 +1841,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1841
1841
|
const metrics = this.metrics;
|
|
1842
1842
|
if (metrics && (slot + 1) % SLOTS_PER_EPOCH === 0) {
|
|
1843
1843
|
// On the last slot of the epoch
|
|
1844
|
-
|
|
1844
|
+
const fork = this.config.getForkName(slot);
|
|
1845
|
+
sleep(this.config.getSlotComponentDurationMs(fork, HALF_SLOT_BPS))
|
|
1845
1846
|
.then(() => this.validatorMonitor?.onceEveryEndOfEpoch(this.getHeadState()))
|
|
1846
1847
|
.catch((e) => {
|
|
1847
1848
|
if (!isErrorAborted(e)) this.logger.error("Error on validator monitor onceEveryEndOfEpoch", {slot}, e);
|
package/src/chain/interface.ts
CHANGED
|
@@ -331,6 +331,7 @@ export type SSZObjectType =
|
|
|
331
331
|
| "syncCommittee"
|
|
332
332
|
| "contributionAndProof";
|
|
333
333
|
|
|
334
|
-
export type CommonBlockBody = phase0.BeaconBlockBody &
|
|
334
|
+
export type CommonBlockBody = Omit<phase0.BeaconBlockBody, "eth1Data" | "deposits"> &
|
|
335
|
+
Partial<Pick<phase0.BeaconBlockBody, "eth1Data" | "deposits">> &
|
|
335
336
|
Pick<capella.BeaconBlockBody, "blsToExecutionChanges"> &
|
|
336
337
|
Pick<altair.BeaconBlockBody, "syncAggregate">;
|
|
@@ -96,6 +96,7 @@ export class PrepareNextSlotScheduler {
|
|
|
96
96
|
const nextEpoch = computeEpochAtSlot(clockSlot) + 1;
|
|
97
97
|
const isEpochTransition = prepareEpoch === nextEpoch;
|
|
98
98
|
const fork = this.config.getForkName(prepareSlot);
|
|
99
|
+
const currentFork = this.config.getForkName(clockSlot);
|
|
99
100
|
|
|
100
101
|
// Early return if we are pre-genesis
|
|
101
102
|
// or we are pre-bellatrix and this is not an epoch transition
|
|
@@ -106,7 +107,7 @@ export class PrepareNextSlotScheduler {
|
|
|
106
107
|
try {
|
|
107
108
|
// At PREPARE_NEXT_SLOT_BPS (~67%) of the current slot we prepare payload for the next slot
|
|
108
109
|
// or precompute epoch transition
|
|
109
|
-
await sleep(this.config.getSlotComponentDurationMs(PREPARE_NEXT_SLOT_BPS), this.signal);
|
|
110
|
+
await sleep(this.config.getSlotComponentDurationMs(currentFork, PREPARE_NEXT_SLOT_BPS), this.signal);
|
|
110
111
|
|
|
111
112
|
// calling updateHead() here before we produce a block to reduce reorg possibility
|
|
112
113
|
const headBlock = this.chain.recomputeForkChoiceHead(ForkchoiceCaller.prepareNextSlot);
|
|
@@ -369,7 +370,7 @@ export class PrepareNextSlotScheduler {
|
|
|
369
370
|
// skip when we're the next-slot proposer — don't compete with block-production prep.
|
|
370
371
|
feeRecipient === undefined
|
|
371
372
|
) {
|
|
372
|
-
const maxDurationMs = this.config.getSlotComponentDurationMs(BUILDER_PREVERIFY_LIMIT_BPS);
|
|
373
|
+
const maxDurationMs = this.config.getSlotComponentDurationMs(currentFork, BUILDER_PREVERIFY_LIMIT_BPS);
|
|
373
374
|
const preVerifyTimer = this.metrics?.builderDepositPreVerify.duration.startTimer();
|
|
374
375
|
const result = headState.preVerifyBuilderDepositsPreGloas(MAX_BUILDER_DEPOSITS_PER_SLOT, maxDurationMs);
|
|
375
376
|
preVerifyTimer?.();
|
|
@@ -423,7 +424,10 @@ export class PrepareNextSlotScheduler {
|
|
|
423
424
|
* later in the slot, connecting at PREPARE_NEXT_SLOT_BPS would go cold before bids are requested.
|
|
424
425
|
*/
|
|
425
426
|
private checkBuilderStatusBeforeSlot(prepareSlot: Slot): void {
|
|
426
|
-
const msBeforeSlot = this.config.getSlotComponentDurationMs(
|
|
427
|
+
const msBeforeSlot = this.config.getSlotComponentDurationMs(
|
|
428
|
+
this.config.getForkName(prepareSlot - 1),
|
|
429
|
+
BUILDER_STATUS_CHECK_BEFORE_SLOT_BPS
|
|
430
|
+
);
|
|
427
431
|
const msUntilCheck = -this.chain.clock.msFromSlot(prepareSlot) - msBeforeSlot;
|
|
428
432
|
sleep(Math.max(0, msUntilCheck), this.signal)
|
|
429
433
|
.then(() => this.chain.builderApiClient.checkStatus())
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import {EMPTY_SIGNATURE, IBeaconStateView, StateHashTreeRootSource} from "@lodestar/state-transition";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
BeaconBlock,
|
|
4
|
+
BlindedBeaconBlock,
|
|
5
|
+
Gwei,
|
|
6
|
+
Root,
|
|
7
|
+
SignedBeaconBlock,
|
|
8
|
+
SignedBlindedBeaconBlock,
|
|
9
|
+
} from "@lodestar/types";
|
|
3
10
|
import {Metrics} from "../../metrics/index.js";
|
|
4
11
|
|
|
5
12
|
/**
|
|
@@ -13,7 +20,7 @@ export function computeNewStateRoot(
|
|
|
13
20
|
block: BeaconBlock | BlindedBeaconBlock
|
|
14
21
|
): {newStateRoot: Root; proposerReward: Gwei; postState: IBeaconStateView} {
|
|
15
22
|
// Set signature to zero to re-use stateTransition() function which requires the SignedBeaconBlock type
|
|
16
|
-
const signedBlock = {message: block, signature: EMPTY_SIGNATURE};
|
|
23
|
+
const signedBlock = {message: block, signature: EMPTY_SIGNATURE} as SignedBeaconBlock | SignedBlindedBeaconBlock;
|
|
17
24
|
const {newStateRoot, proposerReward, postState, hashTreeRootTime} = state.computeNewStateRoot(
|
|
18
25
|
{block: signedBlock},
|
|
19
26
|
{metrics: metrics?.stateTransition}
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
isForkPostAltair,
|
|
21
21
|
isForkPostBellatrix,
|
|
22
22
|
isForkPostGloas,
|
|
23
|
+
isForkPostHeze,
|
|
23
24
|
} from "@lodestar/params";
|
|
24
25
|
import {
|
|
25
26
|
G2_POINT_AT_INFINITY,
|
|
@@ -684,12 +685,11 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
684
685
|
executionPayloadValue = BigInt(0);
|
|
685
686
|
}
|
|
686
687
|
|
|
687
|
-
const {graffiti, attestations,
|
|
688
|
+
const {graffiti, attestations, voluntaryExits, attesterSlashings, proposerSlashings} = blockBody;
|
|
688
689
|
|
|
689
690
|
Object.assign(logMeta, {
|
|
690
691
|
graffiti: fromGraffitiBytes(graffiti),
|
|
691
692
|
attestations: attestations.length,
|
|
692
|
-
deposits: deposits.length,
|
|
693
693
|
voluntaryExits: voluntaryExits.length,
|
|
694
694
|
attesterSlashings: attesterSlashings.length,
|
|
695
695
|
proposerSlashings: proposerSlashings.length,
|
|
@@ -1106,16 +1106,21 @@ export async function produceCommonBlockBody<T extends BlockType>(
|
|
|
1106
1106
|
});
|
|
1107
1107
|
|
|
1108
1108
|
// Live proposal production is supported from Fulu onward.
|
|
1109
|
-
|
|
1109
|
+
const commonBlockBody: CommonBlockBody = {
|
|
1110
1110
|
randaoReveal,
|
|
1111
1111
|
graffiti,
|
|
1112
|
-
eth1Data: currentState.eth1Data,
|
|
1113
1112
|
proposerSlashings: this.opts.disableProposerSlashings === true ? [] : proposerSlashings,
|
|
1114
1113
|
attesterSlashings,
|
|
1115
1114
|
attestations,
|
|
1116
|
-
deposits: [],
|
|
1117
1115
|
voluntaryExits,
|
|
1118
1116
|
blsToExecutionChanges,
|
|
1119
1117
|
syncAggregate,
|
|
1120
1118
|
};
|
|
1119
|
+
|
|
1120
|
+
if (!isForkPostHeze(fork)) {
|
|
1121
|
+
commonBlockBody.eth1Data = currentState.eth1Data;
|
|
1122
|
+
commonBlockBody.deposits = [];
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
return commonBlockBody;
|
|
1121
1126
|
}
|
package/src/chain/reprocess.ts
CHANGED
|
@@ -5,8 +5,9 @@ import {Metrics} from "../metrics/index.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* To prevent our node from having to reprocess while struggling to sync,
|
|
7
7
|
* we only want to reprocess attestations if block reaches our node before this time.
|
|
8
|
+
* Expressed in basis points of slot duration (1667 BPS = 2s for 12s slots).
|
|
8
9
|
*/
|
|
9
|
-
export const
|
|
10
|
+
export const REPROCESS_MIN_TIME_TO_NEXT_SLOT_BPS = 1667;
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Reprocess status for metrics
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
ForkName,
|
|
5
5
|
ForkPostFulu,
|
|
6
6
|
ForkPostGloas,
|
|
7
|
+
ForkPreDeneb,
|
|
7
8
|
ForkPreGloas,
|
|
8
9
|
SLOTS_PER_EPOCH,
|
|
9
10
|
isForkPostDeneb,
|
|
@@ -240,7 +241,7 @@ export class SeenBlockInput {
|
|
|
240
241
|
} else if (!isForkPostDeneb(forkName)) {
|
|
241
242
|
// Pre-deneb
|
|
242
243
|
blockInput = BlockInputPreData.createFromBlock({
|
|
243
|
-
block
|
|
244
|
+
block: block as SignedBeaconBlock<ForkPreDeneb>,
|
|
244
245
|
blockRootHex,
|
|
245
246
|
daOutOfRange,
|
|
246
247
|
forkName,
|
|
@@ -592,7 +592,10 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
592
592
|
}
|
|
593
593
|
|
|
594
594
|
const blockSlot = state.slot;
|
|
595
|
-
const processCPStatesTimeMs = this.config.getSlotComponentDurationMs(
|
|
595
|
+
const processCPStatesTimeMs = this.config.getSlotComponentDurationMs(
|
|
596
|
+
this.config.getForkName(blockSlot),
|
|
597
|
+
PROCESS_CHECKPOINT_STATES_BPS
|
|
598
|
+
);
|
|
596
599
|
// we always have clock in production, fallback value is only for test
|
|
597
600
|
const msFromSlot = this.clock?.msFromSlot(blockSlot) ?? processCPStatesTimeMs;
|
|
598
601
|
const msToProcessCPStates = processCPStatesTimeMs - msFromSlot;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {MIN_ATTESTATION_INCLUSION_DELAY, SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
|
|
2
|
+
import {ForkName, MIN_ATTESTATION_INCLUSION_DELAY, SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
|
|
3
3
|
import {
|
|
4
4
|
IBeaconStateView,
|
|
5
5
|
ParticipationFlags,
|
|
@@ -776,13 +776,14 @@ export function createValidatorMonitor(
|
|
|
776
776
|
|
|
777
777
|
if (isStatePostAltair(headState)) {
|
|
778
778
|
const prevEpochStartSlot = computeStartSlotAtEpoch(prevEpoch);
|
|
779
|
+
const prevEpochFork = config.getForkName(prevEpochStartSlot);
|
|
779
780
|
const prevEpochTargetRoot = toRootHex(headState.getBlockRootAtSlot(prevEpochStartSlot));
|
|
780
781
|
|
|
781
782
|
// Check attestation performance
|
|
782
783
|
for (const [index, validator] of validators.entries()) {
|
|
783
784
|
const flags = parseParticipationFlags(headState.getPreviousEpochParticipation(index));
|
|
784
785
|
const attestationSummary = validator.attestations.get(prevEpoch)?.get(prevEpochTargetRoot);
|
|
785
|
-
const summary = renderAttestationSummary(config, rootCache, attestationSummary, flags);
|
|
786
|
+
const summary = renderAttestationSummary(config, prevEpochFork, rootCache, attestationSummary, flags);
|
|
786
787
|
validatorMonitorMetrics?.prevEpochAttestationSummary.inc({summary});
|
|
787
788
|
log("Previous epoch attestation", {
|
|
788
789
|
validator: index,
|
|
@@ -941,6 +942,7 @@ export function createValidatorMonitor(
|
|
|
941
942
|
*/
|
|
942
943
|
function renderAttestationSummary(
|
|
943
944
|
config: ChainForkConfig,
|
|
945
|
+
fork: ForkName,
|
|
944
946
|
rootCache: RootHexCache,
|
|
945
947
|
summary: AttestationSummary | undefined,
|
|
946
948
|
flags: ParticipationFlags
|
|
@@ -1043,7 +1045,7 @@ function renderAttestationSummary(
|
|
|
1043
1045
|
}
|
|
1044
1046
|
|
|
1045
1047
|
const submittedLate =
|
|
1046
|
-
summary.poolSubmitDelayMinSec > config.getSlotComponentDurationMs(LATE_ATTESTATION_SUBMISSION_BPS) / 1000;
|
|
1048
|
+
summary.poolSubmitDelayMinSec > config.getSlotComponentDurationMs(fork, LATE_ATTESTATION_SUBMISSION_BPS) / 1000;
|
|
1047
1049
|
|
|
1048
1050
|
const aggregateInclusion = summary.aggregateInclusionDelaysSec.length > 0;
|
|
1049
1051
|
|
|
@@ -1178,7 +1180,8 @@ function renderBlockProposalSummary(
|
|
|
1178
1180
|
|
|
1179
1181
|
if (
|
|
1180
1182
|
proposal.poolSubmitDelaySec !== null &&
|
|
1181
|
-
proposal.poolSubmitDelaySec >
|
|
1183
|
+
proposal.poolSubmitDelaySec >
|
|
1184
|
+
config.getSlotComponentDurationMs(config.getForkName(proposalSlot), LATE_BLOCK_SUBMISSION_BPS) / 1000
|
|
1182
1185
|
) {
|
|
1183
1186
|
out += "_late";
|
|
1184
1187
|
}
|
|
@@ -184,7 +184,7 @@ export class BlockArchiveRepository extends Repository<Slot, SignedBeaconBlock>
|
|
|
184
184
|
async remove(value: SignedBeaconBlock): Promise<void> {
|
|
185
185
|
await Promise.all([
|
|
186
186
|
super.remove(value),
|
|
187
|
-
deleteRootIndex(this.db, this.config.getForkTypes(value.message.slot).
|
|
187
|
+
deleteRootIndex(this.db, this.config.getForkTypes(value.message.slot).BeaconBlock, value),
|
|
188
188
|
deleteParentRootIndex(this.db, value),
|
|
189
189
|
]);
|
|
190
190
|
}
|
|
@@ -193,7 +193,7 @@ export class BlockArchiveRepository extends Repository<Slot, SignedBeaconBlock>
|
|
|
193
193
|
await Promise.all([
|
|
194
194
|
super.batchRemove(values),
|
|
195
195
|
...values.map((value) =>
|
|
196
|
-
deleteRootIndex(this.db, this.config.getForkTypes(value.message.slot).
|
|
196
|
+
deleteRootIndex(this.db, this.config.getForkTypes(value.message.slot).BeaconBlock, value)
|
|
197
197
|
),
|
|
198
198
|
...values.map((value) => deleteParentRootIndex(this.db, value)),
|
|
199
199
|
]);
|