From c919d784bfb295048945393d9758ec26551cbffd Mon Sep 17 00:00:00 2001 From: nikugogoi Date: Thu, 30 Jun 2022 15:50:49 +0530 Subject: [PATCH] Fetch transaction arguments for indexed event (#137) --- packages/moby-mask-watcher/demo.md | 107 +++++++++++++--------- packages/moby-mask-watcher/src/hooks.ts | 35 ++++++- packages/moby-mask-watcher/src/indexer.ts | 15 ++- 3 files changed, 110 insertions(+), 47 deletions(-) diff --git a/packages/moby-mask-watcher/demo.md b/packages/moby-mask-watcher/demo.md index 2d026d753..1b42d6d9d 100644 --- a/packages/moby-mask-watcher/demo.md +++ b/packages/moby-mask-watcher/demo.md @@ -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. diff --git a/packages/moby-mask-watcher/src/hooks.ts b/packages/moby-mask-watcher/src/hooks.ts index 09298b7c8..fdb20fc92 100644 --- a/packages/moby-mask-watcher/src/hooks.ts +++ b/packages/moby-mask-watcher/src/hooks.ts @@ -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 => { + const tx = await indexer.getFullTransaction(txHash); + const contractInterface = await indexer.getContractInterface(contractKind); + assert(contractInterface); + const txDescription = contractInterface.parseTransaction({ data: tx.input }); + return txDescription.args; +}; diff --git a/packages/moby-mask-watcher/src/indexer.ts b/packages/moby-mask-watcher/src/indexer.ts index c1be9225d..0f9038279 100644 --- a/packages/moby-mask-watcher/src/indexer.ts +++ b/packages/moby-mask-watcher/src/indexer.ts @@ -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 { + return getFullTransaction(this._ethClient, txHash); + } + + // Get contract interface for specified contract kind. + async getContractInterface (kind: string): Promise { + return this._contractMap.get(kind); + } + getEntityTypesMap (): Map { return this._entityTypesMap; }