diff --git a/package.json b/package.json index 7cabf46..0e221c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gtcr-subgraph", - "version": "1.2.1", + "version": "1.2.3", "description": "Subgraph for Generalized TCR contracts", "scripts": { "clean": "graph clean", diff --git a/src/LightGTCRFactoryMapping.ts b/src/LightGTCRFactoryMapping.ts index 90f11cd..26912bc 100644 --- a/src/LightGTCRFactoryMapping.ts +++ b/src/LightGTCRFactoryMapping.ts @@ -1,30 +1,41 @@ /* eslint-disable prefer-const */ +import { Address, Bytes, log } from '@graphprotocol/graph-ts'; import { NewGTCR } from '../generated/LightGTCRFactory/LightGTCRFactory'; import { MetaEvidence, LRegistry } from '../generated/schema'; import { LightGeneralizedTCR as LightGeneralizedTCRDataSource } from '../generated/templates'; import { ZERO } from './utils'; +export function createNewGTCR(address: Bytes):LRegistry { + + + LightGeneralizedTCRDataSource.create(Address.fromBytes(address)); + + let registry = new LRegistry(address.toHexString()); + + let registrationMetaEvidence = new MetaEvidence(registry.id + '-1'); + registrationMetaEvidence.URI = ''; + registrationMetaEvidence.save(); + + let clearingMetaEvidence = new MetaEvidence(registry.id + '-2'); + clearingMetaEvidence.URI = ''; + clearingMetaEvidence.save(); + + registry.metaEvidenceCount = ZERO; + registry.registrationMetaEvidence = registrationMetaEvidence.id; + registry.clearingMetaEvidence = clearingMetaEvidence.id; + registry.numberOfAbsent = ZERO; + registry.numberOfRegistered = ZERO; + registry.numberOfRegistrationRequested = ZERO; + registry.numberOfClearingRequested = ZERO; + registry.numberOfChallengedRegistrations = ZERO; + registry.numberOfChallengedClearing = ZERO; + registry.save(); + + return registry; +}; + export function handleNewGTCR(event: NewGTCR): void { - LightGeneralizedTCRDataSource.create(event.params._address); - - let registry = new LRegistry(event.params._address.toHexString()); - - let registrationMetaEvidence = new MetaEvidence(registry.id + '-1'); - registrationMetaEvidence.URI = ''; - registrationMetaEvidence.save(); - - let clearingMetaEvidence = new MetaEvidence(registry.id + '-2'); - clearingMetaEvidence.URI = ''; - clearingMetaEvidence.save(); - - registry.metaEvidenceCount = ZERO; - registry.registrationMetaEvidence = registrationMetaEvidence.id; - registry.clearingMetaEvidence = clearingMetaEvidence.id; - registry.numberOfAbsent = ZERO; - registry.numberOfRegistered = ZERO; - registry.numberOfRegistrationRequested = ZERO; - registry.numberOfClearingRequested = ZERO; - registry.numberOfChallengedRegistrations = ZERO; - registry.numberOfChallengedClearing = ZERO; - registry.save(); + + log.warning('Found Registry event : {}',[event.params._address.toHexString()]); + createNewGTCR(event.params._address); } diff --git a/src/LightGeneralizedTCRMapping.ts b/src/LightGeneralizedTCRMapping.ts index 9948479..10223eb 100644 --- a/src/LightGeneralizedTCRMapping.ts +++ b/src/LightGeneralizedTCRMapping.ts @@ -4,6 +4,7 @@ import { Address, log, DataSourceContext, + Bytes, } from '@graphprotocol/graph-ts'; import { LItem, @@ -42,6 +43,7 @@ import { ConnectedTCRSet as ConnectedTCRSetEvent, } from '../generated/templates/LightGeneralizedTCR/LightGeneralizedTCR'; import { ZERO, ZERO_ADDRESS, extractPath } from './utils'; +import { createNewGTCR } from './LightGTCRFactoryMapping'; // Items on a TCR can be in 1 of 4 states: // - (0) Absent: The item is not registered on the TCR and there are no pending requests. @@ -203,7 +205,7 @@ function updateCounters( ): void { let registry = LRegistry.load(registryAddress.toHexString()); if (!registry) { - log.error(`LRegistry at {} not found.`, [registryAddress.toHexString()]); + log.error(`Counters LRegistry at {} not found.`, [registryAddress.toHexString()]); return; } @@ -247,8 +249,7 @@ function updateCounters( registry.save(); } - -export function handleNewItem(event: NewItem): void { +function createNewItem(itemID: Bytes, address: Bytes): LItem { // We assume this is an item added via addItemDirectly and care // only about saving the item json data. // If it was emitted via addItem, all the missing/wrong data regarding @@ -258,22 +259,27 @@ export function handleNewItem(event: NewItem): void { // Accounting for items added or removed directly is done // inside handleStatusUpdated. let graphItemID = - event.params._itemID.toHexString() + '@' + event.address.toHexString(); - let gtcrContract = LightGeneralizedTCR.bind(event.address); - let registry = LRegistry.load(event.address.toHexString()); + itemID.toHexString() + '@' + address.toHexString(); + let gtcrContract = LightGeneralizedTCR.bind(Address.fromBytes(address)); + let registry = LRegistry.load(address.toHexString()); if (!registry) { - log.error(`LRegistry {} not found`, [event.address.toHexString()]); - return; + log.error(`New Item LRegistry {} not found, creating new`, [address.toHexString()]); + registry = createNewGTCR(address); } - let itemInfo = gtcrContract.getItemInfo(event.params._itemID); + let itemInfo = gtcrContract.getItemInfo(itemID); - let item = new LItem(graphItemID); - item.itemID = event.params._itemID; - item.data = event.params._data; + // we might create a dummy item in RequestSubmitted + let item = LItem.load(graphItemID); + if (!item) { + item = new LItem(graphItemID); + } + + item.itemID = itemID; + item.data = ""; // since we use this function to create missing item, this will be set in NewItem event item.numberOfRequests = BigInt.fromI32(0); item.registry = registry.id; - item.registryAddress = event.address; + item.registryAddress = address; item.disputed = false; item.status = getStatus(itemInfo.value0); item.latestRequester = ZERO_ADDRESS; @@ -281,25 +287,53 @@ export function handleNewItem(event: NewItem): void { item.latestRequestResolutionTime = BigInt.fromI32(0); item.latestRequestSubmissionTime = BigInt.fromI32(0); + return item; +} + +export function handleNewItem(event: NewItem): void { + + + log.warning( + 'NewItem for itemId: {}, registry: {}', + [event.params._itemID.toHexString(), event.address.toHexString()], + ); + + let graphItemID = event.params._itemID.toHexString() + '@' + event.address.toHexString(); + + // check if we already created this item in RequestSubmitted, just create the ipfs datasource now + let item = LItem.load(graphItemID); + if(!item){ + item = createNewItem(event.params._itemID, event.address); + } + const ipfsHash = extractPath(event.params._data); - item.metadata = `${ipfsHash}-${graphItemID}`; + item.data = event.params._data; + item.metadata = `${ipfsHash}-${item.id}`; log.debug('Creating datasource for ipfs hash : {}, graphItemID: {}', [ ipfsHash, - graphItemID, + item.id, ]); const context = new DataSourceContext(); - context.setString('graphItemID', graphItemID); + context.setString('graphItemID', item.id); context.setString('address', event.address.toHexString()); LItemMetadataTemplate.createWithContext(ipfsHash, context); item.save(); - registry.save(); } export function handleRequestSubmitted(event: RequestSubmitted): void { + log.warning("Encountered requestSubmitted event, itemId: {}, evidenceGroupId: {}",[event.params._itemID.toHexString(), event.params._evidenceGroupID.toString()]); + + + + log.warning( + 'Found RequestSubmitted for itemId: {}, registry: {}', + [event.params._itemID.toHexString(), event.address.toHexString()], + ); + let graphItemID = event.params._itemID.toHexString() + '@' + event.address.toHexString(); @@ -307,13 +341,13 @@ export function handleRequestSubmitted(event: RequestSubmitted): void { let itemInfo = tcr.getItemInfo(event.params._itemID); let item = LItem.load(graphItemID); if (!item) { - log.error(`LItem for graphItemID {} not found.`, [graphItemID]); - return; + log.error(`RequestSubmitted LItem for graphItemID {} not found. Creating new`, [graphItemID]); + item = createNewItem(event.params._itemID, event.address); } let registry = LRegistry.load(event.address.toHexString()); if (!registry) { - log.error(`LRegistry at address {} not found`, [ + log.error(`RequestSubmitted LRegistry at address {} not found`, [ event.address.toHexString(), ]); return; @@ -424,14 +458,14 @@ export function handleContribution(event: Contribution): void { let requestID = graphItemID + '-' + event.params._requestID.toString(); let request = LRequest.load(requestID); if (!request) { - log.error(`LRequest {} no found.`, [requestID]); + log.error(`Contribution LRequest {} no found.`, [requestID]); return; } let roundID = requestID + '-' + event.params._roundID.toString(); let round = LRound.load(roundID); if (!round) { - log.error(`LRound {} not found.`, [roundID]); + log.error(`Contribution LRound {} not found.`, [roundID]); return; } @@ -488,7 +522,7 @@ export function handleRequestChallenged(event: Dispute): void { let graphItemID = itemID.toHexString() + '@' + event.address.toHexString(); let item = LItem.load(graphItemID); if (!item) { - log.warning(`LItem {} not found.`, [graphItemID]); + log.warning(`Dispute LItem {} not found.`, [graphItemID]); return; } @@ -510,7 +544,7 @@ export function handleRequestChallenged(event: Dispute): void { let requestID = graphItemID + '-' + requestIndex.toString(); let request = LRequest.load(requestID); if (!request) { - log.error(`LRequest {} not found.`, [requestID]); + log.error(`Dispute LRequest {} not found.`, [requestID]); return; } @@ -664,7 +698,7 @@ export function handleStatusUpdated(event: ItemStatusChange): void { event.params._itemID.toHexString() + '@' + event.address.toHexString(); let item = LItem.load(graphItemID); if (!item) { - log.error(`LItem {} not found.`, [graphItemID]); + log.error(`ItemStatusChange LItem {} not found.`, [graphItemID]); return; } @@ -712,7 +746,7 @@ export function handleStatusUpdated(event: ItemStatusChange): void { let requestID = graphItemID + '-' + requestIndex.toString(); let request = LRequest.load(requestID); if (!request) { - log.error(`LRequest {} not found.`, [requestID]); + log.error(`ItemStatusChange LRequest {} not found.`, [requestID]); return; } @@ -739,7 +773,7 @@ export function handleStatusUpdated(event: ItemStatusChange): void { let roundID = requestID + '-' + i.toString(); let round = LRound.load(roundID); if (!round) { - log.error(`LRound {} not found.`, [roundID]); + log.error(`ItemStatusChange LRound {} not found.`, [roundID]); return; } @@ -752,7 +786,7 @@ export function handleStatusUpdated(event: ItemStatusChange): void { let contributionID = roundID + '-' + j.toString(); let contribution = LContribution.load(contributionID); if (!contribution) { - log.error(`LContribution {} not found.`, [contributionID]); + log.error(`ItemStatusChange LContribution {} not found.`, [contributionID]); return; } @@ -805,7 +839,7 @@ export function handleRewardWithdrawn(event: RewardWithdrawn): void { let roundID = requestID + '-' + event.params._round.toString(); let round = LRound.load(roundID); if (!round) { - log.error(`LRound {} not found.`, [roundID]); + log.error(`RewardWithdrawn LRound {} not found.`, [roundID]); return; } @@ -817,7 +851,7 @@ export function handleRewardWithdrawn(event: RewardWithdrawn): void { let contributionID = roundID + '-' + i.toString(); let contribution = LContribution.load(contributionID); if (!contribution) { - log.error(`LContribution {} not found.`, [contributionID]); + log.error(`RewardWithdrawn LContribution {} not found.`, [contributionID]); return; } // Check if the contribution is from the beneficiary. @@ -836,7 +870,7 @@ export function handleRewardWithdrawn(event: RewardWithdrawn): void { export function handleMetaEvidence(event: MetaEvidenceEvent): void { let registry = LRegistry.load(event.address.toHexString()); if (!registry) { - log.error(`LRegistry {} not found.`, [event.address.toHexString()]); + log.error(`MetaEvidenceEvent LRegistry {} not found.`, [event.address.toHexString()]); return; } @@ -897,7 +931,7 @@ export function handleMetaEvidence(event: MetaEvidenceEvent): void { export function handleConnectedTCRSet(event: ConnectedTCRSetEvent): void { let registry = LRegistry.load(event.address.toHexString()); if (!registry) { - log.error(`LRegistry {} not found.`, [event.address.toHexString()]); + log.error(`ConnectedTCRSetEvent LRegistry {} not found.`, [event.address.toHexString()]); return; } registry.connectedTCR = event.params._connectedTCR; diff --git a/subgraph.template.yaml b/subgraph.template.yaml index 90aeb3a..d4813ac 100644 --- a/subgraph.template.yaml +++ b/subgraph.template.yaml @@ -1,5 +1,5 @@ specVersion: 1.0.0 -description: Generalized TCR v1.2.1 +description: Generalized TCR v1.2.3 features: - fullTextSearch - ipfsOnEthereumContracts diff --git a/tests/lregistry.test.ts b/tests/lregistry.test.ts new file mode 100644 index 0000000..8864658 --- /dev/null +++ b/tests/lregistry.test.ts @@ -0,0 +1,38 @@ +import { + afterAll, + assert, + clearStore, + describe, + test, +} from 'matchstick-as/assembly/index'; +import { handleNewGTCR } from '../src/LightGTCRFactoryMapping'; +import { REGISTRY_ADDRESS } from './utils/mockValues'; +import { createNewGTCREvent } from './utils/lregistry-utils'; + +describe('Testing LRegistry creation', () => { + test('Should create LRegistry entity', () => { + const newGTCREvent = createNewGTCREvent(REGISTRY_ADDRESS); + + handleNewGTCR(newGTCREvent); + + assert.fieldEquals( + 'LRegistry', + REGISTRY_ADDRESS, + 'id', + REGISTRY_ADDRESS, + 'LRegistry not created', + ); + }); + + test('Should create datasource', () => { + const newGTCREvent = createNewGTCREvent(REGISTRY_ADDRESS); + + handleNewGTCR(newGTCREvent); + + assert.dataSourceCount('LightGeneralizedTCR', 1); + }); + + afterAll(() => { + clearStore(); + }); +});