Skip to content

Commit

Permalink
fix(pushpair): Fetch Last Update now returns oldest pair update
Browse files Browse the repository at this point in the history
  • Loading branch information
mariocao authored and FranklinWaller committed May 9, 2022
1 parent 62cc7cb commit 1c82253
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 42 deletions.
16 changes: 8 additions & 8 deletions src/modules/pairDeviationChecker/PairDeviationCheckerModule.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import Big from "big.js";
import logger from "../../services/LoggerService";
import { AppConfig } from "../../models/AppConfig";
import { ENABLE_TELEGRAM_NOTIFICATIONS, TELEGRAM_ALERTS_CHAT_ID, TELEGRAM_BOT_API, TELEGRAM_STATS_CHAT_ID } from "../../config";
import { FetchJob } from "../../jobs/fetch/FetchJob";
import { AppConfig } from "../../models/AppConfig";
import { IJob } from "../../models/IJob";
import { InternalPairDeviationCheckerModuleConfig, PairDeviationCheckerModuleConfig, parsePairDeviationCheckerModuleConfig } from "./models/PairDeviationCheckerModuleConfig";
import { Module } from "../../models/Module";
import { OutcomeType } from "../../models/Outcome";
import { PairDeviationReport } from "./models/PairDeviationReport";
import { createRequestsFromPairs, PairDeviationDataRequest } from "./models/PairDeviationDataRequest";
import { createSafeAppConfigString } from "../../services/AppConfigUtils";
import logger from "../../services/LoggerService";
import { debouncedInterval } from "../../services/TimerUtils";
import { InternalPairDeviationCheckerModuleConfig, PairDeviationCheckerModuleConfig, parsePairDeviationCheckerModuleConfig } from "./models/PairDeviationCheckerModuleConfig";
import { createRequestsFromPairs, PairDeviationDataRequest } from "./models/PairDeviationDataRequest";
import { PairDeviationReport } from "./models/PairDeviationReport";
import { fetchLatestPrice, fetchLatestTimestamp } from "./services/FetchLastUpdateService";
import { shouldPricePairUpdate } from "./services/PairDeviationService";
import { notifyTelegram } from "./services/TelegramNotificationService";
import { prettySeconds } from "./utils";
import { shouldPricePairUpdate } from "./services/PairDeviationService";

export class PairDeviationCheckerModule extends Module {
static type = "PairDeviationCheckerModule";
Expand Down Expand Up @@ -100,8 +101,7 @@ export class PairDeviationCheckerModule extends Module {
}

this.prices.set(dataRequest.internalId, new Big(executeOutcome.answer));

logger.info(`[${this.id}] ${dataRequest.extraInfo.pair} has been recently updated`);
logger.info(`[${this.id}] ${dataRequest.extraInfo.pair} has been recently updated (${prettySeconds(Math.floor(timestampDiff / 1000), true)} ago)`);

return {
pair: dataRequest,
Expand Down
7 changes: 6 additions & 1 deletion src/modules/pushPair/PushPairModule.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Big from "big.js";
import EvmNetwork from "../../networks/evm/EvmNetwork";
import logger from "../../services/LoggerService";
import { AppConfig } from "../../models/AppConfig";
Expand All @@ -10,7 +11,7 @@ import { createPairIfNeeded } from "./services/PushPairCreationService";
import { createSafeAppConfigString } from "../../services/AppConfigUtils";
import { fetchEvmLastUpdate, fetchLatestPrice, fetchNearLastUpdate } from './services/FetchLastUpdateService';
import { parsePushPairConfig, PushPairConfig, PushPairInternalConfig } from "./models/PushPairConfig";
import Big from "big.js";
import { prettySeconds } from "../pairChecker/utils";

export class PushPairModule extends Module {
static type = "PushPairModule";
Expand Down Expand Up @@ -47,9 +48,12 @@ export class PushPairModule extends Module {

private async processPairs() {
try {
// TODO: lastUpdates = fetchLastUpdate() should return an array of pair last updates
// TODO: lastUpdate = oldest pair last update
const lastUpdate = await this.fetchLastUpdate();
// Fetch elapsed time (in milliseconds) since last pair(s) update
const timeSinceUpdate = Date.now() - lastUpdate;
logger.debug(`[${this.id}] Oldest pair update: ${prettySeconds(Math.floor(timeSinceUpdate / 1000))} ago`);

let remainingInterval;
if (timeSinceUpdate < this.internalConfig.interval) {
Expand Down Expand Up @@ -78,6 +82,7 @@ export class PushPairModule extends Module {
}

// When the prices don't deviate too much we don't need to update the price pair
// TODO: shouldPricePairUpdate should use `lastUpdates[index]`
if (!shouldPricePairUpdate(unresolvedRequest, lastUpdate, new Big(outcome.answer), this.prices.get(unresolvedRequest.internalId))) {
logger.debug(`[${this.id}] ${unresolvedRequest.internalId} Price ${outcome.answer} doesn't deviate ${unresolvedRequest.extraInfo.deviationPercentage}% from ${this.prices.get(unresolvedRequest.internalId)}`);
remainingInterval = this.internalConfig.interval;
Expand Down
89 changes: 56 additions & 33 deletions src/modules/pushPair/services/FetchLastUpdateService.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import Big from 'big.js';
import EvmNetwork from '../../../networks/evm/EvmNetwork';
import FluxPriceFeed from '../FluxPriceFeed.json';
import FluxPriceFeedFactory from '../FluxPriceFeedFactory.json';
import FluxPriceFeedFactory2 from '../FluxPriceFeedFactory2.json';
import { NearNetwork } from "../../../networks/near/NearNetwork";
import { Network } from '../../../models/Network';
import { PushPairDataRequest } from '../models/PushPairDataRequest';
import { PushPairInternalConfig } from "../models/PushPairConfig";
import { computeFactoryPairId } from "./utils";
import { PushPairDataRequest } from '../models/PushPairDataRequest';
import { Network } from '../../../models/Network';
import Big from 'big.js';

export async function fetchEvmLastUpdate(config: PushPairInternalConfig, network: EvmNetwork) {
let timestamp;

if (config.pairsType === 'single') {
timestamp = await network.view({
method: 'latestTimestamp',
Expand All @@ -20,45 +21,67 @@ export async function fetchEvmLastUpdate(config: PushPairInternalConfig, network
abi: FluxPriceFeed.abi,
});
} else if (config.pairsType === 'factory') {
// Contract returns [answer, updatedAt, statusCode]
timestamp = (await network.view({
method: 'valueFor',
address: config.contractAddress,
amount: '0',
params: {
id: computeFactoryPairId(config.pairs[0].pair, config.pairs[0].decimals)
},
abi: FluxPriceFeedFactory.abi,
}))[1];
let pairTimestamps: Big[] = [];
for await (let pair of config.pairs) {
// Contract returns [answer, updatedAt, statusCode]
const pairTimestamp = (await network.view({
method: 'valueFor',
address: config.contractAddress,
amount: '0',
params: {
id: computeFactoryPairId(pair.pair, pair.decimals)
},
abi: FluxPriceFeedFactory.abi,
}))[1];

pairTimestamps.push(pairTimestamp);
}

timestamp = pairTimestamps.reduce((prev, next) => prev.gt(next) ? next : prev);
} else { // factory2
timestamp = (await network.view({
method: 'valueFor',
address: config.contractAddress,
amount: '0',
params: {
id: computeFactoryPairId(config.pairs[0].pair, config.pairs[0].decimals, network.getWalletPublicAddress()),
},
abi: FluxPriceFeedFactory2.abi,
}))[1];
let pairTimestamps: Big[] = [];
for await (let pair of config.pairs) {
// Contract returns [answer, updatedAt, statusCode]
const pairTimestamp = (await network.view({
method: 'valueFor',
address: config.contractAddress,
amount: '0',
params: {
id: computeFactoryPairId(pair.pair, pair.decimals, network.getWalletPublicAddress()),
},
abi: FluxPriceFeedFactory2.abi,
}))[1];

pairTimestamps.push(pairTimestamp);
}

timestamp = pairTimestamps.reduce((prev, next) => prev.gt(next) ? next : prev);
}

// Convert contract timestamp to milliseconds
return timestamp.toNumber() * 1000;
}

export async function fetchNearLastUpdate(config: PushPairInternalConfig, network: NearNetwork) {
const entry = await network.view({
method: 'get_entry',
address: config.contractAddress,
amount: '0',
params: {
provider: network.internalConfig?.account.accountId,
pair: config.pairs[0].pair,
},
});
let pairTimestamps: number[] = [];
for await (let pair of config.pairs) {
const entry = await network.view({
method: 'get_entry',
address: config.contractAddress,
amount: '0',
params: {
provider: network.internalConfig?.account.accountId,
pair: config.pairs[0].pair,
},
});

// Convert contract timestamp to milliseconds
return Math.floor(entry.last_update / 1000000);
// Convert contract timestamp to milliseconds
pairTimestamps.push(Math.floor(entry.last_update / 1000000));
}

const timestamp = pairTimestamps.reduce((prev, next) => prev > next ? next : prev);

return timestamp;
}

export async function fetchLatestPrice(config: PushPairInternalConfig, pair: PushPairDataRequest, network: Network): Promise<Big> {
Expand Down

0 comments on commit 1c82253

Please sign in to comment.