From 205e5de9847253641c7501f0c7eb9806dec9ce6c Mon Sep 17 00:00:00 2001 From: Juuso Takalainen Date: Wed, 21 May 2025 01:50:56 +0300 Subject: [PATCH 1/2] fix(network-subgraphs): [ETH-876] limit the length of Stream entity id field --- packages/network-subgraphs/schema.graphql | 4 +- .../src/sponsorshipFactory.ts | 7 ++- .../network-subgraphs/src/streamRegistry.ts | 44 +++++++++----- .../src/streamStorageRegistry.ts | 26 +++++---- packages/network-subgraphs/subgraph.yaml | 58 +++++++++---------- 5 files changed, 81 insertions(+), 58 deletions(-) diff --git a/packages/network-subgraphs/schema.graphql b/packages/network-subgraphs/schema.graphql index 6294e92db..305a728b7 100644 --- a/packages/network-subgraphs/schema.graphql +++ b/packages/network-subgraphs/schema.graphql @@ -33,8 +33,10 @@ type StreamPermission @entity { } type Stream @entity { - "stream ID = 'creator address'/'path' where path can be any string" + "NOT THE SAME AS streamId if streamId is over 1000 characters" id: ID! + "stream ID = 'creator address'/'path' where path can be any string" + streamId: String! "Stream metadata JSON" metadata: String! "Permissions that each Ethereum address owns to this stream" diff --git a/packages/network-subgraphs/src/sponsorshipFactory.ts b/packages/network-subgraphs/src/sponsorshipFactory.ts index abda7b593..83f47a447 100644 --- a/packages/network-subgraphs/src/sponsorshipFactory.ts +++ b/packages/network-subgraphs/src/sponsorshipFactory.ts @@ -5,7 +5,7 @@ import { NewSponsorship } from '../generated/SponsorshipFactory/SponsorshipFacto import { Sponsorship, Stream } from '../generated/schema' import { Sponsorship as SponsorshipTemplate } from '../generated/templates' import { loadOrCreateNetwork, loadOrCreateSponsorshipDailyBucket } from './helpers' - +import { getStreamEntityId } from './streamRegistry' export function handleNewSponsorship(event: NewSponsorship): void { const sponsorshipContractAddress = event.params.sponsorshipContract const sponsorshipContractAddressString = sponsorshipContractAddress.toHexString() @@ -40,9 +40,10 @@ export function handleNewSponsorship(event: NewSponsorship): void { sponsorship.save() // try to load stream entity - const stream = Stream.load(event.params.streamId.toString()) + const streamEntityId = getStreamEntityId(event.params.streamId.toString()) + const stream = Stream.load(streamEntityId) if (stream != null) { - sponsorship.stream = stream.id + sponsorship.stream = streamEntityId sponsorship.save() } diff --git a/packages/network-subgraphs/src/streamRegistry.ts b/packages/network-subgraphs/src/streamRegistry.ts index ee4268bc5..0eb3ee3ca 100644 --- a/packages/network-subgraphs/src/streamRegistry.ts +++ b/packages/network-subgraphs/src/streamRegistry.ts @@ -11,14 +11,26 @@ import { Stream, StreamPermission } from '../generated/schema' * TODO: after ETH-876 is solved, streamId can't be over-long, remove the slice(0, 1000) below * because it could cause some streams with same 1k-prefix to mix up when sorting **/ -function getPermissionId(streamId: string, userId: Bytes): string { - return streamId.slice(0, 1000) + "-" + crypto.keccak256(Bytes.fromUTF8(streamId).concat(userId)).toHexString() +function getPermissionId(streamEntityId: string, userId: Bytes): string { + return streamEntityId + "-" + crypto.keccak256(Bytes.fromUTF8(streamEntityId).concat(userId)).toHexString() +} + +/** + * Build the subgraph entity ID; if streamId is short enough, use it as-is (for backwards compatibility) + * @param streamId Stream ID in the StreamRegistry contract + * @returns + */ +export function getStreamEntityId(streamId: string): string { + return streamId.length <= 1000 ? streamId : streamId.slice(0, 1000) + "-" + crypto.keccak256(Bytes.fromUTF8(streamId)).toHexString() } export function handleStreamCreation(event: StreamCreated): void { log.info('handleStreamCreation: id={} metadata={} blockNumber={}', [event.params.id, event.params.metadata, event.block.number.toString()]) - let stream = new Stream(event.params.id) + const streamId = event.params.id + const streamEntityId = getStreamEntityId(streamId) + const stream = new Stream(streamEntityId) + stream.streamId = streamId stream.metadata = event.params.metadata stream.createdAt = event.block.timestamp stream.updatedAt = event.block.timestamp @@ -28,15 +40,19 @@ export function handleStreamCreation(event: StreamCreated): void { export function handleStreamDeletion(event: StreamDeleted): void { log.info('handleDeleteStream: id={} blockNumber={}', [event.params.id, event.block.number.toString()]) - store.remove('Stream', event.params.id) + const streamEntityId = getStreamEntityId(event.params.id) + store.remove('Stream', streamEntityId) } export function handleStreamUpdate(event: StreamUpdated): void { log.info('handleUpdateStream: id={} metadata={} blockNumber={}', [event.params.id, event.params.metadata, event.block.number.toString()]) - let stream = Stream.load(event.params.id) + const streamId = event.params.id + const streamEntityId = getStreamEntityId(streamId) + let stream = Stream.load(streamEntityId) if (stream === null) { - stream = new Stream(event.params.id) + stream = new Stream(streamEntityId) + stream.streamId = streamId stream.createdAt = event.block.timestamp } stream.metadata = event.params.metadata @@ -47,14 +63,15 @@ export function handleStreamUpdate(event: StreamUpdated): void { export function handlePermissionUpdate(event: PermissionUpdated): void { log.info('handlePermissionUpdate: user={} streamId={} blockNumber={}', [event.params.user.toHexString(), event.params.streamId, event.block.number.toString()]) - let stream = Stream.load(event.params.streamId) + const streamEntityId = getStreamEntityId(event.params.streamId) + const stream = Stream.load(streamEntityId) if (stream == null) { return } - let permissionId = getPermissionId(event.params.streamId, event.params.user) - let permission = new StreamPermission(permissionId) + const permissionId = getPermissionId(streamEntityId, event.params.user) + const permission = new StreamPermission(permissionId) permission.userAddress = event.params.user permission.userId = event.params.user - permission.stream = event.params.streamId + permission.stream = streamEntityId permission.canEdit = event.params.canEdit permission.canDelete = event.params.canDelete permission.publishExpiration = event.params.publishExpiration @@ -69,11 +86,12 @@ export function handlePermissionUpdate(event: PermissionUpdated): void { export function handlePermissionUpdateForUserId(event: PermissionUpdatedForUserId): void { log.info('handlePermissionUpdateForUserId: user={} streamId={} blockNumber={}', [event.params.user.toHexString(), event.params.streamId, event.block.number.toString()]) - let stream = Stream.load(event.params.streamId) + const streamEntityId = getStreamEntityId(event.params.streamId) + const stream = Stream.load(streamEntityId) if (stream == null) { return } - let permissionId = getPermissionId(event.params.streamId, event.params.user) - let permission = new StreamPermission(permissionId) + const permissionId = getPermissionId(streamEntityId, event.params.user) + const permission = new StreamPermission(permissionId) // Backwards compatibility: pad/concatenate to 20 bytes, Ethereum addresses remain Ethereum addresses. // This makes it possible to use both *forUserId functions and the old functions for Ethereum addresses. // All new code should use userId instead of userAddress, though; userAddress is marked as deprecated diff --git a/packages/network-subgraphs/src/streamStorageRegistry.ts b/packages/network-subgraphs/src/streamStorageRegistry.ts index 9e7508eb2..4f5e07652 100644 --- a/packages/network-subgraphs/src/streamStorageRegistry.ts +++ b/packages/network-subgraphs/src/streamStorageRegistry.ts @@ -6,36 +6,38 @@ import { } from '../generated/StreamStorageRegistry/StreamStorageRegistry' import { Node } from '../generated/schema' +import { getStreamEntityId } from './streamRegistry' + export function handleStorageNodeAddedToStream(event: Added): void { - let nodeId = event.params.nodeAddress.toHexString() - let streamId = event.params.streamId.toString() - log.info('handleStorageNodeAddedToStream: stream={} node={} blockNumber={}', [streamId, nodeId, event.block.number.toString()]) + const nodeId = event.params.nodeAddress.toHexString() + const streamEntityId = getStreamEntityId(event.params.streamId) + log.info('handleStorageNodeAddedToStream: stream={} node={} blockNumber={}', [streamEntityId, nodeId, event.block.number.toString()]) - let node = Node.load(nodeId)! + const node = Node.load(nodeId)! if (!node.storedStreams) { - node.storedStreams = [streamId] + node.storedStreams = [streamEntityId] } else { let streams = node.storedStreams if (!streams) { streams = [] } - if (streams.includes(streamId)) { return } - streams.push(streamId) + if (streams.includes(streamEntityId)) { return } + streams.push(streamEntityId) node.storedStreams = streams } node.save() } export function handleStorageNodeRemovedFromStream(event: Removed): void { - let nodeId = event.params.nodeAddress.toHexString() - let streamId = event.params.streamId.toString() - log.info('handleStorageNodeRemovedFromStream: stream={} node={} blockNumber={}', [streamId, nodeId, event.block.number.toString()]) + const nodeId = event.params.nodeAddress.toHexString() + const streamEntityId = getStreamEntityId(event.params.streamId) + log.info('handleStorageNodeRemovedFromStream: stream={} node={} blockNumber={}', [streamEntityId, nodeId, event.block.number.toString()]) let node = Node.load(nodeId)! if (!node) { return } if (!node.storedStreams) { return } let streams = node.storedStreams as string[] for (let i = 0; i < streams.length; i++) { - let s = streams[i] as string - if (s == streamId) { + const s = streams[i] as string + if (s == streamEntityId) { streams.splice(i, 1) node.storedStreams = streams node.save() diff --git a/packages/network-subgraphs/subgraph.yaml b/packages/network-subgraphs/subgraph.yaml index 7462fb6e2..599011d37 100644 --- a/packages/network-subgraphs/subgraph.yaml +++ b/packages/network-subgraphs/subgraph.yaml @@ -11,11 +11,11 @@ features: dataSources: - kind: ethereum/contract name: StreamRegistry - network: xDai + network: polygon-amoy source: - address: "0xd04af489677001444280366Dd0885B03dAaDe71D" + address: "0xE9C98bdE63248e58E9137Db8270D9675B9E34b93" abi: StreamRegistry - # startBlock: 10000000 #TODO + startBlock: 6550000 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -40,11 +40,11 @@ dataSources: file: ./src/streamRegistry.ts - kind: ethereum/contract name: NodeRegistry - network: xDai + network: polygon-amoy source: - address: "0xCBAcfA0592B3D809aEc805d527f8ceAe9307D9C0" + address: "0x02fdF917f4e6Ae8F7F1bBDd28179d819E2b76820" abi: NodeRegistry - # startBlock: 10000000 #TODO + startBlock: 6550000 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -62,11 +62,11 @@ dataSources: file: ./src/nodeRegistry.ts - kind: ethereum/contract name: StreamStorageRegistry - network: xDai + network: polygon-amoy source: - address: "0xB9372284e0D61607aF3B7EF5f022e7D599Ed2a37" + address: "0x0f3671A9A92416E1aD32750faCf2AD4FA1b66f78" abi: StreamStorageRegistry - # startBlock: 10000000 #TODO + startBlock: 6550000 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -84,11 +84,11 @@ dataSources: file: ./src/streamStorageRegistry.ts - kind: ethereum/contract name: ProjectRegistryV1 - network: xDai # xDai means dev1 + network: polygon-amoy source: - address: "0x3523F6Ff285D2A3F79A53d1E0953BD41bb7f6022" + address: "0xc5e1434d35c0c7291c7032Fd9C4096b4876C6823" abi: ProjectRegistryV1 - startBlock: 0 + startBlock: 6550000 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -119,11 +119,11 @@ dataSources: file: ./src/projectRegistry.ts - kind: ethereum/contract name: MarketplaceV4 - network: xDai + network: polygon-amoy source: - address: "0x8015bb1954FaF2A6109F5c41b2086B250A6769A0" + address: "0x6C8eaA8e0bF605469c15b6F9106387B4cEC99976" abi: MarketplaceV4 - startBlock: 0 + startBlock: 6550000 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -140,11 +140,11 @@ dataSources: file: ./src/marketplaceV4.ts - kind: ethereum/contract name: ProjectStakingV1 - network: xDai + network: polygon-amoy source: - address: "0x3Dd18E5E8C4f6291Db26795CC154918f7Ac1D875" + address: "0x3A27A16770477EbcFb4B81cE462F4f12591767A0" abi: ProjectStakingV1 - startBlock: 0 + startBlock: 6550000 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -166,11 +166,11 @@ dataSources: file: ./src/projectStaking.ts - kind: ethereum/contract name: StreamrConfig - network: xDai + network: polygon-amoy source: - address: '0xc24BA8c05E5206F1bE57bfA0aD14E9882126eD38' + address: '0x835bC97D2a61bbF5d05932C5105Ca34e1b815F94' abi: StreamrConfig - startBlock: 0 + startBlock: 6550000 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -186,12 +186,12 @@ dataSources: handler: handleConfigChanged - kind: ethereum/contract name: SponsorshipFactory - network: xDai + network: polygon-amoy source: # make sure this is same as config.contracts.SponsorshipFactory in https://github.com/streamr-dev/network-contracts/blob/develop/packages/config/src/networks.json - address: '0xbfa4EcF9d107De5720446e6dd8162ef6bf4b3873' + address: '0xb194a68b166f2e3074B551393fA61490D19c69f8' abi: SponsorshipFactory - startBlock: 0 + startBlock: 6550000 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -211,12 +211,12 @@ dataSources: handler: handleNewSponsorship - kind: ethereum/contract name: OperatorFactory - network: xDai + network: polygon-amoy source: # make sure this is same as config.contracts.OperatorFactory in https://github.com/streamr-dev/network-contracts/blob/develop/packages/config/src/networks.json - address: '0x3AE0ad89b0e094fD09428589849C161f0F7f4E6A' + address: '0xE02E8E9fF5ea6a58F34D00C0e4B091e066B9fA81' abi: OperatorFactory - startBlock: 0 + startBlock: 6550000 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -239,7 +239,7 @@ dataSources: templates: - name: Sponsorship kind: ethereum/contract - network: xDai + network: polygon-amoy source: abi: Sponsorship mapping: @@ -281,7 +281,7 @@ templates: handler: handleSponsorshipReceived - name: Operator kind: ethereum/contract - network: xDai + network: polygon-amoy source: abi: Operator mapping: From f343280af1374779fda71eb811fbe6e4c090b486 Mon Sep 17 00:00:00 2001 From: Juuso Takalainen Date: Wed, 21 May 2025 13:59:44 +0300 Subject: [PATCH 2/2] revert: subgraph.yaml not part of this PR --- packages/network-subgraphs/subgraph.yaml | 58 ++++++++++++------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/network-subgraphs/subgraph.yaml b/packages/network-subgraphs/subgraph.yaml index 599011d37..7462fb6e2 100644 --- a/packages/network-subgraphs/subgraph.yaml +++ b/packages/network-subgraphs/subgraph.yaml @@ -11,11 +11,11 @@ features: dataSources: - kind: ethereum/contract name: StreamRegistry - network: polygon-amoy + network: xDai source: - address: "0xE9C98bdE63248e58E9137Db8270D9675B9E34b93" + address: "0xd04af489677001444280366Dd0885B03dAaDe71D" abi: StreamRegistry - startBlock: 6550000 + # startBlock: 10000000 #TODO mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -40,11 +40,11 @@ dataSources: file: ./src/streamRegistry.ts - kind: ethereum/contract name: NodeRegistry - network: polygon-amoy + network: xDai source: - address: "0x02fdF917f4e6Ae8F7F1bBDd28179d819E2b76820" + address: "0xCBAcfA0592B3D809aEc805d527f8ceAe9307D9C0" abi: NodeRegistry - startBlock: 6550000 + # startBlock: 10000000 #TODO mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -62,11 +62,11 @@ dataSources: file: ./src/nodeRegistry.ts - kind: ethereum/contract name: StreamStorageRegistry - network: polygon-amoy + network: xDai source: - address: "0x0f3671A9A92416E1aD32750faCf2AD4FA1b66f78" + address: "0xB9372284e0D61607aF3B7EF5f022e7D599Ed2a37" abi: StreamStorageRegistry - startBlock: 6550000 + # startBlock: 10000000 #TODO mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -84,11 +84,11 @@ dataSources: file: ./src/streamStorageRegistry.ts - kind: ethereum/contract name: ProjectRegistryV1 - network: polygon-amoy + network: xDai # xDai means dev1 source: - address: "0xc5e1434d35c0c7291c7032Fd9C4096b4876C6823" + address: "0x3523F6Ff285D2A3F79A53d1E0953BD41bb7f6022" abi: ProjectRegistryV1 - startBlock: 6550000 + startBlock: 0 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -119,11 +119,11 @@ dataSources: file: ./src/projectRegistry.ts - kind: ethereum/contract name: MarketplaceV4 - network: polygon-amoy + network: xDai source: - address: "0x6C8eaA8e0bF605469c15b6F9106387B4cEC99976" + address: "0x8015bb1954FaF2A6109F5c41b2086B250A6769A0" abi: MarketplaceV4 - startBlock: 6550000 + startBlock: 0 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -140,11 +140,11 @@ dataSources: file: ./src/marketplaceV4.ts - kind: ethereum/contract name: ProjectStakingV1 - network: polygon-amoy + network: xDai source: - address: "0x3A27A16770477EbcFb4B81cE462F4f12591767A0" + address: "0x3Dd18E5E8C4f6291Db26795CC154918f7Ac1D875" abi: ProjectStakingV1 - startBlock: 6550000 + startBlock: 0 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -166,11 +166,11 @@ dataSources: file: ./src/projectStaking.ts - kind: ethereum/contract name: StreamrConfig - network: polygon-amoy + network: xDai source: - address: '0x835bC97D2a61bbF5d05932C5105Ca34e1b815F94' + address: '0xc24BA8c05E5206F1bE57bfA0aD14E9882126eD38' abi: StreamrConfig - startBlock: 6550000 + startBlock: 0 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -186,12 +186,12 @@ dataSources: handler: handleConfigChanged - kind: ethereum/contract name: SponsorshipFactory - network: polygon-amoy + network: xDai source: # make sure this is same as config.contracts.SponsorshipFactory in https://github.com/streamr-dev/network-contracts/blob/develop/packages/config/src/networks.json - address: '0xb194a68b166f2e3074B551393fA61490D19c69f8' + address: '0xbfa4EcF9d107De5720446e6dd8162ef6bf4b3873' abi: SponsorshipFactory - startBlock: 6550000 + startBlock: 0 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -211,12 +211,12 @@ dataSources: handler: handleNewSponsorship - kind: ethereum/contract name: OperatorFactory - network: polygon-amoy + network: xDai source: # make sure this is same as config.contracts.OperatorFactory in https://github.com/streamr-dev/network-contracts/blob/develop/packages/config/src/networks.json - address: '0xE02E8E9fF5ea6a58F34D00C0e4B091e066B9fA81' + address: '0x3AE0ad89b0e094fD09428589849C161f0F7f4E6A' abi: OperatorFactory - startBlock: 6550000 + startBlock: 0 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -239,7 +239,7 @@ dataSources: templates: - name: Sponsorship kind: ethereum/contract - network: polygon-amoy + network: xDai source: abi: Sponsorship mapping: @@ -281,7 +281,7 @@ templates: handler: handleSponsorshipReceived - name: Operator kind: ethereum/contract - network: polygon-amoy + network: xDai source: abi: Operator mapping: