@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
41 lines • 2.33 kB
JavaScript
import { getVoluntaryExitSignatureSet, isValidVoluntaryExit } from "@lodestar/state-transition";
import { GossipAction, VoluntaryExitError, VoluntaryExitErrorCode } from "../errors/index.js";
import { RegenCaller } from "../regen/index.js";
export async function validateApiVoluntaryExit(chain, voluntaryExit) {
const prioritizeBls = true;
return validateVoluntaryExit(chain, voluntaryExit, prioritizeBls);
}
export async function validateGossipVoluntaryExit(chain, voluntaryExit) {
return validateVoluntaryExit(chain, voluntaryExit);
}
async function validateVoluntaryExit(chain, voluntaryExit, prioritizeBls = false) {
// [IGNORE] The voluntary exit is the first valid voluntary exit received for the validator with index
// signed_voluntary_exit.message.validator_index.
if (chain.opPool.hasSeenVoluntaryExit(voluntaryExit.message.validatorIndex)) {
throw new VoluntaryExitError(GossipAction.IGNORE, {
code: VoluntaryExitErrorCode.ALREADY_EXISTS,
});
}
// What state should the voluntaryExit validate against?
//
// The only condition that is time sensitive and may require a non-head state is
// -> Validator is active && validator has not initiated exit
// The voluntaryExit.epoch must be in the past but the validator's status may change in recent epochs.
// We dial the head state to the current epoch to get the current status of the validator. This is
// relevant on periods of many skipped slots.
const state = await chain.getHeadStateAtCurrentEpoch(RegenCaller.validateGossipVoluntaryExit);
// [REJECT] All of the conditions within process_voluntary_exit pass validation.
// verifySignature = false, verified in batch below
if (!isValidVoluntaryExit(chain.config.getForkSeq(state.slot), state, voluntaryExit, false)) {
throw new VoluntaryExitError(GossipAction.REJECT, {
code: VoluntaryExitErrorCode.INVALID,
});
}
const signatureSet = getVoluntaryExitSignatureSet(state, voluntaryExit);
if (!(await chain.bls.verifySignatureSets([signatureSet], { batchable: true, priority: prioritizeBls }))) {
throw new VoluntaryExitError(GossipAction.REJECT, {
code: VoluntaryExitErrorCode.INVALID_SIGNATURE,
});
}
}
//# sourceMappingURL=voluntaryExit.js.map