import { getBlsToExecutionChangeSignatureSet, isValidBlsToExecutionChange } from "@lodestar/state-transition";
import { BlsToExecutionChangeError, BlsToExecutionChangeErrorCode, GossipAction } from "../errors/index.js";
export async function validateApiBlsToExecutionChange(chain, blsToExecutionChange) {
    const ignoreExists = true;
    const prioritizeBls = true;
    return validateBlsToExecutionChange(chain, blsToExecutionChange, { ignoreExists, prioritizeBls });
}
export async function validateGossipBlsToExecutionChange(chain, blsToExecutionChange) {
    return validateBlsToExecutionChange(chain, blsToExecutionChange);
}
async function validateBlsToExecutionChange(chain, blsToExecutionChange, opts = { ignoreExists: false, prioritizeBls: false }) {
    const { ignoreExists, prioritizeBls } = opts;
    // [IGNORE] The blsToExecutionChange is the first valid blsToExecutionChange received for the validator with index
    // signedBLSToExecutionChange.message.validatorIndex.
    if (!ignoreExists && chain.opPool.hasSeenBlsToExecutionChange(blsToExecutionChange.message.validatorIndex)) {
        throw new BlsToExecutionChangeError(GossipAction.IGNORE, {
            code: BlsToExecutionChangeErrorCode.ALREADY_EXISTS,
        });
    }
    // validate bls to executionChange
    // NOTE: No need to advance head state since the signature's fork is handled with `broadcastedOnFork`,
    // and chanes relevant to `isValidBlsToExecutionChange()` happen only on processBlock(), not processEpoch()
    const state = chain.getHeadState();
    const { config } = chain;
    const addressChange = blsToExecutionChange.message;
    if (addressChange.validatorIndex >= state.validators.length) {
        throw new BlsToExecutionChangeError(GossipAction.REJECT, {
            code: BlsToExecutionChangeErrorCode.INVALID,
        });
    }
    const validator = state.validators.getReadonly(addressChange.validatorIndex);
    // [REJECT] All of the conditions within process_bls_to_execution_change pass validation.
    // verifySignature = false, verified in batch below
    const { valid } = isValidBlsToExecutionChange(config, validator, blsToExecutionChange, false);
    if (!valid) {
        throw new BlsToExecutionChangeError(GossipAction.REJECT, {
            code: BlsToExecutionChangeErrorCode.INVALID,
        });
    }
    const signatureSet = getBlsToExecutionChangeSignatureSet(config, blsToExecutionChange);
    if (!(await chain.bls.verifySignatureSets([signatureSet], { batchable: true, priority: prioritizeBls }))) {
        throw new BlsToExecutionChangeError(GossipAction.REJECT, {
            code: BlsToExecutionChangeErrorCode.INVALID_SIGNATURE,
        });
    }
}
//# sourceMappingURL=blsToExecutionChange.js.map