Merge pull request #2714 from 0xProject/feat/asset-swapper/rfq-maker-blacklist-logging
asset-swapper: log RFQ maker (un)blacklistings
This commit is contained in:
commit
a35d1b8a9d
@ -1,9 +1,10 @@
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { BigNumber, logUtils } from '@0x/utils';
|
||||
|
||||
import {
|
||||
ExchangeProxyContractOpts,
|
||||
ExtensionContractType,
|
||||
ForwarderExtensionContractOpts,
|
||||
LogFunction,
|
||||
OrderPrunerOpts,
|
||||
OrderPrunerPermittedFeeTypes,
|
||||
RfqtRequestOpts,
|
||||
@ -89,6 +90,11 @@ const DEFAULT_RFQT_REQUEST_OPTS: Partial<RfqtRequestOpts> = {
|
||||
makerEndpointMaxResponseTimeMs: 1000,
|
||||
};
|
||||
|
||||
export const DEFAULT_INFO_LOGGER: LogFunction = (obj, msg) =>
|
||||
logUtils.log(`${msg ? `${msg}: ` : ''}${JSON.stringify(obj)}`);
|
||||
export const DEFAULT_WARNING_LOGGER: LogFunction = (obj, msg) =>
|
||||
logUtils.warn(`${msg ? `${msg}: ` : ''}${JSON.stringify(obj)}`);
|
||||
|
||||
export const constants = {
|
||||
ETH_GAS_STATION_API_URL,
|
||||
PROTOCOL_FEE_MULTIPLIER,
|
||||
@ -113,4 +119,6 @@ export const constants = {
|
||||
PROTOCOL_FEE_UTILS_POLLING_INTERVAL_IN_MS,
|
||||
MARKET_UTILS_AMOUNT_BUFFER_PERCENTAGE,
|
||||
BRIDGE_ASSET_DATA_PREFIX: '0xdc1600f3',
|
||||
DEFAULT_INFO_LOGGER,
|
||||
DEFAULT_WARNING_LOGGER,
|
||||
};
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
TokenAdjacencyGraph,
|
||||
} from './utils/market_operation_utils/types';
|
||||
import { QuoteReport } from './utils/quote_report_generator';
|
||||
import { LogFunction } from './utils/quote_requestor';
|
||||
|
||||
/**
|
||||
* expiryBufferMs: The number of seconds to add when calculating whether an order is expired or not. Defaults to 300s (5m).
|
||||
@ -273,7 +272,7 @@ export interface RfqtMakerAssetOfferings {
|
||||
[endpoint: string]: Array<[string, string]>;
|
||||
}
|
||||
|
||||
export { LogFunction } from './utils/quote_requestor';
|
||||
export type LogFunction = (obj: object, msg?: string, ...args: any[]) => void;
|
||||
|
||||
export interface SwapQuoterRfqtOpts {
|
||||
takerApiKeyWhitelist: string[];
|
||||
|
@ -2,13 +2,13 @@ import { schemas, SchemaValidator } from '@0x/json-schemas';
|
||||
import { assetDataUtils, orderCalculationUtils, SignedOrder } from '@0x/order-utils';
|
||||
import { RFQTFirmQuote, RFQTIndicativeQuote, TakerRequest } from '@0x/quote-server';
|
||||
import { ERC20AssetData } from '@0x/types';
|
||||
import { BigNumber, logUtils } from '@0x/utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import Axios, { AxiosInstance } from 'axios';
|
||||
import { Agent as HttpAgent } from 'http';
|
||||
import { Agent as HttpsAgent } from 'https';
|
||||
|
||||
import { constants } from '../constants';
|
||||
import { MarketOperation, RfqtMakerAssetOfferings, RfqtRequestOpts } from '../types';
|
||||
import { LogFunction, MarketOperation, RfqtMakerAssetOfferings, RfqtRequestOpts } from '../types';
|
||||
|
||||
import { ONE_SECOND_MS } from './market_operation_utils/constants';
|
||||
import { RfqMakerBlacklist } from './rfq_maker_blacklist';
|
||||
@ -107,20 +107,18 @@ function convertIfAxiosError(error: any): Error | object /* axios' .d.ts has Axi
|
||||
}
|
||||
}
|
||||
|
||||
export type LogFunction = (obj: object, msg?: string, ...args: any[]) => void;
|
||||
|
||||
export class QuoteRequestor {
|
||||
private readonly _schemaValidator: SchemaValidator = new SchemaValidator();
|
||||
private readonly _orderSignatureToMakerUri: { [orderSignature: string]: string } = {};
|
||||
|
||||
constructor(
|
||||
private readonly _rfqtAssetOfferings: RfqtMakerAssetOfferings,
|
||||
private readonly _warningLogger: LogFunction = (obj, msg) =>
|
||||
logUtils.warn(`${msg ? `${msg}: ` : ''}${JSON.stringify(obj)}`),
|
||||
private readonly _infoLogger: LogFunction = (obj, msg) =>
|
||||
logUtils.log(`${msg ? `${msg}: ` : ''}${JSON.stringify(obj)}`),
|
||||
private readonly _warningLogger: LogFunction = constants.DEFAULT_WARNING_LOGGER,
|
||||
private readonly _infoLogger: LogFunction = constants.DEFAULT_INFO_LOGGER,
|
||||
private readonly _expiryBufferMs: number = constants.DEFAULT_SWAP_QUOTER_OPTS.expiryBufferMs,
|
||||
) {}
|
||||
) {
|
||||
rfqMakerBlacklist.infoLogger = this._infoLogger;
|
||||
}
|
||||
|
||||
public async requestRfqtFirmQuotesAsync(
|
||||
makerAssetData: string,
|
||||
@ -395,7 +393,7 @@ export class QuoteRequestor {
|
||||
},
|
||||
},
|
||||
});
|
||||
rfqMakerBlacklist.logTimeoutOrLackThereof(url, latencyMs > maxResponseTimeMs);
|
||||
rfqMakerBlacklist.logTimeoutOrLackThereof(url, latencyMs >= maxResponseTimeMs);
|
||||
result.push({ response: response.data, makerUri: url });
|
||||
} catch (err) {
|
||||
const latencyMs = Date.now() - timeBeforeAwait;
|
||||
@ -411,7 +409,7 @@ export class QuoteRequestor {
|
||||
},
|
||||
},
|
||||
});
|
||||
rfqMakerBlacklist.logTimeoutOrLackThereof(url, latencyMs > maxResponseTimeMs);
|
||||
rfqMakerBlacklist.logTimeoutOrLackThereof(url, latencyMs >= maxResponseTimeMs);
|
||||
this._warningLogger(
|
||||
convertIfAxiosError(err),
|
||||
`Failed to get RFQ-T ${quoteType} quote from market maker endpoint ${url} for API key ${
|
||||
|
@ -4,11 +4,16 @@
|
||||
*/
|
||||
|
||||
import { constants } from '../constants';
|
||||
import { LogFunction } from '../types';
|
||||
|
||||
export class RfqMakerBlacklist {
|
||||
private readonly _makerTimeoutStreakLength: { [makerUrl: string]: number } = {};
|
||||
private readonly _makerBlacklistedUntilDate: { [makerUrl: string]: number } = {};
|
||||
constructor(private readonly _blacklistDurationMinutes: number, private readonly _timeoutStreakThreshold: number) {}
|
||||
constructor(
|
||||
private readonly _blacklistDurationMinutes: number,
|
||||
private readonly _timeoutStreakThreshold: number,
|
||||
public infoLogger: LogFunction = constants.DEFAULT_INFO_LOGGER,
|
||||
) {}
|
||||
public logTimeoutOrLackThereof(makerUrl: string, didTimeout: boolean): void {
|
||||
if (!this._makerTimeoutStreakLength.hasOwnProperty(makerUrl)) {
|
||||
this._makerTimeoutStreakLength[makerUrl] = 0;
|
||||
@ -16,8 +21,12 @@ export class RfqMakerBlacklist {
|
||||
if (didTimeout) {
|
||||
this._makerTimeoutStreakLength[makerUrl] += 1;
|
||||
if (this._makerTimeoutStreakLength[makerUrl] === this._timeoutStreakThreshold) {
|
||||
this._makerBlacklistedUntilDate[makerUrl] =
|
||||
Date.now() + this._blacklistDurationMinutes * constants.ONE_MINUTE_MS;
|
||||
const blacklistEnd = Date.now() + this._blacklistDurationMinutes * constants.ONE_MINUTE_MS;
|
||||
this._makerBlacklistedUntilDate[makerUrl] = blacklistEnd;
|
||||
this.infoLogger(
|
||||
{ makerUrl, blacklistedUntil: new Date(blacklistEnd).toISOString() },
|
||||
'maker blacklisted',
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this._makerTimeoutStreakLength[makerUrl] = 0;
|
||||
@ -27,6 +36,7 @@ export class RfqMakerBlacklist {
|
||||
const now = Date.now();
|
||||
if (now > this._makerBlacklistedUntilDate[makerUrl]) {
|
||||
delete this._makerBlacklistedUntilDate[makerUrl];
|
||||
this.infoLogger({ makerUrl }, 'maker unblacklisted');
|
||||
}
|
||||
return this._makerBlacklistedUntilDate[makerUrl] > now;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user