diff --git a/indexer/chart/Chart.yaml b/indexer/chart/Chart.yaml index b6fefd4..7376eb6 100644 --- a/indexer/chart/Chart.yaml +++ b/indexer/chart/Chart.yaml @@ -2,4 +2,4 @@ name: tfchainindexer description: Helm Chart for the tfchain hydra indexer version: 2.7.7 apiVersion: v2 -appVersion: '2.11.3' +appVersion: '2.11.5' diff --git a/indexer/docker-compose.yml b/indexer/docker-compose.yml index 7e3c108..e5f58f7 100644 --- a/indexer/docker-compose.yml +++ b/indexer/docker-compose.yml @@ -27,7 +27,9 @@ services: "--out", "postgres://root@db:26257/defaultdb", "--types-bundle", - "/configs/typesBundle.json" + "/configs/typesBundle.json", + "--start-block", + "${START_HEIGHT}" ] gateway: diff --git a/package-lock.json b/package-lock.json index 3eb21fa..0c35952 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "graphql_tfgrid", - "version": "2.11.3", + "version": "2.11.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "graphql_tfgrid", - "version": "2.11.3", + "version": "2.11.5", "license": "ISC", "dependencies": { "@subsquid/archive-registry": "1.0.18", diff --git a/package.json b/package.json index 4dc908c..aac5812 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "graphql_tfgrid", "private": "true", - "version": "2.11.3", + "version": "2.11.5", "description": "GraphQL server and Substrate indexer. Generated with ♥ by Hydra-CLI", "author": "", "license": "ISC", diff --git a/processor-chart/Chart.yaml b/processor-chart/Chart.yaml index 0d68c06..345f744 100644 --- a/processor-chart/Chart.yaml +++ b/processor-chart/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v2 name: tfchain-processor description: A chart for the tfchain graphql processor and query node version: 1.0.6 -appVersion: '2.11.3' +appVersion: '2.11.5' diff --git a/src/mappings/contracts.ts b/src/mappings/contracts.ts index d626c85..cf5a8eb 100644 --- a/src/mappings/contracts.ts +++ b/src/mappings/contracts.ts @@ -15,6 +15,7 @@ import { SmartContractModuleNruConsumptionReportReceivedEvent, SmartContractModuleRentContractCanceledEvent, SmartContractModuleContractGracePeriodStartedEvent, SmartContractModuleContractGracePeriodEndedEvent } from "../types/events"; +import { validateString } from "./nodes" export async function contractCreated( ctx: Ctx, @@ -47,7 +48,7 @@ export async function contractCreated( let newNameContract = new NameContract() newNameContract.id = item.event.id contract = contractEvent.contractType.value - newNameContract.name = contract.name.toString() + newNameContract.name = validateString(ctx, contract.name.toString()) newNameContract.contractID = contractEvent.contractId newNameContract.gridVersion = contractEvent.version newNameContract.twinID = contractEvent.twinId @@ -71,16 +72,9 @@ export async function contractCreated( newNodeContract.nodeID = contract.nodeId newNodeContract.numberOfPublicIPs = contract.publicIps - if (contract.deploymentData.toString().indexOf('\x00') >= 0) { - newNodeContract.deploymentData = "" - } else { - newNodeContract.deploymentData = contract.deploymentData.toString() - } - if (contract.deploymentHash.toString().indexOf('\x00') >= 0) { - newNodeContract.deploymentHash = "" - } else { - newNodeContract.deploymentHash = contract.deploymentHash.toString() - } + + newNodeContract.deploymentData = validateString(ctx, contract.deploymentData.toString()) + newNodeContract.deploymentHash = validateString(ctx, contract.deploymentHash.toString()) // newNodeContract.deploymentHash = contract.deploymentHash.toString() newNodeContract.state = state @@ -164,16 +158,16 @@ export async function contractUpdated( const SavedNodeContract = await ctx.store.get(NodeContract, { where: { contractID: contractEvent.contractId } }) if (SavedNodeContract) { - await updateNodeContract(contractEvent, SavedNodeContract, ctx.store) + await updateNodeContract(ctx, contractEvent, SavedNodeContract, ctx.store) } const SavedNameContract = await ctx.store.get(NameContract, { where: { contractID: contractEvent.contractId } }) if (SavedNameContract) { - await updateNameContract(contractEvent, SavedNameContract, ctx.store) + await updateNameContract(ctx, contractEvent, SavedNameContract, ctx.store) } } -async function updateNodeContract(ctr: any, contract: NodeContract, store: Store) { +async function updateNodeContract(ctx: Ctx, ctr: any, contract: NodeContract, store: Store) { if (ctr.contractType.__kind !== "NodeContract") return const parsedNodeContract = ctr.contractType.value @@ -184,16 +178,9 @@ async function updateNodeContract(ctr: any, contract: NodeContract, store: Store contract.nodeID = parsedNodeContract.nodeId contract.numberOfPublicIPs = parsedNodeContract.publicIps - if (contract.deploymentData.toString().indexOf('\x00') >= 0) { - contract.deploymentData = "" - } else { - contract.deploymentData = contract.deploymentData.toString() - } - if (contract.deploymentHash.toString().indexOf('\x00') >= 0) { - contract.deploymentHash = "" - } else { - contract.deploymentHash = contract.deploymentHash.toString() - } + + contract.deploymentData = validateString(ctx, contract.deploymentData.toString()) + contract.deploymentHash = validateString(ctx, contract.deploymentHash.toString()) let state = ContractState.OutOfFunds switch (ctr.state.__kind) { @@ -208,7 +195,7 @@ async function updateNodeContract(ctr: any, contract: NodeContract, store: Store await store.save(contract) } -async function updateNameContract(ctr: any, contract: NameContract, store: Store) { +async function updateNameContract(ctx: Ctx, ctr: any, contract: NameContract, store: Store) { if (ctr.contractType.__kind !== "NameContract") return const parsedNameContract = ctr.contractType.value @@ -216,7 +203,7 @@ async function updateNameContract(ctr: any, contract: NameContract, store: Store contract.contractID = ctr.contractId contract.gridVersion = ctr.version contract.twinID = ctr.twinId - contract.name = parsedNameContract.name.toString() + contract.name = validateString(ctx, parsedNameContract.name.toString()) let state = ContractState.OutOfFunds switch (ctr.state.__kind) { diff --git a/src/mappings/farms.ts b/src/mappings/farms.ts index 542d4a1..002b84b 100644 --- a/src/mappings/farms.ts +++ b/src/mappings/farms.ts @@ -4,6 +4,7 @@ import { EventItem } from '@subsquid/substrate-processor/lib/interfaces/dataSele import { Ctx } from '../processor' import * as v63 from '../types/v63' +import { validateString } from "./nodes" export class FarmWithIPs { constructor(farmID: number, ips: PublicIp[]) { @@ -41,7 +42,7 @@ export async function farmStored( newFarm.id = item.event.id newFarm.gridVersion = farmStoredEventParsed.version newFarm.farmID = farmStoredEventParsed.id - newFarm.name = farmStoredEventParsed.name.toString() + newFarm.name = validateString(ctx, farmStoredEventParsed.name.toString()) newFarm.twinID = farmStoredEventParsed.twinId newFarm.pricingPolicyID = farmStoredEventParsed.pricingPolicyId newFarm.dedicatedFarm = false @@ -56,15 +57,8 @@ export async function farmStored( newIP.id = item.event.id - if (ip.ip.toString().indexOf('\x00') >= 0) { - return - } - newIP.ip = ip.ip.toString() - - if (ip.gateway.toString().indexOf('\x00') >= 0) { - return - } - newIP.gateway = ip.gateway.toString() + newIP.ip = validateString(ctx, ip.ip.toString()) + newIP.gateway = validateString(ctx, ip.gateway.toString()) newIP.contractId = ip.contractId newIP.farm = newFarm @@ -114,7 +108,7 @@ export async function farmUpdated( if (!savedFarm) return savedFarm.gridVersion = farmUpdatedEventParsed.version - savedFarm.name = farmUpdatedEventParsed.name.toString() + savedFarm.name = validateString(ctx, farmUpdatedEventParsed.name.toString()) savedFarm.twinID = farmUpdatedEventParsed.twinId savedFarm.pricingPolicyID = farmUpdatedEventParsed.pricingPolicyId savedFarm.certification = certification @@ -128,14 +122,14 @@ export async function farmUpdated( const savedIP = await ctx.store.get(PublicIp, { where: { ip: ip.ip.toString() }, relations: { farm: true } }) // ip is already there in storage, don't save it again if (savedIP) { - savedIP.ip = ip.ip.toString() - savedIP.gateway = ip.gateway.toString() + savedIP.ip = validateString(ctx, ip.ip.toString()) // not effective, but for since we already check for \x00 + savedIP.gateway = validateString(ctx, ip.gateway.toString()) await ctx.store.save(savedIP) } else { const newIP = new PublicIp() newIP.id = item.event.id - newIP.ip = ip.ip.toString() - newIP.gateway = ip.gateway.toString() + newIP.ip = validateString(ctx, ip.ip.toString()) + newIP.gateway = validateString(ctx, ip.gateway.toString()) newIP.contractId = ip.contractId newIP.farm = savedFarm @@ -151,7 +145,7 @@ export async function farmUpdated( const publicIPsOfFarm = await ctx.store.find(PublicIp, { where: { farm: { id: savedFarm.id } }, relations: { farm: true } }) publicIPsOfFarm.forEach(async ip => { - if (eventPublicIPs.filter(eventIp => eventIp.ip.toString() === ip.ip).length === 0) { + if (eventPublicIPs.filter(eventIp => validateString(ctx, eventIp.ip.toString()) === ip.ip).length === 0) { // IP got removed from farm await ctx.store.remove(ip) } @@ -188,7 +182,7 @@ export async function farmPayoutV2AddressRegistered( if (savedFarm) { let address = '' if (!stellarAddress.includes(0)) { - address = stellarAddress.toString() + address = validateString(ctx, stellarAddress.toString()) } savedFarm.stellarAddress = address @@ -252,7 +246,7 @@ export async function farmCreateOrUpdateOrDelete(ctx: Ctx): Promise<[Farm[], Far newFarm.id = eventID newFarm.gridVersion = farmStoredEventParsed.version newFarm.farmID = farmStoredEventParsed.id - newFarm.name = farmStoredEventParsed.name.toString() + newFarm.name = validateString(ctx, farmStoredEventParsed.name.toString()) newFarm.twinID = farmStoredEventParsed.twinId newFarm.pricingPolicyID = farmStoredEventParsed.pricingPolicyId newFarm.dedicatedFarm = false @@ -267,15 +261,8 @@ export async function farmCreateOrUpdateOrDelete(ctx: Ctx): Promise<[Farm[], Far newIP.id = eventID - if (ip.ip.toString().indexOf('\x00') >= 0) { - return - } - newIP.ip = ip.ip.toString() - - if (ip.gateway.toString().indexOf('\x00') >= 0) { - return - } - newIP.gateway = ip.gateway.toString() + newIP.ip = validateString(ctx, ip.ip.toString()) + newIP.gateway = validateString(ctx, ip.gateway.toString()) newIP.contractId = ip.contractId newIP.farm = newFarm @@ -313,7 +300,7 @@ export async function farmCreateOrUpdateOrDelete(ctx: Ctx): Promise<[Farm[], Far if (foundInNewListIndex != -1) { const savedFarm: Farm = newFarms[foundInNewListIndex] savedFarm.gridVersion = farmUpdatedEventParsed.version - savedFarm.name = farmUpdatedEventParsed.name.toString() + savedFarm.name = validateString(ctx, farmUpdatedEventParsed.name.toString()) savedFarm.twinID = farmUpdatedEventParsed.twinId savedFarm.pricingPolicyID = farmUpdatedEventParsed.pricingPolicyId // const pubIps = updatePublicIPs(ctx, farmUpdatedEventParsed.publicIps, eventID, savedFarm) @@ -328,7 +315,7 @@ export async function farmCreateOrUpdateOrDelete(ctx: Ctx): Promise<[Farm[], Far if (foundInUpdatedListIndex != -1) { let savedFarm: Farm = updatedFarms[foundInUpdatedListIndex] savedFarm.gridVersion = farmUpdatedEventParsed.version - savedFarm.name = farmUpdatedEventParsed.name.toString() + savedFarm.name = validateString(ctx, farmUpdatedEventParsed.name.toString()) savedFarm.twinID = farmUpdatedEventParsed.twinId savedFarm.pricingPolicyID = farmUpdatedEventParsed.pricingPolicyId updatedFarms[foundInUpdatedListIndex] = savedFarm @@ -342,7 +329,7 @@ export async function farmCreateOrUpdateOrDelete(ctx: Ctx): Promise<[Farm[], Far if (!savedFarm) continue savedFarm.gridVersion = farmUpdatedEventParsed.version - savedFarm.name = farmUpdatedEventParsed.name.toString() + savedFarm.name = validateString(ctx, farmUpdatedEventParsed.name.toString()) savedFarm.twinID = farmUpdatedEventParsed.twinId savedFarm.pricingPolicyID = farmUpdatedEventParsed.pricingPolicyId @@ -379,13 +366,13 @@ function getPublicIPs(ctx: Ctx, farm: Farm, savedFarmIps: FarmWithIPs[], newIps: // console.log(`found index: ${foundIdx}`) if (foundIdx !== -1) { toModify[0].publicIPs[foundIdx].contractId = ip.contractId - toModify[0].publicIPs[foundIdx].ip = ip.ip.toString() - toModify[0].publicIPs[foundIdx].gateway = ip.gateway.toString() + toModify[0].publicIPs[foundIdx].ip = validateString(ctx, ip.ip.toString()) + toModify[0].publicIPs[foundIdx].gateway = validateString(ctx, ip.gateway.toString()) } else { const newIP = new PublicIp() newIP.id = eventID newIP.ip = ip.ip.toString() - newIP.gateway = ip.gateway.toString() + newIP.gateway = validateString(ctx, ip.gateway.toString()) newIP.contractId = ip.contractId newIP.farm = farm // ctx.log.info(`saving new ip: ${newIP.ip}`) diff --git a/src/mappings/nodes.ts b/src/mappings/nodes.ts index 3d1efca..9287176 100644 --- a/src/mappings/nodes.ts +++ b/src/mappings/nodes.ts @@ -56,13 +56,13 @@ export async function nodeStored( if (node.isV9) { nodeEvent = node.asV9 - newNode.country = nodeEvent.country.toString() - newNode.city = nodeEvent.city.toString() + newNode.country = validateString(ctx, nodeEvent.country.toString()) + newNode.city = validateString(ctx, nodeEvent.city.toString()) } if (node.isV28) { nodeEvent = node.asV28 - newNode.country = nodeEvent.country.toString() - newNode.city = nodeEvent.city.toString() + newNode.country = validateString(ctx, nodeEvent.country.toString()) + newNode.city = validateString(ctx, nodeEvent.city.toString()) } newNode.created = Number(nodeEvent.created) @@ -71,22 +71,15 @@ export async function nodeStored( const newLocation = new Location() newLocation.id = item.event.id - newLocation.latitude = nodeEvent.location.latitude.toString() - newLocation.longitude = nodeEvent.location.longitude.toString() + newLocation.latitude = validateString(ctx, nodeEvent.location.latitude.toString()) + newLocation.longitude = validateString(ctx, nodeEvent.location.longitude.toString()) await ctx.store.save(newLocation) newNode.location = newLocation - if (newNode.country?.toString().startsWith('0x')) { - newNode.country = "" - } - if (newNode.city?.toString().startsWith('0x')) { - newNode.city = "" - } - await ctx.store.save(newNode) - const pubConfig = getNodePublicConfig(node) + const pubConfig = getNodePublicConfig(ctx, node) const newPubConfig = new PublicConfig() newPubConfig.id = item.event.id newPubConfig.ipv4 = pubConfig?.ip4 @@ -97,11 +90,11 @@ export async function nodeStored( if (node.isV43) { const nodeAsV43 = node.asV43 - newNode.country = nodeAsV43.country.toString() - newNode.city = nodeAsV43.city.toString() + newNode.country = validateString(ctx, nodeAsV43.country.toString()) + newNode.city = validateString(ctx, nodeAsV43.city.toString()) newNode.secure = nodeAsV43.secureBoot ? true : false newNode.virtualized = nodeAsV43.virtualized ? true : false - newNode.serialNumber = nodeAsV43.serialNumber.toString() + newNode.serialNumber = validateString(ctx, nodeAsV43.serialNumber.toString()) } if (node.isV105 || node.isV101 || node.isV63) { @@ -115,31 +108,24 @@ export async function nodeStored( } else { return } - newNode.country = nodeEvent.country.toString() - newNode.city = nodeEvent.city.toString() + newNode.country = validateString(ctx, nodeEvent.country.toString()) + newNode.city = validateString(ctx, nodeEvent.city.toString()) newNode.secure = nodeEvent.secureBoot ? true : false newNode.virtualized = nodeEvent.virtualized ? true : false - newNode.serialNumber = nodeEvent.serialNumber.toString() + newNode.serialNumber = validateString(ctx, nodeEvent.serialNumber.toString()) newNode.connectionPrice = nodeEvent.connectionPrice } if (node.isV118) { let nodeEvent = node.asV118 - newNode.country = nodeEvent.location.country.toString() - newNode.city = nodeEvent.location.city.toString() + newNode.country = validateString(ctx, nodeEvent.location.country.toString()) + newNode.city = validateString(ctx, nodeEvent.location.city.toString()) newNode.secure = nodeEvent.secureBoot ? true : false newNode.virtualized = nodeEvent.virtualized ? true : false - newNode.serialNumber = nodeEvent.serialNumber ? nodeEvent.serialNumber.toString() : 'Unknown' + newNode.serialNumber = nodeEvent.serialNumber ? validateString(ctx, nodeEvent.serialNumber.toString()) : 'Unknown' newNode.connectionPrice = nodeEvent.connectionPrice } - if (newNode.country?.toString().startsWith('0x')) { - newNode.country = "" - } - if (newNode.city?.toString().startsWith('0x')) { - newNode.city = "" - } - await ctx.store.save(newNode) const resourcesTotal = new NodeResourcesTotal() @@ -157,9 +143,9 @@ export async function nodeStored( const newInterface = new Interfaces() newInterface.id = item.event.id newInterface.node = newNode - newInterface.name = intf.name.toString() - newInterface.mac = intf.mac.toString() - newInterface.ips = intf.ips.map(ip => ip.toString()).join(',') + newInterface.name = validateString(ctx, intf.name.toString()) + newInterface.mac = validateString(ctx, intf.mac.toString()) + newInterface.ips = intf.ips.map(ip => validateString(ctx, ip.toString())).join(',') await ctx.store.save(newInterface) }) @@ -215,21 +201,21 @@ export async function nodeUpdated( if (node.isV9) { nodeEvent = node.asV9 - savedNode.country = nodeEvent.country.toString() - savedNode.city = nodeEvent.city.toString() + savedNode.country = validateString(ctx, nodeEvent.country.toString()) + savedNode.city = validateString(ctx, nodeEvent.city.toString()) } if (node.isV118) { nodeEvent = node.asV118 - savedNode.country = nodeEvent.location.country.toString() - savedNode.city = nodeEvent.location.city.toString() + savedNode.country = validateString(ctx, nodeEvent.location.country.toString()) + savedNode.city = validateString(ctx, nodeEvent.location.city.toString()) } if (savedNode.location) { const location = await ctx.store.get(Location, { where: { id: savedNode.location.id } }) if (location) { - location.latitude = nodeEvent.location.latitude.toString() - location.longitude = nodeEvent.location.longitude.toString() + location.latitude = validateString(ctx, nodeEvent.location.latitude.toString()) + location.longitude = validateString(ctx, nodeEvent.location.longitude.toString()) await ctx.store.save(location) savedNode.location = location } @@ -237,8 +223,8 @@ export async function nodeUpdated( if (node.isV28) { const nodeAsV28 = node.asV28 - savedNode.country = nodeAsV28.country.toString() - savedNode.city = nodeAsV28.city.toString() + savedNode.country = validateString(ctx, nodeAsV28.country.toString()) + savedNode.city = validateString(ctx, nodeAsV28.city.toString()) if (nodeAsV28.certificationType) { const certificationTypeAsString = nodeAsV28.certificationType.__kind.toString() @@ -259,11 +245,11 @@ export async function nodeUpdated( if (node.isV43) { const nodeAsV43 = node.asV43 - savedNode.country = nodeAsV43.country.toString() - savedNode.city = nodeAsV43.city.toString() + savedNode.country = validateString(ctx, nodeAsV43.country.toString()) + savedNode.city = validateString(ctx, nodeAsV43.city.toString()) savedNode.secure = nodeAsV43.secureBoot ? true : false savedNode.virtualized = nodeAsV43.virtualized ? true : false - savedNode.serialNumber = nodeAsV43.serialNumber.toString() + savedNode.serialNumber = validateString(ctx, nodeAsV43.serialNumber.toString()) if (nodeAsV43.certificationType) { const certificationTypeAsString = nodeAsV43.certificationType.__kind.toString() let certType = NodeCertification.Diy @@ -292,11 +278,11 @@ export async function nodeUpdated( } else { return } - savedNode.country = nodeEvent.country.toString() - savedNode.city = nodeEvent.city.toString() + savedNode.country = validateString(ctx, nodeEvent.country.toString()) + savedNode.city = validateString(ctx, nodeEvent.city.toString()) savedNode.secure = nodeEvent.secureBoot ? true : false savedNode.virtualized = nodeEvent.virtualized ? true : false - savedNode.serialNumber = nodeEvent.serialNumber.toString() + savedNode.serialNumber = validateString(ctx, nodeEvent.serialNumber.toString()) if (nodeEvent.certification) { const certificationTypeAsString = nodeEvent.certification.__kind.toString() let certType = NodeCertification.Diy @@ -317,11 +303,11 @@ export async function nodeUpdated( if (node.isV118) { const nodeEvent = node.asV118 - savedNode.country = nodeEvent.location.country.toString() - savedNode.city = nodeEvent.location.city.toString() + savedNode.country = validateString(ctx, nodeEvent.location.country.toString()) + savedNode.city = validateString(ctx, nodeEvent.location.city.toString()) savedNode.secure = nodeEvent.secureBoot ? true : false savedNode.virtualized = nodeEvent.virtualized ? true : false - savedNode.serialNumber = nodeEvent.serialNumber ? nodeEvent.serialNumber.toString() : 'Unknown' + savedNode.serialNumber = nodeEvent.serialNumber ? validateString(ctx, nodeEvent.serialNumber.toString()) : 'Unknown' if (nodeEvent.certification) { const certificationTypeAsString = nodeEvent.certification.__kind.toString() let certType = NodeCertification.Diy @@ -346,10 +332,10 @@ export async function nodeUpdated( // Save ones from update event await Promise.all(nodeEvent.interfaces.map(async intf => { const newInterface = new Interfaces() - newInterface.id = item.event.id + intf.name.toString() - newInterface.name = intf.name.toString() - newInterface.mac = intf.mac.toString() - newInterface.ips = intf.ips.map(ip => ip.toString()).join(',') + newInterface.id = item.event.id + validateString(ctx, intf.name.toString()) + newInterface.name = validateString(ctx, intf.name.toString()) + newInterface.mac = validateString(ctx, intf.mac.toString()) + newInterface.ips = intf.ips.map(ip => validateString(ctx, ip.toString())).join(',') newInterface.node = savedNode await ctx.store.save(newInterface) @@ -445,10 +431,10 @@ export async function nodePublicConfigStored( if (storedEvent.isV49) { [nodeID, config] = storedEvent.asV49 - ipv4 = config.ipv4.toString() - ipv6 = config.ipv6.toString() - gw4 = config.gw4.toString() - gw6 = config.gw6.toString() + ipv4 = validateString(ctx, config.ipv4.toString()) + ipv6 = validateString(ctx, config.ipv6.toString()) + gw4 = validateString(ctx, config.gw4.toString()) + gw6 = validateString(ctx, config.gw6.toString()) domain = config.domain.toString() } else if (storedEvent.isV105) { [nodeID, config] = storedEvent.asV105 @@ -496,11 +482,11 @@ async function handlePublicConfigV105(ctx: Ctx, eventID: string, nodeID: number, publicConfig.node = savedNode } - publicConfig.ipv4 = config?.ip4.ip ? config?.ip4.ip.toString() : null - publicConfig.gw4 = config?.ip4.gw ? config?.ip4.gw.toString() : null - publicConfig.ipv6 = config?.ip6?.ip ? config?.ip6?.ip.toString() : null - publicConfig.gw6 = config?.ip6?.gw ? config?.ip6?.gw.toString() : null - publicConfig.domain = config?.domain ? config.domain.toString() : null + publicConfig.ipv4 = config?.ip4.ip ? validateString(ctx, config?.ip4.ip.toString()) : null + publicConfig.gw4 = config?.ip4.gw ? validateString(ctx, config?.ip4.gw.toString()) : null + publicConfig.ipv6 = config?.ip6?.ip ? validateString(ctx, config?.ip6?.ip.toString()) : null + publicConfig.gw6 = config?.ip6?.gw ? validateString(ctx, config?.ip6?.gw.toString()) : null + publicConfig.domain = config?.domain ? validateString(ctx, config.domain.toString()) : null await ctx.store.save(publicConfig) } @@ -610,61 +596,61 @@ interface NodePublicConfig { domain: string } -function getNodePublicConfig(node: TfgridModuleNodeStoredEvent): NodePublicConfig | null | undefined { +function getNodePublicConfig(ctx: Ctx, node: TfgridModuleNodeStoredEvent): NodePublicConfig | null | undefined { let nodeEvent if (node.isV9) { nodeEvent = node.asV9 if (nodeEvent.publicConfig) { return { - ip4: nodeEvent.publicConfig?.ipv4.toString(), - gw4: nodeEvent.publicConfig?.gw4.toString(), - ip6: nodeEvent.publicConfig?.ipv6.toString(), - gw6: nodeEvent.publicConfig?.gw6.toString(), - domain: nodeEvent.publicConfig?.domain.toString() + ip4: validateString(ctx, nodeEvent.publicConfig?.ipv4.toString()), + gw4: validateString(ctx, nodeEvent.publicConfig?.gw4.toString()), + ip6: validateString(ctx, nodeEvent.publicConfig?.ipv6.toString()), + gw6: validateString(ctx, nodeEvent.publicConfig?.gw6.toString()), + domain: validateString(ctx, nodeEvent.publicConfig?.domain.toString()) } } } else if (node.isV28) { nodeEvent = node.asV28 if (nodeEvent.publicConfig) { return { - ip4: nodeEvent.publicConfig?.ipv4.toString(), - gw4: nodeEvent.publicConfig?.gw4.toString(), - ip6: nodeEvent.publicConfig?.ipv6.toString(), - gw6: nodeEvent.publicConfig?.gw6.toString(), - domain: nodeEvent.publicConfig?.domain.toString() + ip4: validateString(ctx, nodeEvent.publicConfig?.ipv4.toString()), + gw4: validateString(ctx, nodeEvent.publicConfig?.gw4.toString()), + ip6: validateString(ctx, nodeEvent.publicConfig?.ipv6.toString()), + gw6: validateString(ctx, nodeEvent.publicConfig?.gw6.toString()), + domain: validateString(ctx, nodeEvent.publicConfig?.domain.toString()) } } } else if (node.isV43) { nodeEvent = node.asV43 if (nodeEvent.publicConfig) { return { - ip4: nodeEvent.publicConfig?.ipv4.toString(), - gw4: nodeEvent.publicConfig?.gw4.toString(), - ip6: nodeEvent.publicConfig?.ipv6.toString(), - gw6: nodeEvent.publicConfig?.gw6.toString(), - domain: nodeEvent.publicConfig?.domain.toString() + ip4: validateString(ctx, nodeEvent.publicConfig?.ipv4.toString()), + gw4: validateString(ctx, nodeEvent.publicConfig?.gw4.toString()), + ip6: validateString(ctx, nodeEvent.publicConfig?.ipv6.toString()), + gw6: validateString(ctx, nodeEvent.publicConfig?.gw6.toString()), + domain: validateString(ctx, nodeEvent.publicConfig?.domain.toString()) } } } else if (node.isV63) { nodeEvent = node.asV63 if (nodeEvent.publicConfig) { return { - ip4: nodeEvent.publicConfig?.ipv4.toString(), - gw4: nodeEvent.publicConfig?.gw4.toString(), - ip6: nodeEvent.publicConfig?.ipv6.toString(), - gw6: nodeEvent.publicConfig?.gw6.toString(), - domain: nodeEvent.publicConfig?.domain.toString() + ip4: validateString(ctx, nodeEvent.publicConfig?.ipv4.toString()), + gw4: validateString(ctx, nodeEvent.publicConfig?.gw4.toString()), + ip6: validateString(ctx, nodeEvent.publicConfig?.ipv6.toString()), + gw6: validateString(ctx, nodeEvent.publicConfig?.gw6.toString()), + domain: validateString(ctx, nodeEvent.publicConfig?.domain.toString()) } } } else if (node.isV101) { nodeEvent = node.asV101 if (nodeEvent.publicConfig) { return { - ip4: nodeEvent.publicConfig?.ipv4.toString(), - gw4: nodeEvent.publicConfig?.gw4.toString(), - ip6: nodeEvent.publicConfig?.ipv6.toString(), - gw6: nodeEvent.publicConfig?.gw6.toString(), - domain: nodeEvent.publicConfig?.domain.toString() + ip4: validateString(ctx, nodeEvent.publicConfig?.ipv4.toString()), + gw4: validateString(ctx, nodeEvent.publicConfig?.gw4.toString()), + ip6: validateString(ctx, nodeEvent.publicConfig?.ipv6.toString()), + gw6: validateString(ctx, nodeEvent.publicConfig?.gw6.toString()), + domain: validateString(ctx, nodeEvent.publicConfig?.domain.toString()) } } } else if (node.isV105) { @@ -674,11 +660,13 @@ function getNodePublicConfig(node: TfgridModuleNodeStoredEvent): NodePublicConfi if (nodeEvent.publicConfig.domain) { domain = nodeEvent.publicConfig.domain.toString() } + let h = nodeEvent.publicConfig?.ip6?.ip.toString(); + let r = nodeEvent.publicConfig?.ip4.ip.toString(); return { - ip4: nodeEvent.publicConfig?.ip4.ip.toString(), - gw4: nodeEvent.publicConfig?.ip4.gw.toString(), - ip6: nodeEvent.publicConfig?.ip6?.ip.toString() || '', - gw6: nodeEvent.publicConfig?.ip6?.gw.toString() || '', + ip4: validateString(ctx, nodeEvent.publicConfig?.ip4.ip.toString()), + gw4: validateString(ctx, nodeEvent.publicConfig?.ip4.gw.toString()), + ip6: validateString(ctx, nodeEvent.publicConfig?.ip6?.ip.toString() || ''), + gw6: validateString(ctx, nodeEvent.publicConfig?.ip6?.gw.toString() || ''), domain } } @@ -688,3 +676,14 @@ function getNodePublicConfig(node: TfgridModuleNodeStoredEvent): NodePublicConfi return null } + +// validateString checks if the string includes '\x00' which is not accepted by postgres +// if so, it replaces the string with invalid and logs the error +export function validateString(ctx: Ctx, str: string): string { + if (str.includes('\x00')) { + ctx.log.error(`invalid string containing "\\x00": ${str}`) + return "invalid" + } + + return str +} \ No newline at end of file diff --git a/src/mappings/policies.ts b/src/mappings/policies.ts index 1911408..ec11763 100644 --- a/src/mappings/policies.ts +++ b/src/mappings/policies.ts @@ -2,15 +2,16 @@ import * as ss58 from "@subsquid/ss58"; import { Ctx } from "../processor"; import { EventItem } from '@subsquid/substrate-processor/lib/interfaces/dataSelection' -import { +import { PricingPolicy, FarmingPolicy, - Policy, FarmCertification, + Policy, FarmCertification, NodeCertification } from "../model"; -import { - TfgridModulePricingPolicyStoredEvent, TfgridModuleFarmingPolicyStoredEvent, +import { + TfgridModulePricingPolicyStoredEvent, TfgridModuleFarmingPolicyStoredEvent, TfgridModuleFarmingPolicyUpdatedEvent } from "../types/events"; +import { validateString } from "./nodes" export async function pricingPolicyStored( ctx: Ctx, @@ -29,18 +30,18 @@ export async function pricingPolicyStored( } if (!pricingPolicyEventParsed) return - + let pricingPolicy = new PricingPolicy() pricingPolicy.id = item.event.id - const savedPolicy = await ctx.store.get(PricingPolicy, { where: { pricingPolicyID: pricingPolicyEventParsed.id }}) + const savedPolicy = await ctx.store.get(PricingPolicy, { where: { pricingPolicyID: pricingPolicyEventParsed.id } }) if (savedPolicy) { pricingPolicy = savedPolicy } pricingPolicy.gridVersion = pricingPolicyEventParsed.version pricingPolicy.pricingPolicyID = pricingPolicyEventParsed.id - pricingPolicy.name = pricingPolicyEventParsed.name.toString() + pricingPolicy.name = validateString(ctx, pricingPolicyEventParsed.name.toString()) pricingPolicy.dedicatedNodeDiscount = 0 const foundationAccount = ss58.codec("substrate").encode(pricingPolicyEventParsed.foundationAccount); @@ -51,19 +52,19 @@ export async function pricingPolicyStored( const suPolicy = new Policy() suPolicy.value = pricingPolicyEventParsed.su.value - suPolicy.unit = pricingPolicyEventParsed.su.unit.toString() + suPolicy.unit = validateString(ctx, pricingPolicyEventParsed.su.unit.toString()) const nuPolicy = new Policy() nuPolicy.value = pricingPolicyEventParsed.nu.value - nuPolicy.unit = pricingPolicyEventParsed.nu.unit.toString() + nuPolicy.unit = validateString(ctx, pricingPolicyEventParsed.nu.unit.toString()) const cuPolicy = new Policy() cuPolicy.value = pricingPolicyEventParsed.cu.value - cuPolicy.unit = pricingPolicyEventParsed.cu.unit.toString() + cuPolicy.unit = validateString(ctx, pricingPolicyEventParsed.cu.unit.toString()) const IpuPolicy = new Policy() IpuPolicy.value = pricingPolicyEventParsed.ipu.value - IpuPolicy.unit = pricingPolicyEventParsed.ipu.unit.toString() + IpuPolicy.unit = validateString(ctx, pricingPolicyEventParsed.ipu.unit.toString()) pricingPolicy.su = suPolicy pricingPolicy.cu = cuPolicy @@ -94,7 +95,7 @@ export async function farmingPolicyStored( newFarmingPolicy.id = item.event.id newFarmingPolicy.gridVersion = farmingPolicyStoredEvent.version newFarmingPolicy.farmingPolicyID = farmingPolicyStoredEvent.id - newFarmingPolicy.name = farmingPolicyStoredEvent.name.toString() + newFarmingPolicy.name = validateString(ctx, farmingPolicyStoredEvent.name.toString()) newFarmingPolicy.cu = farmingPolicyStoredEvent.cu newFarmingPolicy.su = farmingPolicyStoredEvent.su @@ -108,10 +109,10 @@ export async function farmingPolicyStored( const certificationTypeAsString = farmingPolicyStoredEvent.nodeCertification.__kind.toString() let nodeCertType = NodeCertification.Diy switch (certificationTypeAsString) { - case 'Diy': + case 'Diy': nodeCertType = NodeCertification.Diy break - case 'Certified': + case 'Certified': nodeCertType = NodeCertification.Certified break } @@ -120,10 +121,10 @@ export async function farmingPolicyStored( const farmCertificationTypeAsString = farmingPolicyStoredEvent.farmCertification.__kind.toString() let farmCertType = FarmCertification.NotCertified switch (farmCertificationTypeAsString) { - case 'NotCertified': + case 'NotCertified': farmCertType = FarmCertification.NotCertified break - case 'Gold': + case 'Gold': farmCertType = FarmCertification.Gold break } @@ -149,7 +150,7 @@ export async function farmingPolicyUpdated( savedPolicy.gridVersion = farmingPolicyUpdatedEvent.version savedPolicy.farmingPolicyID = farmingPolicyUpdatedEvent.id - savedPolicy.name = farmingPolicyUpdatedEvent.name.toString() + savedPolicy.name = validateString(ctx, farmingPolicyUpdatedEvent.name.toString()) savedPolicy.cu = farmingPolicyUpdatedEvent.cu savedPolicy.su = farmingPolicyUpdatedEvent.su @@ -163,10 +164,10 @@ export async function farmingPolicyUpdated( const certificationTypeAsString = farmingPolicyUpdatedEvent.nodeCertification.__kind.toString() let nodeCertType = NodeCertification.Diy switch (certificationTypeAsString) { - case 'Diy': + case 'Diy': nodeCertType = NodeCertification.Diy break - case 'Certified': + case 'Certified': nodeCertType = NodeCertification.Certified break } @@ -175,10 +176,10 @@ export async function farmingPolicyUpdated( const farmCertificationTypeAsString = farmingPolicyUpdatedEvent.farmCertification.__kind.toString() let farmCertType = FarmCertification.NotCertified switch (farmCertificationTypeAsString) { - case 'NotCertified': + case 'NotCertified': farmCertType = FarmCertification.NotCertified break - case 'Gold': + case 'Gold': farmCertType = FarmCertification.Gold break } diff --git a/src/mappings/serviceContracts.ts b/src/mappings/serviceContracts.ts index 9d55b94..157014f 100644 --- a/src/mappings/serviceContracts.ts +++ b/src/mappings/serviceContracts.ts @@ -3,6 +3,7 @@ import { Ctx } from '../processor' import { ServiceContract, ServiceContractState, ServiceContractBill } from "../model"; import { SmartContractModuleServiceContractCreatedEvent, SmartContractModuleServiceContractMetadataSetEvent, SmartContractModuleServiceContractFeesSetEvent, SmartContractModuleServiceContractApprovedEvent, SmartContractModuleServiceContractCanceledEvent, SmartContractModuleServiceContractBilledEvent } from "../types/events"; +import { validateString } from "./nodes"; export async function serviceContractCreated( ctx: Ctx, @@ -34,7 +35,7 @@ export async function serviceContractMetadataSet( const savedServiceContract = await ctx.store.get(ServiceContract, { where: { serviceContractID: serviceContractMetadataSetEvent.serviceContractId } }) if (savedServiceContract) { - savedServiceContract.metadata = serviceContractMetadataSetEvent.metadata.toString() + savedServiceContract.metadata = validateString(ctx, serviceContractMetadataSetEvent.metadata.toString()) let state = ServiceContractState.Created switch (serviceContractMetadataSetEvent.state.__kind) { @@ -126,7 +127,7 @@ export async function serviceContractBilled( serviceContractBill.serviceContractID = serviceContractBilledEvent.serviceContract.serviceContractId serviceContractBill.variableAmount = serviceContractBilledEvent.bill.variableAmount serviceContractBill.window = serviceContractBilledEvent.bill.window - serviceContractBill.metadata = serviceContractBilledEvent.bill.metadata.toString() + serviceContractBill.metadata = validateString(ctx, serviceContractBilledEvent.bill.metadata.toString()) serviceContractBill.amount = serviceContractBilledEvent.amount await ctx.store.save(serviceContractBill) diff --git a/src/mappings/solutionProviders.ts b/src/mappings/solutionProviders.ts index d910ed6..661fc4a 100644 --- a/src/mappings/solutionProviders.ts +++ b/src/mappings/solutionProviders.ts @@ -3,10 +3,11 @@ import { Ctx } from '../processor' import { EventItem } from '@subsquid/substrate-processor/lib/interfaces/dataSelection' import { Provider, SolutionProvider } from "../model" -import { - SmartContractModuleSolutionProviderApprovedEvent, - SmartContractModuleSolutionProviderCreatedEvent +import { + SmartContractModuleSolutionProviderApprovedEvent, + SmartContractModuleSolutionProviderCreatedEvent } from "../types/events" +import { validateString } from "./nodes"; export async function solutionProviderCreated( ctx: Ctx, @@ -18,8 +19,8 @@ export async function solutionProviderCreated( provider.id = item.event.id provider.solutionProviderID = providerCreatedEvent.solutionProviderId - provider.description = providerCreatedEvent.description.toString() - provider.link = providerCreatedEvent.link.toString() + provider.description = validateString(ctx, providerCreatedEvent.description.toString()) + provider.link = validateString(ctx, providerCreatedEvent.link.toString()) provider.approved = false provider.providers = [] diff --git a/src/mappings/twins.ts b/src/mappings/twins.ts index 1a239dc..e02cb1c 100644 --- a/src/mappings/twins.ts +++ b/src/mappings/twins.ts @@ -5,6 +5,7 @@ import { SubstrateBlock } from '@subsquid/substrate-processor' import { Twin } from "../model"; import { TfgridModuleTwinStoredEvent, TfgridModuleTwinDeletedEvent, TfgridModuleTwinUpdatedEvent } from "../types/events"; +import { validateString } from "./nodes"; export async function twinStored( ctx: Ctx, @@ -134,21 +135,21 @@ function getTwinCreate( id = item.event.id twinID = twin.id version = twin.version - relay = twin.ip.toString() + relay = validateString(ctx, twin.ip.toString()) accountID = ss58.codec("substrate").encode(twin.accountId) } else if (twinEvent.isV101) { twin = twinEvent.asV101 id = item.event.id twinID = twin.id version = twin.version - relay = twin.ip.toString() + relay = validateString(ctx, twin.ip.toString()) accountID = ss58.codec("substrate").encode(twin.accountId) } else if (twinEvent.isV124) { twin = twinEvent.asV124 id = item.event.id twinID = twin.id if (twin.relay) { - relay = twin.relay?.toString() + relay = validateString(ctx, twin.relay?.toString()) } accountID = ss58.codec("substrate").encode(twin.accountId) if (twin.pk) { @@ -184,25 +185,25 @@ function getTwinUpdate( id = item.event.id twinID = twin.id version = twin.version - relay = twin.ip.toString() + relay = validateString(ctx, twin.ip.toString()) accountID = ss58.codec("substrate").encode(twin.accountId) } else if (twinEvent.isV101) { twin = twinEvent.asV101 id = item.event.id twinID = twin.id version = twin.version - relay = twin.ip.toString() + relay = validateString(ctx, twin.ip.toString()) accountID = ss58.codec("substrate").encode(twin.accountId) } else if (twinEvent.isV124) { twin = twinEvent.asV124 id = item.event.id twinID = twin.id if (twin.relay) { - relay = twin.relay?.toString() + relay = validateString(ctx, twin.relay?.toString()) } accountID = ss58.codec("substrate").encode(twin.accountId) if (twin.pk) { - pk = '0x' + Buffer.from(twin.pk).toString('hex'); + pk = validateString(ctx, '0x' + Buffer.from(twin.pk).toString('hex')); } } diff --git a/src/processor.ts b/src/processor.ts index 52213d5..031a910 100644 --- a/src/processor.ts +++ b/src/processor.ts @@ -47,6 +47,7 @@ const processor = new SubstrateBatchProcessor() chain: process.env.WS_URL || 'ws://localhost:9944' }) .setPrometheusPort(44233) + .setBlockRange({ from: 0 }) // Balances .addEvent('Balances.Transfer', eventOptions) // Twins