"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkGossipPayload = checkGossipPayload;
const console_1 = require("console");
const NodeList = __importStar(require("../p2p/NodeList"));
const CycleCreator = __importStar(require("../p2p/CycleCreator"));
const nestedCounters_1 = require("../utils/nestedCounters");
const logger_1 = require("../logger");
const utils = __importStar(require("../utils"));
const v2_1 = require("../p2p/Join/v2");
const CycleChain = __importStar(require("../p2p/CycleChain"));
/**
 * Validate payload structure; ignore gossip not in Q1 or Q2; if original sender, only accept in Q1.
 * @param payload - The gossip payload to validate.
 * @param validationSchema - The schema against which to validate the payload.
 * @param logContext - Contextual log information.
 * @param sender - The sender of the gossip.
 * @returns {boolean} - True if the payload is valid, false otherwise.
 */
function checkGossipPayload(payload, validationSchema, logContext, sender) {
    if (!payload) {
        if (logger_1.logFlags.error)
            (0, console_1.warn)(`${logContext}-reject: missing payload`);
        return false;
    }
    // Check if the current quarter is either 1 or 2
    if (![1, 2].includes(CycleCreator.currentQuarter)) {
        // count the event if the current quarter is not 1 or 2
        nestedCounters_1.nestedCountersInstance.countEvent('p2p', `${logContext}-reject: not in Q1 or Q2. currentCycle: ${CycleCreator.currentCycle} `);
        // Log warnings if error logging is enabled
        if (logger_1.logFlags.error) {
            (0, console_1.warn)(`${logContext}-reject: not in Q1 or Q2, currentQuarter: ${CycleCreator.currentQuarter}`);
        }
        return false;
    }
    // Verify if the original sender is known to us
    let signer = null;
    if (logContext === 'gossip-unjoin') {
        const nodeIfSelectedLastCycle = CycleChain.newest.joinedConsensors.find((node) => node.publicKey === payload.sign.owner);
        if (nodeIfSelectedLastCycle) {
            signer = NodeList.byPubKey.get(payload.sign.owner);
            if (!signer) {
                if (logger_1.logFlags.error)
                    (0, console_1.warn)(`${logContext}: Got ${logContext} from standby node that was selected to join, but can't find it in NodeList.byPubKey`);
                return false;
            }
        }
        else {
            signer = (0, v2_1.getStandbyNodesInfoMap)().get(payload.sign.owner);
            if (!signer) {
                if (logger_1.logFlags.error)
                    (0, console_1.warn)(`${logContext}: Got ${logContext} from unknown standby node`);
                return false;
            }
        }
    }
    else {
        signer = NodeList.byPubKey.get(payload.sign.owner);
        if (!signer) {
            if (logger_1.logFlags.error)
                (0, console_1.warn)(`${logContext}: Got ${logContext} from unknown node`);
            return false;
        }
    }
    // Only accept original transactions in quarter 1
    const isOrig = signer.id === sender;
    if (isOrig && CycleCreator.currentQuarter > 1) {
        if (logger_1.logFlags.error)
            nestedCounters_1.nestedCountersInstance.countEvent('p2p', `${logContext}-reject: CycleCreator.currentQuarter > 1, currentQuarter: ${CycleCreator.currentQuarter}`);
        return false;
    }
    let err = utils.validateTypes(payload, validationSchema);
    if (err) {
        if (logger_1.logFlags.error)
            (0, console_1.warn)(`${logContext}-reject: bad input ${err}`);
        return false;
    }
    // If 'sign' is part of the schema, validate its structure
    if (validationSchema.sign) {
        err = utils.validateTypes(payload.sign, {
            owner: 's',
            sig: 's',
        });
        if (err) {
            if (logger_1.logFlags.error)
                (0, console_1.warn)(`${logContext}-reject: bad input sign ${err}`);
            return false;
        }
    }
    else {
        if (logger_1.logFlags.error)
            (0, console_1.warn)(`${logContext}-reject: missing sign`);
        return false;
    }
    return true;
}
//# sourceMappingURL=GossipValidation.js.map