Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate IPLD blocks table and related GQL API #260

Merged
merged 21 commits into from
Oct 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions packages/codegen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@
yarn codegen --input-file ./test/examples/contracts/ERC721.sol --contract-name ERC721 --output-folder ../my-erc721-watcher --mode storage --kind lazy
```

Generate code for `ERC721` contract in both `eth_call` and `storage` mode, `active` kind:
Generate code for `ERC20` contract in both `eth_call` and `storage` mode, `active` kind:

```bash
yarn codegen --input-file ../../node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol --contract-name ERC721 --output-folder ../demo-erc721-watcher --mode all --kind active
yarn codegen --input-file ../../node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol --contract-name ERC20 --output-folder ../demo-erc20-watcher --mode all --kind active
```

This will create a folder called `demo-erc721-watcher` containing the generated code at the specified path. Follow the steps in [Run Generated Watcher](#run-generated-watcher) to setup and run the generated watcher.
This will create a folder called `demo-erc20-watcher` containing the generated code at the specified path. Follow the steps in [Run Generated Watcher](#run-generated-watcher) to setup and run the generated watcher.

## Run Generated Watcher

Expand All @@ -79,7 +79,9 @@

* Edit the custom hook function `handleEvent` (triggered on an event) in `src/hooks.ts` to perform corresponding indexing using the `Indexer` object.

* Refer to `src/hooks.example.ts` for an example hook function for events in an ERC20 contract.
* Edit the custom hook function `handleBlock` (triggered on a block) in `src/hooks.ts` to save `IPLDBlock`s using the `Indexer` object.

* The existing example hooks in `src/hooks.ts` are for an `ERC20` contract.

### Run

Expand All @@ -106,7 +108,7 @@
* To watch a contract:

```bash
yarn watch:contract --address <contract-address> --kind ERC721 --starting-block [block-number]
yarn watch:contract --address <contract-address> --kind <contract-kind> --starting-block [block-number]
```

* To fill a block range:
Expand Down
1 change: 1 addition & 0 deletions packages/codegen/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"dependencies": {
"@poanet/solidity-flattener": "https://github.com/vulcanize/solidity-flattener.git",
"@solidity-parser/parser": "^0.13.2",
"@vulcanize/util": "^0.1.0",
"gql-generator": "https://github.com/vulcanize/gql-generator.git",
"graphql": "^15.5.0",
"graphql-compose": "^9.0.3",
Expand Down
4 changes: 4 additions & 0 deletions packages/codegen/src/data/entities/BlockProgress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ indexOn:
- columns:
- parentHash
columns:
- name: cid
pgType: varchar
tsType: string
columnType: Column
- name: blockHash
pgType: varchar
tsType: string
Expand Down
41 changes: 41 additions & 0 deletions packages/codegen/src/data/entities/IPLDBlock.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
className: IPLDBlock
indexOn:
- columns:
- block
- contractAddress
columns:
- name: block
tsType: BlockProgress
columnType: ManyToOne
lhs: ()
rhs: BlockProgress
- name: contractAddress
pgType: varchar
tsType: string
columnType: Column
columnOptions:
- option: length
value: 42
- name: cid
pgType: varchar
tsType: string
columnType: Column
- name: kind
pgType: varchar
tsType: string
columnType: Column
- name: data
pgType: text
tsType: string
columnType: Column
imports:
- toImport:
- Entity
- PrimaryGeneratedColumn
- Column
- Index
- ManyToOne
from: typeorm
- toImport:
- BlockProgress
from: ./BlockProgress
7 changes: 6 additions & 1 deletion packages/codegen/src/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export class Entity {
}

const entityObject: any = {
// Capitalize the first letter of name.
className: '',
indexOn: [],
columns: [],
Expand Down Expand Up @@ -188,6 +187,7 @@ export class Entity {
this._addSyncStatusEntity();
this._addContractEntity();
this._addBlockProgressEntity();
this._addIPLDBlockEntity();

const template = Handlebars.compile(this._templateString);
this._entities.forEach(entityObj => {
Expand Down Expand Up @@ -218,4 +218,9 @@ export class Entity {
const entity = yaml.load(fs.readFileSync(path.resolve(__dirname, TABLES_DIR, 'BlockProgress.yaml'), 'utf8'));
this._entities.push(entity);
}

_addIPLDBlockEntity (): void {
const entity = yaml.load(fs.readFileSync(path.resolve(__dirname, TABLES_DIR, 'IPLDBlock.yaml'), 'utf8'));
this._entities.push(entity);
}
}
7 changes: 2 additions & 5 deletions packages/codegen/src/generate-code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import fetch from 'node-fetch';
import path from 'path';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import { flatten } from '@poanet/solidity-flattener';

import { flatten } from '@poanet/solidity-flattener';
import { parse, visit } from '@solidity-parser/parser';
import { KIND_ACTIVE, KIND_LAZY } from '@vulcanize/util';

Expand Down Expand Up @@ -209,15 +209,12 @@ function generateWatcher (data: string, visitor: Visitor, argv: any) {
exportWatchContract(outStream);

let hooksOutStream;
let exampleOutStream;
if (outputDir) {
hooksOutStream = fs.createWriteStream(path.join(outputDir, 'src/hooks.ts'));
exampleOutStream = fs.createWriteStream(path.join(outputDir, 'src/hooks.example.ts'));
} else {
hooksOutStream = process.stdout;
exampleOutStream = process.stdout;
}
exportHooks(hooksOutStream, exampleOutStream);
exportHooks(hooksOutStream);

outStream = outputDir
? fs.createWriteStream(path.join(outputDir, 'src/fill.ts'))
Expand Down
13 changes: 2 additions & 11 deletions packages/codegen/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,14 @@ import Handlebars from 'handlebars';
import { Writable } from 'stream';

const HOOKS_TEMPLATE_FILE = './templates/hooks-template.handlebars';
const EXAMPLE_TEMPLATE_FILE = './templates/hooks-example-template.handlebars';

/**
* Writes the hooks and hooks.example files generated from templates to a stream.
* Writes the hooks file generated from template to a stream.
* @param outStream A writable output stream to write the hooks file to.
* @param exampleOutStream A writable output stream to write the hooks.example file to.
*/
export function exportHooks (hooksOutStream: Writable, exampleOutStream: Writable): void {
export function exportHooks (hooksOutStream: Writable): void {
const hooksTemplateString = fs.readFileSync(path.resolve(__dirname, HOOKS_TEMPLATE_FILE)).toString();
const exampleTemplateString = fs.readFileSync(path.resolve(__dirname, EXAMPLE_TEMPLATE_FILE)).toString();

const hooksTemplate = Handlebars.compile(hooksTemplateString);
const exampleTemplate = Handlebars.compile(exampleTemplateString);

const hooks = hooksTemplate({});
const example = exampleTemplate({});

hooksOutStream.write(hooks);
exampleOutStream.write(example);
}
39 changes: 39 additions & 0 deletions packages/codegen/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ export class Schema {
// Add a mutation for watching a contract.
this._addWatchContractMutation();

this._addIPLDType();
this._addIPLDQuery();

return this._composer.buildSchema();
}

Expand Down Expand Up @@ -173,6 +176,7 @@ export class Schema {
this._composer.createObjectTC({
name: blockName,
fields: {
cid: 'String!',
hash: 'String!',
number: 'Int!',
timestamp: 'Int!',
Expand Down Expand Up @@ -234,6 +238,40 @@ export class Schema {
});
}

_addIPLDType (): void {
this._composer.createObjectTC({
name: 'ResultIPLDBlock',
fields: {
block: () => this._composer.getOTC('Block').NonNull,
contractAddress: 'String!',
cid: 'String!',
kind: 'String!',
data: 'String!'
}
});
}

_addIPLDQuery (): void {
this._composer.Query.addFields({
getStateByCID: {
type: this._composer.getOTC('ResultIPLDBlock'),
args: {
cid: 'String!'
}
}
});

this._composer.Query.addFields({
getState: {
type: this._composer.getOTC('ResultIPLDBlock'),
args: {
blockHash: 'String!',
contractAddress: 'String!'
}
}
});
}

/**
* Adds an event subscription to the schema.
*/
Expand All @@ -254,6 +292,7 @@ export class Schema {
type: 'Boolean!',
args: {
contractAddress: 'String!',
kind: 'String!',
startingBlock: 'Int'
}
}
Expand Down
1 change: 0 additions & 1 deletion packages/codegen/src/templates/client-template.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
//

import { gql } from '@apollo/client/core';

import { GraphQLClient, GraphQLConfig } from '@vulcanize/ipld-eth-client';

import { queries, mutations, subscriptions } from './gql';
Expand Down
6 changes: 6 additions & 0 deletions packages/codegen/src/templates/config-template.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
port = 3008
kind = "{{watcherKind}}"

# Checkpointing derived state.
checkpointing = true

# Checkpoint interval in number of blocks.
checkpointInterval = 2000

[database]
type = "postgres"
host = "localhost"
Expand Down
Loading