Skip to content

Commit

Permalink
Handle subgraph schema field with derivedFrom directive (#60)
Browse files Browse the repository at this point in the history
* Handle subgraph schema field with derivedFrom directive

* Handle derivedFrom directive in eden-watcher

* Fix 1 to N relation error by removing limit from query

* Order by id for derivedFrom relations to match graph-node

* Refactor example subgraph schema entities

* Fix watcher queries to return correct relation field values

* Fix hierarchical query for getting two entities at same block
  • Loading branch information
nikugogoi authored Nov 26, 2021
1 parent 2e367d3 commit 285b785
Show file tree
Hide file tree
Showing 27 changed files with 480 additions and 372 deletions.
11 changes: 2 additions & 9 deletions packages/eden-watcher/src/entity/Account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
// Copyright 2021 Vulcanize, Inc.
//

import { Entity, PrimaryColumn, Column, ManyToOne } from 'typeorm';
import { Claim } from './Claim';
import { Slash } from './Slash';
import { Entity, PrimaryColumn, Column } from 'typeorm';

import { bigintTransformer } from '@vulcanize/util';

@Entity()
Expand All @@ -23,10 +22,4 @@ export class Account {

@Column('bigint', { transformer: bigintTransformer })
totalSlashed!: bigint;

@ManyToOne(() => Claim)
claims!: Claim;

@ManyToOne(() => Slash)
slashes!: Slash;
}
6 changes: 1 addition & 5 deletions packages/eden-watcher/src/entity/Epoch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
// Copyright 2021 Vulcanize, Inc.
//

import { Entity, PrimaryColumn, Column, ManyToOne } from 'typeorm';
import { Entity, PrimaryColumn, Column } from 'typeorm';
import Decimal from 'decimal.js';

import { ProducerEpoch } from './ProducerEpoch';
import { bigintTransformer, decimalTransformer } from '@vulcanize/util';

@Entity()
Expand Down Expand Up @@ -39,7 +38,4 @@ export class Epoch {

@Column('numeric', { default: 0, transformer: decimalTransformer })
producerBlocksRatio!: Decimal;

@ManyToOne(() => ProducerEpoch)
producerRewards!: ProducerEpoch;
}
7 changes: 1 addition & 6 deletions packages/eden-watcher/src/entity/Slot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
// Copyright 2021 Vulcanize, Inc.
//

import { Entity, PrimaryColumn, Column, ManyToOne } from 'typeorm';
import { Entity, PrimaryColumn, Column } from 'typeorm';
import Decimal from 'decimal.js';

import { bigintTransformer, decimalTransformer } from '@vulcanize/util';

import { SlotClaim } from './SlotClaim';

@Entity()
export class Slot {
@PrimaryColumn('varchar')
Expand Down Expand Up @@ -40,7 +38,4 @@ export class Slot {

@Column('numeric', { default: 0, transformer: decimalTransformer })
taxRatePerDay!: Decimal;

@ManyToOne(() => SlotClaim)
claims!: SlotClaim;
}
72 changes: 57 additions & 15 deletions packages/eden-watcher/src/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { BaseProvider } from '@ethersproject/providers';
import * as codec from '@ipld/dag-cbor';
import { EthClient } from '@vulcanize/ipld-eth-client';
import { StorageLayout } from '@vulcanize/solidity-mapper';
import { EventInterface, Indexer as BaseIndexer, IndexerInterface, UNKNOWN_EVENT_NAME, ServerConfig } from '@vulcanize/util';
import { EventInterface, Indexer as BaseIndexer, IndexerInterface, UNKNOWN_EVENT_NAME, ServerConfig, BlockHeight } from '@vulcanize/util';
import { GraphWatcher } from '@vulcanize/graph-node';

import { Database } from './database';
Expand Down Expand Up @@ -549,10 +549,10 @@ export class Indexer implements IndexerInterface {
return (ipfsAddr !== undefined && ipfsAddr !== null && ipfsAddr !== '');
}

async getSubgraphEntity<Entity> (entity: new () => Entity, id: string, blockHash?: string): Promise<any> {
async getSubgraphEntity<Entity> (entity: new () => Entity, id: string, block?: BlockHeight): Promise<any> {
const relations = this._relationsMap.get(entity) || {};

const data = await this._graphWatcher.getEntity(entity, id, relations, blockHash);
const data = await this._graphWatcher.getEntity(entity, id, relations, block);

return data;
}
Expand Down Expand Up @@ -1154,78 +1154,120 @@ export class Indexer implements IndexerInterface {
this._relationsMap.set(ProducerSet, {
producers: {
entity: Producer,
isArray: true
isArray: true,
isDerived: false
}
});

this._relationsMap.set(RewardSchedule, {
rewardScheduleEntries: {
entity: RewardScheduleEntry,
isArray: true
isArray: true,
isDerived: false
},
activeRewardScheduleEntry: {
entity: RewardScheduleEntry,
isArray: false
isArray: false,
isDerived: false
}
});

this._relationsMap.set(ProducerEpoch, {
epoch: {
entity: Epoch,
isArray: false
isArray: false,
isDerived: false
}
});

this._relationsMap.set(Epoch, {
startBlock: {
entity: Block,
isArray: false
isArray: false,
isDerived: false
},
endBlock: {
entity: Block,
isArray: false
isArray: false,
isDerived: false
},
producerRewards: {
entity: ProducerEpoch,
isArray: true,
isDerived: true,
field: 'epoch'
}
});

this._relationsMap.set(SlotClaim, {
slot: {
entity: Slot,
isArray: false
isArray: false,
isDerived: false
}
});

this._relationsMap.set(Network, {
stakers: {
entity: Staker,
isArray: true
isArray: true,
isDerived: false
}
});

this._relationsMap.set(Distributor, {
currentDistribution: {
entity: Distribution,
isArray: false
isArray: false,
isDerived: false
}
});

this._relationsMap.set(Distribution, {
distributor: {
entity: Distributor,
isArray: false
isArray: false,
isDerived: false
}
});

this._relationsMap.set(Claim, {
account: {
entity: Account,
isArray: false
isArray: false,
isDerived: false
}
});

this._relationsMap.set(Slash, {
account: {
entity: Account,
isArray: false
isArray: false,
isDerived: false
}
});

this._relationsMap.set(Slot, {
claims: {
entity: SlotClaim,
isArray: true,
isDerived: true,
field: 'slot'
}
});

this._relationsMap.set(Account, {
claims: {
entity: Claim,
isArray: true,
isDerived: true,
field: 'account'
},
slashes: {
entity: Slash,
isArray: true,
isDerived: true,
field: 'account'
}
});
}
Expand Down
36 changes: 18 additions & 18 deletions packages/eden-watcher/src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,109 +64,109 @@ export const createResolvers = async (indexer: Indexer, eventWatcher: EventWatch
producer: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('producer', id, block);

return indexer.getSubgraphEntity(Producer, id, block.hash);
return indexer.getSubgraphEntity(Producer, id, block);
},

producerSet: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('producerSet', id, block);

return indexer.getSubgraphEntity(ProducerSet, id, block.hash);
return indexer.getSubgraphEntity(ProducerSet, id, block);
},

producerSetChange: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('producerSetChange', id, block);

return indexer.getSubgraphEntity(ProducerSetChange, id, block.hash);
return indexer.getSubgraphEntity(ProducerSetChange, id, block);
},

producerRewardCollectorChange: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('producerRewardCollectorChange', id, block);

return indexer.getSubgraphEntity(ProducerRewardCollectorChange, id, block.hash);
return indexer.getSubgraphEntity(ProducerRewardCollectorChange, id, block);
},

rewardScheduleEntry: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('rewardScheduleEntry', id, block);

return indexer.getSubgraphEntity(RewardScheduleEntry, id, block.hash);
return indexer.getSubgraphEntity(RewardScheduleEntry, id, block);
},

rewardSchedule: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('rewardSchedule', id, block);

return indexer.getSubgraphEntity(RewardSchedule, id, block.hash);
return indexer.getSubgraphEntity(RewardSchedule, id, block);
},

producerEpoch: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('producerEpoch', id, block);

return indexer.getSubgraphEntity(ProducerEpoch, id, block.hash);
return indexer.getSubgraphEntity(ProducerEpoch, id, block);
},

block: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('block', id, block);

return indexer.getSubgraphEntity(Block, id, block.hash);
return indexer.getSubgraphEntity(Block, id, block);
},

epoch: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('epoch', id, block);

return indexer.getSubgraphEntity(Epoch, id, block.hash);
return indexer.getSubgraphEntity(Epoch, id, block);
},

slotClaim: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('slotClaim', id, block);

return indexer.getSubgraphEntity(SlotClaim, id, block.hash);
return indexer.getSubgraphEntity(SlotClaim, id, block);
},

slot: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('slot', id, block);

return indexer.getSubgraphEntity(Slot, id, block.hash);
return indexer.getSubgraphEntity(Slot, id, block);
},

staker: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('staker', id, block);

return indexer.getSubgraphEntity(Staker, id, block.hash);
return indexer.getSubgraphEntity(Staker, id, block);
},

network: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('network', id, block);

return indexer.getSubgraphEntity(Network, id, block.hash);
return indexer.getSubgraphEntity(Network, id, block);
},

distributor: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('distributor', id, block);

return indexer.getSubgraphEntity(Distributor, id, block.hash);
return indexer.getSubgraphEntity(Distributor, id, block);
},

distribution: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('distribution', id, block);

return indexer.getSubgraphEntity(Distribution, id, block.hash);
return indexer.getSubgraphEntity(Distribution, id, block);
},

claim: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('claim', id, block);

return indexer.getSubgraphEntity(Claim, id, block.hash);
return indexer.getSubgraphEntity(Claim, id, block);
},

slash: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('slash', id, block);

return indexer.getSubgraphEntity(Slash, id, block.hash);
return indexer.getSubgraphEntity(Slash, id, block);
},

account: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('account', id, block);

return indexer.getSubgraphEntity(Account, id, block.hash);
return indexer.getSubgraphEntity(Account, id, block);
},

events: async (_: any, { blockHash, contractAddress, name }: { blockHash: string, contractAddress: string, name?: string }) => {
Expand Down
10 changes: 5 additions & 5 deletions packages/graph-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
## Run

* Compare query results from two different GQL endpoints:

* In a config file (sample: `environments/compare-cli-config.toml`):

* Specify the two GQL endpoints in the endpoints config.
Expand All @@ -53,7 +53,7 @@
[endpoints]
gqlEndpoint1 = "http://localhost:8000/subgraphs/name/example1"
gqlEndpoint2 = "http://localhost:3008/graphql"
[queries]
queryDir = "../graph-test-watcher/src/gql/queries"
```
Expand All @@ -70,11 +70,11 @@
* `block-hash`(alias: `b`): Block hash (required).
* `entity-id`(alias: `i`): Entity Id (required).
* `raw-json`(alias: `j`): Whether to print out a raw diff object (default: `false`).
Example:
```bash
yarn compare-entity --config-file environments/compare-cli-config.toml --query-name exampleEntity --block-hash 0xceed7ee9d3de97c99db12e42433cae9115bb311c516558539fb7114fa17d545b --entity-id 0x2886bae64814bd959aec4282f86f3a97bf1e16e4111b39fd7bdd592b516c66c6
yarn compare-entity --config-file environments/compare-cli-config.toml --query-name author --block-hash 0xceed7ee9d3de97c99db12e42433cae9115bb311c516558539fb7114fa17d545b --entity-id 0xdc7d7a8920c8eecc098da5b7522a5f31509b5bfc
```
* The program will exit with code `1` if the query results are not equal.
Loading

0 comments on commit 285b785

Please sign in to comment.