"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.XrpVerificationPeer = void 0;
const logger_1 = __importDefault(require("../../../logger"));
const block_1 = require("../models/block");
const p2p_1 = require("../p2p");
class XrpVerificationPeer extends p2p_1.XrpP2pWorker {
    constructor() {
        super(...arguments);
        this.prevBlockNum = 0;
        this.prevHash = '';
        this.nextBlockHash = '';
        this.deepScan = false;
    }
    enableDeepScan() {
        this.deepScan = true;
    }
    disableDeepScan() {
        this.deepScan = false;
    }
    async setupListeners() {
        this.events.on('connected', async () => {
            this.client?.emitter.on('ledger', async (block) => {
                const transformedBlock = this.provider.transformLedger(block, this.network);
                this.events.emit('block', transformedBlock);
            });
        });
    }
    async resync(start, end) {
        const { chain, network } = this;
        const client = await this.provider.getClient(this.network);
        let currentHeight = Math.max(1, start);
        while (currentHeight <= end) {
            let lastLog = Date.now();
            const block = await client.getBlock({
                index: currentHeight,
                transactions: true,
                expand: true
            });
            const transformedBlock = this.provider.transformLedger(block, network);
            const nextBlock = await block_1.XrpBlockStorage.collection.findOne({
                chain,
                network,
                previousBlockHash: transformedBlock.hash
            });
            const coinsAndTxs = (block.transactions || [])
                .map((tx) => ({
                tx: this.provider.transform(tx, network, transformedBlock),
                coins: this.provider.transformToCoins(tx, network)
            }))
                .filter(data => {
                return 'txid' in data.tx && data.tx.txid != null;
            });
            const blockTxs = new Array();
            const blockCoins = new Array();
            for (const coinAndTx of coinsAndTxs) {
                const { transaction, coins } = await this.provider.tag(chain, network, coinAndTx.tx, coinAndTx.coins);
                if (this.chainConfig.walletOnlySync && !transaction.wallets.length) {
                    continue;
                }
                blockTxs.push(transaction);
                blockCoins.push(...coins);
            }
            if (nextBlock) {
                transformedBlock.nextBlockHash = nextBlock.hash;
            }
            await this.blockModel.processBlock({
                chain,
                network,
                block: transformedBlock,
                transactions: blockTxs,
                coins: blockCoins,
                initialSyncComplete: true
            });
            currentHeight++;
            if (Date.now() - lastLog > 100) {
                logger_1.default.info('Re-Sync: %o', {
                    chain,
                    network,
                    height: currentHeight
                });
                lastLog = Date.now();
            }
        }
    }
    async getBlockForNumber(blockNum) {
        return this.getBlock(blockNum);
    }
    async validateDataForBlock(blockNum, _, log = false) {
        let success = true;
        const { chain, network } = this;
        const errors = new Array();
        const block = await this.blockModel.collection.findOne({
            chain,
            network,
            height: blockNum,
            processed: true
        });
        if (!block) {
            success = false;
            const error = {
                model: 'block',
                err: true,
                type: 'MISSING_BLOCK',
                payload: { blockNum }
            };
            errors.push(error);
            if (log) {
                console.log(JSON.stringify(error));
            }
            return { success, errors };
        }
        return { success, errors };
    }
}
exports.XrpVerificationPeer = XrpVerificationPeer;
//# sourceMappingURL=verification.js.map