Fetch transaction arguments for indexed event (#137)

This commit is contained in:
nikugogoi 2022-06-30 15:50:49 +05:30 committed by GitHub
parent 26d998d3a7
commit c919d784bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 110 additions and 47 deletions

View File

@ -2,12 +2,6 @@
* Clone the [stack-orchestrator](https://github.com/vulcanize/stack-orchestrator) repo. * Clone the [stack-orchestrator](https://github.com/vulcanize/stack-orchestrator) repo.
* Checkout the `develop` branch in stack-orchestrator repo.
```bash
git checkout develop
```
* Create a `config.sh` file. * Create a `config.sh` file.
```bash ```bash
@ -25,7 +19,7 @@
```bash ```bash
# In go-ethereum repo. # In go-ethereum repo.
git checkout v1.10.19-statediff-4.0.3-alpha git checkout v1.10.19-statediff-4.0.4-alpha
``` ```
* To run the stack-orchestrator, the docker-compose version used is: * To run the stack-orchestrator, the docker-compose version used is:
@ -148,6 +142,44 @@
} }
``` ```
* Get the latest block
```graphql
query {
latestBlock {
hash
number
}
}
```
* Run the following GQL query in GraphQL endpoint
```graphql
query {
isPhisher(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS"
key0: "TWT:phishername"
) {
value
proof {
data
}
}
isMember(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS"
key0: "TWT:membername"
) {
value
proof {
data
}
}
}
```
* Run the following GQL subscription in generated watcher GraphQL endpoint: * Run the following GQL subscription in generated watcher GraphQL endpoint:
```graphql ```graphql
@ -182,45 +214,36 @@
yarn claimMember --contract $MOBY_ADDRESS --name memberName yarn claimMember --contract $MOBY_ADDRESS --name memberName
``` ```
* The events should be visible in the subscription at GQL endpoint. * The events should be visible in the subscription at GQL endpoint. Note down the event blockHash from result.
* Check the names in the watcher GraphQL playground http://localhost:3010/graphql * The isMember and isPhisher lists should be indexed. Check the database (moby-mask-watcher) tables `is_phisher` and `is_member`, there should be entries at the event blockHash and the value should be true. The data is indexed in `handleEvent` method in the [hooks file](./src/hooks.ts).
* Get the latest block * Update the the previous query with event blockHash and check isPhisher and isMember in GraphQL playground
```graphql ```graphql
query { query {
latestBlock { isPhisher(
hash blockHash: "EVENT_BLOCK_HASH"
number contractAddress: "MOBY_ADDRESS",
key0: "TWT:phishername"
) {
value
proof {
data
} }
} }
```
isMember(
* Check the `isPhisher` and `isMember` maps blockHash: "EVENT_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS",
```graphql key0: "TWT:membername"
query { ) {
isPhisher( value
blockHash: "LATEST_BLOCK_HASH" proof {
contractAddress: "MOBY_ADDRESS", data
key0: "TWT:phishername"
) {
value
proof {
data
}
}
isMember(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS",
key0: "TWT:membername"
) {
value
proof {
data
}
} }
} }
``` }
```
The data is fetched from watcher database as it is already indexed.

View File

@ -3,10 +3,11 @@
// //
import assert from 'assert'; import assert from 'assert';
import { utils } from 'ethers';
// import { updateStateForMappingType, updateStateForElementaryType } from '@vulcanize/util'; // import { updateStateForMappingType, updateStateForElementaryType } from '@vulcanize/util';
import { Indexer, ResultEvent } from './indexer'; import { Indexer, KIND_PHISHERREGISTRY, ResultEvent } from './indexer';
/** /**
* Hook function to store an initial state. * Hook function to store an initial state.
@ -75,6 +76,34 @@ export async function handleEvent (indexer: Indexer, eventData: ResultEvent): Pr
assert(indexer); assert(indexer);
assert(eventData); assert(eventData);
// Use indexer methods to index data. // Perform indexing based on the type of event.
// Pass `diff` parameter to indexer methods as true to save an auto-generated state from the indexed data. switch (eventData.event.__typename) {
// In case of PhisherRegistry 'PhisherStatusUpdated' event.
case 'PhisherStatusUpdatedEvent': {
const txArgs = await getTxArgs(indexer, KIND_PHISHERREGISTRY, eventData.tx.hash);
// Update isPhisher entry for the identifier in database.
await indexer.isPhisher(eventData.block.hash, eventData.contract, txArgs.identifier, true);
break;
}
// In case of PhisherRegistry 'MemberStatusUpdated' event.
case 'MemberStatusUpdatedEvent': {
const txArgs = await getTxArgs(indexer, KIND_PHISHERREGISTRY, eventData.tx.hash);
// Update isPhisher entry for the identifier in database.
await indexer.isMember(eventData.block.hash, eventData.contract, txArgs.identifier, true);
break;
}
}
} }
// Get transaction arguments for specified txHash.
const getTxArgs = async (indexer: Indexer, contractKind: string, txHash: string): Promise<utils.Result> => {
const tx = await indexer.getFullTransaction(txHash);
const contractInterface = await indexer.getContractInterface(contractKind);
assert(contractInterface);
const txDescription = contractInterface.parseTransaction({ data: tx.input });
return txDescription.args;
};

View File

@ -27,7 +27,8 @@ import {
BlockHeight, BlockHeight,
IPFSClient, IPFSClient,
StateKind, StateKind,
IpldStatus as IpldStatusInterface IpldStatus as IpldStatusInterface,
getFullTransaction
} from '@vulcanize/util'; } from '@vulcanize/util';
import { GraphWatcher } from '@vulcanize/graph-node'; import { GraphWatcher } from '@vulcanize/graph-node';
@ -43,7 +44,7 @@ import { IPLDBlock } from './entity/IPLDBlock';
const log = debug('vulcanize:indexer'); const log = debug('vulcanize:indexer');
const KIND_PHISHERREGISTRY = 'PhisherRegistry'; export const KIND_PHISHERREGISTRY = 'PhisherRegistry';
const DELEGATIONTRIGGERED_EVENT = 'DelegationTriggered'; const DELEGATIONTRIGGERED_EVENT = 'DelegationTriggered';
const MEMBERSTATUSUPDATED_EVENT = 'MemberStatusUpdated'; const MEMBERSTATUSUPDATED_EVENT = 'MemberStatusUpdated';
@ -797,6 +798,16 @@ export class Indexer implements IPLDIndexerInterface {
return block; return block;
} }
// Get full transaction data.
async getFullTransaction (txHash: string): Promise<any> {
return getFullTransaction(this._ethClient, txHash);
}
// Get contract interface for specified contract kind.
async getContractInterface (kind: string): Promise<ethers.utils.Interface | undefined> {
return this._contractMap.get(kind);
}
getEntityTypesMap (): Map<string, { [key: string]: string }> { getEntityTypesMap (): Map<string, { [key: string]: string }> {
return this._entityTypesMap; return this._entityTypesMap;
} }