@lodestar/beacon-node 1.36.0-dev.6f46a8bd20 → 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 +29 -1
- 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/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 +21 -14
- package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
- package/lib/chain/errors/dataColumnSidecarError.js +4 -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 +64 -19
- 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/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 +6 -1
- 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/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 +15 -1
- 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/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 +20 -15
- package/src/api/impl/beacon/blocks/index.ts +47 -25
- package/src/api/impl/lodestar/index.ts +36 -1
- package/src/api/impl/node/utils.ts +1 -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 +31 -16
- 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 +76 -19
- package/src/index.ts +2 -0
- package/src/network/core/networkCore.ts +5 -1
- package/src/network/core/networkCoreWorker.ts +7 -2
- package/src/network/core/networkCoreWorkerHandler.ts +1 -1
- 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 +16 -1
- 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/sszBytes.ts +30 -0
|
@@ -73,7 +73,7 @@ export class WorkerNetworkCore implements INetworkCore {
|
|
|
73
73
|
// Handles ReqResp response from worker and calls async generator in main thread
|
|
74
74
|
this.reqRespBridgeRespHandler = new AsyncIterableBridgeHandler(
|
|
75
75
|
getReqRespBridgeRespEvents(this.reqRespBridgeEventBus),
|
|
76
|
-
(data) => modules.getReqRespHandler(data.method)(data.req, peerIdFromString(data.peerId))
|
|
76
|
+
(data) => modules.getReqRespHandler(data.method)(data.req, peerIdFromString(data.peerId), data.peerClient)
|
|
77
77
|
);
|
|
78
78
|
|
|
79
79
|
wireEventsOnMainThread<NetworkEventData>(
|
package/src/network/events.ts
CHANGED
|
@@ -29,7 +29,7 @@ export type NetworkEventData = {
|
|
|
29
29
|
clientAgent: string;
|
|
30
30
|
};
|
|
31
31
|
[NetworkEvent.peerDisconnected]: {peer: PeerIdStr};
|
|
32
|
-
[NetworkEvent.reqRespRequest]: {request: RequestTypedContainer; peer: PeerId};
|
|
32
|
+
[NetworkEvent.reqRespRequest]: {request: RequestTypedContainer; peer: PeerId; peerClient: string};
|
|
33
33
|
[NetworkEvent.pendingGossipsubMessage]: PendingGossipsubMessage;
|
|
34
34
|
[NetworkEvent.gossipMessageValidationResult]: {
|
|
35
35
|
msgId: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {Message} from "@libp2p/interface";
|
|
2
|
-
import {compress, uncompress} from "snappyjs";
|
|
3
2
|
import xxhashFactory from "xxhash-wasm";
|
|
3
|
+
import {compress, uncompress} from "#snappy";
|
|
4
4
|
import {digest} from "@chainsafe/as-sha256";
|
|
5
5
|
import {RPC} from "@chainsafe/libp2p-gossipsub/message";
|
|
6
6
|
import {DataTransform} from "@chainsafe/libp2p-gossipsub/types";
|
|
@@ -296,6 +296,10 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
296
296
|
// Get seenTimestamp before adding the message to the queue or add async delays
|
|
297
297
|
const seenTimestampSec = Date.now() / 1000;
|
|
298
298
|
|
|
299
|
+
const peerIdStr = propagationSource.toString();
|
|
300
|
+
const clientAgent = this.peersData.getPeerKind(peerIdStr) ?? "Unknown";
|
|
301
|
+
const clientVersion = this.peersData.getAgentVersion(peerIdStr);
|
|
302
|
+
|
|
299
303
|
// Use setTimeout to yield to the macro queue
|
|
300
304
|
// Without this we'll have huge event loop lag
|
|
301
305
|
// See https://github.com/ChainSafe/lodestar/issues/5604
|
|
@@ -305,7 +309,9 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
305
309
|
msg,
|
|
306
310
|
msgId,
|
|
307
311
|
// Hot path, use cached .toString() version
|
|
308
|
-
propagationSource:
|
|
312
|
+
propagationSource: peerIdStr,
|
|
313
|
+
clientVersion,
|
|
314
|
+
clientAgent,
|
|
309
315
|
seenTimestampSec,
|
|
310
316
|
startProcessUnixSec: null,
|
|
311
317
|
});
|
package/src/network/metadata.ts
CHANGED
|
@@ -126,7 +126,7 @@ export class MetadataController {
|
|
|
126
126
|
* 2. Network MUST call this method on fork transition.
|
|
127
127
|
* Current Clock implementation ensures no race conditions, epoch is correct if re-fetched
|
|
128
128
|
*/
|
|
129
|
-
updateEth2Field(epoch: Epoch):
|
|
129
|
+
updateEth2Field(epoch: Epoch): phase0.ENRForkID {
|
|
130
130
|
const config = this.networkConfig.config;
|
|
131
131
|
const enrForkId = getENRForkID(config, epoch);
|
|
132
132
|
const {forkDigest, nextForkVersion, nextForkEpoch} = enrForkId;
|
|
@@ -143,6 +143,8 @@ export class MetadataController {
|
|
|
143
143
|
: ssz.ForkDigest.defaultValue();
|
|
144
144
|
this.onSetValue(ENRKey.nfd, nextForkDigest);
|
|
145
145
|
this.logger.debug("Updated nfd field in ENR", {nextForkDigest: toHex(nextForkDigest)});
|
|
146
|
+
|
|
147
|
+
return enrForkId;
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
150
|
|
package/src/network/options.ts
CHANGED
|
@@ -391,8 +391,8 @@ export class PeerDiscovery {
|
|
|
391
391
|
// tcp multiaddr is known to be be present, checked inside the worker
|
|
392
392
|
const multiaddrTCP = enr.getLocationMultiaddr(ENRKey.tcp);
|
|
393
393
|
if (!multiaddrTCP) {
|
|
394
|
-
this.logger.
|
|
395
|
-
this.metrics?.discovery.discoveredStatus.inc({status: DiscoveredPeerStatus.
|
|
394
|
+
this.logger.warn("Discv5 worker sent enr without tcp multiaddr", {enr: enr.encodeTxt()});
|
|
395
|
+
this.metrics?.discovery.discoveredStatus.inc({status: DiscoveredPeerStatus.no_multiaddrs});
|
|
396
396
|
return;
|
|
397
397
|
}
|
|
398
398
|
// Are this fields mandatory?
|
|
@@ -296,6 +296,21 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
296
296
|
const slot = dataColumnBlockHeader.slot;
|
|
297
297
|
const blockRootHex = toRootHex(ssz.phase0.BeaconBlockHeader.hashTreeRoot(dataColumnBlockHeader));
|
|
298
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
|
+
|
|
299
314
|
// first check if we should even process this column (we may have already processed it via getBlobsV2)
|
|
300
315
|
{
|
|
301
316
|
const blockInput = chain.seenBlockInputCache.get(blockRootHex);
|
|
@@ -307,7 +322,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
307
322
|
});
|
|
308
323
|
throw new DataColumnSidecarGossipError(GossipAction.IGNORE, {
|
|
309
324
|
code: DataColumnSidecarErrorCode.ALREADY_KNOWN,
|
|
310
|
-
|
|
325
|
+
columnIndex: dataColumnSidecar.index,
|
|
311
326
|
slot,
|
|
312
327
|
});
|
|
313
328
|
}
|
|
@@ -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,
|