Skip to content

Commit 454e428

Browse files
authored
fix(network-subgraphs): [ETH-876] Ignore overlong stream ids (#993)
Added stream ID length check to all events handlers which process stream related events. If the stream ID is more than 1000 characters, the event is just ignored. That causes the stream to be fully ignored in The Graph (it won't appear e.g. in the `streams` query). ## TODO (in a separate PR) We need to document to our public document that overlong streams are not supported (i.e. the behavior is undefined in our system for those streams). ## Manual test ```bash PRIVATE_KEY="1111111111111111111111111111111111111111111111111111111111111111" NOW=$(date +%Y%m%d%H%M%S) LONG_SNIPPET=$(printf 'a%.0s' {1..2000}) echo 'Create streams' npx tsx bin/streamr.ts internal token-mint self 1000000 1000000 --env dev2 --private-key $PRIVATE_KEY npx tsx bin/streamr.ts stream create /short1-$NOW --env dev2 --private-key $PRIVATE_KEY npx tsx bin/streamr.ts stream create /long-$NOW-$LONG_SNIPPET --env dev2 --private-key $PRIVATE_KEY npx tsx bin/streamr.ts stream create /short2-$NOW --env dev2 --private-key $PRIVATE_KEY echo 'Wait for The Graph to index' sleep 10s echo 'Query streams:' npx tsx bin/streamr.ts stream search $NOW --env dev2 ``` ## Related changed - Simplified `getPermissionId(`) as the slicing and concatenation which is no longer needed ## Future improvements - We could avoid code repetition by using some kind of wrapper function which does the length check
1 parent acb1d0b commit 454e428

File tree

5 files changed

+40
-5
lines changed

5 files changed

+40
-5
lines changed

packages/network-subgraphs/src/helpers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { Operator as OperatorContract } from '../generated/templates/Operator/Op
1717

1818
const BUCKET_SECONDS = BigInt.fromI32(60 * 60 * 24) // 1 day
1919
const NETWORK_ENTITY_ID = "network-entity-id"
20+
export const MAX_STREAM_ID_LENGTH = 1000
2021

2122
/**
2223
* Helper function to load a project or create a project with default values. It will probably silence some errors.

packages/network-subgraphs/src/projectRegistry.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
StreamRemoved,
1111
PaymentDetailsByChainUpdated,
1212
} from '../generated/ProjectRegistryV1/ProjectRegistryV1'
13-
import { getIsDataUnionValue, loadOrCreateProject } from './helpers'
13+
import { getIsDataUnionValue, loadOrCreateProject, MAX_STREAM_ID_LENGTH } from './helpers'
1414

1515
export function handleProjectCreation(event: ProjectCreated): void {
1616
const id = event.params.id.toHexString()
@@ -151,7 +151,11 @@ export function handleStreamAddition(event: StreamAdded): void {
151151
const streamId = event.params.streamId
152152
log.info('handleStreamAddition: projectId={} streamId={} blockNumber={}',
153153
[projectId, streamId, event.block.number.toString()])
154-
154+
if (streamId.length > MAX_STREAM_ID_LENGTH) {
155+
log.warning("Overlong stream id not supported: {}", [streamId])
156+
return
157+
}
158+
155159
let project = loadOrCreateProject(event.params.projectId)
156160

157161
const streams = project.streams
@@ -165,6 +169,10 @@ export function handleStreamRemoval(event: StreamRemoved): void {
165169
const streamId = event.params.streamId
166170
log.info('handleStreamRemoval: projectId={} streamId={} blockNumber={}',
167171
[projectId, streamId, event.block.number.toString()])
172+
if (streamId.length > MAX_STREAM_ID_LENGTH) {
173+
log.warning("Overlong stream id not supported: {}", [streamId])
174+
return
175+
}
168176

169177
let project = loadOrCreateProject(event.params.projectId)
170178

packages/network-subgraphs/src/sponsorshipFactory.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Sponsorship as SponsorshipContract } from '../generated/templates/Spons
44
import { NewSponsorship } from '../generated/SponsorshipFactory/SponsorshipFactory'
55
import { Sponsorship, Stream } from '../generated/schema'
66
import { Sponsorship as SponsorshipTemplate } from '../generated/templates'
7-
import { loadOrCreateNetwork, loadOrCreateSponsorshipDailyBucket } from './helpers'
7+
import { loadOrCreateNetwork, loadOrCreateSponsorshipDailyBucket, MAX_STREAM_ID_LENGTH } from './helpers'
88

99
export function handleNewSponsorship(event: NewSponsorship): void {
1010
const sponsorshipContractAddress = event.params.sponsorshipContract
@@ -14,6 +14,10 @@ export function handleNewSponsorship(event: NewSponsorship): void {
1414
[event.block.number.toString(), sponsorshipContractAddressString,
1515
event.params.policies.map<string>((x) => x.toHexString()).join(", "), event.params.policyParams.toString(), creator]
1616
)
17+
if (event.params.streamId.length > MAX_STREAM_ID_LENGTH) {
18+
log.warning("Overlong stream id not supported: {}", [event.params.streamId])
19+
return
20+
}
1721

1822
const sponsorship = new Sponsorship(sponsorshipContractAddressString)
1923
sponsorship.totalStakedWei = BigInt.zero()

packages/network-subgraphs/src/streamRegistry.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ByteArray, Bytes, log, store, crypto } from '@graphprotocol/graph-ts'
33
import { StreamCreated, StreamDeleted, StreamUpdated, PermissionUpdated, PermissionUpdatedForUserId }
44
from '../generated/StreamRegistry/StreamRegistry'
55
import { Stream, StreamPermission } from '../generated/schema'
6+
import { MAX_STREAM_ID_LENGTH } from './helpers'
67

78
/**
89
* Hash the streamId and the userId, in order to get constant-length permission IDs (ETH-867)
@@ -12,12 +13,16 @@ import { Stream, StreamPermission } from '../generated/schema'
1213
* because it could cause some streams with same 1k-prefix to mix up when sorting
1314
**/
1415
function getPermissionId(streamId: string, userId: Bytes): string {
15-
return streamId.slice(0, 1000) + "-" + crypto.keccak256(Bytes.fromUTF8(streamId).concat(userId)).toHexString()
16+
return streamId + "-" + crypto.keccak256(userId).toHexString()
1617
}
1718

1819
export function handleStreamCreation(event: StreamCreated): void {
1920
log.info('handleStreamCreation: id={} metadata={} blockNumber={}',
2021
[event.params.id, event.params.metadata, event.block.number.toString()])
22+
if (event.params.id.length > MAX_STREAM_ID_LENGTH) {
23+
log.warning("Overlong stream id not supported: {}", [event.params.id])
24+
return
25+
}
2126
let stream = new Stream(event.params.id)
2227
stream.metadata = event.params.metadata
2328
stream.createdAt = event.block.timestamp
@@ -47,6 +52,10 @@ export function handleStreamUpdate(event: StreamUpdated): void {
4752
export function handlePermissionUpdate(event: PermissionUpdated): void {
4853
log.info('handlePermissionUpdate: user={} streamId={} blockNumber={}',
4954
[event.params.user.toHexString(), event.params.streamId, event.block.number.toString()])
55+
if (event.params.streamId.length > MAX_STREAM_ID_LENGTH) {
56+
log.warning("Overlong stream id not supported: {}", [event.params.streamId])
57+
return
58+
}
5059
let stream = Stream.load(event.params.streamId)
5160
if (stream == null) { return }
5261

@@ -69,6 +78,10 @@ export function handlePermissionUpdate(event: PermissionUpdated): void {
6978
export function handlePermissionUpdateForUserId(event: PermissionUpdatedForUserId): void {
7079
log.info('handlePermissionUpdateForUserId: user={} streamId={} blockNumber={}',
7180
[event.params.user.toHexString(), event.params.streamId, event.block.number.toString()])
81+
if (event.params.streamId.length > MAX_STREAM_ID_LENGTH) {
82+
log.warning("Overlong stream id not supported: {}", [event.params.streamId])
83+
return
84+
}
7285
let stream = Stream.load(event.params.streamId)
7386
if (stream == null) { return }
7487

packages/network-subgraphs/src/streamStorageRegistry.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@ import {
55
Removed
66
} from '../generated/StreamStorageRegistry/StreamStorageRegistry'
77
import { Node } from '../generated/schema'
8+
import { MAX_STREAM_ID_LENGTH } from './helpers'
89

910
export function handleStorageNodeAddedToStream(event: Added): void {
1011
let nodeId = event.params.nodeAddress.toHexString()
1112
let streamId = event.params.streamId.toString()
1213
log.info('handleStorageNodeAddedToStream: stream={} node={} blockNumber={}', [streamId, nodeId, event.block.number.toString()])
14+
if (event.params.streamId.length > MAX_STREAM_ID_LENGTH) {
15+
log.warning("Overlong stream id not supported: {}", [event.params.streamId])
16+
return
17+
}
1318

1419
let node = Node.load(nodeId)!
1520
if (!node.storedStreams) {
@@ -28,7 +33,11 @@ export function handleStorageNodeRemovedFromStream(event: Removed): void {
2833
let nodeId = event.params.nodeAddress.toHexString()
2934
let streamId = event.params.streamId.toString()
3035
log.info('handleStorageNodeRemovedFromStream: stream={} node={} blockNumber={}', [streamId, nodeId, event.block.number.toString()])
31-
36+
if (event.params.streamId.length > MAX_STREAM_ID_LENGTH) {
37+
log.warning("Overlong stream id not supported: {}", [event.params.streamId])
38+
return
39+
}
40+
3241
let node = Node.load(nodeId)!
3342
if (!node) { return }
3443
if (!node.storedStreams) { return }

0 commit comments

Comments
 (0)