Skip to content

Commit 5f1bbe0

Browse files
committed
feat(subgraph): add-additional-fields-in-evidence-entity
1 parent 9ea71a5 commit 5f1bbe0

File tree

4 files changed

+77
-3
lines changed

4 files changed

+77
-3
lines changed

subgraph/core/schema.graphql

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ interface Evidence {
5454
evidenceGroup: EvidenceGroup!
5555
sender: User!
5656
timestamp: BigInt!
57+
name: String
58+
description: String
59+
fileURI: String
60+
fileTypeExtension: String
5761
}
5862

5963
############
@@ -292,12 +296,16 @@ type ClassicEvidenceGroup implements EvidenceGroup @entity {
292296
nextEvidenceIndex: BigInt!
293297
}
294298

295-
type ClassicEvidence implements Evidence @entity {
299+
type ClassicEvidence implements Evidence @entity(immutable: true) {
296300
id: ID! # classicEvidenceGroup.id-nextEvidenceIndex
297301
evidence: String!
298302
evidenceGroup: EvidenceGroup!
299303
sender: User!
300304
timestamp: BigInt!
305+
name: String
306+
description: String
307+
fileURI: String
308+
fileTypeExtension: String
301309
}
302310

303311
type ClassicContribution implements Contribution @entity {

subgraph/core/src/EvidenceModule.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,61 @@
1+
import { json, JSONValueKind, log } from "@graphprotocol/graph-ts";
12
import { Evidence as EvidenceEvent } from "../generated/EvidenceModule/EvidenceModule";
23
import { ClassicEvidence } from "../generated/schema";
34
import { ensureClassicEvidenceGroup } from "./entities/ClassicEvidenceGroup";
45
import { ensureUser } from "./entities/User";
56
import { ONE } from "./utils";
7+
import { JSONValueToMaybeString } from "../../utils";
68

79
export function handleEvidenceEvent(event: EvidenceEvent): void {
810
const evidenceGroupID = event.params._externalDisputeID.toString();
911
const evidenceGroup = ensureClassicEvidenceGroup(evidenceGroupID);
1012
const evidenceIndex = evidenceGroup.nextEvidenceIndex;
1113
evidenceGroup.nextEvidenceIndex = evidenceGroup.nextEvidenceIndex.plus(ONE);
1214
evidenceGroup.save();
13-
const evidence = new ClassicEvidence(`${evidenceGroupID}-${evidenceIndex.toString()}`);
15+
const evidenceId = `${evidenceGroupID}-${evidenceIndex.toString()}`;
16+
const evidence = new ClassicEvidence(evidenceId);
1417
const userId = event.params._party.toHexString();
1518
evidence.timestamp = event.block.timestamp;
1619
evidence.evidence = event.params._evidence;
1720
evidence.evidenceGroup = evidenceGroupID.toString();
1821
evidence.sender = userId;
1922
ensureUser(userId);
23+
24+
let jsonObjValueAndSuccess = json.try_fromString(event.params._evidence);
25+
if (!jsonObjValueAndSuccess.isOk || jsonObjValueAndSuccess.isError) {
26+
log.error(`Error getting json object for evidenceId {}`, [evidenceId]);
27+
evidence.save();
28+
return;
29+
}
30+
31+
if (jsonObjValueAndSuccess.value.isNull() || jsonObjValueAndSuccess.value.kind !== JSONValueKind.OBJECT) {
32+
log.error(`Encountered invalid parsed value for evidenceId {}`, [evidenceId]);
33+
evidence.save();
34+
return;
35+
}
36+
37+
let jsonObj = jsonObjValueAndSuccess.value.toObject();
38+
if (!jsonObj) {
39+
log.error(`Error converting json object for evidenceId {}`, [evidenceId]);
40+
evidence.save();
41+
return;
42+
}
43+
44+
let name = jsonObj.get("name");
45+
let description = jsonObj.get("description");
46+
let fileURI = jsonObj.get("fileURI");
47+
let fileTypeExtension = jsonObj.get("fileTypeExtension");
48+
49+
evidence.name = JSONValueToMaybeString(name);
50+
evidence.description = JSONValueToMaybeString(description);
51+
52+
if (fileURI) {
53+
evidence.fileURI = JSONValueToMaybeString(fileURI);
54+
}
55+
56+
if (fileTypeExtension) {
57+
evidence.fileTypeExtension = JSONValueToMaybeString(fileTypeExtension);
58+
}
59+
2060
evidence.save();
2161
}

subgraph/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@kleros/kleros-v2-subgraph",
3-
"version": "0.5.1",
3+
"version": "0.6.2",
44
"license": "MIT",
55
"scripts": {
66
"update:core:arbitrum-sepolia-devnet": "./scripts/update.sh arbitrumSepoliaDevnet arbitrum-sepolia core/subgraph.yaml",

subgraph/utils/index.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { JSONValue, JSONValueKind } from "@graphprotocol/graph-ts";
2+
3+
export function JSONValueToMaybeString(value: JSONValue | null, _default: string = "-"): string {
4+
// Subgraph considers an empty string to be null and
5+
// the handler crashes when attempting to save the entity.
6+
// This is a security vulnerability because an adversary
7+
// could manually craft an item with missing columns
8+
// and the item would not show up in the UI, passing
9+
// the challenge period unoticed.
10+
//
11+
// We fix this by setting the field manually to a hifen.
12+
if (value == null || value.isNull()) {
13+
return "-";
14+
}
15+
16+
switch (value.kind) {
17+
case JSONValueKind.BOOL:
18+
return value.toBool() == true ? "true" : "false";
19+
case JSONValueKind.STRING:
20+
return value.toString();
21+
case JSONValueKind.NUMBER:
22+
return value.toBigInt().toHexString();
23+
default:
24+
return _default;
25+
}
26+
}

0 commit comments

Comments
 (0)