"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AcrossConfigStoreClient = exports.GLOBAL_CONFIG_STORE_KEYS = exports.DEFAULT_CONFIG_STORE_VERSION = void 0;
var tslib_1 = require("tslib");
var sdk_1 = require("@uma/sdk");
var assert_1 = tslib_1.__importDefault(require("assert"));
var typeguards_1 = require("../../typeguards");
var utils_1 = require("../../utils");
var constants_1 = require("../../constants");
var JSONUtils_1 = require("../../utils/JSONUtils");
var BaseAbstractClient_1 = require("../BaseAbstractClient");
var rateModel_1 = require("../../lpFeeCalculator/rateModel");
exports.DEFAULT_CONFIG_STORE_VERSION = 0;
var GLOBAL_CONFIG_STORE_KEYS;
(function (GLOBAL_CONFIG_STORE_KEYS) {
    GLOBAL_CONFIG_STORE_KEYS["MAX_RELAYER_REPAYMENT_LEAF_SIZE"] = "MAX_RELAYER_REPAYMENT_LEAF_SIZE";
    GLOBAL_CONFIG_STORE_KEYS["MAX_POOL_REBALANCE_LEAF_SIZE"] = "MAX_POOL_REBALANCE_LEAF_SIZE";
    GLOBAL_CONFIG_STORE_KEYS["VERSION"] = "VERSION";
    GLOBAL_CONFIG_STORE_KEYS["DISABLED_CHAINS"] = "DISABLED_CHAINS";
    GLOBAL_CONFIG_STORE_KEYS["CHAIN_ID_INDICES"] = "CHAIN_ID_INDICES";
    GLOBAL_CONFIG_STORE_KEYS["LITE_CHAIN_ID_INDICES"] = "LITE_CHAIN_ID_INDICES";
})(GLOBAL_CONFIG_STORE_KEYS || (exports.GLOBAL_CONFIG_STORE_KEYS = GLOBAL_CONFIG_STORE_KEYS = {}));
var KNOWN_INVALID_TOKEN_CONFIG_UPDATE_HASHES = [
    "0x422abc617c6598e4b91859f99c392939d2034c1a839a342a963a34a2f0390195",
    "0x36c85e388279714b2c98d46e3377dc37a1575665b2cac5e52fe97d8d77efcd2b",
    "0x6f0a93119e538dd84e02adfce821fb4e6dd9baddcceb041977e8ba3c39185ab8",
    "0xc28d8bb445e0b747201e6f98ee62aa03009f4c04b8d6f9fad8f214ec1166463d",
    "0x3b0719ef1e3cae2dc1a854a1012332a288e50ad24adc52861d42bcc30fd3deaf",
    "0xbae5c792f74d9f0b6554acf793df0d6b3610868bd6f6a377371b9dec10038003",
    "0xd983142980ac2451e913b152413e769f7a7007fe7305c2e8a03db432e892f84c",
    "0xf64610347950488503428fd720132f8188aa26dcc48e3fc9a89b7bc24aa7fda2",
    "0x1970fcd1e5d5d6cf3bbb640d30d5e471ce5161d65580cedb388526a32b2f7638",
    "0xf098c547d726be8fda419faaee1850280ded1ea75a1b10f4a1614805fa4207d3",
    "0xbfa181663761a78c66dd2c7012604eb910c4c39bad17089e2cc4a011ccc0e981",
    "0x89830f5e81b9e8b44ac2f8966b2fa4bf8e71d7f546e2bc0e773d8ee8df4bdb36",
    "0xb0ad6270124c925a234d9c4f87b60396f2b52fdc250cd2fc9cac792d0d62e467",
    "0x779bc3bf2dba1128d5dda6be8ae99b503cae23343a7265a86bca3d5572ed4268",
].map(function (hash) { return hash.toLowerCase(); });
var AcrossConfigStoreClient = (function (_super) {
    tslib_1.__extends(AcrossConfigStoreClient, _super);
    function AcrossConfigStoreClient(logger, configStore, eventSearchConfig, configStoreVersion) {
        if (eventSearchConfig === void 0) { eventSearchConfig = { from: 0, maxLookBack: 0 }; }
        var _this = _super.call(this, eventSearchConfig) || this;
        _this.logger = logger;
        _this.configStore = configStore;
        _this.configStoreVersion = configStoreVersion;
        _this.cumulativeRateModelUpdates = [];
        _this.cumulativeRouteRateModelUpdates = [];
        _this.cumulativeMaxRefundCountUpdates = [];
        _this.cumulativeMaxL1TokenCountUpdates = [];
        _this.chainIdIndicesUpdates = [];
        _this.liteChainIndicesUpdates = [];
        _this.cumulativeSpokeTargetBalanceUpdates = [];
        _this.cumulativeConfigStoreVersionUpdates = [];
        _this.cumulativeDisabledChainUpdates = [];
        _this.hasLatestConfigStoreVersion = false;
        _this.firstHeightToSearch = eventSearchConfig.from;
        _this.latestHeightSearched = 0;
        return _this;
    }
    AcrossConfigStoreClient.prototype.getRateModelForBlockNumber = function (l1Token, originChainId, destinationChainId, blockNumber) {
        if (blockNumber === void 0) { blockNumber = undefined; }
        var route = "".concat(originChainId, "-").concat(destinationChainId);
        var routeRateModel = this.getRouteRateModelForBlockNumber(l1Token, route, blockNumber);
        if (routeRateModel) {
            return routeRateModel;
        }
        var defaultRateModelUpdate = (0, utils_1.sortEventsDescending)(this.cumulativeRateModelUpdates).find(function (config) {
            return config.blockNumber <= (blockNumber !== null && blockNumber !== void 0 ? blockNumber : 0) &&
                config.l1Token === l1Token.toEvmAddress() &&
                config.rateModel !== undefined;
        });
        if (!defaultRateModelUpdate) {
            throw new Error("Could not find TokenConfig update for ".concat(l1Token, " at block ").concat(blockNumber));
        }
        return (0, rateModel_1.parseAndReturnRateModelFromString)(defaultRateModelUpdate.rateModel);
    };
    AcrossConfigStoreClient.prototype.getRouteRateModelForBlockNumber = function (l1Token, route, blockNumber) {
        if (blockNumber === void 0) { blockNumber = undefined; }
        var config = (0, utils_1.sortEventsDescending)(this.cumulativeRouteRateModelUpdates).find(function (config) { return config.blockNumber <= (blockNumber !== null && blockNumber !== void 0 ? blockNumber : 0) && config.l1Token === l1Token.toEvmAddress(); });
        if ((config === null || config === void 0 ? void 0 : config.routeRateModel[route]) === undefined) {
            return undefined;
        }
        return (0, rateModel_1.parseAndReturnRateModelFromString)(config.routeRateModel[route]);
    };
    AcrossConfigStoreClient.prototype.implicitChainIdIndices = function (chainId) {
        (0, assert_1.default)((0, utils_1.isDefined)(chainId), "ConfigStoreClient used before update");
        return constants_1.PROTOCOL_DEFAULT_CHAIN_ID_INDICES[0] === chainId ? constants_1.PROTOCOL_DEFAULT_CHAIN_ID_INDICES : [chainId];
    };
    AcrossConfigStoreClient.prototype.getChainIdIndicesForBlock = function (blockNumber) {
        var _a;
        if (blockNumber === void 0) { blockNumber = Number.MAX_SAFE_INTEGER; }
        var chainIdUpdates = (0, utils_1.sortEventsDescending)(this.chainIdIndicesUpdates);
        var chainIdIndices = (_a = chainIdUpdates.find(function (update) { return update.blockNumber <= blockNumber; })) === null || _a === void 0 ? void 0 : _a.value;
        return chainIdIndices !== null && chainIdIndices !== void 0 ? chainIdIndices : this.implicitChainIdIndices(this.chainId);
    };
    AcrossConfigStoreClient.prototype.getLiteChainIdIndicesForBlock = function (blockNumber) {
        var _a, _b;
        if (blockNumber === void 0) { blockNumber = Number.MAX_SAFE_INTEGER; }
        var liteChainIdList = (0, utils_1.sortEventsDescending)(this.liteChainIndicesUpdates);
        return (_b = (_a = liteChainIdList.find(function (update) { return update.blockNumber <= blockNumber; })) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : [];
    };
    AcrossConfigStoreClient.prototype.getLiteChainIdIndicesForTimestamp = function (timestamp) {
        var _a, _b;
        if (timestamp === void 0) { timestamp = Number.MAX_SAFE_INTEGER; }
        var liteChainIdList = (0, utils_1.sortEventsDescending)(this.liteChainIndicesUpdates);
        return (_b = (_a = liteChainIdList.find(function (update) { return update.timestamp <= timestamp; })) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : [];
    };
    AcrossConfigStoreClient.prototype.isChainLiteChainAtTimestamp = function (chainId, timestamp) {
        if (timestamp === void 0) { timestamp = Number.MAX_SAFE_INTEGER; }
        return this.getLiteChainIdIndicesForTimestamp(timestamp).includes(chainId);
    };
    AcrossConfigStoreClient.prototype.getSpokeTargetBalancesForBlock = function (l1Token, chainId, blockNumber) {
        var _a;
        if (blockNumber === void 0) { blockNumber = Number.MAX_SAFE_INTEGER; }
        var config = (0, utils_1.sortEventsDescending)(this.cumulativeSpokeTargetBalanceUpdates).find(function (config) { return config.l1Token === l1Token && config.blockNumber <= blockNumber; });
        var targetBalance = (_a = config === null || config === void 0 ? void 0 : config.spokeTargetBalances) === null || _a === void 0 ? void 0 : _a[chainId];
        return targetBalance || { target: (0, utils_1.toBN)(0), threshold: (0, utils_1.toBN)(0) };
    };
    AcrossConfigStoreClient.prototype.getMaxRefundCountForRelayerRefundLeafForBlock = function (blockNumber) {
        if (blockNumber === void 0) { blockNumber = Number.MAX_SAFE_INTEGER; }
        var config = (0, utils_1.sortEventsDescending)(this.cumulativeMaxRefundCountUpdates).find(function (config) { return config.blockNumber <= blockNumber; });
        if (!config) {
            throw new Error("Could not find MaxRefundCount before block ".concat(blockNumber));
        }
        return Number(config.value);
    };
    AcrossConfigStoreClient.prototype.getMaxL1TokenCountForPoolRebalanceLeafForBlock = function (blockNumber) {
        if (blockNumber === void 0) { blockNumber = Number.MAX_SAFE_INTEGER; }
        var config = (0, utils_1.sortEventsDescending)(this.cumulativeMaxL1TokenCountUpdates).find(function (config) { return config.blockNumber <= blockNumber; });
        if (!config) {
            throw new Error("Could not find MaxL1TokenCount before block ".concat(blockNumber));
        }
        return Number(config.value);
    };
    AcrossConfigStoreClient.prototype.getEnabledChainsInBlockRange = function (fromBlock, toBlock) {
        if (toBlock === void 0) { toBlock = Number.MAX_SAFE_INTEGER; }
        if (fromBlock > toBlock) {
            throw new Error("Invalid block range: fromBlock ".concat(fromBlock, " > toBlock ").concat(toBlock));
        }
        var disabledChainsAtFromBlock = this.getDisabledChainsForBlock(fromBlock);
        var allPossibleChains = this.getChainIdIndicesForBlock(toBlock);
        var enabledChainsInBlockRange = allPossibleChains.filter(function (chainId) { return !disabledChainsAtFromBlock.includes(chainId); });
        this.cumulativeDisabledChainUpdates
            .filter(function (e) { return e.blockNumber <= toBlock && e.blockNumber >= fromBlock; })
            .forEach(function (e) {
            var newDisabledSet = e.chainIds;
            disabledChainsAtFromBlock.forEach(function (disabledChain) {
                if (!newDisabledSet.includes(disabledChain)) {
                    enabledChainsInBlockRange.push(disabledChain);
                }
            });
        });
        return allPossibleChains.filter(function (chainId) { return enabledChainsInBlockRange.includes(chainId); });
    };
    AcrossConfigStoreClient.prototype.getEnabledChains = function (block) {
        if (block === void 0) { block = Number.MAX_SAFE_INTEGER; }
        var currentlyDisabledChains = this.getDisabledChainsForBlock(block);
        return this.getChainIdIndicesForBlock(block).filter(function (chainId) { return !currentlyDisabledChains.includes(chainId); });
    };
    AcrossConfigStoreClient.prototype.getDisabledChainsForBlock = function (blockNumber) {
        var _a, _b;
        if (blockNumber === void 0) { blockNumber = Number.MAX_SAFE_INTEGER; }
        return ((_b = (_a = (0, utils_1.sortEventsDescending)(this.cumulativeDisabledChainUpdates).find(function (config) { return config.blockNumber <= blockNumber; })) === null || _a === void 0 ? void 0 : _a.chainIds) !== null && _b !== void 0 ? _b : []);
    };
    AcrossConfigStoreClient.prototype.getConfigStoreVersionForTimestamp = function (timestamp) {
        if (timestamp === void 0) { timestamp = Number.MAX_SAFE_INTEGER; }
        var config = this.cumulativeConfigStoreVersionUpdates.find(function (config) { return config.timestamp <= timestamp; });
        return (0, utils_1.isDefined)(config) ? Number(config.value) : exports.DEFAULT_CONFIG_STORE_VERSION;
    };
    AcrossConfigStoreClient.prototype.getConfigStoreVersionForBlock = function (blockNumber) {
        if (blockNumber === void 0) { blockNumber = Number.MAX_SAFE_INTEGER; }
        var config = this.cumulativeConfigStoreVersionUpdates.find(function (config) { return config.blockNumber <= blockNumber; });
        return (0, utils_1.isDefined)(config) ? Number(config.value) : exports.DEFAULT_CONFIG_STORE_VERSION;
    };
    AcrossConfigStoreClient.prototype.hasValidConfigStoreVersionForTimestamp = function (timestamp) {
        if (timestamp === void 0) { timestamp = Number.MAX_SAFE_INTEGER; }
        var version = this.getConfigStoreVersionForTimestamp(timestamp);
        return this.configStoreVersion >= version;
    };
    AcrossConfigStoreClient.prototype.resolveChainId = function () {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var _b;
            return tslib_1.__generator(this, function (_c) {
                switch (_c.label) {
                    case 0:
                        if (!((_a = this.chainId) !== null && _a !== void 0)) return [3, 1];
                        _b = _a;
                        return [3, 3];
                    case 1: return [4, this.configStore.provider.getNetwork()];
                    case 2:
                        _b = (_c.sent()).chainId;
                        _c.label = 3;
                    case 3: return [2, _b];
                }
            });
        });
    };
    AcrossConfigStoreClient.prototype._update = function () {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var chainId, searchConfig, reason, _a, updatedTokenConfigEvents, updatedGlobalConfigEvents, updatedTokenConfigSortableEvents, updatedGlobalConfigSortableEvents, globalConfigUpdateTimes;
            var _this = this;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0: return [4, this.resolveChainId()];
                    case 1:
                        chainId = _b.sent();
                        return [4, this.updateSearchConfig(this.configStore.provider)];
                    case 2:
                        searchConfig = _b.sent();
                        if ((0, BaseAbstractClient_1.isUpdateFailureReason)(searchConfig)) {
                            reason = searchConfig;
                            return [2, { success: false, reason: reason }];
                        }
                        this.logger.debug({ at: "AcrossConfigStore", message: "Updating ConfigStore client", searchConfig: searchConfig });
                        return [4, Promise.all([
                                (0, utils_1.paginatedEventQuery)(this.configStore, this.configStore.filters.UpdatedTokenConfig(), searchConfig),
                                (0, utils_1.paginatedEventQuery)(this.configStore, this.configStore.filters.UpdatedGlobalConfig(), searchConfig),
                            ])];
                    case 3:
                        _a = _b.sent(), updatedTokenConfigEvents = _a[0], updatedGlobalConfigEvents = _a[1];
                        updatedTokenConfigSortableEvents = updatedTokenConfigEvents.map(utils_1.spreadEventWithBlockNumber);
                        updatedGlobalConfigSortableEvents = updatedGlobalConfigEvents.map(utils_1.spreadEventWithBlockNumber);
                        [updatedTokenConfigSortableEvents, updatedGlobalConfigSortableEvents].forEach(function (events) {
                            return (0, utils_1.sortEventsAscendingInPlace)(events);
                        });
                        return [4, Promise.all(updatedGlobalConfigEvents.map(function (event) { return _this.configStore.provider.getBlock(event.blockNumber); }))];
                    case 4:
                        globalConfigUpdateTimes = (_b.sent()).map(function (block) { return block.timestamp; });
                        return [2, {
                                success: true,
                                chainId: chainId,
                                searchEndBlock: searchConfig.to,
                                events: {
                                    updatedTokenConfigEvents: updatedTokenConfigSortableEvents,
                                    updatedGlobalConfigEvents: updatedGlobalConfigSortableEvents,
                                    globalConfigUpdateTimes: globalConfigUpdateTimes,
                                },
                            }];
                }
            });
        });
    };
    AcrossConfigStoreClient.prototype.update = function () {
        var _a, _b, _c, _d, _e;
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var result, chainId, _f, updatedTokenConfigEvents, updatedGlobalConfigEvents, globalConfigUpdateTimes, _i, updatedTokenConfigEvents_1, event_1, args, _g, rateModel, routeRateModel, spokeTargetBalances, value, l1Token, eventData, err_1, maxWarnAge, _h, errMsg, _loop_1, this_1, i;
            return tslib_1.__generator(this, function (_j) {
                switch (_j.label) {
                    case 0: return [4, this._update()];
                    case 1:
                        result = _j.sent();
                        if (!result.success) {
                            if (result.reason !== BaseAbstractClient_1.UpdateFailureReason.AlreadyUpdated) {
                                throw new Error("Unable to update ConfigStoreClient: ".concat(result.reason));
                            }
                            return [2];
                        }
                        chainId = result.chainId;
                        _f = result.events, updatedTokenConfigEvents = _f.updatedTokenConfigEvents, updatedGlobalConfigEvents = _f.updatedGlobalConfigEvents, globalConfigUpdateTimes = _f.globalConfigUpdateTimes;
                        (0, assert_1.default)(updatedGlobalConfigEvents.length === globalConfigUpdateTimes.length, "GlobalConfigUpdate events mismatch (".concat(updatedGlobalConfigEvents.length, " != ").concat(globalConfigUpdateTimes.length, ")"));
                        _i = 0, updatedTokenConfigEvents_1 = updatedTokenConfigEvents;
                        _j.label = 2;
                    case 2:
                        if (!(_i < updatedTokenConfigEvents_1.length)) return [3, 7];
                        event_1 = updatedTokenConfigEvents_1[_i];
                        if (KNOWN_INVALID_TOKEN_CONFIG_UPDATE_HASHES.includes(event_1.txnRef.toLowerCase())) {
                            return [3, 6];
                        }
                        args = event_1;
                        _j.label = 3;
                    case 3:
                        _j.trys.push([3, 4, , 6]);
                        _g = this.validateTokenConfigUpdate(args), rateModel = _g.rateModel, routeRateModel = _g.routeRateModel, spokeTargetBalances = _g.spokeTargetBalances;
                        value = args.value, l1Token = args.key, eventData = tslib_1.__rest(args, ["value", "key"]);
                        if (rateModel !== undefined) {
                            this.cumulativeRateModelUpdates.push(tslib_1.__assign(tslib_1.__assign({}, eventData), { rateModel: rateModel, l1Token: l1Token }));
                            this.cumulativeSpokeTargetBalanceUpdates.push(tslib_1.__assign(tslib_1.__assign({}, eventData), { spokeTargetBalances: spokeTargetBalances, l1Token: l1Token }));
                            this.cumulativeRouteRateModelUpdates.push(tslib_1.__assign(tslib_1.__assign({}, eventData), { routeRateModel: routeRateModel, l1Token: l1Token }));
                        }
                        return [3, 6];
                    case 4:
                        err_1 = _j.sent();
                        _h = (24 * 60 * 60);
                        return [4, sdk_1.utils.averageBlockTimeSeconds()];
                    case 5:
                        maxWarnAge = _h / (_j.sent());
                        if (result.searchEndBlock - event_1.blockNumber < maxWarnAge) {
                            errMsg = (0, typeguards_1.isError)(err_1) ? err_1.message : "unknown error";
                            this.logger.warn({
                                at: "ConfigStore::update",
                                message: "Caught error during ConfigStore update: ".concat(errMsg),
                                update: args,
                            });
                        }
                        else {
                            this.logger.debug({
                                at: "ConfigStoreClient::update",
                                message: "Skipping invalid historical update at block ".concat(event_1.blockNumber),
                                txnRef: event_1.txnRef,
                            });
                        }
                        return [3, 6];
                    case 6:
                        _i++;
                        return [3, 2];
                    case 7:
                        _loop_1 = function (i) {
                            var args = updatedGlobalConfigEvents[i];
                            if (args.key === (0, utils_1.utf8ToHex)(GLOBAL_CONFIG_STORE_KEYS.MAX_RELAYER_REPAYMENT_LEAF_SIZE)) {
                                if (!isNaN(args.value)) {
                                    this_1.cumulativeMaxRefundCountUpdates.push(args);
                                }
                            }
                            else if (args.key === (0, utils_1.utf8ToHex)(GLOBAL_CONFIG_STORE_KEYS.LITE_CHAIN_ID_INDICES)) {
                                if (!/^\s*["']?\[(\d+(,\d+)*)?\]["']?\s*$/.test(args.value)) {
                                    this_1.logger.warn({ at: "ConfigStore", message: "The lite chain indices array ".concat(args.value, " is invalid.") });
                                    return "continue";
                                }
                                var chainIndices = JSON.parse(args.value.replace(/['"\s]/g, ""));
                                if (!(0, utils_1.isArrayOf)(chainIndices, utils_1.isPositiveInteger)) {
                                    this_1.logger.warn({ at: "ConfigStore", message: "The array ".concat(chainIndices, " is invalid.") });
                                    return "continue";
                                }
                                if (new Set(chainIndices).size !== chainIndices.length) {
                                    this_1.logger.warn({
                                        at: "ConfigStore",
                                        message: "The array ".concat(chainIndices, " contains duplicates making it invalid."),
                                    });
                                    return "continue";
                                }
                                this_1.liteChainIndicesUpdates.push(tslib_1.__assign(tslib_1.__assign({}, args), { value: chainIndices, timestamp: globalConfigUpdateTimes[i] }));
                            }
                            else if (args.key === (0, utils_1.utf8ToHex)(GLOBAL_CONFIG_STORE_KEYS.CHAIN_ID_INDICES)) {
                                try {
                                    var chainIndices_1 = JSON.parse(args.value.replace(/['"\s]/g, ""));
                                    if (!(0, utils_1.isArrayOf)(chainIndices_1, utils_1.isPositiveInteger)) {
                                        this_1.logger.warn({ at: "ConfigStore", message: "The array ".concat(chainIndices_1, " is invalid.") });
                                        return "continue";
                                    }
                                    if (new Set(chainIndices_1).size !== chainIndices_1.length) {
                                        this_1.logger.warn({
                                            at: "ConfigStore",
                                            message: "The array ".concat(chainIndices_1, " contains duplicates making it invalid."),
                                        });
                                        return "continue";
                                    }
                                    var previousUpdate = (_b = (_a = this_1.chainIdIndicesUpdates.at(-1)) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : this_1.implicitChainIdIndices(chainId);
                                    if (!previousUpdate.every(function (chainId, idx) { return chainIndices_1[idx] === chainId; })) {
                                        this_1.logger.warn({
                                            at: "ConfigStoreClient#update",
                                            message: "The array ".concat(chainIndices_1, " is invalid. It must be a superset of the previous array ").concat(previousUpdate),
                                        });
                                        return "continue";
                                    }
                                    this_1.chainIdIndicesUpdates.push(tslib_1.__assign(tslib_1.__assign({}, args), { value: chainIndices_1 }));
                                }
                                catch (e) {
                                    this_1.logger.warn({ at: "ConfigStore::update", message: "Failed to parse chain ID indices: ".concat(args.value) });
                                }
                            }
                            else if (args.key === (0, utils_1.utf8ToHex)(GLOBAL_CONFIG_STORE_KEYS.MAX_POOL_REBALANCE_LEAF_SIZE)) {
                                if (!isNaN(args.value)) {
                                    this_1.cumulativeMaxL1TokenCountUpdates.push(args);
                                }
                            }
                            else if (args.key === (0, utils_1.utf8ToHex)(GLOBAL_CONFIG_STORE_KEYS.VERSION)) {
                                if (isNaN(args.value)) {
                                    return "continue";
                                }
                                var value = Number(args.value);
                                if (!Number.isInteger(value)) {
                                    return "continue";
                                }
                                var lastValue = Number((_d = (_c = this_1.cumulativeConfigStoreVersionUpdates[0]) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : exports.DEFAULT_CONFIG_STORE_VERSION);
                                if (value <= lastValue) {
                                    return "continue";
                                }
                                this_1.cumulativeConfigStoreVersionUpdates = tslib_1.__spreadArray([
                                    tslib_1.__assign(tslib_1.__assign({}, args), { timestamp: globalConfigUpdateTimes[i] })
                                ], this_1.cumulativeConfigStoreVersionUpdates, true);
                            }
                            else if (args.key === (0, utils_1.utf8ToHex)(GLOBAL_CONFIG_STORE_KEYS.DISABLED_CHAINS)) {
                                try {
                                    var chainIds = this_1.filterDisabledChains(JSON.parse(args.value));
                                    this_1.cumulativeDisabledChainUpdates.push(tslib_1.__assign(tslib_1.__assign({}, args), { chainIds: chainIds }));
                                }
                                catch (err) {
                                }
                            }
                            else {
                                return "continue";
                            }
                        };
                        this_1 = this;
                        for (i = 0; i < updatedGlobalConfigEvents.length; i++) {
                            _loop_1(i);
                        }
                        this.hasLatestConfigStoreVersion = this.hasValidConfigStoreVersionForTimestamp();
                        this.latestHeightSearched = result.searchEndBlock;
                        this.firstHeightToSearch = result.searchEndBlock + 1;
                        this.eventSearchConfig.to = undefined;
                        this.chainId = (_e = this.chainId) !== null && _e !== void 0 ? _e : chainId;
                        this.isUpdated = true;
                        this.logger.debug({ at: "ConfigStore", message: "ConfigStore client updated!" });
                        return [2];
                }
            });
        });
    };
    AcrossConfigStoreClient.prototype.validateTokenConfigUpdate = function (args) {
        var _this = this;
        var value = args.value, key = args.key, txnRef = args.txnRef;
        var parsedValue = (0, JSONUtils_1.parseJSONWithNumericString)(value);
        var l1Token = key;
        var rateModelForToken = undefined;
        var spokeTargetBalances = {};
        var routeRateModel = {};
        if ((parsedValue === null || parsedValue === void 0 ? void 0 : parsedValue.rateModel) !== undefined) {
            var rateModel = parsedValue.rateModel;
            (0, assert_1.default)(this.isValidRateModel(rateModel), "Invalid rateModel UBar for ".concat(l1Token, " at transaction ").concat(txnRef, ", ").concat(JSON.stringify(rateModel)));
            rateModelForToken = JSON.stringify(rateModel);
            if (parsedValue === null || parsedValue === void 0 ? void 0 : parsedValue.spokeTargetBalances) {
                spokeTargetBalances = Object.fromEntries(Object.entries(parsedValue.spokeTargetBalances).map(function (_a) {
                    var chainId = _a[0], targetBalance = _a[1];
                    var target = (0, utils_1.max)((0, utils_1.toBN)(targetBalance.target), (0, utils_1.toBN)(0));
                    var threshold = (0, utils_1.max)((0, utils_1.toBN)(targetBalance.threshold), (0, utils_1.toBN)(0));
                    return [chainId, { target: target, threshold: threshold }];
                }));
            }
            if (parsedValue === null || parsedValue === void 0 ? void 0 : parsedValue.routeRateModel) {
                routeRateModel = Object.fromEntries(Object.entries(parsedValue.routeRateModel).map(function (_a) {
                    var path = _a[0], routeRateModel = _a[1];
                    (0, assert_1.default)(_this.isValidRateModel(routeRateModel) &&
                        "Invalid routeRateModel UBar for ".concat(path, " for ").concat(l1Token, " at transaction ").concat(txnRef, ", ").concat(JSON.stringify(routeRateModel)));
                    return [path, JSON.stringify(routeRateModel)];
                }));
            }
        }
        return {
            spokeTargetBalances: spokeTargetBalances,
            rateModel: rateModelForToken,
            routeRateModel: routeRateModel,
        };
    };
    AcrossConfigStoreClient.prototype.isValidRateModel = function (rateModel) {
        return (0, utils_1.toBN)(rateModel.UBar).gt(0) && (0, utils_1.toBN)(rateModel.UBar).lt((0, utils_1.toWei)("1"));
    };
    AcrossConfigStoreClient.prototype.filterDisabledChains = function (disabledChains) {
        return disabledChains.filter(function (chainId) { return !isNaN(chainId) && Number.isInteger(chainId) && chainId !== 1; });
    };
    return AcrossConfigStoreClient;
}(BaseAbstractClient_1.BaseAbstractClient));
exports.AcrossConfigStoreClient = AcrossConfigStoreClient;
//# sourceMappingURL=AcrossConfigStoreClient.js.map