@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
105 lines • 4.72 kB
JavaScript
import { ForkSeq } from "@lodestar/params";
import { computeStartSlotAtEpoch } from "@lodestar/state-transition";
import { ssz } from "@lodestar/types";
import { toHex } from "@lodestar/utils";
import { FAR_FUTURE_EPOCH } from "../constants/index.js";
import { getCurrentAndNextForkBoundary } from "./forks.js";
export var ENRKey;
(function (ENRKey) {
ENRKey["tcp"] = "tcp";
ENRKey["eth2"] = "eth2";
ENRKey["attnets"] = "attnets";
ENRKey["syncnets"] = "syncnets";
ENRKey["nfd"] = "nfd";
})(ENRKey || (ENRKey = {}));
export var SubnetType;
(function (SubnetType) {
SubnetType["attnets"] = "attnets";
SubnetType["syncnets"] = "syncnets";
})(SubnetType || (SubnetType = {}));
/**
* Implementation of Ethereum Consensus p2p MetaData.
* For the spec that this code is based on, see:
* https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#metadata
*/
export class MetadataController {
constructor(opts, modules) {
this.config = modules.config;
this.logger = modules.logger;
this.onSetValue = modules.onSetValue;
this._metadata = opts.metadata || ssz.altair.Metadata.defaultValue();
}
upstreamValues(currentEpoch) {
// updateEth2Field() MUST be called with clock epoch
this.updateEth2Field(currentEpoch);
this.onSetValue(ENRKey.attnets, ssz.phase0.AttestationSubnets.serialize(this._metadata.attnets));
if (this.config.getForkSeq(computeStartSlotAtEpoch(currentEpoch)) >= ForkSeq.altair) {
// Only persist syncnets if altair fork is already activated. If currentFork is altair but head is phase0
// adding syncnets to the ENR is not a problem, we will just have a useless field for a few hours.
this.onSetValue(ENRKey.syncnets, ssz.phase0.AttestationSubnets.serialize(this._metadata.syncnets));
}
}
get seqNumber() {
return this._metadata.seqNumber;
}
get syncnets() {
return this._metadata.syncnets;
}
set syncnets(syncnets) {
this.onSetValue(ENRKey.syncnets, ssz.altair.SyncSubnets.serialize(syncnets));
this._metadata.syncnets = syncnets;
}
get attnets() {
return this._metadata.attnets;
}
set attnets(attnets) {
this.onSetValue(ENRKey.attnets, ssz.phase0.AttestationSubnets.serialize(attnets));
this._metadata.seqNumber++;
this._metadata.attnets = attnets;
}
/** Consumers that need the phase0.Metadata type can just ignore the .syncnets property */
get json() {
return this._metadata;
}
/**
* From spec:
* fork_digest is compute_fork_digest(current_fork_version, genesis_validators_root) where
* - current_fork_version is the fork version at the node's current epoch defined by the wall-clock time (not
* necessarily the epoch to which the node is sync)
* - genesis_validators_root is the static Root found in state.genesis_validators_root
* - epoch of fork boundary is used to get blob parameters of current Blob Parameter Only (BPO) fork
*
* 1. MUST be called on start to populate ENR
* 2. Network MUST call this method on fork transition.
* Current Clock implementation ensures no race conditions, epoch is correct if re-fetched
*/
updateEth2Field(epoch) {
const enrForkId = getENRForkID(this.config, epoch);
const { forkDigest, nextForkVersion, nextForkEpoch } = enrForkId;
this.onSetValue(ENRKey.eth2, ssz.phase0.ENRForkID.serialize(enrForkId));
this.logger.debug("Updated eth2 field in ENR", {
forkDigest: toHex(forkDigest),
nextForkVersion: toHex(nextForkVersion),
nextForkEpoch,
});
const nextForkDigest = nextForkEpoch !== FAR_FUTURE_EPOCH
? this.config.forkBoundary2ForkDigest(this.config.getForkBoundaryAtEpoch(nextForkEpoch))
: ssz.ForkDigest.defaultValue();
this.onSetValue(ENRKey.nfd, nextForkDigest);
this.logger.debug("Updated nfd field in ENR", { nextForkDigest: toHex(nextForkDigest) });
}
}
export function getENRForkID(config, clockEpoch) {
const { currentBoundary, nextBoundary } = getCurrentAndNextForkBoundary(config, clockEpoch);
return {
// Current fork digest
forkDigest: config.forkBoundary2ForkDigest(currentBoundary),
// Next planned fork version
nextForkVersion: nextBoundary
? config.forks[nextBoundary.fork].version
: config.forks[currentBoundary.fork].version,
// Next fork epoch
nextForkEpoch: nextBoundary ? nextBoundary.epoch : FAR_FUTURE_EPOCH,
};
}
//# sourceMappingURL=metadata.js.map