mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-01-06 19:38:05 +00:00
Update subgraph watcher demo readme (#480)
* Update subgraph watcher demo readme * Pass extra block data required in subgraph block handler (#486) * Use codegen config directory name instead of file path * Get block data from extra event data * Add extra event data in processBlockAfterEvents --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com> * Update example subgraph mapping code for graph-cli upgrade * Return 0 value for block size in ipld-eth-client --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com> Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
This commit is contained in:
parent
937aed139f
commit
6decf61d4c
@ -499,10 +499,10 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{{#if (subgraphPath)}}
|
{{#if (subgraphPath)}}
|
||||||
async processBlockAfterEvents (blockHash: string, blockNumber: number): Promise<void> {
|
async processBlockAfterEvents (blockHash: string, blockNumber: number, extraData: ExtraEventData): Promise<void> {
|
||||||
console.time('time:indexer#processBlockAfterEvents-mapping_code');
|
console.time('time:indexer#processBlockAfterEvents-mapping_code');
|
||||||
// Call subgraph handler for block.
|
// Call subgraph handler for block.
|
||||||
await this._graphWatcher.handleBlock(blockHash, blockNumber);
|
await this._graphWatcher.handleBlock(blockHash, blockNumber, extraData);
|
||||||
console.timeEnd('time:indexer#processBlockAfterEvents-mapping_code');
|
console.timeEnd('time:indexer#processBlockAfterEvents-mapping_code');
|
||||||
|
|
||||||
console.time('time:indexer#processBlockAfterEvents-dump_subgraph_state');
|
console.time('time:indexer#processBlockAfterEvents-dump_subgraph_state');
|
||||||
|
@ -69,7 +69,8 @@ export async function buildSubgraph (
|
|||||||
network?: string
|
network?: string
|
||||||
}
|
}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const subgraphDirectory = path.resolve(codegenConfigPath, subgraphConfig.directory);
|
const codegenConfigDirName = path.dirname(codegenConfigPath);
|
||||||
|
const subgraphDirectory = path.resolve(codegenConfigDirName, subgraphConfig.directory);
|
||||||
const codegenWorkingDir = process.cwd();
|
const codegenWorkingDir = process.cwd();
|
||||||
// Change directory to subgraph repo
|
// Change directory to subgraph repo
|
||||||
shell.cd(subgraphDirectory);
|
shell.cd(subgraphDirectory);
|
||||||
@ -102,7 +103,7 @@ export async function buildSubgraph (
|
|||||||
const { code: installCode } = shell.exec(`${packageManager} install --force`);
|
const { code: installCode } = shell.exec(`${packageManager} install --force`);
|
||||||
assert(installCode === 0, 'Installing dependencies exited with error');
|
assert(installCode === 0, 'Installing dependencies exited with error');
|
||||||
|
|
||||||
const subgraphConfigPath = path.resolve(codegenConfigPath, subgraphConfig.configFile);
|
const subgraphConfigPath = path.resolve(codegenConfigDirName, subgraphConfig.configFile);
|
||||||
|
|
||||||
// Run graph-cli codegen
|
// Run graph-cli codegen
|
||||||
const { code: codegenCode } = shell.exec(`${packageManager === 'npm' ? 'npx' : packageManager} graph codegen ${subgraphConfigPath}`);
|
const { code: codegenCode } = shell.exec(`${packageManager === 'npm' ? 'npx' : packageManager} graph codegen ${subgraphConfigPath}`);
|
||||||
@ -112,7 +113,7 @@ export async function buildSubgraph (
|
|||||||
let buildCommand = `${packageManager === 'npm' ? 'npx' : packageManager} graph build ${subgraphConfigPath}`;
|
let buildCommand = `${packageManager === 'npm' ? 'npx' : packageManager} graph build ${subgraphConfigPath}`;
|
||||||
|
|
||||||
if (subgraphConfig.networkFilePath) {
|
if (subgraphConfig.networkFilePath) {
|
||||||
const subgraphNetworkFilePath = path.resolve(codegenConfigPath, subgraphConfig.networkFilePath);
|
const subgraphNetworkFilePath = path.resolve(codegenConfigDirName, subgraphConfig.networkFilePath);
|
||||||
assert(subgraphConfig.network, 'Config subgraph.network should be set if using networkFilePath');
|
assert(subgraphConfig.network, 'Config subgraph.network should be set if using networkFilePath');
|
||||||
const subgraphNetwork = subgraphConfig.network;
|
const subgraphNetwork = subgraphConfig.network;
|
||||||
buildCommand = `${buildCommand} --network-file ${subgraphNetworkFilePath} --network ${subgraphNetwork}`;
|
buildCommand = `${buildCommand} --network-file ${subgraphNetworkFilePath} --network ${subgraphNetwork}`;
|
||||||
|
@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
* For this demo, an [example subgraph](../graph-node/test/subgraph/example1) will be used
|
* For this demo, an [example subgraph](../graph-node/test/subgraph/example1) will be used
|
||||||
|
|
||||||
* In [package.json](../graph-node/test/subgraph/example1/package.json), the graph-ts and graph-cli dependencies are replaced by their respective cerc-io forked dependencies
|
|
||||||
|
|
||||||
* This needs to be done for running any subgraph project with watcher-ts
|
|
||||||
|
|
||||||
* In watcher-ts [packages/graph-node](../graph-node/), deploy an `Example` contract:
|
* In watcher-ts [packages/graph-node](../graph-node/), deploy an `Example` contract:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -32,13 +28,7 @@
|
|||||||
export EXAMPLE_ADDRESS=<EXAMPLE_ADDRESS>
|
export EXAMPLE_ADDRESS=<EXAMPLE_ADDRESS>
|
||||||
```
|
```
|
||||||
|
|
||||||
* In [packages/graph-node/test/subgraph/example1/subgraph.yaml](../graph-node/test/subgraph/example1/subgraph.yaml), set the source address for `Example1` datasource to the `EXAMPLE_ADDRESS`. Then in [packages/graph-node](../graph-node/) run:
|
* In [packages/graph-node/test/subgraph/example1/subgraph.yaml](../graph-node/test/subgraph/example1/subgraph.yaml), set the source address for `Example1` datasource to the `EXAMPLE_ADDRESS`
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn build:example
|
|
||||||
```
|
|
||||||
|
|
||||||
* This will run `yarn && yarn codegen && yarn build` script in the example subgraph directory
|
|
||||||
|
|
||||||
* In [packages/codegen](./), create a `config.yaml` file:
|
* In [packages/codegen](./), create a `config.yaml` file:
|
||||||
|
|
||||||
@ -63,10 +53,16 @@
|
|||||||
# Flatten the input contract file(s) [true | false] (default: true).
|
# Flatten the input contract file(s) [true | false] (default: true).
|
||||||
flatten: true
|
flatten: true
|
||||||
|
|
||||||
# Path to the subgraph build (optional).
|
# Config for subgraph
|
||||||
# Can set empty contracts array when using subgraphPath.
|
subgraph:
|
||||||
# Subgraph WASM files should be compiled using @cerc-io/graph-cli
|
# Path to subgraph repo directory containing package.json
|
||||||
subgraphPath: ../graph-node/test/subgraph/example1/build
|
directory: ../graph-node/test/subgraph/example1
|
||||||
|
|
||||||
|
# Package manager that is used in subgraph repo for dependencies
|
||||||
|
packageManager: yarn
|
||||||
|
|
||||||
|
# Path to subgraph manifest/config file
|
||||||
|
configFile: ../graph-node/test/subgraph/example1/subgraph.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
* Run codegen to generate watcher:
|
* Run codegen to generate watcher:
|
||||||
@ -116,13 +112,7 @@
|
|||||||
yarn && yarn build
|
yarn && yarn build
|
||||||
```
|
```
|
||||||
|
|
||||||
* In `packages/test-watcher`, run fill for the subgraph start block:
|
* Configure the upstream GQL and RPC endpoints
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn fill --start-block 10 --end-block 10
|
|
||||||
```
|
|
||||||
|
|
||||||
* Subgraph start block is the lowest `startBlock` in example [subgraph.yaml](../graph-node/test/subgraph/example1/subgraph.yaml)
|
|
||||||
|
|
||||||
* Run the job-runner:
|
* Run the job-runner:
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ export class GraphWatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleBlock (blockHash: string, blockNumber: number) {
|
async handleBlock (blockHash: string, blockNumber: number, extraData: ExtraEventData) {
|
||||||
// Clear transactions map on handling new block.
|
// Clear transactions map on handling new block.
|
||||||
this._transactionsMap.clear();
|
this._transactionsMap.clear();
|
||||||
|
|
||||||
@ -258,11 +258,10 @@ export class GraphWatcher {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use extraData full block
|
// Check if block data is already fetched in handleEvent method for the same block.
|
||||||
// // Check if block data is already fetched in handleEvent method for the same block.
|
if (!this._context.block || this._context.block.blockHash !== blockHash) {
|
||||||
// if (!this._context.block || this._context.block.blockHash !== blockHash) {
|
this._context.block = await getFullBlock(extraData.ethFullBlock);
|
||||||
// this._context.block = await getFullBlock(this._ethClient, this._ethProvider, blockHash, blockNumber);
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
const blockData = this._context.block;
|
const blockData = this._context.block;
|
||||||
assert(blockData);
|
assert(blockData);
|
||||||
|
@ -50,6 +50,7 @@ export function handleTest (event: Test): void {
|
|||||||
if (!category) {
|
if (!category) {
|
||||||
category = new Category(author.blogCount.toString());
|
category = new Category(author.blogCount.toString());
|
||||||
category.name = event.params.param1;
|
category.name = event.params.param1;
|
||||||
|
category.count = BigInt.zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
category.count = category.count + BigInt.fromString('1');
|
category.count = category.count + BigInt.fromString('1');
|
||||||
@ -59,13 +60,14 @@ export function handleTest (event: Test): void {
|
|||||||
blog.kind = 'long';
|
blog.kind = 'long';
|
||||||
blog.isActive = true;
|
blog.isActive = true;
|
||||||
|
|
||||||
const blogReviews = blog.reviews;
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
const blogReviews: BigInt[] = new Array(0);
|
||||||
blogReviews.push(BigInt.fromString('4'));
|
blogReviews.push(BigInt.fromString('4'));
|
||||||
blog.reviews = blogReviews;
|
blog.reviews = blogReviews;
|
||||||
|
|
||||||
blog.author = author.id;
|
blog.author = author.id;
|
||||||
|
|
||||||
const categories = blog.categories;
|
const categories: string[] = new Array(0);
|
||||||
categories.push(category.id);
|
categories.push(category.id);
|
||||||
blog.categories = categories;
|
blog.categories = categories;
|
||||||
|
|
||||||
|
@ -102,7 +102,15 @@ export class EthClient implements EthClientInterface {
|
|||||||
);
|
);
|
||||||
console.timeEnd(`time:eth-client#getFullBlocks-${JSON.stringify({ blockNumber, blockHash })}`);
|
console.timeEnd(`time:eth-client#getFullBlocks-${JSON.stringify({ blockNumber, blockHash })}`);
|
||||||
|
|
||||||
return allEthHeaderCids.nodes;
|
return this.addBlockSize(allEthHeaderCids.nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Get block size from ipld-eth-server
|
||||||
|
private addBlockSize (nodes: any[]): any[] {
|
||||||
|
// Populate block size with 0 value
|
||||||
|
return nodes.map(obj => {
|
||||||
|
return { ...obj, size: '0' };
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFullTransaction (txHash: string, blockNumber?: number): Promise<EthFullTransaction> {
|
async getFullTransaction (txHash: string, blockNumber?: number): Promise<EthFullTransaction> {
|
||||||
|
@ -185,7 +185,7 @@ export const processBatchEvents = async (
|
|||||||
|
|
||||||
if (indexer.processBlockAfterEvents) {
|
if (indexer.processBlockAfterEvents) {
|
||||||
if (!dbBlock.isComplete) {
|
if (!dbBlock.isComplete) {
|
||||||
await indexer.processBlockAfterEvents(dbBlock.blockHash, dbBlock.blockNumber);
|
await indexer.processBlockAfterEvents(dbBlock.blockHash, dbBlock.blockNumber, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ export interface IndexerInterface {
|
|||||||
processInitialState: (contractAddress: string, blockHash: string) => Promise<any>
|
processInitialState: (contractAddress: string, blockHash: string) => Promise<any>
|
||||||
processStateCheckpoint: (contractAddress: string, blockHash: string) => Promise<boolean>
|
processStateCheckpoint: (contractAddress: string, blockHash: string) => Promise<boolean>
|
||||||
processBlock: (blockProgres: BlockProgressInterface) => Promise<void>
|
processBlock: (blockProgres: BlockProgressInterface) => Promise<void>
|
||||||
processBlockAfterEvents?: (blockHash: string, blockNumber: number) => Promise<void>
|
processBlockAfterEvents?: (blockHash: string, blockNumber: number, data: ExtraEventData) => Promise<void>
|
||||||
processCanonicalBlock (blockHash: string, blockNumber: number): Promise<void>
|
processCanonicalBlock (blockHash: string, blockNumber: number): Promise<void>
|
||||||
processCheckpoint (blockHash: string): Promise<void>
|
processCheckpoint (blockHash: string): Promise<void>
|
||||||
processCLICheckpoint (contractAddress: string, blockHash?: string): Promise<string | undefined>
|
processCLICheckpoint (contractAddress: string, blockHash?: string): Promise<string | undefined>
|
||||||
|
Loading…
Reference in New Issue
Block a user