mirror of
https://github.com/cerc-io/watcher-ts
synced 2026-09-07 16:34:06 +00:00
Changes to use packages in uniswap-watcher (#196)
* Changes to use util from uniswap-watcher * Refactor ResultIPLDBlock to util * Verify state in compare CLI for uniswap multiple queries * Prepare watcher-ts for publishing packages * Fix verify state in compare CLI for multiple entities query * Fix codegen util imports
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
entitiesDir = "../../graph-test-watcher/dist/entity/*"
|
||||
endpoint = "gqlEndpoint2"
|
||||
verifyState = true
|
||||
derivedFields = []
|
||||
skipFields = []
|
||||
|
||||
[cache]
|
||||
endpoint = "gqlEndpoint1"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"main": "dist/index.js",
|
||||
"license": "AGPL-3.0",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@graphprotocol/graph-ts": "^0.22.0",
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||
|
||||
@@ -12,7 +12,7 @@ import _ from 'lodash';
|
||||
import { getConfig as getWatcherConfig, wait } from '@cerc-io/util';
|
||||
import { GraphQLClient } from '@cerc-io/ipld-eth-client';
|
||||
|
||||
import { checkEntityInIPLDState, compareQuery, Config, getIPLDsByBlock, checkIPLDMetaData, combineIPLDState, getClients, getConfig } from './utils';
|
||||
import { checkGQLEntityInIPLDState, compareQuery, Config, getIPLDsByBlock, checkIPLDMetaData, combineIPLDState, getClients, getConfig, checkGQLEntitiesInIPLDState } from './utils';
|
||||
import { Database } from '../../database';
|
||||
import { getSubgraphConfig } from '../../utils';
|
||||
|
||||
@@ -168,7 +168,7 @@ export const main = async (): Promise<void> => {
|
||||
);
|
||||
|
||||
if (config.watcher.verifyState) {
|
||||
const ipldDiff = await checkEntityInIPLDState(ipldStateByBlock, queryName, result, id, rawJson, config.watcher.derivedFields);
|
||||
const ipldDiff = await checkGQLEntityInIPLDState(ipldStateByBlock, entityName, result[queryName], id, rawJson, config.watcher.skipFields);
|
||||
|
||||
if (ipldDiff) {
|
||||
log('Results mismatch for IPLD state:', ipldDiff);
|
||||
@@ -182,13 +182,24 @@ export const main = async (): Promise<void> => {
|
||||
}
|
||||
} else {
|
||||
if (updatedEntities.has(entityName)) {
|
||||
({ diff: resultDiff } = await compareQuery(
|
||||
let result;
|
||||
|
||||
({ diff: resultDiff, result1: result } = await compareQuery(
|
||||
clients,
|
||||
queryName,
|
||||
{ block },
|
||||
rawJson,
|
||||
timeDiff
|
||||
));
|
||||
|
||||
if (config.watcher.verifyState) {
|
||||
const ipldDiff = await checkGQLEntitiesInIPLDState(ipldStateByBlock, entityName, result[queryName], rawJson, config.watcher.skipFields);
|
||||
|
||||
if (ipldDiff) {
|
||||
log('Results mismatch for IPLD state:', ipldDiff);
|
||||
diffFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ interface QueryConfig {
|
||||
queryLimits: { [queryName: string]: number }
|
||||
}
|
||||
|
||||
interface EntityDerivedFields {
|
||||
interface EntitySkipFields {
|
||||
entity: string;
|
||||
fields: string[];
|
||||
}
|
||||
@@ -63,7 +63,7 @@ export interface Config {
|
||||
entitiesDir: string;
|
||||
verifyState: boolean;
|
||||
endpoint: keyof EndpointConfig;
|
||||
derivedFields: EntityDerivedFields[]
|
||||
skipFields: EntitySkipFields[]
|
||||
}
|
||||
cache: {
|
||||
endpoint: keyof EndpointConfig;
|
||||
@@ -312,34 +312,69 @@ export const combineIPLDState = (contractIPLDs: {[key: string]: any}[]): {[key:
|
||||
return contractIPLDStates.reduce((acc, state) => _.merge(acc, state));
|
||||
};
|
||||
|
||||
export const checkEntityInIPLDState = async (
|
||||
export const checkGQLEntityInIPLDState = async (
|
||||
ipldState: {[key: string]: any},
|
||||
queryName: string,
|
||||
entityName: string,
|
||||
entityResult: {[key: string]: any},
|
||||
id: string,
|
||||
rawJson: boolean,
|
||||
derivedFields: EntityDerivedFields[] = []
|
||||
skipFields: EntitySkipFields[] = []
|
||||
): Promise<string> => {
|
||||
const entityName = _.upperFirst(queryName);
|
||||
const ipldEntity = ipldState[entityName][id];
|
||||
|
||||
// Filter __typename key in GQL result.
|
||||
const resultEntity = omitDeep(entityResult[queryName], '__typename');
|
||||
entityResult = omitDeep(entityResult, '__typename');
|
||||
|
||||
// Filter derived fields in GQL result.
|
||||
derivedFields.forEach(({ entity, fields }) => {
|
||||
// Filter skipped fields in state comaparison.
|
||||
skipFields.forEach(({ entity, fields }) => {
|
||||
if (entityName === entity) {
|
||||
fields.forEach(field => {
|
||||
delete resultEntity[field];
|
||||
});
|
||||
omitDeep(entityResult, fields);
|
||||
omitDeep(ipldEntity, fields);
|
||||
}
|
||||
});
|
||||
|
||||
const diff = compareObjects(resultEntity, ipldEntity, rawJson);
|
||||
const diff = compareObjects(entityResult, ipldEntity, rawJson);
|
||||
|
||||
return diff;
|
||||
};
|
||||
|
||||
export const checkGQLEntitiesInIPLDState = async (
|
||||
ipldState: {[key: string]: any},
|
||||
entityName: string,
|
||||
entitiesResult: any[],
|
||||
rawJson: boolean,
|
||||
skipFields: EntitySkipFields[] = []
|
||||
): Promise<string> => {
|
||||
// Form entities from state to compare with GQL result
|
||||
const stateEntities = ipldState[entityName];
|
||||
|
||||
for (const entityResult of entitiesResult) {
|
||||
const stateEntity = stateEntities[entityResult.id];
|
||||
|
||||
// Verify state if entity from GQL result is present in state.
|
||||
if (stateEntity) {
|
||||
// Filter __typename key in GQL result.
|
||||
entitiesResult = omitDeep(entityResult, '__typename');
|
||||
|
||||
// Filter skipped fields in state comaparison.
|
||||
skipFields.forEach(({ entity, fields }) => {
|
||||
if (entityName === entity) {
|
||||
omitDeep(entityResult, fields);
|
||||
omitDeep(stateEntity, fields);
|
||||
}
|
||||
});
|
||||
|
||||
const diff = compareObjects(entityResult, stateEntity, rawJson);
|
||||
|
||||
if (diff) {
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
// obj1: expected
|
||||
// obj2: actual
|
||||
const compareObjects = (obj1: any, obj2: any, rawJson: boolean): string => {
|
||||
|
||||
@@ -100,6 +100,7 @@ export const instantiate = async (
|
||||
database.cacheUpdatedEntity(entityName, dbEntity);
|
||||
|
||||
// Update the in-memory subgraph state if not disabled.
|
||||
// TODO: enableSubgraphState
|
||||
if (!indexer.serverConfig.disableSubgraphState) {
|
||||
// Prepare diff data for the entity update
|
||||
assert(indexer.getRelationsMap);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { SelectionNode } from 'graphql';
|
||||
|
||||
import { ResultObject } from '@vulcanize/assemblyscript/lib/loader';
|
||||
import { EthClient } from '@cerc-io/ipld-eth-client';
|
||||
import { getFullBlock, BlockHeight, ServerConfig, getFullTransaction, QueryOptions, IPLDBlockInterface, IPLDIndexerInterface, BlockProgressInterface } from '@cerc-io/util';
|
||||
import { getFullBlock, BlockHeight, ServerConfig, getFullTransaction, QueryOptions, IPLDBlockInterface, IndexerInterface, BlockProgressInterface } from '@cerc-io/util';
|
||||
|
||||
import { createBlock, createEvent, getSubgraphConfig, resolveEntityFieldConflicts, Transaction } from './utils';
|
||||
import { Context, GraphData, instantiate } from './loader';
|
||||
@@ -28,7 +28,7 @@ interface DataSource {
|
||||
|
||||
export class GraphWatcher {
|
||||
_database: Database;
|
||||
_indexer?: IPLDIndexerInterface;
|
||||
_indexer?: IndexerInterface;
|
||||
_ethClient: EthClient;
|
||||
_ethProvider: providers.BaseProvider;
|
||||
_subgraphPath: string;
|
||||
@@ -254,7 +254,7 @@ export class GraphWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
setIndexer (indexer: IPLDIndexerInterface): void {
|
||||
setIndexer (indexer: IndexerInterface): void {
|
||||
this._indexer = indexer;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,10 @@ import {
|
||||
EventInterface,
|
||||
SyncStatusInterface,
|
||||
ServerConfig as ServerConfigInterface,
|
||||
ValueResult
|
||||
ValueResult,
|
||||
ContractInterface,
|
||||
IpldStatus as IpldStatusInterface,
|
||||
IPLDBlockInterface
|
||||
} from '@cerc-io/util';
|
||||
import { EthClient } from '@cerc-io/ipld-eth-client';
|
||||
import { GetStorageAt, getStorageValue, MappingKey, StorageLayout } from '@cerc-io/solidity-mapper';
|
||||
@@ -85,7 +88,7 @@ export class Indexer implements IndexerInterface {
|
||||
return '';
|
||||
}
|
||||
|
||||
async fetchBlockEvents (block: BlockProgressInterface): Promise<BlockProgressInterface> {
|
||||
async fetchBlockWithEvents (block: BlockProgressInterface): Promise<BlockProgressInterface> {
|
||||
return block;
|
||||
}
|
||||
|
||||
@@ -153,6 +156,22 @@ export class Indexer implements IndexerInterface {
|
||||
async processEvent (event: EventInterface): Promise<void> {
|
||||
assert(event);
|
||||
}
|
||||
|
||||
isWatchedContract (address : string): ContractInterface | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async processBlock (blockProgress: BlockProgressInterface): Promise<void> {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getIPLDData (ipldBlock: IPLDBlockInterface): any {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async updateIPLDStatusMap (address: string, ipldStatus: IpldStatusInterface): Promise<void> {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
class SyncStatus implements SyncStatusInterface {
|
||||
|
||||
Reference in New Issue
Block a user