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.
* Checkout the `develop` branch in stack-orchestrator repo.
```bash
git checkout develop
```
* Create a `config.sh` file.
```bash
@ -25,7 +19,7 @@
```bash
# 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:
@ -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:
```graphql
@ -182,45 +214,36 @@
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
query {
latestBlock {
hash
number
```graphql
query {
isPhisher(
blockHash: "EVENT_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS",
key0: "TWT:phishername"
) {
value
proof {
data
}
}
```
* Check the `isPhisher` and `isMember` maps
```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
}
isMember(
blockHash: "EVENT_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 { utils } from 'ethers';
// 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.
@ -75,6 +76,34 @@ export async function handleEvent (indexer: Indexer, eventData: ResultEvent): Pr
assert(indexer);
assert(eventData);
// Use indexer methods to index data.
// Pass `diff` parameter to indexer methods as true to save an auto-generated state from the indexed data.
// Perform indexing based on the type of event.
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,
IPFSClient,
StateKind,
IpldStatus as IpldStatusInterface
IpldStatus as IpldStatusInterface,
getFullTransaction
} from '@vulcanize/util';
import { GraphWatcher } from '@vulcanize/graph-node';
@ -43,7 +44,7 @@ import { IPLDBlock } from './entity/IPLDBlock';
const log = debug('vulcanize:indexer');
const KIND_PHISHERREGISTRY = 'PhisherRegistry';
export const KIND_PHISHERREGISTRY = 'PhisherRegistry';
const DELEGATIONTRIGGERED_EVENT = 'DelegationTriggered';
const MEMBERSTATUSUPDATED_EVENT = 'MemberStatusUpdated';
@ -797,6 +798,16 @@ export class Indexer implements IPLDIndexerInterface {
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 }> {
return this._entityTypesMap;
}