Skip to content

Commit d10eb2f

Browse files
feat: assert fork digest to match our current fork (#7950)
Currently we only check if the incoming peer's ENR's fork digest is known by ours. As long as it matches one of the fork digest, it will pass our check. This PR asserts the fork digest must be of our current fork. --------- Co-authored-by: Nazar Hussain <nazarhussain@gmail.com>
1 parent 0be30f6 commit d10eb2f

File tree

5 files changed

+26
-3
lines changed

5 files changed

+26
-3
lines changed

packages/beacon-node/src/network/discv5/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type Discv5Opts = {
1414
discv5: LodestarDiscv5Opts;
1515
logger: LoggerNode;
1616
config: BeaconConfig;
17+
genesisTime: number;
1718
metrics?: NetworkCoreMetrics;
1819
};
1920

@@ -48,6 +49,7 @@ export class Discv5Worker extends (EventEmitter as {new (): StrictEventEmitter<E
4849
chainConfig: chainConfigFromJson(chainConfigToJson(opts.config)),
4950
genesisValidatorsRoot: opts.config.genesisValidatorsRoot,
5051
loggerOpts: opts.logger.toOpts(),
52+
genesisTime: opts.genesisTime,
5153
};
5254
const worker = new Worker("./worker.js", {workerData} as ConstructorParameters<typeof Worker>[1]);
5355

packages/beacon-node/src/network/discv5/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export interface Discv5WorkerData {
3939
chainConfig: ChainConfig;
4040
genesisValidatorsRoot: Uint8Array;
4141
loggerOpts: LoggerNodeOpts;
42+
genesisTime: number;
4243
}
4344

4445
/**

packages/beacon-node/src/network/discv5/utils.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import {ENR} from "@chainsafe/enr";
22
import {BeaconConfig} from "@lodestar/config";
3+
import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../../constants/constants.js";
4+
import {IClock} from "../../util/clock.js";
35
import {ENRKey} from "../metadata.js";
46

57
export enum ENRRelevance {
68
no_tcp = "no_tcp",
79
no_eth2 = "no_eth2",
810
// biome-ignore lint/style/useNamingConvention: Need to use the this name for network convention
911
unknown_forkDigest = "unknown_forkDigest",
12+
current_fork_mismatch = "current_fork_mismatch",
1013
relevant = "relevant",
1114
}
1215

13-
export function enrRelevance(enr: ENR, config: BeaconConfig): ENRRelevance {
16+
export function enrRelevance(enr: ENR, config: BeaconConfig, clock: IClock): ENRRelevance {
1417
// We are not interested in peers that don't advertise their tcp addr
1518
const multiaddrTCP = enr.getLocationMultiaddr(ENRKey.tcp);
1619
if (!multiaddrTCP) {
@@ -31,7 +34,16 @@ export function enrRelevance(enr: ENR, config: BeaconConfig): ENRRelevance {
3134
return ENRRelevance.unknown_forkDigest;
3235
}
3336

34-
// TODO: Then check if the next fork info matches ours
37+
// Check if fork digest's fork matches ours
38+
const currentSlot = clock.slotWithFutureTolerance(MAXIMUM_GOSSIP_CLOCK_DISPARITY);
39+
const localForkInfo = config.getForkInfo(currentSlot);
40+
// We only connect if the ENR's fork matches our current fork.
41+
// We also allow it to be the previous fork due to delay and infrequent update of DHT.
42+
if (forkName !== localForkInfo.name && forkName !== localForkInfo.prevForkName) {
43+
return ENRRelevance.current_fork_mismatch;
44+
}
45+
46+
// TODO: If we have next fork scheduled, check if next fork info matches ours
3547
// const enrForkId = ssz.phase0.ENRForkID.deserialize(eth2);
3648

3749
return ENRRelevance.relevant;

packages/beacon-node/src/network/discv5/worker.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {Gauge} from "@lodestar/utils";
1313
import {Multiaddr, multiaddr} from "@multiformats/multiaddr";
1414
import {RegistryMetricCreator} from "../../metrics/index.js";
1515
import {collectNodeJSMetrics} from "../../metrics/nodeJsMetrics.js";
16+
import {Clock} from "../../util/clock.js";
1617
import {profileNodeJS, writeHeapSnapshot} from "../../util/profile.js";
1718
import {Discv5WorkerApi, Discv5WorkerData} from "./types.js";
1819
import {ENRRelevance, enrRelevance} from "./utils.js";
@@ -68,8 +69,12 @@ for (const bootEnr of workerData.bootEnrs) {
6869
/** Used to push discovered ENRs */
6970
const subject = new Subject<ENRData>();
7071

72+
/** Define a new clock */
73+
const abortController = new AbortController();
74+
const clock = new Clock({config, genesisTime: workerData.genesisTime, signal: abortController.signal});
75+
7176
const onDiscovered = (enr: ENR): void => {
72-
const status = enrRelevance(enr, config);
77+
const status = enrRelevance(enr, config, clock);
7378
enrRelevanceMetric?.inc({status});
7479
if (status === ENRRelevance.relevant) {
7580
subject.next(enr.toObject());

packages/beacon-node/src/network/peers/discover.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {ATTESTATION_SUBNET_COUNT, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/p
66
import {SubnetID} from "@lodestar/types";
77
import {pruneSetToMax, sleep} from "@lodestar/utils";
88
import {Multiaddr} from "@multiformats/multiaddr";
9+
import {IClock} from "../../util/clock.js";
910
import {NetworkCoreMetrics} from "../core/metrics.js";
1011
import {Discv5Worker} from "../discv5/index.js";
1112
import {LodestarDiscv5Opts} from "../discv5/types.js";
@@ -30,6 +31,7 @@ export type PeerDiscoveryOpts = {
3031
export type PeerDiscoveryModules = {
3132
privateKey: PrivateKey;
3233
libp2p: Libp2p;
34+
clock: IClock;
3335
peerRpcScores: IPeerRpcScoreStore;
3436
metrics: NetworkCoreMetrics | null;
3537
logger: LoggerNode;
@@ -165,6 +167,7 @@ export class PeerDiscovery {
165167
metrics: modules.metrics ?? undefined,
166168
logger: modules.logger,
167169
config: modules.config,
170+
genesisTime: modules.clock.genesisTime,
168171
});
169172

170173
return new PeerDiscovery(modules, opts, discv5);

0 commit comments

Comments
 (0)