@lodestar/beacon-node 1.44.0-dev.2defe36dd3 → 1.44.0-dev.2e279005cc
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 +20 -29
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +0 -25
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/config/constants.d.ts +1 -0
- package/lib/api/impl/config/constants.d.ts.map +1 -1
- package/lib/api/impl/config/constants.js +2 -1
- package/lib/api/impl/config/constants.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +69 -12
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.d.ts.map +1 -1
- package/lib/api/impl/lodestar/index.js +28 -0
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +37 -30
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +0 -4
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +8 -1
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +2 -1
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +0 -7
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +0 -3
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +6 -0
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadBid.js +1 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts +4 -4
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +10 -7
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +1 -0
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +3 -3
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +0 -1
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/queued.d.ts +0 -1
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +0 -4
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +0 -5
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js +0 -5
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -4
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +5 -2
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +0 -2
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/stateCache/types.js.map +1 -1
- package/lib/chain/validation/block.d.ts +5 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +4 -14
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +12 -1
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +0 -2
- package/lib/chain/validation/executionPayloadEnvelope.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 +10 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +750 -3
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +9 -2
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/index.d.ts +2 -2
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +25 -23
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +9 -5
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +13 -3
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts +2 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +16 -6
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts +2 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +15 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/index.js +4 -4
- package/lib/network/reqresp/handlers/index.js.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js +22 -3
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
- package/lib/sync/types.d.ts +9 -1
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js +9 -2
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +64 -30
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/util/dataColumns.d.ts.map +1 -1
- package/lib/util/dataColumns.js +16 -11
- package/lib/util/dataColumns.js.map +1 -1
- package/lib/util/sszBytes.js +1 -1
- package/package.json +15 -17
- package/src/api/impl/beacon/blocks/index.ts +24 -38
- package/src/api/impl/beacon/pool/index.ts +1 -41
- package/src/api/impl/config/constants.ts +2 -0
- package/src/api/impl/debug/index.ts +73 -12
- package/src/api/impl/lodestar/index.ts +30 -0
- package/src/api/impl/validator/index.ts +48 -47
- package/src/chain/archiveStore/archiveStore.ts +0 -5
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +2 -4
- package/src/chain/chain.ts +10 -1
- package/src/chain/emitter.ts +3 -2
- package/src/chain/errors/blockError.ts +0 -4
- package/src/chain/errors/executionPayloadBid.ts +7 -0
- package/src/chain/forkChoice/index.ts +13 -0
- package/src/chain/options.ts +1 -0
- package/src/chain/produceBlock/produceBlockBody.ts +3 -3
- package/src/chain/regen/interface.ts +0 -1
- package/src/chain/regen/queued.ts +0 -5
- package/src/chain/stateCache/fifoBlockStateCache.ts +0 -6
- package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
- package/src/chain/stateCache/types.ts +0 -2
- package/src/chain/validation/block.ts +12 -16
- package/src/chain/validation/executionPayloadBid.ts +13 -1
- package/src/chain/validation/executionPayloadEnvelope.ts +0 -2
- package/src/metrics/metrics/lodestar.ts +11 -0
- package/src/network/processor/gossipHandlers.ts +9 -2
- package/src/network/processor/index.ts +27 -27
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +12 -5
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -3
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -1
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +22 -6
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +20 -1
- package/src/network/reqresp/handlers/index.ts +4 -4
- package/src/network/reqresp/utils/dataColumnResponseValidation.ts +21 -3
- package/src/sync/types.ts +11 -2
- package/src/sync/unknownBlock.ts +70 -31
- package/src/util/dataColumns.ts +17 -12
- package/src/util/sszBytes.ts +1 -1
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.44.0-dev.
|
|
14
|
+
"version": "1.44.0-dev.2e279005cc",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -116,7 +116,6 @@
|
|
|
116
116
|
"@chainsafe/libp2p-quic": "^2.0.1",
|
|
117
117
|
"@chainsafe/persistent-merkle-tree": "^1.2.5",
|
|
118
118
|
"@chainsafe/prometheus-gc-stats": "^1.0.0",
|
|
119
|
-
"@chainsafe/pubkey-index-map": "^3.0.0",
|
|
120
119
|
"@chainsafe/snappy-wasm": "^0.5.0",
|
|
121
120
|
"@chainsafe/ssz": "^1.4.0",
|
|
122
121
|
"@chainsafe/threads": "^1.11.3",
|
|
@@ -127,7 +126,7 @@
|
|
|
127
126
|
"@fastify/swagger-ui": "^5.0.1",
|
|
128
127
|
"@libp2p/bootstrap": "^12.0.14",
|
|
129
128
|
"@libp2p/crypto": "^5.1.13",
|
|
130
|
-
"@libp2p/gossipsub": "^
|
|
129
|
+
"@libp2p/gossipsub": "^16.0.2",
|
|
131
130
|
"@libp2p/identify": "^4.0.13",
|
|
132
131
|
"@libp2p/interface": "^3.1.0",
|
|
133
132
|
"@libp2p/mdns": "^12.0.14",
|
|
@@ -135,17 +134,17 @@
|
|
|
135
134
|
"@libp2p/peer-id": "^6.0.4",
|
|
136
135
|
"@libp2p/prometheus-metrics": "^5.0.14",
|
|
137
136
|
"@libp2p/tcp": "^11.0.13",
|
|
138
|
-
"@lodestar/api": "^1.44.0-dev.
|
|
139
|
-
"@lodestar/config": "^1.44.0-dev.
|
|
140
|
-
"@lodestar/db": "^1.44.0-dev.
|
|
141
|
-
"@lodestar/fork-choice": "^1.44.0-dev.
|
|
142
|
-
"@lodestar/logger": "^1.44.0-dev.
|
|
143
|
-
"@lodestar/params": "^1.44.0-dev.
|
|
144
|
-
"@lodestar/reqresp": "^1.44.0-dev.
|
|
145
|
-
"@lodestar/state-transition": "^1.44.0-dev.
|
|
146
|
-
"@lodestar/types": "^1.44.0-dev.
|
|
147
|
-
"@lodestar/utils": "^1.44.0-dev.
|
|
148
|
-
"@lodestar/validator": "^1.44.0-dev.
|
|
137
|
+
"@lodestar/api": "^1.44.0-dev.2e279005cc",
|
|
138
|
+
"@lodestar/config": "^1.44.0-dev.2e279005cc",
|
|
139
|
+
"@lodestar/db": "^1.44.0-dev.2e279005cc",
|
|
140
|
+
"@lodestar/fork-choice": "^1.44.0-dev.2e279005cc",
|
|
141
|
+
"@lodestar/logger": "^1.44.0-dev.2e279005cc",
|
|
142
|
+
"@lodestar/params": "^1.44.0-dev.2e279005cc",
|
|
143
|
+
"@lodestar/reqresp": "^1.44.0-dev.2e279005cc",
|
|
144
|
+
"@lodestar/state-transition": "^1.44.0-dev.2e279005cc",
|
|
145
|
+
"@lodestar/types": "^1.44.0-dev.2e279005cc",
|
|
146
|
+
"@lodestar/utils": "^1.44.0-dev.2e279005cc",
|
|
147
|
+
"@lodestar/validator": "^1.44.0-dev.2e279005cc",
|
|
149
148
|
"@multiformats/multiaddr": "^13.0.1",
|
|
150
149
|
"datastore-core": "^11.0.2",
|
|
151
150
|
"datastore-fs": "^11.0.2",
|
|
@@ -168,13 +167,12 @@
|
|
|
168
167
|
"@libp2p/interface-internal": "^3.0.13",
|
|
169
168
|
"@libp2p/logger": "^6.2.2",
|
|
170
169
|
"@libp2p/utils": "^7.0.13",
|
|
171
|
-
"@lodestar/spec-test-util": "^1.44.0-dev.
|
|
170
|
+
"@lodestar/spec-test-util": "^1.44.0-dev.2e279005cc",
|
|
172
171
|
"@types/js-yaml": "^4.0.5",
|
|
173
172
|
"@types/qs": "^6.9.7",
|
|
174
173
|
"@types/tmp": "^0.2.3",
|
|
175
174
|
"dotenv": "^16.4.5",
|
|
176
175
|
"js-yaml": "^4.1.0",
|
|
177
|
-
"rewiremock": "^3.14.5",
|
|
178
176
|
"rimraf": "^4.4.1",
|
|
179
177
|
"snappy": "^7.2.2",
|
|
180
178
|
"snappyjs": "^0.7.0",
|
|
@@ -186,5 +184,5 @@
|
|
|
186
184
|
"beacon",
|
|
187
185
|
"blockchain"
|
|
188
186
|
],
|
|
189
|
-
"gitHead": "
|
|
187
|
+
"gitHead": "fcc5eca359ff37bcca0c2c8a23143e578e1cf35b"
|
|
190
188
|
}
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
SLOTS_PER_HISTORICAL_ROOT,
|
|
12
12
|
isForkPostBellatrix,
|
|
13
13
|
isForkPostDeneb,
|
|
14
|
-
isForkPostElectra,
|
|
15
14
|
isForkPostFulu,
|
|
16
15
|
isForkPostGloas,
|
|
17
16
|
} from "@lodestar/params";
|
|
@@ -94,7 +93,7 @@ export function getBeaconBlockApi({
|
|
|
94
93
|
ApiModules,
|
|
95
94
|
"chain" | "config" | "metrics" | "network" | "db"
|
|
96
95
|
>): ApplicationMethods<routes.beacon.block.Endpoints> {
|
|
97
|
-
const
|
|
96
|
+
const publishBlockV2: ApplicationMethods<routes.beacon.block.Endpoints>["publishBlockV2"] = async (
|
|
98
97
|
{signedBlockContents, broadcastValidation},
|
|
99
98
|
_context,
|
|
100
99
|
opts: PublishBlockOpts = {}
|
|
@@ -205,11 +204,19 @@ export function getBeaconBlockApi({
|
|
|
205
204
|
try {
|
|
206
205
|
await validateGossipBlock(config, chain, signedBlock, fork);
|
|
207
206
|
} catch (error) {
|
|
208
|
-
if (error instanceof BlockGossipError
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
207
|
+
if (error instanceof BlockGossipError) {
|
|
208
|
+
switch (error.type.code) {
|
|
209
|
+
case BlockErrorCode.ALREADY_KNOWN:
|
|
210
|
+
// Block has already been seen, e.g. via gossip racing the publish API. Benign.
|
|
211
|
+
chain.logger.debug("Ignoring already-known block during publishing", valLogMeta);
|
|
212
|
+
return;
|
|
213
|
+
case BlockErrorCode.REPEAT_PROPOSAL:
|
|
214
|
+
// The proposer already produced a block for this slot. For a solo setup this is a
|
|
215
|
+
// notable signal (duplicate-proposal attempt). For fallback / DVT setups it is
|
|
216
|
+
// expected on every block where another node published first.
|
|
217
|
+
chain.logger.warn("Ignoring repeat-proposal block during publishing", valLogMeta);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
213
220
|
}
|
|
214
221
|
|
|
215
222
|
chain.logger.error("Gossip validations failed while publishing the block", valLogMeta, error as Error);
|
|
@@ -398,8 +405,8 @@ export function getBeaconBlockApi({
|
|
|
398
405
|
}
|
|
399
406
|
};
|
|
400
407
|
|
|
401
|
-
const
|
|
402
|
-
{signedBlindedBlock},
|
|
408
|
+
const publishBlindedBlockV2: ApplicationMethods<routes.beacon.block.Endpoints>["publishBlindedBlockV2"] = async (
|
|
409
|
+
{signedBlindedBlock, broadcastValidation},
|
|
403
410
|
context,
|
|
404
411
|
opts: PublishBlockOpts = {}
|
|
405
412
|
) => {
|
|
@@ -429,7 +436,7 @@ export function getBeaconBlockApi({
|
|
|
429
436
|
);
|
|
430
437
|
|
|
431
438
|
chain.logger.info("Publishing assembled block", {slot, blockRoot, source});
|
|
432
|
-
return
|
|
439
|
+
return publishBlockV2({signedBlockContents, broadcastValidation}, {...context, sszBytes: null}, opts);
|
|
433
440
|
}
|
|
434
441
|
|
|
435
442
|
const source = ProducedBlockSource.builder;
|
|
@@ -455,7 +462,11 @@ export function getBeaconBlockApi({
|
|
|
455
462
|
//
|
|
456
463
|
// see: https://github.com/ChainSafe/lodestar/issues/5404
|
|
457
464
|
chain.logger.info("Publishing assembled block", {slot, blockRoot, source});
|
|
458
|
-
return
|
|
465
|
+
return publishBlockV2(
|
|
466
|
+
{signedBlockContents, broadcastValidation},
|
|
467
|
+
{...context, sszBytes: null},
|
|
468
|
+
{...opts, ignoreIfKnown: true}
|
|
469
|
+
);
|
|
459
470
|
}
|
|
460
471
|
};
|
|
461
472
|
|
|
@@ -590,23 +601,6 @@ export function getBeaconBlockApi({
|
|
|
590
601
|
};
|
|
591
602
|
},
|
|
592
603
|
|
|
593
|
-
async getBlockAttestations({blockId}) {
|
|
594
|
-
const {block, executionOptimistic, finalized} = await getBlockResponse(chain, blockId);
|
|
595
|
-
const fork = config.getForkName(block.message.slot);
|
|
596
|
-
|
|
597
|
-
if (isForkPostElectra(fork)) {
|
|
598
|
-
throw new ApiError(
|
|
599
|
-
400,
|
|
600
|
-
`Use getBlockAttestationsV2 to retrieve block attestations for post-electra fork=${fork}`
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
return {
|
|
605
|
-
data: block.message.body.attestations,
|
|
606
|
-
meta: {executionOptimistic, finalized},
|
|
607
|
-
};
|
|
608
|
-
},
|
|
609
|
-
|
|
610
604
|
async getBlockAttestationsV2({blockId}) {
|
|
611
605
|
const {block, executionOptimistic, finalized} = await getBlockResponse(chain, blockId);
|
|
612
606
|
return {
|
|
@@ -654,16 +648,8 @@ export function getBeaconBlockApi({
|
|
|
654
648
|
};
|
|
655
649
|
},
|
|
656
650
|
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
async publishBlindedBlockV2(args, context, opts) {
|
|
661
|
-
await publishBlindedBlock(args, context, opts);
|
|
662
|
-
},
|
|
663
|
-
|
|
664
|
-
async publishBlockV2(args, context, opts) {
|
|
665
|
-
await publishBlock(args, context, opts);
|
|
666
|
-
},
|
|
651
|
+
publishBlockV2,
|
|
652
|
+
publishBlindedBlockV2,
|
|
667
653
|
|
|
668
654
|
async publishExecutionPayloadEnvelope({signedExecutionPayloadEnvelope}) {
|
|
669
655
|
const seenTimestampSec = Date.now() / 1000;
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
isForkPostGloas,
|
|
10
10
|
} from "@lodestar/params";
|
|
11
11
|
import {isStatePostAltair} from "@lodestar/state-transition";
|
|
12
|
-
import {
|
|
12
|
+
import {Epoch, SingleAttestation, isElectraAttestation, ssz, sszTypesFor} from "@lodestar/types";
|
|
13
13
|
import {toRootHex} from "@lodestar/utils";
|
|
14
14
|
import {
|
|
15
15
|
AttestationError,
|
|
@@ -40,25 +40,6 @@ export function getBeaconPoolApi({
|
|
|
40
40
|
network,
|
|
41
41
|
}: Pick<ApiModules, "chain" | "logger" | "metrics" | "network">): ApplicationMethods<routes.beacon.pool.Endpoints> {
|
|
42
42
|
return {
|
|
43
|
-
async getPoolAttestations({slot, committeeIndex}) {
|
|
44
|
-
// Already filtered by slot
|
|
45
|
-
let attestations: Attestation[] = chain.aggregatedAttestationPool.getAll(slot);
|
|
46
|
-
const fork = chain.config.getForkName(slot ?? chain.clock.currentSlot);
|
|
47
|
-
|
|
48
|
-
if (isForkPostElectra(fork)) {
|
|
49
|
-
throw new ApiError(
|
|
50
|
-
400,
|
|
51
|
-
`Use getPoolAttestationsV2 to retrieve pool attestations for post-electra fork=${fork}`
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (committeeIndex !== undefined) {
|
|
56
|
-
attestations = attestations.filter((attestation) => committeeIndex === attestation.data.index);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return {data: attestations};
|
|
60
|
-
},
|
|
61
|
-
|
|
62
43
|
async getPoolAttestationsV2({slot, committeeIndex}) {
|
|
63
44
|
// Already filtered by slot
|
|
64
45
|
let attestations = chain.aggregatedAttestationPool.getAll(slot);
|
|
@@ -134,19 +115,6 @@ export function getBeaconPoolApi({
|
|
|
134
115
|
}
|
|
135
116
|
},
|
|
136
117
|
|
|
137
|
-
async getPoolAttesterSlashings() {
|
|
138
|
-
const fork = chain.config.getForkName(chain.clock.currentSlot);
|
|
139
|
-
|
|
140
|
-
if (isForkPostElectra(fork)) {
|
|
141
|
-
throw new ApiError(
|
|
142
|
-
400,
|
|
143
|
-
`Use getPoolAttesterSlashingsV2 to retrieve pool attester slashings for post-electra fork=${fork}`
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return {data: chain.opPool.getAllAttesterSlashings()};
|
|
148
|
-
},
|
|
149
|
-
|
|
150
118
|
async getPoolAttesterSlashingsV2() {
|
|
151
119
|
const fork = chain.config.getForkName(chain.clock.currentSlot);
|
|
152
120
|
return {data: chain.opPool.getAllAttesterSlashings(), meta: {version: fork}};
|
|
@@ -164,10 +132,6 @@ export function getBeaconPoolApi({
|
|
|
164
132
|
return {data: chain.opPool.getAllBlsToExecutionChanges().map(({data}) => data)};
|
|
165
133
|
},
|
|
166
134
|
|
|
167
|
-
async submitPoolAttestations({signedAttestations}) {
|
|
168
|
-
await this.submitPoolAttestationsV2({signedAttestations});
|
|
169
|
-
},
|
|
170
|
-
|
|
171
135
|
async submitPoolAttestationsV2({signedAttestations}) {
|
|
172
136
|
const fork = chain.config.getForkName(chain.clock.currentSlot);
|
|
173
137
|
const seenTimestampSec = Date.now() / 1000;
|
|
@@ -247,10 +211,6 @@ export function getBeaconPoolApi({
|
|
|
247
211
|
}
|
|
248
212
|
},
|
|
249
213
|
|
|
250
|
-
async submitPoolAttesterSlashings({attesterSlashing}) {
|
|
251
|
-
await this.submitPoolAttesterSlashingsV2({attesterSlashing});
|
|
252
|
-
},
|
|
253
|
-
|
|
254
214
|
async submitPoolAttesterSlashingsV2({attesterSlashing}) {
|
|
255
215
|
await validateApiAttesterSlashing(chain, attesterSlashing);
|
|
256
216
|
const fork = chain.config.getForkName(Number(attesterSlashing.attestation1.data.slot));
|
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
VERSIONED_HASH_VERSION_KZG,
|
|
54
54
|
WEIGHT_DENOMINATOR,
|
|
55
55
|
WITHDRAWAL_REQUEST_TYPE,
|
|
56
|
+
ZERO_HASH_HEX,
|
|
56
57
|
} from "@lodestar/params";
|
|
57
58
|
|
|
58
59
|
/**
|
|
@@ -69,6 +70,7 @@ export const specConstants = {
|
|
|
69
70
|
DEPOSIT_CONTRACT_TREE_DEPTH,
|
|
70
71
|
JUSTIFICATION_BITS_LENGTH,
|
|
71
72
|
ENDIANNESS: "little",
|
|
73
|
+
EMPTY_BLOCK_HASH: ZERO_HASH_HEX,
|
|
72
74
|
// ## Withdrawal prefixes
|
|
73
75
|
BLS_WITHDRAWAL_PREFIX: toHexByte(BLS_WITHDRAWAL_PREFIX),
|
|
74
76
|
ETH1_ADDRESS_WITHDRAWAL_PREFIX: toHexByte(ETH1_ADDRESS_WITHDRAWAL_PREFIX),
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
2
|
import {ApplicationMethods} from "@lodestar/api/server";
|
|
3
|
-
import {ExecutionStatus} from "@lodestar/fork-choice";
|
|
3
|
+
import {ExecutionStatus, PayloadStatus} from "@lodestar/fork-choice";
|
|
4
4
|
import {ForkPostDeneb, ZERO_HASH_HEX, isForkPostDeneb, isForkPostFulu} from "@lodestar/params";
|
|
5
|
+
import {computeTimeAtSlot} from "@lodestar/state-transition";
|
|
5
6
|
import {BeaconState, DataColumnSidecar, DataColumnSidecars, type SignedBeaconBlock, sszTypesFor} from "@lodestar/types";
|
|
6
7
|
import {toRootHex} from "@lodestar/utils";
|
|
7
8
|
import {getBlobKzgCommitments} from "../../../util/dataColumns.js";
|
|
@@ -12,6 +13,29 @@ import {getStateResponseWithRegen} from "../beacon/state/utils.js";
|
|
|
12
13
|
import {ApiModules} from "../types.js";
|
|
13
14
|
import {assertUniqueItems} from "../utils.js";
|
|
14
15
|
|
|
16
|
+
function toForkChoiceValidity(status: ExecutionStatus): "valid" | "invalid" | "optimistic" {
|
|
17
|
+
switch (status) {
|
|
18
|
+
case ExecutionStatus.Valid:
|
|
19
|
+
return "valid";
|
|
20
|
+
case ExecutionStatus.Invalid:
|
|
21
|
+
return "invalid";
|
|
22
|
+
case ExecutionStatus.Syncing:
|
|
23
|
+
case ExecutionStatus.PreMerge:
|
|
24
|
+
return "optimistic";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function toPayloadStatusName(status: PayloadStatus): "pending" | "empty" | "full" {
|
|
29
|
+
switch (status) {
|
|
30
|
+
case PayloadStatus.PENDING:
|
|
31
|
+
return "pending";
|
|
32
|
+
case PayloadStatus.EMPTY:
|
|
33
|
+
return "empty";
|
|
34
|
+
case PayloadStatus.FULL:
|
|
35
|
+
return "full";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
15
39
|
export function getDebugApi({
|
|
16
40
|
chain,
|
|
17
41
|
config,
|
|
@@ -40,23 +64,60 @@ export function getDebugApi({
|
|
|
40
64
|
justifiedEpoch: node.justifiedEpoch,
|
|
41
65
|
finalizedEpoch: node.finalizedEpoch,
|
|
42
66
|
weight: node.weight,
|
|
43
|
-
validity: (
|
|
44
|
-
switch (node.executionStatus) {
|
|
45
|
-
case ExecutionStatus.Valid:
|
|
46
|
-
return "valid";
|
|
47
|
-
case ExecutionStatus.Invalid:
|
|
48
|
-
return "invalid";
|
|
49
|
-
case ExecutionStatus.Syncing:
|
|
50
|
-
case ExecutionStatus.PreMerge:
|
|
51
|
-
return "optimistic";
|
|
52
|
-
}
|
|
53
|
-
})(),
|
|
67
|
+
validity: toForkChoiceValidity(node.executionStatus),
|
|
54
68
|
executionBlockHash: node.executionPayloadBlockHash ?? ZERO_HASH_HEX,
|
|
55
69
|
})),
|
|
56
70
|
},
|
|
57
71
|
};
|
|
58
72
|
},
|
|
59
73
|
|
|
74
|
+
async getDebugForkChoiceV2() {
|
|
75
|
+
const {forkChoice} = chain;
|
|
76
|
+
return {
|
|
77
|
+
data: {
|
|
78
|
+
justifiedCheckpoint: forkChoice.getJustifiedCheckpoint(),
|
|
79
|
+
finalizedCheckpoint: forkChoice.getFinalizedCheckpoint(),
|
|
80
|
+
forkChoiceNodes: forkChoice.getAllNodes().map((node) => {
|
|
81
|
+
// Payload-specific fields apply only to a revealed Gloas payload = the FULL variant of a
|
|
82
|
+
// Gloas block
|
|
83
|
+
const ptc = node.payloadStatus === PayloadStatus.FULL ? forkChoice.getPTCVoteCounts(node.blockRoot) : null;
|
|
84
|
+
return {
|
|
85
|
+
payloadStatus: toPayloadStatusName(node.payloadStatus),
|
|
86
|
+
slot: node.slot,
|
|
87
|
+
blockRoot: node.blockRoot,
|
|
88
|
+
parentRoot: node.parentRoot,
|
|
89
|
+
weight: node.weight,
|
|
90
|
+
validity: toForkChoiceValidity(node.executionStatus),
|
|
91
|
+
executionBlockHash: node.executionPayloadBlockHash ?? ZERO_HASH_HEX,
|
|
92
|
+
extraData: {
|
|
93
|
+
executionOptimistic: isOptimisticBlock(node),
|
|
94
|
+
timestamp: computeTimeAtSlot(config, node.slot, chain.genesisTime),
|
|
95
|
+
target: node.targetRoot,
|
|
96
|
+
justifiedEpoch: node.justifiedEpoch,
|
|
97
|
+
finalizedEpoch: node.finalizedEpoch,
|
|
98
|
+
unrealizedJustifiedEpoch: node.unrealizedJustifiedEpoch,
|
|
99
|
+
unrealizedFinalizedEpoch: node.unrealizedFinalizedEpoch,
|
|
100
|
+
payloadAttesterCount: ptc?.attesterCount ?? null,
|
|
101
|
+
payloadAvailabilityYesCount: ptc?.payloadPresentCount ?? null,
|
|
102
|
+
payloadDataAvailabilityYesCount: ptc?.dataAvailableCount ?? null,
|
|
103
|
+
gasLimit:
|
|
104
|
+
node.payloadStatus === PayloadStatus.FULL && "executionPayloadGasLimit" in node
|
|
105
|
+
? node.executionPayloadGasLimit
|
|
106
|
+
: null,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}),
|
|
110
|
+
extraData: {
|
|
111
|
+
unrealizedJustifiedCheckpoint: forkChoice.getUnrealizedJustifiedCheckpoint(),
|
|
112
|
+
unrealizedFinalizedCheckpoint: forkChoice.getUnrealizedFinalizedCheckpoint(),
|
|
113
|
+
proposerBoostRoot: forkChoice.getProposerBoostRoot(),
|
|
114
|
+
previousProposerBoostRoot: forkChoice.getPreviousProposerBoostRoot(),
|
|
115
|
+
headRoot: forkChoice.getHeadRoot(),
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
|
|
60
121
|
async getProtoArrayNodes() {
|
|
61
122
|
const nodes = chain.forkChoice.getAllNodes().map((node) => ({
|
|
62
123
|
// if node has executionPayloadNumber, it will overwrite the below default
|
|
@@ -280,6 +280,36 @@ export function getLodestarApi({
|
|
|
280
280
|
};
|
|
281
281
|
},
|
|
282
282
|
|
|
283
|
+
async getFastConfirmationInfo() {
|
|
284
|
+
const confirmedRoot = chain.forkChoice.getConfirmedRoot();
|
|
285
|
+
const confirmedBlock = chain.forkChoice.getConfirmedBlock();
|
|
286
|
+
const justifiedCheckpoint = chain.forkChoice.getJustifiedCheckpoint();
|
|
287
|
+
const finalizedCheckpoint = chain.forkChoice.getFinalizedCheckpoint();
|
|
288
|
+
const headRoot = chain.forkChoice.getHeadRoot();
|
|
289
|
+
const head = chain.forkChoice.getHead();
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
data: {
|
|
293
|
+
confirmed: {
|
|
294
|
+
rootHex: confirmedRoot,
|
|
295
|
+
slot: confirmedBlock?.slot ?? null,
|
|
296
|
+
},
|
|
297
|
+
head: {
|
|
298
|
+
rootHex: headRoot,
|
|
299
|
+
slot: head.slot,
|
|
300
|
+
},
|
|
301
|
+
justifiedCheckpoint: {
|
|
302
|
+
rootHex: justifiedCheckpoint.rootHex,
|
|
303
|
+
epoch: justifiedCheckpoint.epoch,
|
|
304
|
+
},
|
|
305
|
+
finalizedCheckpoint: {
|
|
306
|
+
rootHex: finalizedCheckpoint.rootHex,
|
|
307
|
+
epoch: finalizedCheckpoint.epoch,
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
},
|
|
312
|
+
|
|
283
313
|
async getAttesterSlashingsFromBlocks({signedBlocks}) {
|
|
284
314
|
const attestations = new Map<Epoch, Attestation[]>();
|
|
285
315
|
|
|
@@ -927,11 +927,9 @@ export function getValidatorApi(
|
|
|
927
927
|
// TODO GLOAS: respect builderSelection (MaxProfit, BuilderAlways, ExecutionAlways, etc.) to let
|
|
928
928
|
// the user control bid source preferences and value comparison. Also add external builder api
|
|
929
929
|
// support when it is implemented.
|
|
930
|
-
const
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
parentBlockRootHex
|
|
934
|
-
);
|
|
930
|
+
const isBuildingOnFull = chain.forkChoice.shouldBuildOnFull(parentBlock, slot);
|
|
931
|
+
const bidParentBlockHash = isBuildingOnFull ? parentBlock.executionPayloadBlockHash : parentBlock.parentBlockHash;
|
|
932
|
+
const builderBid = chain.executionPayloadBidPool.getBestBid(slot, bidParentBlockHash, parentBlockRootHex);
|
|
935
933
|
|
|
936
934
|
const logCtx = {
|
|
937
935
|
slot,
|
|
@@ -1123,11 +1121,24 @@ export function getValidatorApi(
|
|
|
1123
1121
|
// into the slot. Use the envelope's own arrival time (getPayloadEnvelopeSource), not
|
|
1124
1122
|
// the input's creation time.
|
|
1125
1123
|
const payloadDueSec = config.getPayloadDueMs() / 1000;
|
|
1126
|
-
const
|
|
1127
|
-
payloadInput?.hasPayloadEnvelope() === true
|
|
1128
|
-
|
|
1124
|
+
const payloadSeenSec =
|
|
1125
|
+
payloadInput?.hasPayloadEnvelope() === true
|
|
1126
|
+
? chain.clock.secFromSlot(slot, payloadInput.getPayloadEnvelopeSource().seenTimestampSec)
|
|
1127
|
+
: null;
|
|
1128
|
+
const payloadPresent = payloadSeenSec !== null && payloadSeenSec < payloadDueSec;
|
|
1129
1129
|
const blobDataAvailable = payloadInput?.hasAllData() === true;
|
|
1130
1130
|
|
|
1131
|
+
logger.debug("Produced payload attestation data", {
|
|
1132
|
+
slot,
|
|
1133
|
+
blockRoot: block.blockRoot,
|
|
1134
|
+
blockSlot: block.slot,
|
|
1135
|
+
payloadPresent,
|
|
1136
|
+
blobDataAvailable,
|
|
1137
|
+
hasPayloadInput: payloadInput !== undefined,
|
|
1138
|
+
payloadSeenSec,
|
|
1139
|
+
payloadDueSec,
|
|
1140
|
+
});
|
|
1141
|
+
|
|
1131
1142
|
return {
|
|
1132
1143
|
data: {
|
|
1133
1144
|
beaconBlockRoot: fromHex(block.blockRoot),
|
|
@@ -1196,7 +1207,10 @@ export function getValidatorApi(
|
|
|
1196
1207
|
const isPostFulu = isForkPostFulu(config.getForkName(startSlot));
|
|
1197
1208
|
const maxFutureEpoch = isPostFulu && nearNextEpoch && opts?.v2 ? nextEpoch + 1 : nextEpoch;
|
|
1198
1209
|
if (currentEpoch >= 0 && epoch > maxFutureEpoch) {
|
|
1199
|
-
throw new ApiError(
|
|
1210
|
+
throw new ApiError(
|
|
1211
|
+
400,
|
|
1212
|
+
`Requested epoch ${epoch} must not be more than ${maxFutureEpoch}, currentEpoch=${currentEpoch}, v2=${opts?.v2 ?? false}`
|
|
1213
|
+
);
|
|
1200
1214
|
}
|
|
1201
1215
|
|
|
1202
1216
|
const head = chain.forkChoice.getHead();
|
|
@@ -1280,17 +1294,35 @@ export function getValidatorApi(
|
|
|
1280
1294
|
duties.push({slot: startSlot + i, validatorIndex: indexes[i], pubkey: pubkeys[i]});
|
|
1281
1295
|
}
|
|
1282
1296
|
|
|
1283
|
-
//
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1297
|
+
// In v2 the dependent root is different after fulu due to deterministic proposer lookahead
|
|
1298
|
+
let dependentRoot = proposerShufflingDecisionRoot(
|
|
1299
|
+
opts?.v2 ? config.getForkName(startSlot) : ForkName.phase0,
|
|
1300
|
+
state,
|
|
1301
|
+
epoch
|
|
1302
|
+
);
|
|
1303
|
+
const logCtx = {
|
|
1304
|
+
epoch,
|
|
1305
|
+
stateSlot: state.slot,
|
|
1306
|
+
stateEpoch: state.epoch,
|
|
1307
|
+
v2: opts?.v2 ?? false,
|
|
1308
|
+
};
|
|
1309
|
+
if (dependentRoot === null) {
|
|
1310
|
+
// fallback to get_proposer_duties() v1, also in lodestar v1.43
|
|
1311
|
+
logger.verbose("Proposer duties decision root not in state, falling back to state epoch", logCtx);
|
|
1312
|
+
dependentRoot = proposerShufflingDecisionRoot(ForkName.phase0, state, state.epoch);
|
|
1313
|
+
}
|
|
1314
|
+
if (dependentRoot === null) {
|
|
1315
|
+
logger.verbose("Proposer duties decision root not in state, falling back to genesis block root", logCtx);
|
|
1316
|
+
dependentRoot = await getGenesisBlockRoot(state);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
const dependentRootHex = toRootHex(dependentRoot);
|
|
1320
|
+
logger.verbose("Computed proposer duties decision root", {...logCtx, dependentRoot: dependentRootHex});
|
|
1289
1321
|
|
|
1290
1322
|
return {
|
|
1291
1323
|
data: duties,
|
|
1292
1324
|
meta: {
|
|
1293
|
-
dependentRoot:
|
|
1325
|
+
dependentRoot: dependentRootHex,
|
|
1294
1326
|
executionOptimistic: isOptimisticBlock(head),
|
|
1295
1327
|
},
|
|
1296
1328
|
};
|
|
@@ -1469,33 +1501,6 @@ export function getValidatorApi(
|
|
|
1469
1501
|
};
|
|
1470
1502
|
},
|
|
1471
1503
|
|
|
1472
|
-
async getAggregatedAttestation({attestationDataRoot, slot}) {
|
|
1473
|
-
notWhileSyncing();
|
|
1474
|
-
|
|
1475
|
-
await waitForSlot(slot); // Must never request for a future slot > currentSlot
|
|
1476
|
-
|
|
1477
|
-
const dataRootHex = toRootHex(attestationDataRoot);
|
|
1478
|
-
const aggregate = chain.attestationPool.getAggregate(slot, dataRootHex, null);
|
|
1479
|
-
const fork = chain.config.getForkName(slot);
|
|
1480
|
-
|
|
1481
|
-
if (isForkPostElectra(fork)) {
|
|
1482
|
-
throw new ApiError(
|
|
1483
|
-
400,
|
|
1484
|
-
`Use getAggregatedAttestationV2 to retrieve aggregated attestations for post-electra fork=${fork}`
|
|
1485
|
-
);
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
|
-
if (!aggregate) {
|
|
1489
|
-
throw new ApiError(404, `No aggregated attestation for slot=${slot}, dataRoot=${dataRootHex}`);
|
|
1490
|
-
}
|
|
1491
|
-
|
|
1492
|
-
metrics?.production.producedAggregateParticipants.observe(aggregate.aggregationBits.getTrueBitIndexes().length);
|
|
1493
|
-
|
|
1494
|
-
return {
|
|
1495
|
-
data: aggregate,
|
|
1496
|
-
};
|
|
1497
|
-
},
|
|
1498
|
-
|
|
1499
1504
|
async getAggregatedAttestationV2({attestationDataRoot, slot, committeeIndex}) {
|
|
1500
1505
|
notWhileSyncing();
|
|
1501
1506
|
|
|
@@ -1519,10 +1524,6 @@ export function getValidatorApi(
|
|
|
1519
1524
|
};
|
|
1520
1525
|
},
|
|
1521
1526
|
|
|
1522
|
-
async publishAggregateAndProofs({signedAggregateAndProofs}) {
|
|
1523
|
-
await this.publishAggregateAndProofsV2({signedAggregateAndProofs});
|
|
1524
|
-
},
|
|
1525
|
-
|
|
1526
1527
|
async publishAggregateAndProofsV2({signedAggregateAndProofs}) {
|
|
1527
1528
|
notWhileSyncing();
|
|
1528
1529
|
|
|
@@ -30,7 +30,6 @@ export enum ArchiveStoreTask {
|
|
|
30
30
|
PruneHistory = "prune_history",
|
|
31
31
|
OnFinalizedCheckpoint = "on_finalized_checkpoint",
|
|
32
32
|
MaybeArchiveState = "maybe_archive_state",
|
|
33
|
-
RegenPruneOnFinalized = "regen_prune_on_finalized",
|
|
34
33
|
ForkchoicePrune = "forkchoice_prune",
|
|
35
34
|
UpdateBackfillRange = "update_backfill_range",
|
|
36
35
|
}
|
|
@@ -229,10 +228,6 @@ export class ArchiveStore {
|
|
|
229
228
|
await this.statesArchiverStrategy.maybeArchiveState(finalized, this.metrics);
|
|
230
229
|
timer?.({source: ArchiveStoreTask.MaybeArchiveState});
|
|
231
230
|
|
|
232
|
-
timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
|
|
233
|
-
this.chain.regen.pruneOnFinalized(finalizedEpoch);
|
|
234
|
-
timer?.({source: ArchiveStoreTask.RegenPruneOnFinalized});
|
|
235
|
-
|
|
236
231
|
// tasks rely on extended fork choice
|
|
237
232
|
timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
|
|
238
233
|
const prunedBlocks = this.chain.forkChoice.prune(finalized.rootHex);
|
|
@@ -61,10 +61,8 @@ export function verifyExecutionPayloadEnvelope(
|
|
|
61
61
|
`Prev randao mismatch between bid and payload bid=${toHex(bid.prevRandao)} payload=${toHex(payload.prevRandao)}`
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
|
-
if (
|
|
65
|
-
throw new Error(
|
|
66
|
-
`Gas limit mismatch between payload and bid payload=${payload.gasLimit} bid=${Number(bid.gasLimit)}`
|
|
67
|
-
);
|
|
64
|
+
if (bid.gasLimit !== payload.gasLimit) {
|
|
65
|
+
throw new Error(`Gas limit mismatch between payload and bid payload=${payload.gasLimit} bid=${bid.gasLimit}`);
|
|
68
66
|
}
|
|
69
67
|
if (!byteArrayEquals(bid.blockHash, payload.blockHash)) {
|
|
70
68
|
throw new Error(
|
package/src/chain/chain.ts
CHANGED
|
@@ -2,7 +2,7 @@ import path from "node:path";
|
|
|
2
2
|
import {PrivateKey} from "@libp2p/interface";
|
|
3
3
|
import {Type} from "@chainsafe/ssz";
|
|
4
4
|
import {BeaconConfig} from "@lodestar/config";
|
|
5
|
-
import {CheckpointWithHex, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
|
|
5
|
+
import {CheckpointWithHex, ForkChoiceStateGetter, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
|
|
6
6
|
import {LoggerNode} from "@lodestar/logger/node";
|
|
7
7
|
import {
|
|
8
8
|
EFFECTIVE_BALANCE_INCREMENT,
|
|
@@ -382,6 +382,14 @@ export class BeaconChain implements IBeaconChain {
|
|
|
382
382
|
blockStateCache.setHeadState(anchorState);
|
|
383
383
|
checkpointStateCache.add(checkpoint, anchorState);
|
|
384
384
|
|
|
385
|
+
const forkChoiceStateGetter: ForkChoiceStateGetter = ({stateRoot, checkpoint}) => {
|
|
386
|
+
if (stateRoot) return blockStateCache.get(stateRoot);
|
|
387
|
+
|
|
388
|
+
if (checkpoint) return checkpointStateCache.get({epoch: checkpoint.epoch, rootHex: checkpoint.rootHex});
|
|
389
|
+
|
|
390
|
+
return null;
|
|
391
|
+
};
|
|
392
|
+
|
|
385
393
|
const forkChoice = initializeForkChoice(
|
|
386
394
|
config,
|
|
387
395
|
emitter,
|
|
@@ -390,6 +398,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
390
398
|
isAnchorStateFinalized,
|
|
391
399
|
opts,
|
|
392
400
|
this.justifiedBalancesGetter.bind(this),
|
|
401
|
+
forkChoiceStateGetter,
|
|
393
402
|
metrics,
|
|
394
403
|
logger
|
|
395
404
|
);
|
package/src/chain/emitter.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {StrictEventEmitter} from "strict-event-emitter-types";
|
|
|
3
3
|
import {routes} from "@lodestar/api";
|
|
4
4
|
import {CheckpointWithHex} from "@lodestar/fork-choice";
|
|
5
5
|
import {IBeaconStateView} from "@lodestar/state-transition";
|
|
6
|
-
import {DataColumnSidecar, RootHex, deneb, phase0} from "@lodestar/types";
|
|
6
|
+
import {DataColumnSidecar, RootHex, Slot, deneb, phase0} from "@lodestar/types";
|
|
7
7
|
import {PeerIdStr} from "../util/peerId.js";
|
|
8
8
|
import {BlockInputSource, IBlockInput} from "./blocks/blockInput/types.js";
|
|
9
9
|
import {PayloadEnvelopeInput} from "./blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
@@ -94,7 +94,8 @@ export type ChainEventData = {
|
|
|
94
94
|
peer: PeerIdStr;
|
|
95
95
|
source: BlockInputSource;
|
|
96
96
|
};
|
|
97
|
-
|
|
97
|
+
// slot is the message slot, not necessarily the envelope's slot, but useful as a logging/prune hint
|
|
98
|
+
[ChainEvent.unknownEnvelopeBlockRoot]: {rootHex: RootHex; slot: Slot; peer?: PeerIdStr; source: BlockInputSource};
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
export type IChainEvents = ApiEvents & {
|