import { Signature, aggregatePublicKeys, aggregateSignatures, verify } from "@chainsafe/blst";
import { verifySignatureSetsMaybeBatch } from "./maybeBatch.js";
import { getAggregatedPubkey, getAggregatedPubkeysCount } from "./utils.js";
export class BlsSingleThreadVerifier {
    metrics;
    pubkeyCache;
    constructor({ metrics = null, pubkeyCache }) {
        this.metrics = metrics;
        this.pubkeyCache = pubkeyCache;
    }
    async verifySignatureSets(sets) {
        this.metrics?.bls.aggregatedPubkeys.inc(getAggregatedPubkeysCount(sets));
        const setsAggregated = sets.map((set) => ({
            publicKey: getAggregatedPubkey(set, this.pubkeyCache, this.metrics),
            message: set.signingRoot,
            signature: set.signature,
        }));
        // Count time after aggregating
        const timer = this.metrics?.blsThreadPool.mainThreadDurationInThreadPool.startTimer();
        const isValid = verifySignatureSetsMaybeBatch(setsAggregated);
        // Don't use a try/catch, only count run without exceptions
        if (timer) {
            timer();
        }
        return isValid;
    }
    async verifySignatureSetsSameMessage(sets, message) {
        const timer = this.metrics?.blsThreadPool.mainThreadDurationInThreadPool.startTimer();
        const pubkey = aggregatePublicKeys(sets.map((set) => set.publicKey));
        let isAllValid = true;
        // validate signature = true
        const signatures = sets.map((set) => {
            try {
                return Signature.fromBytes(set.signature, true);
            }
            catch (_) {
                // at least one set has malformed signature
                isAllValid = false;
                return null;
            }
        });
        if (isAllValid) {
            const signature = aggregateSignatures(signatures);
            isAllValid = verify(message, pubkey, signature);
        }
        let result;
        if (isAllValid) {
            result = sets.map(() => true);
        }
        else {
            result = sets.map((set, i) => {
                const sig = signatures[i];
                if (sig === null) {
                    return false;
                }
                return verify(message, set.publicKey, sig);
            });
        }
        if (timer) {
            timer();
        }
        return result;
    }
    async close() {
        // nothing to do
    }
    canAcceptWork() {
        // Since sigs are verified blocking the main thread, there's no mechanism to throttle
        return true;
    }
}
//# sourceMappingURL=singleThread.js.map