Skip to content

Commit

Permalink
Fetch transaction arguments for indexed event (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikugogoi committed Jun 30, 2022
1 parent 26d998d commit c919d78
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 47 deletions.
107 changes: 65 additions & 42 deletions packages/moby-mask-watcher/demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
35 changes: 32 additions & 3 deletions packages/moby-mask-watcher/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
};
15 changes: 13 additions & 2 deletions packages/moby-mask-watcher/src/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import {
BlockHeight,
IPFSClient,
StateKind,
IpldStatus as IpldStatusInterface
IpldStatus as IpldStatusInterface,
getFullTransaction
} from '@vulcanize/util';
import { GraphWatcher } from '@vulcanize/graph-node';

Expand All @@ -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';
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit c919d78

Please sign in to comment.