Skip to content

Commit

Permalink
feat: cron job cache relayer balances
Browse files Browse the repository at this point in the history
  • Loading branch information
dohaki committed Sep 11, 2024
1 parent 889dac9 commit 0b283aa
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 24 deletions.
19 changes: 18 additions & 1 deletion api/_cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export async function getCachedValue<T>(
ttl: number,
fetcher: () => Promise<T>,
parser?: (value: T) => T
) {
): Promise<T> {
const cachedValue = await redisCache.get<T>(key);
if (cachedValue) {
return parser ? parser(cachedValue) : cachedValue;
Expand All @@ -76,3 +76,20 @@ export async function getCachedValue<T>(
await redisCache.set(key, value, ttl);
return value;
}

export function makeCacheGetterAndSetter<T>(
key: string,
ttl: number,
fetcher: () => Promise<T>,
parser?: (value: T) => T
) {
return {
get: async () => {
return getCachedValue(key, ttl, fetcher, parser);
},
set: async () => {
const value = await fetcher();
await redisCache.set(key, value, ttl);
},
};
}
37 changes: 14 additions & 23 deletions api/_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ import {
relayerFeeCapitalCostConfig,
} from "./_constants";
import { PoolStateOfUser, PoolStateResult } from "./_types";
import { buildInternalCacheKey, getCachedValue } from "./_cache";
import {
buildInternalCacheKey,
getCachedValue,
makeCacheGetterAndSetter,
} from "./_cache";

type LoggingUtility = sdk.relayFeeCalculator.Logger;
type RpcProviderName = keyof typeof rpcProvidersJson.providers.urls;
Expand Down Expand Up @@ -1085,7 +1089,11 @@ export const getCachedTokenBalance = async (
account: string,
token: string
): Promise<BigNumber> => {
const balance = await getCachedLatestBalance(Number(chainId), token, account);
const balance = await latestBalanceCache(
Number(chainId),
token,
account
).get();
return balance;
};

Expand Down Expand Up @@ -1896,34 +1904,17 @@ export function getCachedLatestBlock(chainId: number) {
);
}

export function getCachedGasPrice(chainId: number) {
const ttlPerChain = {
default: 5,
[CHAIN_IDs.ARBITRUM]: 2,
};

return getCachedValue(
buildInternalCacheKey("gasPrice", chainId),
ttlPerChain[chainId] || ttlPerChain.default,
async () => {
const gasPrice = await getProvider(chainId).getGasPrice();
return gasPrice.mul(2);
},
(bnFromCache) => BigNumber.from(bnFromCache)
);
}

export function getCachedLatestBalance(
export function latestBalanceCache(
chainId: number,
tokenAddress: string,
address: string
) {
const ttlPerChain = {
default: 30,
[CHAIN_IDs.MAINNET]: 30,
default: 60,
[CHAIN_IDs.MAINNET]: 60,
};

return getCachedValue(
return makeCacheGetterAndSetter(
buildInternalCacheKey("latestBalance", tokenAddress, chainId, address),
ttlPerChain[chainId] || ttlPerChain.default,
() => getBalance(chainId, address, tokenAddress),
Expand Down
69 changes: 69 additions & 0 deletions api/cron-cache-balances.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { VercelResponse } from "@vercel/node";
import { ethers } from "ethers";
import { TypedVercelRequest } from "./_types";

import {
HUB_POOL_CHAIN_ID,
getLogger,
handleErrorCondition,
latestBalanceCache,
} from "./_utils";

import mainnetChains from "../src/data/chains_1.json";

const handler = async (
_: TypedVercelRequest<Record<string, never>>,
response: VercelResponse
) => {
const logger = getLogger();
logger.debug({
at: "CronCacheBalances",
message: "Starting cron job...",
});
try {
const {
REACT_APP_FULL_RELAYERS, // These are relayers running a full auto-rebalancing strategy.
REACT_APP_TRANSFER_RESTRICTED_RELAYERS, // These are relayers whose funds stay put.
} = process.env;

const fullRelayers = !REACT_APP_FULL_RELAYERS
? []
: (JSON.parse(REACT_APP_FULL_RELAYERS) as string[]).map((relayer) => {
return ethers.utils.getAddress(relayer);
});
const transferRestrictedRelayers = !REACT_APP_TRANSFER_RESTRICTED_RELAYERS
? []
: (JSON.parse(REACT_APP_TRANSFER_RESTRICTED_RELAYERS) as string[]).map(
(relayer) => {
return ethers.utils.getAddress(relayer);
}
);

// Skip cron job on testnet
if (HUB_POOL_CHAIN_ID !== 1) {
return;
}

for (const chain of mainnetChains) {
for (const token of chain.inputTokens) {
const setTokenBalance = async (relayer: string) => {
await latestBalanceCache(chain.chainId, relayer, token.address).set();
};
await Promise.all([
Promise.all(fullRelayers.map(setTokenBalance)),
Promise.all(transferRestrictedRelayers.map(setTokenBalance)),
]);
}
}

logger.debug({
at: "CronCacheBalances",
message: "Finished",
});
response.status(200);
} catch (error: unknown) {
return handleErrorCondition("cron-cache-balances", response, logger, error);
}
};

export default handler;
6 changes: 6 additions & 0 deletions vercel.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
{
"devCommand": "yarn dev",
"crons": [
{
"path": "/api/cron-cache-balances",
"schedule": "* * * * *"
}
],
"rewrites": [
{
"source": "/api/deposit/status",
Expand Down

0 comments on commit 0b283aa

Please sign in to comment.