mirror of
https://github.com/cerc-io/watcher-ts
synced 2024-11-19 12:26:19 +00:00
Bug fixes from smoke testing (#238)
* Fix update for entity relations. * Implement demo values in uni-info-watcher indexer code. * amend Co-authored-by: nabarun <nabarun@deepstacksoft.com>
This commit is contained in:
parent
f1f70ad7d4
commit
fc4f49113b
13
README.md
13
README.md
@ -48,6 +48,7 @@ Create the databases for the job queues and enable the `pgcrypto` extension on t
|
||||
```
|
||||
createdb address-watcher-job-queue
|
||||
createdb uni-watcher-job-queue
|
||||
createdb uni-info-watcher-job-queue
|
||||
```
|
||||
|
||||
```
|
||||
@ -74,6 +75,18 @@ CREATE EXTENSION
|
||||
uni-watcher-job-queue=# exit
|
||||
```
|
||||
|
||||
```
|
||||
postgres@tesla:~$ psql -U postgres -h localhost uni-info-watcher-job-queue
|
||||
Password for user postgres:
|
||||
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
|
||||
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
|
||||
Type "help" for help.
|
||||
|
||||
uni-info-watcher-job-queue=# CREATE EXTENSION pgcrypto;
|
||||
CREATE EXTENSION
|
||||
uni-info-watcher-job-queue=# exit
|
||||
```
|
||||
|
||||
#### Reset
|
||||
|
||||
Reset the databases used by the watchers:
|
||||
|
@ -7,7 +7,8 @@ import yargs from 'yargs';
|
||||
import 'reflect-metadata';
|
||||
import { ethers } from 'ethers';
|
||||
|
||||
import { Config, getConfig } from '../config';
|
||||
import { Config, getConfig } from '@vulcanize/util';
|
||||
|
||||
import { Database } from '../database';
|
||||
|
||||
(async () => {
|
||||
|
@ -463,8 +463,11 @@ export class Indexer implements IndexerInterface {
|
||||
token0.whitelistPools.push(pool);
|
||||
}
|
||||
|
||||
await this._db.saveToken(dbTx, token0, block);
|
||||
await this._db.saveToken(dbTx, token1, block);
|
||||
token0 = await this._db.saveToken(dbTx, token0, block);
|
||||
token1 = await this._db.saveToken(dbTx, token1, block);
|
||||
pool.token0 = token0;
|
||||
pool.token1 = token1;
|
||||
await this._db.savePool(dbTx, pool, block);
|
||||
await this._db.saveFactory(dbTx, factory, block);
|
||||
await dbTx.commitTransaction();
|
||||
} catch (error) {
|
||||
@ -511,7 +514,7 @@ export class Indexer implements IndexerInterface {
|
||||
// Update ETH price now that prices could have changed.
|
||||
const bundle = await this._db.getBundle(dbTx, { id: '1', blockHash: block.hash });
|
||||
assert(bundle);
|
||||
bundle.ethPriceUSD = await getEthPriceInUSD(this._db, dbTx, block);
|
||||
bundle.ethPriceUSD = await getEthPriceInUSD(this._db, dbTx, block, this._isDemo);
|
||||
|
||||
// Update token prices.
|
||||
const [token0, token1] = await Promise.all([
|
||||
@ -521,11 +524,13 @@ export class Indexer implements IndexerInterface {
|
||||
|
||||
assert(token0 && token1, 'Pool tokens not found.');
|
||||
|
||||
token0.derivedETH = await findEthPerToken(token0);
|
||||
token1.derivedETH = await findEthPerToken(token1);
|
||||
token0.derivedETH = await findEthPerToken(this._db, dbTx, token0, this._isDemo);
|
||||
token1.derivedETH = await findEthPerToken(this._db, dbTx, token1, this._isDemo);
|
||||
|
||||
this._db.savePool(dbTx, pool, block);
|
||||
this._db.saveBundle(dbTx, bundle, block);
|
||||
pool.token0 = token0;
|
||||
pool.token1 = token1;
|
||||
await this._db.savePool(dbTx, pool, block);
|
||||
await this._db.saveBundle(dbTx, bundle, block);
|
||||
|
||||
await updatePoolDayData(this._db, dbTx, { contractAddress, block });
|
||||
await updatePoolHourData(this._db, dbTx, { contractAddress, block });
|
||||
@ -551,15 +556,17 @@ export class Indexer implements IndexerInterface {
|
||||
const bundle = await this._db.getBundle(dbTx, { id: '1', blockHash: block.hash });
|
||||
assert(bundle);
|
||||
const poolAddress = contractAddress;
|
||||
const pool = await this._db.getPool(dbTx, { id: poolAddress, blockHash: block.hash });
|
||||
let pool = await this._db.getPool(dbTx, { id: poolAddress, blockHash: block.hash });
|
||||
assert(pool);
|
||||
|
||||
// TODO: In subgraph factory is fetched by hardcoded factory address.
|
||||
// Currently fetching first factory in database as only one exists.
|
||||
const [factory] = await this._db.getModelEntities(dbTx, Factory, { hash: block.hash }, {}, { limit: 1 });
|
||||
|
||||
const token0 = pool.token0;
|
||||
const token1 = pool.token1;
|
||||
let token0 = await this._db.getToken(dbTx, pool.token0);
|
||||
let token1 = await this._db.getToken(dbTx, pool.token1);
|
||||
assert(token0);
|
||||
assert(token1);
|
||||
const amount0 = convertTokenToDecimal(BigInt(mintEvent.amount0), BigInt(token0.decimals));
|
||||
const amount1 = convertTokenToDecimal(BigInt(mintEvent.amount1), BigInt(token1.decimals));
|
||||
|
||||
@ -664,16 +671,24 @@ export class Indexer implements IndexerInterface {
|
||||
await updatePoolDayData(this._db, dbTx, { block, contractAddress });
|
||||
await updatePoolHourData(this._db, dbTx, { block, contractAddress });
|
||||
|
||||
await Promise.all([
|
||||
[token0, token1] = await Promise.all([
|
||||
this._db.saveToken(dbTx, token0, block),
|
||||
this._db.saveToken(dbTx, token1, block)
|
||||
]);
|
||||
|
||||
await this._db.savePool(dbTx, pool, block);
|
||||
pool.token0 = token0;
|
||||
pool.token1 = token1;
|
||||
|
||||
pool = await this._db.savePool(dbTx, pool, block);
|
||||
await this._db.saveFactory(dbTx, factory, block);
|
||||
|
||||
mint.pool = pool;
|
||||
mint.token0 = token0;
|
||||
mint.token1 = token1;
|
||||
await this._db.saveMint(dbTx, mint, block);
|
||||
|
||||
lowerTick.pool = pool;
|
||||
upperTick.pool = pool;
|
||||
await Promise.all([
|
||||
await this._db.saveTick(dbTx, lowerTick, block),
|
||||
await this._db.saveTick(dbTx, upperTick, block)
|
||||
@ -696,15 +711,17 @@ export class Indexer implements IndexerInterface {
|
||||
const bundle = await this._db.getBundle(dbTx, { id: '1', blockHash: block.hash });
|
||||
assert(bundle);
|
||||
const poolAddress = contractAddress;
|
||||
const pool = await this._db.getPool(dbTx, { id: poolAddress, blockHash: block.hash });
|
||||
let pool = await this._db.getPool(dbTx, { id: poolAddress, blockHash: block.hash });
|
||||
assert(pool);
|
||||
|
||||
// TODO: In subgraph factory is fetched by hardcoded factory address.
|
||||
// Currently fetching first factory in database as only one exists.
|
||||
const [factory] = await this._db.getModelEntities(dbTx, Factory, { hash: block.hash }, {}, { limit: 1 });
|
||||
|
||||
const token0 = pool.token0;
|
||||
const token1 = pool.token1;
|
||||
let token0 = await this._db.getToken(dbTx, pool.token0);
|
||||
let token1 = await this._db.getToken(dbTx, pool.token1);
|
||||
assert(token0);
|
||||
assert(token1);
|
||||
const amount0 = convertTokenToDecimal(BigInt(burnEvent.amount0), BigInt(token0.decimals));
|
||||
const amount1 = convertTokenToDecimal(BigInt(burnEvent.amount1), BigInt(token1.decimals));
|
||||
|
||||
@ -794,21 +811,28 @@ export class Indexer implements IndexerInterface {
|
||||
await updatePoolDayData(this._db, dbTx, { block, contractAddress });
|
||||
await updatePoolHourData(this._db, dbTx, { block, contractAddress });
|
||||
|
||||
await Promise.all([
|
||||
[token0, token1] = await Promise.all([
|
||||
this._db.saveToken(dbTx, token0, block),
|
||||
this._db.saveToken(dbTx, token1, block)
|
||||
]);
|
||||
|
||||
await this._db.savePool(dbTx, pool, block);
|
||||
pool.token0 = token0;
|
||||
pool.token1 = token1;
|
||||
pool = await this._db.savePool(dbTx, pool, block);
|
||||
await this._db.saveFactory(dbTx, factory, block);
|
||||
|
||||
// Skipping update Tick fee and Tick day data as they are not queried.
|
||||
|
||||
lowerTick.pool = pool;
|
||||
upperTick.pool = pool;
|
||||
await Promise.all([
|
||||
await this._db.saveTick(dbTx, lowerTick, block),
|
||||
await this._db.saveTick(dbTx, upperTick, block)
|
||||
]);
|
||||
|
||||
burn.pool = pool;
|
||||
burn.token0 = token0;
|
||||
burn.token1 = token1;
|
||||
await this._db.saveBurn(dbTx, burn, block);
|
||||
await dbTx.commitTransaction();
|
||||
} catch (error) {
|
||||
@ -823,14 +847,14 @@ export class Indexer implements IndexerInterface {
|
||||
const dbTx = await this._db.createTransactionRunner();
|
||||
|
||||
try {
|
||||
const bundle = await this._db.getBundle(dbTx, { id: '1', blockHash: block.hash });
|
||||
let bundle = await this._db.getBundle(dbTx, { id: '1', blockHash: block.hash });
|
||||
assert(bundle);
|
||||
|
||||
// TODO: In subgraph factory is fetched by hardcoded factory address.
|
||||
// Currently fetching first factory in database as only one exists.
|
||||
const [factory] = await this._db.getModelEntities(dbTx, Factory, { hash: block.hash }, {}, { limit: 1 });
|
||||
|
||||
const pool = await this._db.getPool(dbTx, { id: contractAddress, blockHash: block.hash });
|
||||
let pool = await this._db.getPool(dbTx, { id: contractAddress, blockHash: block.hash });
|
||||
assert(pool);
|
||||
|
||||
// Hot fix for bad pricing.
|
||||
@ -838,7 +862,7 @@ export class Indexer implements IndexerInterface {
|
||||
return;
|
||||
}
|
||||
|
||||
const [token0, token1] = await Promise.all([
|
||||
let [token0, token1] = await Promise.all([
|
||||
this._db.getToken(dbTx, { id: pool.token0.id, blockHash: block.hash }),
|
||||
this._db.getToken(dbTx, { id: pool.token1.id, blockHash: block.hash })
|
||||
]);
|
||||
@ -924,9 +948,10 @@ export class Indexer implements IndexerInterface {
|
||||
pool.token1Price = prices[1];
|
||||
|
||||
// Update USD pricing.
|
||||
bundle.ethPriceUSD = await getEthPriceInUSD(this._db, dbTx, block);
|
||||
token0.derivedETH = await findEthPerToken(token0);
|
||||
token1.derivedETH = await findEthPerToken(token1);
|
||||
bundle.ethPriceUSD = await getEthPriceInUSD(this._db, dbTx, block, this._isDemo);
|
||||
bundle = await this._db.saveBundle(dbTx, bundle, block);
|
||||
token0.derivedETH = await findEthPerToken(this._db, dbTx, token0, this._isDemo);
|
||||
token1.derivedETH = await findEthPerToken(this._db, dbTx, token1, this._isDemo);
|
||||
|
||||
/**
|
||||
* Things afffected by new USD rates.
|
||||
@ -1008,16 +1033,31 @@ export class Indexer implements IndexerInterface {
|
||||
token1HourData.untrackedVolumeUSD = token1HourData.untrackedVolumeUSD.plus(amountTotalUSDTracked);
|
||||
token1HourData.feesUSD = token1HourData.feesUSD.plus(feesUSD);
|
||||
|
||||
await this._db.saveBundle(dbTx, bundle, block);
|
||||
await this._db.saveFactory(dbTx, factory, block);
|
||||
|
||||
[token0, token1] = await Promise.all([
|
||||
this._db.saveToken(dbTx, token0, block),
|
||||
this._db.saveToken(dbTx, token1, block)
|
||||
]);
|
||||
|
||||
pool.token0 = token0;
|
||||
pool.token1 = token1;
|
||||
pool = await this._db.savePool(dbTx, pool, block);
|
||||
|
||||
swap.token0 = token0;
|
||||
swap.token1 = token1;
|
||||
swap.pool = pool;
|
||||
await this._db.saveSwap(dbTx, swap, block);
|
||||
|
||||
token0DayData.token = token0;
|
||||
token1DayData.token = token1;
|
||||
await this._db.saveTokenDayData(dbTx, token0DayData, block);
|
||||
await this._db.saveTokenDayData(dbTx, token1DayData, block);
|
||||
|
||||
await this._db.saveUniswapDayData(dbTx, uniswapDayData, block);
|
||||
|
||||
poolDayData.pool = pool;
|
||||
await this._db.savePoolDayData(dbTx, poolDayData, block);
|
||||
await this._db.saveFactory(dbTx, factory, block);
|
||||
await this._db.savePool(dbTx, pool, block);
|
||||
await this._db.saveToken(dbTx, token0, block);
|
||||
await this._db.saveToken(dbTx, token1, block);
|
||||
|
||||
// Skipping update of inner vars of current or crossed ticks as they are not queried.
|
||||
await dbTx.commitTransaction();
|
||||
|
@ -117,7 +117,7 @@ export const createResolvers = async (indexer: Indexer, eventWatcher: EventWatch
|
||||
tokens: async (_: any, { block = {}, first, orderBy, orderDirection, where }: { block: BlockHeight, first: number, orderBy: string, orderDirection: OrderDirection, where: { [key: string]: any } }) => {
|
||||
log('tokens', orderBy, orderDirection, where);
|
||||
|
||||
return indexer.getEntities(Token, block, where, { limit: first, orderBy, orderDirection });
|
||||
return indexer.getEntities(Token, block, where, { limit: first, orderBy, orderDirection }, ['token.whitelistPools']);
|
||||
},
|
||||
|
||||
tokenDayDatas: async (_: any, { first, skip, orderBy, orderDirection, where }: { first: number, skip: number, orderBy: string, orderDirection: OrderDirection, where: { [key: string]: any } }) => {
|
||||
|
@ -120,6 +120,7 @@ type Token {
|
||||
txCount: BigInt!
|
||||
volume: BigDecimal!
|
||||
volumeUSD: BigDecimal!
|
||||
whitelistPools: [Pool]
|
||||
}
|
||||
|
||||
type TokenDayData {
|
||||
|
@ -46,6 +46,9 @@ export const WHITELIST_TOKENS: string[] = [
|
||||
const MINIMUM_ETH_LOCKED = new Decimal(52);
|
||||
const Q192 = 2 ** 192;
|
||||
|
||||
// Constants used in demo.
|
||||
const ETH_PRICE_IN_USD = '3200.00';
|
||||
|
||||
export const sqrtPriceX96ToTokenPrices = (sqrtPriceX96: bigint, token0: Token, token1: Token): Decimal[] => {
|
||||
const num = new Decimal((sqrtPriceX96 * sqrtPriceX96).toString());
|
||||
const denom = new Decimal(Q192.toString());
|
||||
@ -60,7 +63,13 @@ export const sqrtPriceX96ToTokenPrices = (sqrtPriceX96: bigint, token0: Token, t
|
||||
return [price0, price1];
|
||||
};
|
||||
|
||||
export const getEthPriceInUSD = async (db: Database, dbTx: QueryRunner, block: Block): Promise<Decimal> => {
|
||||
export const getEthPriceInUSD = async (db: Database, dbTx: QueryRunner, block: Block, isDemo: boolean): Promise<Decimal> => {
|
||||
if (isDemo) {
|
||||
// For demo purpose in local development.
|
||||
const ethPriceInUSD = new Decimal(ETH_PRICE_IN_USD);
|
||||
return ethPriceInUSD;
|
||||
}
|
||||
|
||||
// Fetch eth prices for each stablecoin.
|
||||
const usdcPool = await db.getPool(dbTx, { id: USDC_WETH_03_POOL, blockHash: block.hash }); // DAI is token0.
|
||||
|
||||
@ -75,8 +84,8 @@ export const getEthPriceInUSD = async (db: Database, dbTx: QueryRunner, block: B
|
||||
* Search through graph to find derived Eth per token.
|
||||
* @todo update to be derived ETH (add stablecoin estimates)
|
||||
**/
|
||||
export const findEthPerToken = async (token: Token): Promise<Decimal> => {
|
||||
if (token.id === WETH_ADDRESS) {
|
||||
export const findEthPerToken = async (db: Database, dbTx: QueryRunner, token: Token, isDemo: boolean): Promise<Decimal> => {
|
||||
if (token.id === WETH_ADDRESS || isDemo) {
|
||||
return new Decimal(1);
|
||||
}
|
||||
|
||||
@ -87,7 +96,9 @@ export const findEthPerToken = async (token: Token): Promise<Decimal> => {
|
||||
let priceSoFar = new Decimal(0);
|
||||
|
||||
for (let i = 0; i < whiteList.length; ++i) {
|
||||
const pool = whiteList[i];
|
||||
const poolAddress = whiteList[i].id;
|
||||
const pool = await db.getPool(dbTx, { id: poolAddress });
|
||||
assert(pool);
|
||||
|
||||
if (BigNumber.from(pool.liquidity).gt(0)) {
|
||||
if (pool.token0.id === token.id) {
|
||||
|
Loading…
Reference in New Issue
Block a user