mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-07-28 11:02:07 +00:00
Add a table for entites in frothy region for subgraph watchers (#231)
* Add a table for entites in frothy region and update it in a subscriber * Accommodate changes to other watchers and codegen
This commit is contained in:
parent
7e5974ccf7
commit
408a3927c0
31
packages/codegen/src/data/entities/FrothyEntity.yaml
Normal file
31
packages/codegen/src/data/entities/FrothyEntity.yaml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
className: FrothyEntity
|
||||||
|
indexOn:
|
||||||
|
- columns:
|
||||||
|
- blockNumber
|
||||||
|
columns:
|
||||||
|
- name: id
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: PrimaryColumn
|
||||||
|
- name: name
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: PrimaryColumn
|
||||||
|
- name: blockHash
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: PrimaryColumn
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 66
|
||||||
|
- name: blockNumber
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
imports:
|
||||||
|
- toImport:
|
||||||
|
- Entity
|
||||||
|
- PrimaryColumn
|
||||||
|
- Column
|
||||||
|
- Index
|
||||||
|
from: typeorm
|
@ -16,10 +16,12 @@ const TEMPLATE_FILE = './templates/database-template.handlebars';
|
|||||||
|
|
||||||
export class Database {
|
export class Database {
|
||||||
_queries: Array<any>;
|
_queries: Array<any>;
|
||||||
|
_subgraphEntities: Array<any>;
|
||||||
_templateString: string;
|
_templateString: string;
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
this._queries = [];
|
this._queries = [];
|
||||||
|
this._subgraphEntities = [];
|
||||||
this._templateString = fs.readFileSync(path.resolve(__dirname, TEMPLATE_FILE)).toString();
|
this._templateString = fs.readFileSync(path.resolve(__dirname, TEMPLATE_FILE)).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +74,23 @@ export class Database {
|
|||||||
this._queries.push(queryObject);
|
this._queries.push(queryObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addSubgraphEntities (subgraphSchemaDocument: any): void {
|
||||||
|
// Add subgraph entities for adding them to the entities list.
|
||||||
|
const subgraphTypeDefs = subgraphSchemaDocument.definitions;
|
||||||
|
|
||||||
|
subgraphTypeDefs.forEach((def: any) => {
|
||||||
|
if (def.kind !== 'ObjectTypeDefinition') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const entityObject: any = {
|
||||||
|
className: def.name.value
|
||||||
|
};
|
||||||
|
|
||||||
|
this._subgraphEntities.push(entityObject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the database file generated from a template to a stream.
|
* Writes the database file generated from a template to a stream.
|
||||||
* @param outStream A writable output stream to write the database file to.
|
* @param outStream A writable output stream to write the database file to.
|
||||||
@ -79,7 +98,8 @@ export class Database {
|
|||||||
exportDatabase (outStream: Writable): void {
|
exportDatabase (outStream: Writable): void {
|
||||||
const template = Handlebars.compile(this._templateString);
|
const template = Handlebars.compile(this._templateString);
|
||||||
const obj = {
|
const obj = {
|
||||||
queries: this._queries
|
queries: this._queries,
|
||||||
|
subgraphEntities: this._subgraphEntities
|
||||||
};
|
};
|
||||||
const database = template(obj);
|
const database = template(obj);
|
||||||
outStream.write(database);
|
outStream.write(database);
|
||||||
|
@ -173,7 +173,7 @@ export class Entity {
|
|||||||
* Writes the generated entity files in the given directory.
|
* Writes the generated entity files in the given directory.
|
||||||
* @param entityDir Directory to write the entities to.
|
* @param entityDir Directory to write the entities to.
|
||||||
*/
|
*/
|
||||||
exportEntities (entityDir: string): void {
|
exportEntities (entityDir: string, subgraphPath: string): void {
|
||||||
this._addEventEntity();
|
this._addEventEntity();
|
||||||
this._addSyncStatusEntity();
|
this._addSyncStatusEntity();
|
||||||
this._addContractEntity();
|
this._addContractEntity();
|
||||||
@ -181,6 +181,11 @@ export class Entity {
|
|||||||
this._addStateEntity();
|
this._addStateEntity();
|
||||||
this._addStateSyncStatusEntity();
|
this._addStateSyncStatusEntity();
|
||||||
|
|
||||||
|
// Add FrothyEntity table only for subgraph watchers
|
||||||
|
if (subgraphPath) {
|
||||||
|
this._addFrothyEntity();
|
||||||
|
}
|
||||||
|
|
||||||
const template = Handlebars.compile(this._templateString);
|
const template = Handlebars.compile(this._templateString);
|
||||||
this._entities.forEach(entityObj => {
|
this._entities.forEach(entityObj => {
|
||||||
const entity = template(entityObj);
|
const entity = template(entityObj);
|
||||||
@ -288,6 +293,11 @@ export class Entity {
|
|||||||
this._entities.push(entity);
|
this._entities.push(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_addFrothyEntity (): void {
|
||||||
|
const entity = yaml.load(fs.readFileSync(path.resolve(__dirname, TABLES_DIR, 'FrothyEntity.yaml'), 'utf8'));
|
||||||
|
this._entities.push(entity);
|
||||||
|
}
|
||||||
|
|
||||||
_addBigIntTransformerOption (entityObject: any): void {
|
_addBigIntTransformerOption (entityObject: any): void {
|
||||||
let importObject = entityObject.imports.find((element: any) => {
|
let importObject = entityObject.imports.find((element: any) => {
|
||||||
return element.from === '@cerc-io/util';
|
return element.from === '@cerc-io/util';
|
||||||
|
@ -37,6 +37,7 @@ import { importState } from './import-state';
|
|||||||
import { exportInspectCID } from './inspect-cid';
|
import { exportInspectCID } from './inspect-cid';
|
||||||
import { getSubgraphConfig } from './utils/subgraph';
|
import { getSubgraphConfig } from './utils/subgraph';
|
||||||
import { exportIndexBlock } from './index-block';
|
import { exportIndexBlock } from './index-block';
|
||||||
|
import { exportSubscriber } from './subscriber';
|
||||||
|
|
||||||
const main = async (): Promise<void> => {
|
const main = async (): Promise<void> => {
|
||||||
const argv = await yargs(hideBin(process.argv))
|
const argv = await yargs(hideBin(process.argv))
|
||||||
@ -217,7 +218,7 @@ function generateWatcher (visitor: Visitor, contracts: any[], config: any) {
|
|||||||
const entityDir = outputDir
|
const entityDir = outputDir
|
||||||
? path.join(outputDir, 'src/entity')
|
? path.join(outputDir, 'src/entity')
|
||||||
: '';
|
: '';
|
||||||
visitor.exportEntities(entityDir);
|
visitor.exportEntities(entityDir, config.subgraphPath);
|
||||||
|
|
||||||
outStream = outputDir
|
outStream = outputDir
|
||||||
? fs.createWriteStream(path.join(outputDir, 'README.md'))
|
? fs.createWriteStream(path.join(outputDir, 'README.md'))
|
||||||
@ -323,6 +324,13 @@ function generateWatcher (visitor: Visitor, contracts: any[], config: any) {
|
|||||||
? fs.createWriteStream(path.join(outputDir, 'src/cli/index-block.ts'))
|
? fs.createWriteStream(path.join(outputDir, 'src/cli/index-block.ts'))
|
||||||
: process.stdout;
|
: process.stdout;
|
||||||
exportIndexBlock(outStream);
|
exportIndexBlock(outStream);
|
||||||
|
|
||||||
|
if (config.subgraphPath) {
|
||||||
|
outStream = outputDir
|
||||||
|
? fs.createWriteStream(path.join(outputDir, 'src/entity/Subscriber.ts'))
|
||||||
|
: process.stdout;
|
||||||
|
exportSubscriber(outStream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConfig (configFile: string): any {
|
function getConfig (configFile: string): any {
|
||||||
|
21
packages/codegen/src/subscriber.ts
Normal file
21
packages/codegen/src/subscriber.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2022 Vulcanize, Inc.
|
||||||
|
//
|
||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import Handlebars from 'handlebars';
|
||||||
|
import { Writable } from 'stream';
|
||||||
|
|
||||||
|
const SUBSCRIBER_TEMPLATE_FILE = './templates/subscriber-template.handlebars';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the subscriber file generated from template to a stream.
|
||||||
|
* @param outStream A writable output stream to write the subscriber file to.
|
||||||
|
*/
|
||||||
|
export function exportSubscriber (subscriberOutStream: Writable): void {
|
||||||
|
const subscriberTemplateString = fs.readFileSync(path.resolve(__dirname, SUBSCRIBER_TEMPLATE_FILE)).toString();
|
||||||
|
const subscriberTemplate = Handlebars.compile(subscriberTemplateString);
|
||||||
|
const subscriber = subscriberTemplate({});
|
||||||
|
subscriberOutStream.write(subscriber);
|
||||||
|
}
|
@ -17,6 +17,15 @@ import { State } from './entity/State';
|
|||||||
{{#each queries as | query |}}
|
{{#each queries as | query |}}
|
||||||
import { {{query.entityName}} } from './entity/{{query.entityName}}';
|
import { {{query.entityName}} } from './entity/{{query.entityName}}';
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
{{#each subgraphEntities as | subgraphEntity |}}
|
||||||
|
import { {{subgraphEntity.className}} } from './entity/{{subgraphEntity.className}}';
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
export const ENTITIES = [
|
||||||
|
{{~#each queries as | query |}}{{query.entityName}}, {{/each}}
|
||||||
|
{{~#each subgraphEntities as | subgraphEntity |}}{{subgraphEntity.className}}
|
||||||
|
{{~#unless @last}}, {{/unless}}
|
||||||
|
{{~/each}}];
|
||||||
|
|
||||||
export class Database implements DatabaseInterface {
|
export class Database implements DatabaseInterface {
|
||||||
_config: ConnectionOptions;
|
_config: ConnectionOptions;
|
||||||
|
@ -41,7 +41,7 @@ import { GraphWatcher } from '@cerc-io/graph-node';
|
|||||||
{{#each contracts as | contract |}}
|
{{#each contracts as | contract |}}
|
||||||
import {{contract.contractName}}Artifacts from './artifacts/{{contract.contractName}}.json';
|
import {{contract.contractName}}Artifacts from './artifacts/{{contract.contractName}}.json';
|
||||||
{{/each}}
|
{{/each}}
|
||||||
import { Database } from './database';
|
import { Database, ENTITIES } from './database';
|
||||||
import { createInitialState, handleEvent, createStateDiff, createStateCheckpoint } from './hooks';
|
import { createInitialState, handleEvent, createStateDiff, createStateCheckpoint } from './hooks';
|
||||||
import { Contract } from './entity/Contract';
|
import { Contract } from './entity/Contract';
|
||||||
import { Event } from './entity/Event';
|
import { Event } from './entity/Event';
|
||||||
@ -49,13 +49,12 @@ import { SyncStatus } from './entity/SyncStatus';
|
|||||||
import { StateSyncStatus } from './entity/StateSyncStatus';
|
import { StateSyncStatus } from './entity/StateSyncStatus';
|
||||||
import { BlockProgress } from './entity/BlockProgress';
|
import { BlockProgress } from './entity/BlockProgress';
|
||||||
import { State } from './entity/State';
|
import { State } from './entity/State';
|
||||||
|
|
||||||
{{#each queries as | query |}}
|
|
||||||
import { {{query.entityName}} } from './entity/{{query.entityName}}';
|
|
||||||
{{/each}}
|
|
||||||
{{#each subgraphEntities as | subgraphEntity |}}
|
{{#each subgraphEntities as | subgraphEntity |}}
|
||||||
import { {{subgraphEntity.className}} } from './entity/{{subgraphEntity.className}}';
|
import { {{subgraphEntity.className}} } from './entity/{{subgraphEntity.className}}';
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
{{#if (subgraphPath)}}
|
||||||
|
import { FrothyEntity } from './entity/FrothyEntity';
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
const log = debug('vulcanize:indexer');
|
const log = debug('vulcanize:indexer');
|
||||||
const JSONbigNative = JSONbig({ useNativeBigInt: true });
|
const JSONbigNative = JSONbig({ useNativeBigInt: true });
|
||||||
@ -521,7 +520,12 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateSyncStatusCanonicalBlock (blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
async updateSyncStatusCanonicalBlock (blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
||||||
return this._baseIndexer.updateSyncStatusCanonicalBlock(blockHash, blockNumber, force);
|
const syncStatus = this._baseIndexer.updateSyncStatusCanonicalBlock(blockHash, blockNumber, force);
|
||||||
|
{{#if (subgraphPath)}}
|
||||||
|
await this.pruneFrothyEntities(blockNumber);
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
return syncStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getEvent (id: string): Promise<Event | undefined> {
|
async getEvent (id: string): Promise<Event | undefined> {
|
||||||
@ -556,6 +560,12 @@ export class Indexer implements IndexerInterface {
|
|||||||
return this._baseIndexer.markBlocksAsPruned(blocks);
|
return this._baseIndexer.markBlocksAsPruned(blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{{#if (subgraphPath)}}
|
||||||
|
async pruneFrothyEntities (blockNumber: number): Promise<void> {
|
||||||
|
await this._graphWatcher.pruneFrothyEntities(FrothyEntity, blockNumber);
|
||||||
|
}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
async updateBlockProgress (block: BlockProgress, lastProcessedEventIndex: number): Promise<BlockProgress> {
|
async updateBlockProgress (block: BlockProgress, lastProcessedEventIndex: number): Promise<BlockProgress> {
|
||||||
return this._baseIndexer.updateBlockProgress(block, lastProcessedEventIndex);
|
return this._baseIndexer.updateBlockProgress(block, lastProcessedEventIndex);
|
||||||
}
|
}
|
||||||
@ -565,14 +575,11 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
||||||
const entities = [
|
{{#if (subgraphPath)}}
|
||||||
{{#each queries as | query |}}
|
const entities = [...ENTITIES, FrothyEntity];
|
||||||
{{query.entityName}},
|
{{else}}
|
||||||
{{/each}}
|
const entities = [...ENTITIES];
|
||||||
{{#each subgraphEntities as | subgraphEntity |}}
|
{{/if}}
|
||||||
{{subgraphEntity.className}},
|
|
||||||
{{/each}}
|
|
||||||
];
|
|
||||||
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2022 Vulcanize, Inc.
|
||||||
|
//
|
||||||
|
|
||||||
|
import { EventSubscriber, EntitySubscriberInterface, InsertEvent, UpdateEvent } from 'typeorm';
|
||||||
|
|
||||||
|
import { FrothyEntity } from './FrothyEntity';
|
||||||
|
import { ENTITIES } from '../database';
|
||||||
|
import { afterEntityInsertOrUpdate } from '@cerc-io/graph-node';
|
||||||
|
|
||||||
|
@EventSubscriber()
|
||||||
|
export class EntitySubscriber implements EntitySubscriberInterface {
|
||||||
|
async afterInsert (event: InsertEvent<any>): Promise<void> {
|
||||||
|
await afterEntityInsertOrUpdate(FrothyEntity, ENTITIES, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
async afterUpdate (event: UpdateEvent<any>): Promise<void> {
|
||||||
|
await afterEntityInsertOrUpdate(FrothyEntity, ENTITIES, event);
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,7 @@
|
|||||||
// "removeComments": true, /* Do not emit comments to output. */
|
// "removeComments": true, /* Do not emit comments to output. */
|
||||||
// "noEmit": true, /* Do not emit outputs. */
|
// "noEmit": true, /* Do not emit outputs. */
|
||||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
"downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||||
|
|
||||||
/* Strict Type-Checking Options */
|
/* Strict Type-Checking Options */
|
||||||
|
@ -155,6 +155,7 @@ export class Visitor {
|
|||||||
this._resolvers.addSubgraphResolvers(subgraphSchemaDocument);
|
this._resolvers.addSubgraphResolvers(subgraphSchemaDocument);
|
||||||
this._reset.addSubgraphEntities(subgraphSchemaDocument);
|
this._reset.addSubgraphEntities(subgraphSchemaDocument);
|
||||||
this._indexer.addSubgraphEntities(subgraphSchemaDocument);
|
this._indexer.addSubgraphEntities(subgraphSchemaDocument);
|
||||||
|
this._database.addSubgraphEntities(subgraphSchemaDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,8 +188,8 @@ export class Visitor {
|
|||||||
* Writes the generated entity files in the given directory.
|
* Writes the generated entity files in the given directory.
|
||||||
* @param entityDir Directory to write the entities to.
|
* @param entityDir Directory to write the entities to.
|
||||||
*/
|
*/
|
||||||
exportEntities (entityDir: string): void {
|
exportEntities (entityDir: string, subgraphPath: string): void {
|
||||||
this._entity.exportEntities(entityDir);
|
this._entity.exportEntities(entityDir, subgraphPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
21
packages/eden-watcher/src/entity/FrothyEntity.ts
Normal file
21
packages/eden-watcher/src/entity/FrothyEntity.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2022 Vulcanize, Inc.
|
||||||
|
//
|
||||||
|
|
||||||
|
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
@Index(['blockNumber'])
|
||||||
|
export class FrothyEntity {
|
||||||
|
@PrimaryColumn('varchar')
|
||||||
|
id!: string;
|
||||||
|
|
||||||
|
@PrimaryColumn('varchar')
|
||||||
|
name!: string;
|
||||||
|
|
||||||
|
@PrimaryColumn('varchar', { length: 66 })
|
||||||
|
blockHash!: string;
|
||||||
|
|
||||||
|
@Column('integer')
|
||||||
|
blockNumber!: number;
|
||||||
|
}
|
20
packages/eden-watcher/src/entity/Subscriber.ts
Normal file
20
packages/eden-watcher/src/entity/Subscriber.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2022 Vulcanize, Inc.
|
||||||
|
//
|
||||||
|
|
||||||
|
import { EventSubscriber, EntitySubscriberInterface, InsertEvent, UpdateEvent } from 'typeorm';
|
||||||
|
|
||||||
|
import { FrothyEntity } from './FrothyEntity';
|
||||||
|
import { ENTITIES } from '../database';
|
||||||
|
import { afterEntityInsertOrUpdate } from '@cerc-io/graph-node';
|
||||||
|
|
||||||
|
@EventSubscriber()
|
||||||
|
export class EntitySubscriber implements EntitySubscriberInterface {
|
||||||
|
async afterInsert (event: InsertEvent<any>): Promise<void> {
|
||||||
|
await afterEntityInsertOrUpdate(FrothyEntity, ENTITIES, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
async afterUpdate (event: UpdateEvent<any>): Promise<void> {
|
||||||
|
await afterEntityInsertOrUpdate(FrothyEntity, ENTITIES, event);
|
||||||
|
}
|
||||||
|
}
|
@ -55,6 +55,7 @@ import { Distribution } from './entity/Distribution';
|
|||||||
import { Claim } from './entity/Claim';
|
import { Claim } from './entity/Claim';
|
||||||
import { Account } from './entity/Account';
|
import { Account } from './entity/Account';
|
||||||
import { Slash } from './entity/Slash';
|
import { Slash } from './entity/Slash';
|
||||||
|
import { FrothyEntity } from './entity/FrothyEntity';
|
||||||
|
|
||||||
const KIND_EDENNETWORK = 'EdenNetwork';
|
const KIND_EDENNETWORK = 'EdenNetwork';
|
||||||
const KIND_MERKLEDISTRIBUTOR = 'EdenNetworkDistribution';
|
const KIND_MERKLEDISTRIBUTOR = 'EdenNetworkDistribution';
|
||||||
@ -444,7 +445,10 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateSyncStatusCanonicalBlock (blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
async updateSyncStatusCanonicalBlock (blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
||||||
return this._baseIndexer.updateSyncStatusCanonicalBlock(blockHash, blockNumber, force);
|
const syncStatus = this._baseIndexer.updateSyncStatusCanonicalBlock(blockHash, blockNumber, force);
|
||||||
|
await this.pruneFrothyEntities(blockNumber);
|
||||||
|
|
||||||
|
return syncStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getEvent (id: string): Promise<Event | undefined> {
|
async getEvent (id: string): Promise<Event | undefined> {
|
||||||
@ -481,6 +485,10 @@ export class Indexer implements IndexerInterface {
|
|||||||
await this._graphWatcher.pruneEntities(blocks, ENTITIES);
|
await this._graphWatcher.pruneEntities(blocks, ENTITIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async pruneFrothyEntities (blockNumber: number): Promise<void> {
|
||||||
|
await this._graphWatcher.pruneFrothyEntities(FrothyEntity, blockNumber);
|
||||||
|
}
|
||||||
|
|
||||||
async updateBlockProgress (block: BlockProgress, lastProcessedEventIndex: number): Promise<BlockProgress> {
|
async updateBlockProgress (block: BlockProgress, lastProcessedEventIndex: number): Promise<BlockProgress> {
|
||||||
return this._baseIndexer.updateBlockProgress(block, lastProcessedEventIndex);
|
return this._baseIndexer.updateBlockProgress(block, lastProcessedEventIndex);
|
||||||
}
|
}
|
||||||
@ -522,7 +530,7 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
||||||
const entities = [ProducerSet, Producer, RewardSchedule, RewardScheduleEntry, Network, Staker, ProducerEpoch, Epoch, Block, SlotClaim, Slot, Distributor, Distribution, Claim, Account, Slash];
|
const entities = [...ENTITIES, FrothyEntity];
|
||||||
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
// "removeComments": true, /* Do not emit comments to output. */
|
// "removeComments": true, /* Do not emit comments to output. */
|
||||||
// "noEmit": true, /* Do not emit outputs. */
|
// "noEmit": true, /* Do not emit outputs. */
|
||||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
"downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||||
|
|
||||||
/* Strict Type-Checking Options */
|
/* Strict Type-Checking Options */
|
||||||
|
@ -17,6 +17,8 @@ import { BlockProgress } from './entity/BlockProgress';
|
|||||||
import { State } from './entity/State';
|
import { State } from './entity/State';
|
||||||
import { StateSyncStatus } from './entity/StateSyncStatus';
|
import { StateSyncStatus } from './entity/StateSyncStatus';
|
||||||
|
|
||||||
|
export const ENTITIES = new Set([Allowance, Balance]);
|
||||||
|
|
||||||
export class Database implements DatabaseInterface {
|
export class Database implements DatabaseInterface {
|
||||||
_config: ConnectionOptions
|
_config: ConnectionOptions
|
||||||
_conn!: Connection
|
_conn!: Connection
|
||||||
|
@ -14,7 +14,7 @@ import { EthClient } from '@cerc-io/ipld-eth-client';
|
|||||||
import { MappingKey, StorageLayout } from '@cerc-io/solidity-mapper';
|
import { MappingKey, StorageLayout } from '@cerc-io/solidity-mapper';
|
||||||
import { IndexerInterface, Indexer as BaseIndexer, ValueResult, JobQueue, Where, QueryOptions, ServerConfig, StateStatus } from '@cerc-io/util';
|
import { IndexerInterface, Indexer as BaseIndexer, ValueResult, JobQueue, Where, QueryOptions, ServerConfig, StateStatus } from '@cerc-io/util';
|
||||||
|
|
||||||
import { Database } from './database';
|
import { Database, ENTITIES } from './database';
|
||||||
import { Event } from './entity/Event';
|
import { Event } from './entity/Event';
|
||||||
import { fetchTokenDecimals, fetchTokenName, fetchTokenSymbol, fetchTokenTotalSupply } from './utils';
|
import { fetchTokenDecimals, fetchTokenName, fetchTokenSymbol, fetchTokenTotalSupply } from './utils';
|
||||||
import { SyncStatus } from './entity/SyncStatus';
|
import { SyncStatus } from './entity/SyncStatus';
|
||||||
@ -23,8 +23,6 @@ import artifacts from './artifacts/ERC20.json';
|
|||||||
import { BlockProgress } from './entity/BlockProgress';
|
import { BlockProgress } from './entity/BlockProgress';
|
||||||
import { Contract } from './entity/Contract';
|
import { Contract } from './entity/Contract';
|
||||||
import { State } from './entity/State';
|
import { State } from './entity/State';
|
||||||
import { Allowance } from './entity/Allowance';
|
|
||||||
import { Balance } from './entity/Balance';
|
|
||||||
|
|
||||||
const log = debug('vulcanize:indexer');
|
const log = debug('vulcanize:indexer');
|
||||||
const JSONbigNative = JSONbig({ useNativeBigInt: true });
|
const JSONbigNative = JSONbig({ useNativeBigInt: true });
|
||||||
@ -430,7 +428,7 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
||||||
const entities = [Allowance, Balance];
|
const entities = [...ENTITIES];
|
||||||
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ import { _TokenApprovals } from './entity/_TokenApprovals';
|
|||||||
import { _OperatorApprovals } from './entity/_OperatorApprovals';
|
import { _OperatorApprovals } from './entity/_OperatorApprovals';
|
||||||
import { TransferCount } from './entity/TransferCount';
|
import { TransferCount } from './entity/TransferCount';
|
||||||
|
|
||||||
|
export const ENTITIES = new Set([_Balances, _Name, _OperatorApprovals, _Owners, _Symbol, _TokenApprovals, BalanceOf, GetApproved, IsApprovedForAll, Name, OwnerOf, SupportsInterface, Symbol, TokenURI, TransferCount]);
|
||||||
|
|
||||||
export class Database implements DatabaseInterface {
|
export class Database implements DatabaseInterface {
|
||||||
_config: ConnectionOptions;
|
_config: ConnectionOptions;
|
||||||
_conn!: Connection;
|
_conn!: Connection;
|
||||||
|
@ -30,7 +30,7 @@ import {
|
|||||||
} from '@cerc-io/util';
|
} from '@cerc-io/util';
|
||||||
|
|
||||||
import ERC721Artifacts from './artifacts/ERC721.json';
|
import ERC721Artifacts from './artifacts/ERC721.json';
|
||||||
import { Database } from './database';
|
import { Database, ENTITIES } from './database';
|
||||||
import { createInitialState, handleEvent, createStateDiff, createStateCheckpoint } from './hooks';
|
import { createInitialState, handleEvent, createStateDiff, createStateCheckpoint } from './hooks';
|
||||||
import { Contract } from './entity/Contract';
|
import { Contract } from './entity/Contract';
|
||||||
import { Event } from './entity/Event';
|
import { Event } from './entity/Event';
|
||||||
@ -38,20 +38,6 @@ import { SyncStatus } from './entity/SyncStatus';
|
|||||||
import { StateSyncStatus } from './entity/StateSyncStatus';
|
import { StateSyncStatus } from './entity/StateSyncStatus';
|
||||||
import { BlockProgress } from './entity/BlockProgress';
|
import { BlockProgress } from './entity/BlockProgress';
|
||||||
import { State } from './entity/State';
|
import { State } from './entity/State';
|
||||||
import { SupportsInterface } from './entity/SupportsInterface';
|
|
||||||
import { BalanceOf } from './entity/BalanceOf';
|
|
||||||
import { OwnerOf } from './entity/OwnerOf';
|
|
||||||
import { GetApproved } from './entity/GetApproved';
|
|
||||||
import { IsApprovedForAll } from './entity/IsApprovedForAll';
|
|
||||||
import { Name } from './entity/Name';
|
|
||||||
import { Symbol } from './entity/Symbol';
|
|
||||||
import { TokenURI } from './entity/TokenURI';
|
|
||||||
import { _Name } from './entity/_Name';
|
|
||||||
import { _Symbol } from './entity/_Symbol';
|
|
||||||
import { _Owners } from './entity/_Owners';
|
|
||||||
import { _Balances } from './entity/_Balances';
|
|
||||||
import { _TokenApprovals } from './entity/_TokenApprovals';
|
|
||||||
import { _OperatorApprovals } from './entity/_OperatorApprovals';
|
|
||||||
import { TransferCount } from './entity/TransferCount';
|
import { TransferCount } from './entity/TransferCount';
|
||||||
|
|
||||||
const log = debug('vulcanize:indexer');
|
const log = debug('vulcanize:indexer');
|
||||||
@ -878,7 +864,7 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
||||||
const entities = [SupportsInterface, BalanceOf, OwnerOf, GetApproved, IsApprovedForAll, Name, Symbol, TokenURI, _Name, _Symbol, _Owners, _Balances, _TokenApprovals, _OperatorApprovals, TransferCount];
|
const entities = [...ENTITIES];
|
||||||
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
// "removeComments": true, /* Do not emit comments to output. */
|
// "removeComments": true, /* Do not emit comments to output. */
|
||||||
// "noEmit": true, /* Do not emit outputs. */
|
// "noEmit": true, /* Do not emit outputs. */
|
||||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
"downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||||
|
|
||||||
/* Strict Type-Checking Options */
|
/* Strict Type-Checking Options */
|
||||||
|
@ -1256,6 +1256,11 @@ export class Database {
|
|||||||
await Promise.all(updatePromises);
|
await Promise.all(updatePromises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async pruneFrothyEntities<Entity> (queryRunner: QueryRunner, frothyEntityType: new () => Entity, blockNumber: number): Promise<void> {
|
||||||
|
// Remove frothy entity entries at | below the prune block height
|
||||||
|
return this._baseDatabase.removeEntities(queryRunner, frothyEntityType, { where: { blockNumber: LessThanOrEqual(blockNumber) } });
|
||||||
|
}
|
||||||
|
|
||||||
_measureCachedPrunedEntities () {
|
_measureCachedPrunedEntities () {
|
||||||
const totalEntities = Array.from(this.cachedEntities.latestPrunedEntities.values())
|
const totalEntities = Array.from(this.cachedEntities.latestPrunedEntities.values())
|
||||||
.reduce((acc, idEntitiesMap) => acc + idEntitiesMap.size, 0);
|
.reduce((acc, idEntitiesMap) => acc + idEntitiesMap.size, 0);
|
||||||
|
@ -3,5 +3,6 @@ export * from './database';
|
|||||||
export {
|
export {
|
||||||
prepareEntityState,
|
prepareEntityState,
|
||||||
updateEntitiesFromState,
|
updateEntitiesFromState,
|
||||||
resolveEntityFieldConflicts
|
resolveEntityFieldConflicts,
|
||||||
|
afterEntityInsertOrUpdate
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
@ -3,9 +3,10 @@ import path from 'path';
|
|||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import { ValueTransformer } from 'typeorm';
|
import { EntityTarget, InsertEvent, UpdateEvent, ValueTransformer } from 'typeorm';
|
||||||
import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
|
import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { GraphDecimal, IndexerInterface, jsonBigIntStringReplacer, StateInterface } from '@cerc-io/util';
|
import { GraphDecimal, IndexerInterface, jsonBigIntStringReplacer, StateInterface } from '@cerc-io/util';
|
||||||
import { MappingKey, StorageLayout } from '@cerc-io/solidity-mapper';
|
import { MappingKey, StorageLayout } from '@cerc-io/solidity-mapper';
|
||||||
@ -897,3 +898,29 @@ export const updateEntitiesFromState = async (database: Database, indexer: Index
|
|||||||
console.timeEnd(`time:watcher#GraphWatcher-updateEntitiesFromState-update-entity-${entityName}`);
|
console.timeEnd(`time:watcher#GraphWatcher-updateEntitiesFromState-update-entity-${entityName}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const afterEntityInsertOrUpdate = async<Entity> (frothyEntityType: EntityTarget<Entity>, entities: Set<any>, event: InsertEvent<any> | UpdateEvent<any>): Promise<void> => {
|
||||||
|
const entity = event.entity;
|
||||||
|
|
||||||
|
// TODO: Check and return if entity is being pruned (is_pruned flag update)
|
||||||
|
|
||||||
|
// Insert the entity details in FrothyEntity table
|
||||||
|
if (entities.has(entity.constructor)) {
|
||||||
|
const frothyEntity = event.manager.create(
|
||||||
|
frothyEntityType,
|
||||||
|
{
|
||||||
|
..._.pick(entity, ['id', 'blockHash', 'blockNumber']),
|
||||||
|
...{ name: entity.constructor.name }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await event.manager.createQueryBuilder()
|
||||||
|
.insert()
|
||||||
|
.into(frothyEntityType)
|
||||||
|
.values(frothyEntity as any)
|
||||||
|
.orIgnore()
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOOD: Update latest entity tables
|
||||||
|
};
|
||||||
|
@ -372,6 +372,20 @@ export class GraphWatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async pruneFrothyEntities<Entity> (frothyEntityType: new () => Entity, blockNumber: number): Promise<void> {
|
||||||
|
const dbTx = await this._database.createTransactionRunner();
|
||||||
|
try {
|
||||||
|
await this._database.pruneFrothyEntities(dbTx, frothyEntityType, blockNumber);
|
||||||
|
|
||||||
|
dbTx.commitTransaction();
|
||||||
|
} catch (error) {
|
||||||
|
await dbTx.rollbackTransaction();
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
await dbTx.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pruneEntityCacheFrothyBlocks (canonicalBlockHash: string, canonicalBlockNumber: number) {
|
pruneEntityCacheFrothyBlocks (canonicalBlockHash: string, canonicalBlockNumber: number) {
|
||||||
this._database.pruneEntityCacheFrothyBlocks(canonicalBlockHash, canonicalBlockNumber);
|
this._database.pruneEntityCacheFrothyBlocks(canonicalBlockHash, canonicalBlockNumber);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,11 @@ import { State } from './entity/State';
|
|||||||
|
|
||||||
import { GetMethod } from './entity/GetMethod';
|
import { GetMethod } from './entity/GetMethod';
|
||||||
import { _Test } from './entity/_Test';
|
import { _Test } from './entity/_Test';
|
||||||
|
import { Author } from './entity/Author';
|
||||||
|
import { Blog } from './entity/Blog';
|
||||||
|
import { Category } from './entity/Category';
|
||||||
|
|
||||||
|
export const ENTITIES = new Set([_Test, Author, Blog, Category, GetMethod]);
|
||||||
|
|
||||||
export class Database implements DatabaseInterface {
|
export class Database implements DatabaseInterface {
|
||||||
_config: ConnectionOptions;
|
_config: ConnectionOptions;
|
||||||
|
21
packages/graph-test-watcher/src/entity/FrothyEntity.ts
Normal file
21
packages/graph-test-watcher/src/entity/FrothyEntity.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2022 Vulcanize, Inc.
|
||||||
|
//
|
||||||
|
|
||||||
|
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
@Index(['blockNumber'])
|
||||||
|
export class FrothyEntity {
|
||||||
|
@PrimaryColumn('varchar')
|
||||||
|
id!: string;
|
||||||
|
|
||||||
|
@PrimaryColumn('varchar')
|
||||||
|
name!: string;
|
||||||
|
|
||||||
|
@PrimaryColumn('varchar', { length: 66 })
|
||||||
|
blockHash!: string;
|
||||||
|
|
||||||
|
@Column('integer')
|
||||||
|
blockNumber!: number;
|
||||||
|
}
|
20
packages/graph-test-watcher/src/entity/Subscriber.ts
Normal file
20
packages/graph-test-watcher/src/entity/Subscriber.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2022 Vulcanize, Inc.
|
||||||
|
//
|
||||||
|
|
||||||
|
import { EventSubscriber, EntitySubscriberInterface, InsertEvent, UpdateEvent } from 'typeorm';
|
||||||
|
|
||||||
|
import { FrothyEntity } from './FrothyEntity';
|
||||||
|
import { ENTITIES } from '../database';
|
||||||
|
import { afterEntityInsertOrUpdate } from '@cerc-io/graph-node';
|
||||||
|
|
||||||
|
@EventSubscriber()
|
||||||
|
export class EntitySubscriber implements EntitySubscriberInterface {
|
||||||
|
async afterInsert (event: InsertEvent<any>): Promise<void> {
|
||||||
|
await afterEntityInsertOrUpdate(FrothyEntity, ENTITIES, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
async afterUpdate (event: UpdateEvent<any>): Promise<void> {
|
||||||
|
await afterEntityInsertOrUpdate(FrothyEntity, ENTITIES, event);
|
||||||
|
}
|
||||||
|
}
|
@ -31,7 +31,7 @@ import {
|
|||||||
} from '@cerc-io/util';
|
} from '@cerc-io/util';
|
||||||
import { GraphWatcher } from '@cerc-io/graph-node';
|
import { GraphWatcher } from '@cerc-io/graph-node';
|
||||||
|
|
||||||
import { Database } from './database';
|
import { Database, ENTITIES } from './database';
|
||||||
import { Contract } from './entity/Contract';
|
import { Contract } from './entity/Contract';
|
||||||
import { Event } from './entity/Event';
|
import { Event } from './entity/Event';
|
||||||
import { SyncStatus } from './entity/SyncStatus';
|
import { SyncStatus } from './entity/SyncStatus';
|
||||||
@ -43,6 +43,7 @@ import { createInitialState, handleEvent, createStateDiff, createStateCheckpoint
|
|||||||
import { Author } from './entity/Author';
|
import { Author } from './entity/Author';
|
||||||
import { Blog } from './entity/Blog';
|
import { Blog } from './entity/Blog';
|
||||||
import { Category } from './entity/Category';
|
import { Category } from './entity/Category';
|
||||||
|
import { FrothyEntity } from './entity/FrothyEntity';
|
||||||
|
|
||||||
const log = debug('vulcanize:indexer');
|
const log = debug('vulcanize:indexer');
|
||||||
const JSONbigNative = JSONbig({ useNativeBigInt: true });
|
const JSONbigNative = JSONbig({ useNativeBigInt: true });
|
||||||
@ -449,7 +450,10 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateSyncStatusCanonicalBlock (blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
async updateSyncStatusCanonicalBlock (blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
||||||
return this._baseIndexer.updateSyncStatusCanonicalBlock(blockHash, blockNumber, force);
|
const syncStatus = this._baseIndexer.updateSyncStatusCanonicalBlock(blockHash, blockNumber, force);
|
||||||
|
await this.pruneFrothyEntities(blockNumber);
|
||||||
|
|
||||||
|
return syncStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getEvent (id: string): Promise<Event | undefined> {
|
async getEvent (id: string): Promise<Event | undefined> {
|
||||||
@ -484,6 +488,10 @@ export class Indexer implements IndexerInterface {
|
|||||||
return this._baseIndexer.markBlocksAsPruned(blocks);
|
return this._baseIndexer.markBlocksAsPruned(blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async pruneFrothyEntities (blockNumber: number): Promise<void> {
|
||||||
|
await this._graphWatcher.pruneFrothyEntities(FrothyEntity, blockNumber);
|
||||||
|
}
|
||||||
|
|
||||||
async updateBlockProgress (block: BlockProgress, lastProcessedEventIndex: number): Promise<BlockProgress> {
|
async updateBlockProgress (block: BlockProgress, lastProcessedEventIndex: number): Promise<BlockProgress> {
|
||||||
return this._baseIndexer.updateBlockProgress(block, lastProcessedEventIndex);
|
return this._baseIndexer.updateBlockProgress(block, lastProcessedEventIndex);
|
||||||
}
|
}
|
||||||
@ -525,7 +533,7 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
||||||
const entities = [Author, Blog, Category];
|
const entities = [...ENTITIES, FrothyEntity];
|
||||||
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
// "removeComments": true, /* Do not emit comments to output. */
|
// "removeComments": true, /* Do not emit comments to output. */
|
||||||
// "noEmit": true, /* Do not emit outputs. */
|
// "noEmit": true, /* Do not emit outputs. */
|
||||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
"downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||||
|
|
||||||
/* Strict Type-Checking Options */
|
/* Strict Type-Checking Options */
|
||||||
|
@ -20,6 +20,8 @@ import { IsRevoked } from './entity/IsRevoked';
|
|||||||
import { IsPhisher } from './entity/IsPhisher';
|
import { IsPhisher } from './entity/IsPhisher';
|
||||||
import { IsMember } from './entity/IsMember';
|
import { IsMember } from './entity/IsMember';
|
||||||
|
|
||||||
|
export const ENTITIES = new Set([_Owner, IsMember, IsPhisher, IsRevoked, MultiNonce]);
|
||||||
|
|
||||||
export class Database implements DatabaseInterface {
|
export class Database implements DatabaseInterface {
|
||||||
_config: ConnectionOptions;
|
_config: ConnectionOptions;
|
||||||
_conn!: Connection;
|
_conn!: Connection;
|
||||||
|
@ -31,7 +31,7 @@ import {
|
|||||||
} from '@cerc-io/util';
|
} from '@cerc-io/util';
|
||||||
|
|
||||||
import PhisherRegistryArtifacts from './artifacts/PhisherRegistry.json';
|
import PhisherRegistryArtifacts from './artifacts/PhisherRegistry.json';
|
||||||
import { Database } from './database';
|
import { Database, ENTITIES } from './database';
|
||||||
import { createInitialState, handleEvent, createStateDiff, createStateCheckpoint } from './hooks';
|
import { createInitialState, handleEvent, createStateDiff, createStateCheckpoint } from './hooks';
|
||||||
import { Contract } from './entity/Contract';
|
import { Contract } from './entity/Contract';
|
||||||
import { Event } from './entity/Event';
|
import { Event } from './entity/Event';
|
||||||
@ -608,7 +608,7 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
async resetWatcherToBlock (blockNumber: number): Promise<void> {
|
||||||
const entities = [MultiNonce, _Owner, IsRevoked, IsPhisher, IsMember];
|
const entities = [...ENTITIES];
|
||||||
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
await this._baseIndexer.resetWatcherToBlock(blockNumber, entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
// "removeComments": true, /* Do not emit comments to output. */
|
// "removeComments": true, /* Do not emit comments to output. */
|
||||||
// "noEmit": true, /* Do not emit outputs. */
|
// "noEmit": true, /* Do not emit outputs. */
|
||||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
"downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||||
|
|
||||||
/* Strict Type-Checking Options */
|
/* Strict Type-Checking Options */
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import { DeepPartial, EntityTarget, FindConditions, FindManyOptions, MoreThan } from 'typeorm';
|
import { DeepPartial, EntityTarget, FindConditions, FindManyOptions, LessThanOrEqual, MoreThan } from 'typeorm';
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
import JSONbig from 'json-bigint';
|
import JSONbig from 'json-bigint';
|
||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
|
Loading…
Reference in New Issue
Block a user