@lodestar/beacon-node 1.36.0-dev.6d67a79656 → 1.36.0-dev.782dc5ee45
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 +41 -22
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.d.ts +5 -0
- package/lib/api/impl/lodestar/index.d.ts.map +1 -1
- package/lib/api/impl/lodestar/index.js +35 -10
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/node/utils.js +1 -1
- package/lib/api/impl/node/utils.js.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +6 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
- package/lib/chain/chain.d.ts +5 -2
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +32 -16
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/blobSidecarError.d.ts +5 -0
- package/lib/chain/errors/blobSidecarError.d.ts.map +1 -1
- package/lib/chain/errors/blobSidecarError.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +1 -0
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/dataColumnSidecarError.d.ts +27 -13
- package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
- package/lib/chain/errors/dataColumnSidecarError.js +5 -0
- package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts +9 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +109 -4
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +2 -0
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/options.d.ts +0 -2
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +2 -2
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/stateCache/datastore/db.d.ts +12 -0
- package/lib/chain/stateCache/datastore/db.d.ts.map +1 -1
- package/lib/chain/stateCache/datastore/db.js +70 -0
- package/lib/chain/stateCache/datastore/db.js.map +1 -1
- package/lib/chain/stateCache/datastore/file.d.ts +1 -0
- package/lib/chain/stateCache/datastore/file.d.ts.map +1 -1
- package/lib/chain/stateCache/datastore/file.js +7 -0
- package/lib/chain/stateCache/datastore/file.js.map +1 -1
- package/lib/chain/stateCache/datastore/types.d.ts +1 -0
- package/lib/chain/stateCache/datastore/types.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +16 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +31 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/validation/blobSidecar.d.ts +4 -1
- package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
- package/lib/chain/validation/blobSidecar.js +46 -11
- package/lib/chain/validation/blobSidecar.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +1 -0
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts +4 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +76 -20
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/metrics/metrics/lodestar.js +1 -1
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/core/networkCore.d.ts.map +1 -1
- package/lib/network/core/networkCore.js +5 -1
- package/lib/network/core/networkCore.js.map +1 -1
- package/lib/network/core/networkCoreWorker.js +8 -8
- package/lib/network/core/networkCoreWorker.js.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.js +1 -1
- package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
- package/lib/network/discv5/worker.js +2 -7
- package/lib/network/discv5/worker.js.map +1 -1
- package/lib/network/events.d.ts +1 -0
- package/lib/network/events.d.ts.map +1 -1
- package/lib/network/gossip/encoding.js +1 -1
- package/lib/network/gossip/encoding.js.map +1 -1
- package/lib/network/gossip/gossipsub.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.js +6 -1
- package/lib/network/gossip/gossipsub.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +2 -0
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/snappy_bun.d.ts +3 -0
- package/lib/network/gossip/snappy_bun.d.ts.map +1 -0
- package/lib/network/gossip/snappy_bun.js +3 -0
- package/lib/network/gossip/snappy_bun.js.map +1 -0
- package/lib/network/metadata.d.ts +1 -1
- package/lib/network/metadata.d.ts.map +1 -1
- package/lib/network/metadata.js +1 -0
- package/lib/network/metadata.js.map +1 -1
- package/lib/network/options.d.ts +0 -1
- package/lib/network/options.d.ts.map +1 -1
- package/lib/network/options.js.map +1 -1
- package/lib/network/peers/discover.js +2 -2
- package/lib/network/peers/discover.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +28 -8
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
- package/lib/network/processor/gossipValidatorFn.js +3 -2
- package/lib/network/processor/gossipValidatorFn.js.map +1 -1
- package/lib/network/processor/types.d.ts +2 -0
- package/lib/network/processor/types.d.ts.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js +3 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts +2 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -3
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts +2 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +9 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.d.ts +2 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +9 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/index.js +6 -6
- package/lib/network/reqresp/handlers/index.js.map +1 -1
- package/lib/network/reqresp/types.d.ts +1 -0
- package/lib/network/reqresp/types.d.ts.map +1 -1
- package/lib/node/nodejs.d.ts +2 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +2 -1
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/range/range.d.ts.map +1 -1
- package/lib/sync/range/range.js +2 -1
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/unknownBlock.js +1 -1
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +59 -15
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +204 -83
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts +8 -14
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +18 -33
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/lib/sync/utils/remoteSyncType.d.ts +2 -1
- package/lib/sync/utils/remoteSyncType.d.ts.map +1 -1
- package/lib/sync/utils/remoteSyncType.js +19 -4
- package/lib/sync/utils/remoteSyncType.js.map +1 -1
- package/lib/util/blobs.d.ts +1 -1
- package/lib/util/blobs.d.ts.map +1 -1
- package/lib/util/blobs.js +53 -20
- package/lib/util/blobs.js.map +1 -1
- package/lib/util/profile.d.ts +6 -4
- package/lib/util/profile.d.ts.map +1 -1
- package/lib/util/profile.js +40 -3
- package/lib/util/profile.js.map +1 -1
- package/lib/util/sszBytes.d.ts +2 -0
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +25 -0
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +32 -25
- package/src/api/impl/beacon/blocks/index.ts +47 -25
- package/src/api/impl/lodestar/index.ts +42 -10
- package/src/api/impl/node/utils.ts +1 -1
- package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +5 -1
- package/src/chain/chain.ts +48 -23
- package/src/chain/errors/blobSidecarError.ts +12 -2
- package/src/chain/errors/blockError.ts +1 -1
- package/src/chain/errors/dataColumnSidecarError.ts +38 -15
- package/src/chain/forkChoice/index.ts +178 -2
- package/src/chain/interface.ts +2 -0
- package/src/chain/options.ts +2 -3
- package/src/chain/stateCache/datastore/db.ts +89 -1
- package/src/chain/stateCache/datastore/file.ts +8 -0
- package/src/chain/stateCache/datastore/types.ts +1 -0
- package/src/chain/stateCache/persistentCheckpointsCache.ts +45 -2
- package/src/chain/validation/blobSidecar.ts +54 -10
- package/src/chain/validation/block.ts +1 -0
- package/src/chain/validation/dataColumnSidecar.ts +95 -21
- package/src/index.ts +2 -0
- package/src/metrics/metrics/lodestar.ts +1 -1
- package/src/network/core/networkCore.ts +5 -1
- package/src/network/core/networkCoreWorker.ts +9 -9
- package/src/network/core/networkCoreWorkerHandler.ts +1 -1
- package/src/network/discv5/worker.ts +2 -7
- package/src/network/events.ts +1 -1
- package/src/network/gossip/encoding.ts +1 -1
- package/src/network/gossip/gossipsub.ts +7 -1
- package/src/network/gossip/interface.ts +2 -0
- package/src/network/gossip/snappy_bun.ts +2 -0
- package/src/network/metadata.ts +3 -1
- package/src/network/options.ts +0 -1
- package/src/network/peers/discover.ts +2 -2
- package/src/network/processor/gossipHandlers.ts +31 -7
- package/src/network/processor/gossipValidatorFn.ts +15 -2
- package/src/network/processor/types.ts +2 -0
- package/src/network/reqresp/ReqRespBeaconNode.ts +3 -1
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +18 -3
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +13 -1
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +13 -1
- package/src/network/reqresp/handlers/index.ts +6 -6
- package/src/network/reqresp/types.ts +1 -0
- package/src/node/nodejs.ts +3 -0
- package/src/sync/range/range.ts +2 -1
- package/src/sync/unknownBlock.ts +1 -1
- package/src/sync/utils/downloadByRange.ts +273 -108
- package/src/sync/utils/downloadByRoot.ts +22 -56
- package/src/sync/utils/remoteSyncType.ts +23 -4
- package/src/util/blobs.ts +64 -20
- package/src/util/profile.ts +45 -3
- package/src/util/sszBytes.ts +30 -0
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
BlockError,
|
|
40
40
|
BlockErrorCode,
|
|
41
41
|
BlockGossipError,
|
|
42
|
+
DataColumnSidecarErrorCode,
|
|
42
43
|
DataColumnSidecarGossipError,
|
|
43
44
|
GossipAction,
|
|
44
45
|
GossipActionError,
|
|
@@ -295,6 +296,21 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
295
296
|
const slot = dataColumnBlockHeader.slot;
|
|
296
297
|
const blockRootHex = toRootHex(ssz.phase0.BeaconBlockHeader.hashTreeRoot(dataColumnBlockHeader));
|
|
297
298
|
|
|
299
|
+
// check to see if block has already been processed and BlockInput has been deleted (column received via reqresp or other means)
|
|
300
|
+
if (chain.forkChoice.hasBlockHex(blockRootHex)) {
|
|
301
|
+
metrics?.peerDas.dataColumnSidecarProcessingSkip.inc();
|
|
302
|
+
logger.debug("Already processed block for column sidecar, skipping processing", {
|
|
303
|
+
slot,
|
|
304
|
+
blockRoot: blockRootHex,
|
|
305
|
+
index: dataColumnSidecar.index,
|
|
306
|
+
});
|
|
307
|
+
throw new DataColumnSidecarGossipError(GossipAction.IGNORE, {
|
|
308
|
+
code: DataColumnSidecarErrorCode.ALREADY_KNOWN,
|
|
309
|
+
columnIndex: dataColumnSidecar.index,
|
|
310
|
+
slot,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
298
314
|
// first check if we should even process this column (we may have already processed it via getBlobsV2)
|
|
299
315
|
{
|
|
300
316
|
const blockInput = chain.seenBlockInputCache.get(blockRootHex);
|
|
@@ -304,7 +320,11 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
304
320
|
...blockInput.getLogMeta(),
|
|
305
321
|
index: dataColumnSidecar.index,
|
|
306
322
|
});
|
|
307
|
-
|
|
323
|
+
throw new DataColumnSidecarGossipError(GossipAction.IGNORE, {
|
|
324
|
+
code: DataColumnSidecarErrorCode.ALREADY_KNOWN,
|
|
325
|
+
columnIndex: dataColumnSidecar.index,
|
|
326
|
+
slot,
|
|
327
|
+
});
|
|
308
328
|
}
|
|
309
329
|
}
|
|
310
330
|
|
|
@@ -556,6 +576,16 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
556
576
|
metrics?.dataColumns.elapsedTimeTillReceived.observe({receivedOrder: receivedColumns}, delaySec);
|
|
557
577
|
break;
|
|
558
578
|
}
|
|
579
|
+
|
|
580
|
+
if (!blockInput.hasAllData()) {
|
|
581
|
+
// immediately attempt fetch of data columns from execution engine
|
|
582
|
+
chain.getBlobsTracker.triggerGetBlobs(blockInput);
|
|
583
|
+
// if we've received at least half of the columns, trigger reconstruction of the rest
|
|
584
|
+
if (blockInput.columnCount >= NUMBER_OF_COLUMNS / 2) {
|
|
585
|
+
chain.columnReconstructionTracker.triggerColumnReconstruction(blockInput);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
559
589
|
if (!blockInput.hasBlockAndAllData()) {
|
|
560
590
|
const cutoffTimeMs = getCutoffTimeMs(chain, dataColumnSlot, BLOCK_AVAILABILITY_CUTOFF_MS);
|
|
561
591
|
chain.logger.debug("Received gossip data column, waiting for full data availability", {
|
|
@@ -578,12 +608,6 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
578
608
|
source: BlockInputSource.gossip,
|
|
579
609
|
});
|
|
580
610
|
});
|
|
581
|
-
// immediately attempt fetch of data columns from execution engine
|
|
582
|
-
chain.getBlobsTracker.triggerGetBlobs(blockInput);
|
|
583
|
-
// if we've received at least half of the columns, trigger reconstruction of the rest
|
|
584
|
-
if (blockInput.columnCount >= NUMBER_OF_COLUMNS / 2) {
|
|
585
|
-
chain.columnReconstructionTracker.triggerColumnReconstruction(blockInput);
|
|
586
|
-
}
|
|
587
611
|
}
|
|
588
612
|
},
|
|
589
613
|
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
GossipValidatorBatchFn,
|
|
12
12
|
GossipValidatorFn,
|
|
13
13
|
} from "../gossip/interface.js";
|
|
14
|
+
import {prettyPrintPeerIdStr} from "../util.ts";
|
|
14
15
|
|
|
15
16
|
export type ValidatorFnModules = {
|
|
16
17
|
config: ChainForkConfig;
|
|
@@ -99,7 +100,15 @@ export function getGossipValidatorBatchFn(
|
|
|
99
100
|
export function getGossipValidatorFn(gossipHandlers: GossipHandlers, modules: ValidatorFnModules): GossipValidatorFn {
|
|
100
101
|
const {logger, metrics} = modules;
|
|
101
102
|
|
|
102
|
-
return async function gossipValidatorFn({
|
|
103
|
+
return async function gossipValidatorFn({
|
|
104
|
+
topic,
|
|
105
|
+
msg,
|
|
106
|
+
propagationSource,
|
|
107
|
+
clientAgent,
|
|
108
|
+
clientVersion,
|
|
109
|
+
seenTimestampSec,
|
|
110
|
+
msgSlot,
|
|
111
|
+
}) {
|
|
103
112
|
const type = topic.type;
|
|
104
113
|
|
|
105
114
|
try {
|
|
@@ -134,7 +143,11 @@ export function getGossipValidatorFn(gossipHandlers: GossipHandlers, modules: Va
|
|
|
134
143
|
|
|
135
144
|
case GossipAction.REJECT:
|
|
136
145
|
metrics?.networkProcessor.gossipValidationReject.inc({topic: type});
|
|
137
|
-
logger.debug(
|
|
146
|
+
logger.debug(
|
|
147
|
+
`Gossip validation ${type} rejected`,
|
|
148
|
+
{peerId: prettyPrintPeerIdStr(propagationSource), clientAgent, clientVersion},
|
|
149
|
+
e
|
|
150
|
+
);
|
|
138
151
|
return TopicValidatorResult.Reject;
|
|
139
152
|
}
|
|
140
153
|
}
|
|
@@ -15,6 +15,8 @@ export type PendingGossipsubMessage = {
|
|
|
15
15
|
msgSlot?: Slot;
|
|
16
16
|
msgId: string;
|
|
17
17
|
propagationSource: PeerIdStr;
|
|
18
|
+
clientAgent: string;
|
|
19
|
+
clientVersion: string;
|
|
18
20
|
seenTimestampSec: number;
|
|
19
21
|
startProcessUnixSec: number | null;
|
|
20
22
|
// specific properties for IndexedGossipQueueMinSize, for beacon_attestation topic only
|
|
@@ -19,6 +19,7 @@ import {callInNextEventLoop} from "../../util/eventLoop.js";
|
|
|
19
19
|
import {NetworkCoreMetrics} from "../core/metrics.js";
|
|
20
20
|
import {INetworkEventBus, NetworkEvent} from "../events.js";
|
|
21
21
|
import {MetadataController} from "../metadata.js";
|
|
22
|
+
import {ClientKind} from "../peers/client.ts";
|
|
22
23
|
import {PeersData} from "../peers/peersData.js";
|
|
23
24
|
import {IPeerRpcScoreStore, PeerAction} from "../peers/score/index.js";
|
|
24
25
|
import {StatusCache} from "../statusCache.js";
|
|
@@ -300,10 +301,11 @@ export class ReqRespBeaconNode extends ReqResp {
|
|
|
300
301
|
}
|
|
301
302
|
|
|
302
303
|
protected onIncomingRequestBody(request: RequestTypedContainer, peer: PeerId): void {
|
|
304
|
+
const peerClient = this.peersData.getPeerKind(peer.toString()) ?? ClientKind.Unknown;
|
|
303
305
|
// Allow onRequest to return and close the stream
|
|
304
306
|
// For Goodbye there may be a race condition where the listener of `receivedGoodbye`
|
|
305
307
|
// disconnects in the same synchronous call, preventing the stream from ending cleanly
|
|
306
|
-
callInNextEventLoop(() => this.networkEventBus.emit(NetworkEvent.reqRespRequest, {request, peer}));
|
|
308
|
+
callInNextEventLoop(() => this.networkEventBus.emit(NetworkEvent.reqRespRequest, {request, peer, peerClient}));
|
|
307
309
|
}
|
|
308
310
|
|
|
309
311
|
protected onIncomingRequest(peerId: PeerId, protocol: ProtocolDescriptor): void {
|
|
@@ -1,25 +1,40 @@
|
|
|
1
|
+
import {PeerId} from "@libp2p/interface";
|
|
1
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
|
-
import {GENESIS_SLOT, isForkPostDeneb} from "@lodestar/params";
|
|
3
|
+
import {GENESIS_SLOT, isForkPostDeneb, isForkPostFulu} from "@lodestar/params";
|
|
3
4
|
import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
|
|
4
5
|
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
5
6
|
import {deneb, phase0} from "@lodestar/types";
|
|
6
7
|
import {fromHex} from "@lodestar/utils";
|
|
7
8
|
import {IBeaconChain} from "../../../chain/index.js";
|
|
8
9
|
import {IBeaconDb} from "../../../db/index.js";
|
|
10
|
+
import {prettyPrintPeerId} from "../../util.ts";
|
|
9
11
|
|
|
10
12
|
// TODO: Unit test
|
|
11
13
|
|
|
12
14
|
export async function* onBeaconBlocksByRange(
|
|
13
15
|
request: phase0.BeaconBlocksByRangeRequest,
|
|
14
16
|
chain: IBeaconChain,
|
|
15
|
-
db: IBeaconDb
|
|
17
|
+
db: IBeaconDb,
|
|
18
|
+
peerId: PeerId,
|
|
19
|
+
peerClient: string
|
|
16
20
|
): AsyncIterable<ResponseOutgoing> {
|
|
17
21
|
const {startSlot, count} = validateBeaconBlocksByRangeRequest(chain.config, request);
|
|
18
22
|
const endSlot = startSlot + count;
|
|
19
23
|
|
|
20
24
|
const finalized = db.blockArchive;
|
|
21
25
|
const unfinalized = db.block;
|
|
22
|
-
|
|
26
|
+
// in the case of initializing from a non-finalized state, we don't have the finalized block so this api does not work
|
|
27
|
+
// chain.forkChoice.getFinalizeBlock().slot
|
|
28
|
+
const finalizedSlot = chain.forkChoice.getFinalizedCheckpointSlot();
|
|
29
|
+
|
|
30
|
+
const forkName = chain.config.getForkName(startSlot);
|
|
31
|
+
if (isForkPostFulu(forkName) && startSlot < chain.earliestAvailableSlot) {
|
|
32
|
+
chain.logger.verbose("Peer did not respect earliestAvailableSlot for BeaconBlocksByRange", {
|
|
33
|
+
peer: prettyPrintPeerId(peerId),
|
|
34
|
+
client: peerClient,
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
23
38
|
|
|
24
39
|
// Finalized range of blocks
|
|
25
40
|
if (startSlot <= finalizedSlot) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {PeerId} from "@libp2p/interface";
|
|
1
2
|
import {ChainConfig} from "@lodestar/config";
|
|
2
3
|
import {GENESIS_SLOT} from "@lodestar/params";
|
|
3
4
|
import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
|
|
@@ -6,6 +7,7 @@ import {ColumnIndex, fulu} from "@lodestar/types";
|
|
|
6
7
|
import {fromHex} from "@lodestar/utils";
|
|
7
8
|
import {IBeaconChain} from "../../../chain/index.js";
|
|
8
9
|
import {IBeaconDb} from "../../../db/index.js";
|
|
10
|
+
import {prettyPrintPeerId} from "../../util.ts";
|
|
9
11
|
import {
|
|
10
12
|
handleColumnSidecarUnavailability,
|
|
11
13
|
validateRequestedDataColumns,
|
|
@@ -14,7 +16,9 @@ import {
|
|
|
14
16
|
export async function* onDataColumnSidecarsByRange(
|
|
15
17
|
request: fulu.DataColumnSidecarsByRangeRequest,
|
|
16
18
|
chain: IBeaconChain,
|
|
17
|
-
db: IBeaconDb
|
|
19
|
+
db: IBeaconDb,
|
|
20
|
+
peerId: PeerId,
|
|
21
|
+
peerClient: string
|
|
18
22
|
): AsyncIterable<ResponseOutgoing> {
|
|
19
23
|
// Non-finalized range of columns
|
|
20
24
|
const {startSlot, count, columns: requestedColumns} = validateDataColumnSidecarsByRangeRequest(chain.config, request);
|
|
@@ -25,6 +29,14 @@ export async function* onDataColumnSidecarsByRange(
|
|
|
25
29
|
return;
|
|
26
30
|
}
|
|
27
31
|
|
|
32
|
+
if (startSlot < chain.earliestAvailableSlot) {
|
|
33
|
+
chain.logger.verbose("Peer did not respect earliestAvailableSlot for DataColumnSidecarsByRange", {
|
|
34
|
+
peer: prettyPrintPeerId(peerId),
|
|
35
|
+
client: peerClient,
|
|
36
|
+
});
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
28
40
|
const finalized = db.dataColumnSidecarArchive;
|
|
29
41
|
const unfinalized = db.dataColumnSidecar;
|
|
30
42
|
const finalizedSlot = chain.forkChoice.getFinalizedBlock().slot;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {PeerId} from "@libp2p/interface";
|
|
1
2
|
import {ResponseOutgoing} from "@lodestar/reqresp";
|
|
2
3
|
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
3
4
|
import {ColumnIndex} from "@lodestar/types";
|
|
@@ -5,6 +6,7 @@ import {toRootHex} from "@lodestar/utils";
|
|
|
5
6
|
import {IBeaconChain} from "../../../chain/index.js";
|
|
6
7
|
import {IBeaconDb} from "../../../db/index.js";
|
|
7
8
|
import {DataColumnSidecarsByRootRequest} from "../../../util/types.js";
|
|
9
|
+
import {prettyPrintPeerId} from "../../util.ts";
|
|
8
10
|
import {
|
|
9
11
|
handleColumnSidecarUnavailability,
|
|
10
12
|
validateRequestedDataColumns,
|
|
@@ -13,7 +15,9 @@ import {
|
|
|
13
15
|
export async function* onDataColumnSidecarsByRoot(
|
|
14
16
|
requestBody: DataColumnSidecarsByRootRequest,
|
|
15
17
|
chain: IBeaconChain,
|
|
16
|
-
db: IBeaconDb
|
|
18
|
+
db: IBeaconDb,
|
|
19
|
+
peerId: PeerId,
|
|
20
|
+
peerClient: string
|
|
17
21
|
): AsyncIterable<ResponseOutgoing> {
|
|
18
22
|
// SPEC: minimum_request_epoch = max(current_epoch - MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS, FULU_FORK_EPOCH)
|
|
19
23
|
const currentEpoch = chain.clock.currentEpoch;
|
|
@@ -39,6 +43,14 @@ export async function* onDataColumnSidecarsByRoot(
|
|
|
39
43
|
continue;
|
|
40
44
|
}
|
|
41
45
|
|
|
46
|
+
if (slot < chain.earliestAvailableSlot) {
|
|
47
|
+
chain.logger.verbose("Peer did not respect earliestAvailableSlot for DataColumnSidecarsByRoot", {
|
|
48
|
+
peer: prettyPrintPeerId(peerId),
|
|
49
|
+
client: peerClient,
|
|
50
|
+
});
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
|
|
42
54
|
const requestedEpoch = computeEpochAtSlot(slot);
|
|
43
55
|
|
|
44
56
|
// SPEC: Clients MUST support requesting sidecars since minimum_request_epoch.
|
|
@@ -35,9 +35,9 @@ export function getReqRespHandlers({db, chain}: {db: IBeaconDb; chain: IBeaconCh
|
|
|
35
35
|
[ReqRespMethod.Goodbye]: notImplemented(ReqRespMethod.Goodbye),
|
|
36
36
|
[ReqRespMethod.Ping]: notImplemented(ReqRespMethod.Ping),
|
|
37
37
|
[ReqRespMethod.Metadata]: notImplemented(ReqRespMethod.Metadata),
|
|
38
|
-
[ReqRespMethod.BeaconBlocksByRange]: (req) => {
|
|
38
|
+
[ReqRespMethod.BeaconBlocksByRange]: (req, peerId, peerClient) => {
|
|
39
39
|
const body = ssz.phase0.BeaconBlocksByRangeRequest.deserialize(req.data);
|
|
40
|
-
return onBeaconBlocksByRange(body, chain, db);
|
|
40
|
+
return onBeaconBlocksByRange(body, chain, db, peerId, peerClient);
|
|
41
41
|
},
|
|
42
42
|
[ReqRespMethod.BeaconBlocksByRoot]: (req) => {
|
|
43
43
|
const fork = chain.config.getForkName(chain.clock.currentSlot);
|
|
@@ -53,13 +53,13 @@ export function getReqRespHandlers({db, chain}: {db: IBeaconDb; chain: IBeaconCh
|
|
|
53
53
|
const body = ssz.deneb.BlobSidecarsByRangeRequest.deserialize(req.data);
|
|
54
54
|
return onBlobSidecarsByRange(body, chain, db);
|
|
55
55
|
},
|
|
56
|
-
[ReqRespMethod.DataColumnSidecarsByRange]: (req) => {
|
|
56
|
+
[ReqRespMethod.DataColumnSidecarsByRange]: (req, peerId, peerClient) => {
|
|
57
57
|
const body = ssz.fulu.DataColumnSidecarsByRangeRequest.deserialize(req.data);
|
|
58
|
-
return onDataColumnSidecarsByRange(body, chain, db);
|
|
58
|
+
return onDataColumnSidecarsByRange(body, chain, db, peerId, peerClient);
|
|
59
59
|
},
|
|
60
|
-
[ReqRespMethod.DataColumnSidecarsByRoot]: (req) => {
|
|
60
|
+
[ReqRespMethod.DataColumnSidecarsByRoot]: (req, peerId, peerClient) => {
|
|
61
61
|
const body = DataColumnSidecarsByRootRequestType(chain.config).deserialize(req.data);
|
|
62
|
-
return onDataColumnSidecarsByRoot(body, chain, db);
|
|
62
|
+
return onDataColumnSidecarsByRoot(body, chain, db, peerId, peerClient);
|
|
63
63
|
},
|
|
64
64
|
|
|
65
65
|
[ReqRespMethod.LightClientBootstrap]: (req) => {
|
package/src/node/nodejs.ts
CHANGED
|
@@ -53,6 +53,7 @@ export type BeaconNodeInitModules = {
|
|
|
53
53
|
dataDir: string;
|
|
54
54
|
peerStoreDir?: string;
|
|
55
55
|
anchorState: BeaconStateAllForks;
|
|
56
|
+
isAnchorStateFinalized: boolean;
|
|
56
57
|
wsCheckpoint?: phase0.Checkpoint;
|
|
57
58
|
metricsRegistries?: Registry[];
|
|
58
59
|
};
|
|
@@ -154,6 +155,7 @@ export class BeaconNode {
|
|
|
154
155
|
dataDir,
|
|
155
156
|
peerStoreDir,
|
|
156
157
|
anchorState,
|
|
158
|
+
isAnchorStateFinalized,
|
|
157
159
|
wsCheckpoint,
|
|
158
160
|
metricsRegistries = [],
|
|
159
161
|
}: BeaconNodeInitModules): Promise<T> {
|
|
@@ -217,6 +219,7 @@ export class BeaconNode {
|
|
|
217
219
|
metrics,
|
|
218
220
|
validatorMonitor,
|
|
219
221
|
anchorState,
|
|
222
|
+
isAnchorStateFinalized,
|
|
220
223
|
eth1: initializeEth1ForBlockProduction(opts.eth1, {
|
|
221
224
|
config,
|
|
222
225
|
db,
|
package/src/sync/range/range.ts
CHANGED
|
@@ -114,13 +114,14 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
|
|
|
114
114
|
*/
|
|
115
115
|
addPeer(peerId: PeerIdStr, localStatus: Status, peerStatus: Status): void {
|
|
116
116
|
// Compute if we should do a Finalized or Head sync with this peer
|
|
117
|
-
const {syncType, startEpoch, target} = getRangeSyncTarget(localStatus, peerStatus, this.chain
|
|
117
|
+
const {syncType, startEpoch, target} = getRangeSyncTarget(localStatus, peerStatus, this.chain);
|
|
118
118
|
this.logger.debug("Sync peer joined", {
|
|
119
119
|
peer: peerId,
|
|
120
120
|
syncType,
|
|
121
121
|
startEpoch,
|
|
122
122
|
targetSlot: target.slot,
|
|
123
123
|
targetRoot: toRootHex(target.root),
|
|
124
|
+
localHeadSlot: localStatus.headSlot,
|
|
124
125
|
earliestAvailableSlot: (peerStatus as fulu.Status).earliestAvailableSlot ?? Infinity,
|
|
125
126
|
});
|
|
126
127
|
|
package/src/sync/unknownBlock.ts
CHANGED
|
@@ -532,7 +532,7 @@ export class BlockInputSync {
|
|
|
532
532
|
const downloadResult = await downloadByRoot({
|
|
533
533
|
config: this.config,
|
|
534
534
|
network: this.network,
|
|
535
|
-
|
|
535
|
+
chain: this.chain,
|
|
536
536
|
emitter: this.chain.emitter,
|
|
537
537
|
peerMeta,
|
|
538
538
|
cacheItem,
|