Skip to content

Commit

Permalink
fix(relayer): Post-process external inventory config (#1333)
Browse files Browse the repository at this point in the history
The recent change to support externally-defined inventory configs
neglected to post-process the imported config. It's important to scale
each configured amount before taking the config into use.

This change also relocates parsing back to the RelayerConfig
constructor, which helps to simplify the implementation.
  • Loading branch information
pxrl authored Mar 25, 2024
1 parent 5257f48 commit 3213842
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 28 deletions.
21 changes: 2 additions & 19 deletions src/relayer/RelayerClientHelper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { typeguards, utils as sdkUtils } from "@across-protocol/sdk-v2";
import { utils as sdkUtils } from "@across-protocol/sdk-v2";
import winston from "winston";
import { AcrossApiClient, BundleDataClient, InventoryClient, ProfitClient, TokenClient } from "../clients";
import { AdapterManager, CrossChainTransferClient } from "../clients/bridges";
Expand All @@ -11,7 +11,7 @@ import {
updateSpokePoolClients,
} from "../common";
import { SpokePoolClientsByChain } from "../interfaces";
import { isDefined, readFile, Signer } from "../utils";
import { Signer } from "../utils";
import { RelayerConfig } from "./RelayerConfig";

export interface RelayerClients extends Clients {
Expand Down Expand Up @@ -115,23 +115,6 @@ export async function constructRelayerClients(
adapterManager
);

// If an external inventory configuration was defined, read it in now before instantiating the InventoryClient.
if (isDefined(config.externalInventoryConfig)) {
const _inventoryConfig = await readFile(config.externalInventoryConfig);
try {
config.inventoryConfig = JSON.parse(_inventoryConfig);
} catch (err) {
const msg = typeguards.isError(err) ? err.message : (err as Record<string, unknown>)?.code;
throw new Error(`Inventory config error in ${config.externalInventoryConfig} (${msg ?? "unknown error"})`);
}
logger.debug({
at: "Relayer#constructRelayerClients",
message: "Updated Inventory config.",
source: config.externalInventoryConfig,
inventoryConfig: config.inventoryConfig,
});
}

const inventoryClient = new InventoryClient(
signerAddr,
logger,
Expand Down
24 changes: 15 additions & 9 deletions src/relayer/RelayerConfig.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { BigNumber, toBNWei, assert, isDefined, toBN, replaceAddressCase, ethers } from "../utils";
import { typeguards } from "@across-protocol/sdk-v2";
import { BigNumber, toBNWei, assert, isDefined, readFileSync, toBN, replaceAddressCase, ethers } from "../utils";
import { CommonConfig, ProcessEnv } from "../common";
import * as Constants from "../common/Constants";
import { InventoryConfig } from "../interfaces";

export class RelayerConfig extends CommonConfig {
readonly externalInventoryConfig?: string;
inventoryConfig: InventoryConfig;

readonly inventoryConfig: InventoryConfig;
readonly debugProfitability: boolean;
// Whether token price fetch failures will be ignored when computing relay profitability.
// If this is false, the relayer will throw an error when fetching prices fails.
Expand Down Expand Up @@ -71,14 +70,20 @@ export class RelayerConfig extends CommonConfig {
? JSON.parse(SLOW_DEPOSITORS).map((depositor) => ethers.utils.getAddress(depositor))
: [];

this.minRelayerFeePct = toBNWei(MIN_RELAYER_FEE_PCT || Constants.RELAYER_MIN_FEE_PCT);

assert(
!isDefined(RELAYER_EXTERNAL_INVENTORY_CONFIG) || !isDefined(RELAYER_INVENTORY_CONFIG),
"Concurrent inventory management configurations detected."
);
this.externalInventoryConfig = RELAYER_EXTERNAL_INVENTORY_CONFIG;
this.inventoryConfig = JSON.parse(RELAYER_INVENTORY_CONFIG ?? "{}");

this.minRelayerFeePct = toBNWei(MIN_RELAYER_FEE_PCT || Constants.RELAYER_MIN_FEE_PCT);
try {
this.inventoryConfig = isDefined(RELAYER_EXTERNAL_INVENTORY_CONFIG)
? JSON.parse(readFileSync(RELAYER_EXTERNAL_INVENTORY_CONFIG))
: JSON.parse(RELAYER_INVENTORY_CONFIG ?? "{}");
} catch (err) {
const msg = typeguards.isError(err) ? err.message : (err as Record<string, unknown>)?.code;
throw new Error(`Inventory config error (${msg ?? "unknown error"})`);
}

if (Object.keys(this.inventoryConfig).length > 0) {
this.inventoryConfig = replaceAddressCase(this.inventoryConfig); // Cast any non-address case addresses.
Expand All @@ -92,7 +97,7 @@ export class RelayerConfig extends CommonConfig {
this.inventoryConfig.wrapEtherTargetPerChain ??= {};
assert(
this.inventoryConfig.wrapEtherThreshold.gte(this.inventoryConfig.wrapEtherTarget),
`default wrapEtherThreshold ${this.inventoryConfig.wrapEtherThreshold} must be >= default wrapEtherTarget ${this.inventoryConfig.wrapEtherTarget}}`
`default wrapEtherThreshold ${this.inventoryConfig.wrapEtherThreshold} must be >= default wrapEtherTarget ${this.inventoryConfig.wrapEtherTarget}`
);

// Validate the per chain target and thresholds for wrapping ETH:
Expand Down Expand Up @@ -141,6 +146,7 @@ export class RelayerConfig extends CommonConfig {
});
});
}

this.debugProfitability = DEBUG_PROFITABILITY === "true";
this.relayerGasPadding = toBNWei(RELAYER_GAS_PADDING || Constants.DEFAULT_RELAYER_GAS_PADDING);
this.relayerGasMultiplier = toBNWei(RELAYER_GAS_MULTIPLIER || Constants.DEFAULT_RELAYER_GAS_MULTIPLIER);
Expand Down
11 changes: 11 additions & 0 deletions src/utils/fsUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import * as fs from "fs/promises";
import { readFileSync as _readFileSync } from "node:fs";
import { typeguards } from "@across-protocol/sdk-v2";

export function readFileSync(fileName: string): string {
try {
return _readFileSync(fileName, { encoding: "utf8" });
} catch (err) {
// @dev fs methods can return errors that are not Error objects (i.e. errno).
const msg = typeguards.isError(err) ? err.message : (err as Record<string, unknown>)?.code;
throw new Error(`Unable to read ${fileName} (${msg ?? "unknown error"})`);
}
}

export async function readFile(fileName: string): Promise<string> {
try {
return await fs.readFile(fileName, { encoding: "utf8" });
Expand Down

0 comments on commit 3213842

Please sign in to comment.