@lodestar/beacon-node 1.50.0 → 1.51.0-dev.17f78227c7
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 +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.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 +4 -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 +11 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +31 -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/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/index.d.ts +5 -0
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +13 -4
- 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 +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 +8 -4
- package/src/chain/chain.ts +4 -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 +32 -1
- package/src/network/gossip/gossipsub.ts +3 -1
- package/src/network/peers/utils/enrSubnetsDeserialize.ts +5 -2
- package/src/network/processor/index.ts +13 -4
- 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.17f78227c7",
|
|
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.17f78227c7",
|
|
131
|
+
"@lodestar/config": "^1.51.0-dev.17f78227c7",
|
|
132
|
+
"@lodestar/db": "^1.51.0-dev.17f78227c7",
|
|
133
|
+
"@lodestar/fork-choice": "^1.51.0-dev.17f78227c7",
|
|
134
|
+
"@lodestar/logger": "^1.51.0-dev.17f78227c7",
|
|
135
|
+
"@lodestar/params": "^1.51.0-dev.17f78227c7",
|
|
136
|
+
"@lodestar/reqresp": "^1.51.0-dev.17f78227c7",
|
|
137
|
+
"@lodestar/state-transition": "^1.51.0-dev.17f78227c7",
|
|
138
|
+
"@lodestar/types": "^1.51.0-dev.17f78227c7",
|
|
139
|
+
"@lodestar/utils": "^1.51.0-dev.17f78227c7",
|
|
140
|
+
"@lodestar/validator": "^1.51.0-dev.17f78227c7",
|
|
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.17f78227c7",
|
|
163
|
+
"@lodestar/test-utils": "^1.51.0-dev.17f78227c7",
|
|
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": "8e93bb4295540a4c3679098edd4da0e9cc247bf9"
|
|
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
|
|
@@ -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) {
|
|
@@ -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";
|
|
@@ -509,6 +509,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
509
509
|
emitter,
|
|
510
510
|
metrics,
|
|
511
511
|
config,
|
|
512
|
+
signal,
|
|
512
513
|
});
|
|
513
514
|
|
|
514
515
|
this.archiveStore = new ArchiveStore(
|
|
@@ -1841,7 +1842,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1841
1842
|
const metrics = this.metrics;
|
|
1842
1843
|
if (metrics && (slot + 1) % SLOTS_PER_EPOCH === 0) {
|
|
1843
1844
|
// On the last slot of the epoch
|
|
1844
|
-
|
|
1845
|
+
const fork = this.config.getForkName(slot);
|
|
1846
|
+
sleep(this.config.getSlotComponentDurationMs(fork, HALF_SLOT_BPS))
|
|
1845
1847
|
.then(() => this.validatorMonitor?.onceEveryEndOfEpoch(this.getHeadState()))
|
|
1846
1848
|
.catch((e) => {
|
|
1847
1849
|
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
|
}
|