Skip to content

Commit 2321845

Browse files
feat(subgraph): notification schema
1 parent 6d2a0bd commit 2321845

File tree

8 files changed

+114
-10
lines changed

8 files changed

+114
-10
lines changed

subgraph/schema.graphql

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ type User @entity {
6666
shifts: [TokenAndETHShift!]! @derivedFrom(field: "juror")
6767
draws: [Draw!]! @derivedFrom(field: "juror")
6868
activeDisputes: BigInt!
69+
rounds: [Round!]!
6970
disputes: [Dispute!]!
7071
resolvedDisputes: [Dispute!]!
7172
totalResolvedDisputes: BigInt!
@@ -118,6 +119,9 @@ type Court @entity {
118119
id: ID!
119120
policy: String
120121
name: String
122+
description: String
123+
summary: String
124+
requiredSkills: String
121125
parent: Court
122126
hiddenVotes: Boolean!
123127
children: [Court!]! @derivedFrom(field: "parent")
@@ -142,16 +146,20 @@ type Court @entity {
142146

143147
type Dispute @entity {
144148
id: ID!
149+
disputeID: BigInt!
145150
court: Court!
146151
arbitrated: Arbitrable!
147152
period: Period!
148153
ruled: Boolean!
149154
currentRuling: BigInt!
150155
tied: Boolean!
151156
overridden: Boolean!
152-
lastPeriodChange: BigInt!
157+
periodDeadline: BigInt! # uint256j
158+
periodNotificationIndex: BigInt!
159+
lastPeriodChangeTs: BigInt!
160+
users: [User!]!
161+
lastPeriodChangeBlock: BigInt!
153162
lastPeriodChangeBlockNumber: BigInt!
154-
periodDeadline: BigInt!
155163
rounds: [Round!]! @derivedFrom(field: "dispute")
156164
currentRound: Round!
157165
currentRoundIndex: BigInt!
@@ -160,12 +168,18 @@ type Dispute @entity {
160168
disputeKitDispute: DisputeKitDispute @derivedFrom(field: "coreDispute")
161169
}
162170

171+
type PeriodIndexCounter @entity {
172+
id: String!
173+
counter: BigInt!
174+
}
175+
163176
type Round @entity {
164177
id: ID! # dispute.id-dispute.rounds.length
165178
disputeKit: DisputeKit!
166179
tokensAtStakePerJuror: BigInt!
167180
totalFeesForJurors: BigInt!
168181
nbVotes: BigInt!
182+
isCurrentRound: Boolean!
169183
repartitions: BigInt!
170184
penalties: BigInt!
171185
drawnJurors: [Draw!]! @derivedFrom(field: "round")
@@ -181,6 +195,7 @@ type Draw @entity(immutable: true) {
181195
juror: User!
182196
voteID: BigInt!
183197
vote: Vote @derivedFrom(field: "draw")
198+
drawNotificationIndex: BigInt
184199
}
185200

186201
type DisputeKit @entity {

subgraph/src/KlerosCore.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorToken
2525
import { createDrawFromEvent } from "./entities/Draw";
2626
import { updateTokenAndEthShiftFromEvent } from "./entities/TokenAndEthShift";
2727
import { updateArbitrableCases } from "./entities/Arbitrable";
28-
import { Court, Dispute, User } from "../generated/schema";
28+
import { Court, Dispute, User, PeriodIndexCounter } from "../generated/schema";
2929
import { BigInt } from "@graphprotocol/graph-ts";
3030
import { updatePenalty } from "./entities/Penalty";
3131
import { ensureFeeToken } from "./entities/FeeToken";
@@ -126,7 +126,19 @@ export function handleNewPeriod(event: NewPeriod): void {
126126
}
127127

128128
dispute.period = newPeriod;
129-
dispute.lastPeriodChange = event.block.timestamp;
129+
dispute.lastPeriodChangeTs = event.block.timestamp;
130+
dispute.lastPeriodChangeBlock = event.block.number;
131+
let counter = PeriodIndexCounter.load(newPeriod);
132+
if (!counter) {
133+
counter = new PeriodIndexCounter(newPeriod);
134+
counter.counter = BigInt.fromI32(0);
135+
}
136+
dispute.periodNotificationIndex = counter.counter;
137+
const contract = KlerosCore.bind(event.address);
138+
const courtContractState = contract.getTimesPerPeriod(BigInt.fromString(dispute.court));
139+
dispute.periodDeadline = event.block.timestamp.plus(courtContractState[event.params._period]);
140+
counter.counter = counter.counter.plus(ONE);
141+
counter.save();
130142
dispute.lastPeriodChangeBlockNumber = event.block.number;
131143
if (newPeriod !== "execution") {
132144
dispute.periodDeadline = event.block.timestamp.plus(court.timesPerPeriod[event.params._period]);

subgraph/src/PolicyRegistry.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,49 @@
11
import { PolicyUpdate } from "../generated/PolicyRegistry/PolicyRegistry";
22
import { Court } from "../generated/schema";
3+
import { ipfs, log, json, Bytes } from "@graphprotocol/graph-ts";
34

45
export function handlePolicyUpdate(event: PolicyUpdate): void {
56
const courtID = event.params._courtID.toString();
67
const court = Court.load(courtID);
78
if (court) {
89
court.policy = event.params._policy;
910
court.name = event.params._courtName;
11+
12+
let jsonStr = ipfs.cat(event.params._policy);
13+
if (!jsonStr) {
14+
log.error("Failed to fetch policy #{} SubcourtID: {}", [event.params._policy, event.params._courtID.toString()]);
15+
court.save();
16+
return;
17+
}
18+
19+
let jsonObjValueAndSuccess = json.try_fromBytes(jsonStr as Bytes);
20+
if (!jsonObjValueAndSuccess.isOk) {
21+
log.error(`Error getting json object value for policy #{} SubcourtID: {}`, [
22+
event.params._policy,
23+
event.params._courtID.toString(),
24+
]);
25+
court.save();
26+
return;
27+
}
28+
29+
let jsonObj = jsonObjValueAndSuccess.value.toObject();
30+
if (!jsonObj) {
31+
log.error(`Error converting object value for policy #{} SubcourtID: {}`, [
32+
event.params._policy,
33+
event.params._courtID.toString(),
34+
]);
35+
court.save();
36+
return;
37+
}
38+
39+
const name = jsonObj.get("name");
40+
court.name = name ? name.toString() : null;
41+
42+
const description = jsonObj.get("description");
43+
court.description = description ? description.toString() : null;
44+
45+
const requiredSkills = jsonObj.get("requiredSkills");
46+
court.requiredSkills = requiredSkills ? requiredSkills.toString() : null;
1047
court.save();
1148
}
1249
}

subgraph/src/entities/Dispute.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { KlerosCore, DisputeCreation } from "../../generated/KlerosCore/KlerosCore";
2-
import { Court, Dispute } from "../../generated/schema";
3-
import { ZERO } from "../utils";
2+
import { Court, Dispute, PeriodIndexCounter } from "../../generated/schema";
3+
import { ZERO, ONE } from "../utils";
4+
import { BigInt } from "@graphprotocol/graph-ts";
45

56
export function createDisputeFromEvent(event: DisputeCreation): void {
67
const contract = KlerosCore.bind(event.address);
@@ -9,14 +10,25 @@ export function createDisputeFromEvent(event: DisputeCreation): void {
910
const dispute = new Dispute(disputeID.toString());
1011
const courtID = disputeContractState.value0.toString();
1112
dispute.court = courtID;
13+
dispute.disputeID = disputeID;
1214
dispute.arbitrated = event.params._arbitrable.toHexString();
1315
dispute.period = "evidence";
1416
dispute.ruled = false;
1517
dispute.currentRuling = ZERO;
1618
dispute.tied = true;
1719
dispute.overridden = false;
18-
dispute.lastPeriodChange = event.block.timestamp;
20+
dispute.users = [];
21+
dispute.lastPeriodChangeTs = event.block.timestamp;
22+
dispute.lastPeriodChangeBlock = event.block.timestamp;
1923
dispute.lastPeriodChangeBlockNumber = event.block.number;
24+
let counter = PeriodIndexCounter.load("evidence");
25+
if (!counter) {
26+
counter = new PeriodIndexCounter("evidence");
27+
counter.counter = BigInt.fromI32(0);
28+
}
29+
dispute.periodNotificationIndex = counter.counter;
30+
counter.counter = counter.counter.plus(ONE);
31+
counter.save();
2032
const court = Court.load(courtID);
2133
if (!court) return;
2234
dispute.periodDeadline = event.block.timestamp.plus(court.timesPerPeriod[0]);

subgraph/src/entities/Draw.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Draw as DrawEvent } from "../../generated/KlerosCore/KlerosCore";
2-
import { Draw } from "../../generated/schema";
2+
import { Draw, PeriodIndexCounter, User } from "../../generated/schema";
3+
import { BigInt } from "@graphprotocol/graph-ts";
34

45
export function createDrawFromEvent(event: DrawEvent): void {
56
const disputeID = event.params._disputeID.toString();
@@ -9,6 +10,20 @@ export function createDrawFromEvent(event: DrawEvent): void {
910
const drawID = `${disputeID}-${roundIndex.toString()}-${voteID.toString()}`;
1011
const draw = new Draw(drawID);
1112
draw.blockNumber = event.block.number;
13+
let counter = PeriodIndexCounter.load("draw");
14+
if (!counter) {
15+
counter = new PeriodIndexCounter("draw");
16+
counter.counter = BigInt.fromI32(0);
17+
}
18+
const user = User.load(event.params._address.toHexString());
19+
if (user) {
20+
const duplicateNotification = user.disputes.includes(disputeID);
21+
if (!duplicateNotification) {
22+
draw.drawNotificationIndex = counter.counter;
23+
counter.counter = counter.counter.plus(BigInt.fromI32(1));
24+
counter.save();
25+
}
26+
}
1227
draw.dispute = disputeID;
1328
draw.round = roundID;
1429
draw.juror = event.params._address.toHexString();

subgraph/src/entities/Round.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export function createRoundFromRoundInfo(
99
): void {
1010
const roundID = `${disputeID.toString()}-${roundIndex.toString()}`;
1111
const round = new Round(roundID);
12+
round.isCurrentRound = true;
1213
const feeToken = roundInfo.feeToken.toHexString();
1314
round.feeToken = feeToken === "0x0000000000000000000000000000000000000000" ? null : feeToken;
1415
round.disputeKit = roundInfo.disputeKitID.toString();

subgraph/src/entities/User.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { BigInt } from "@graphprotocol/graph-ts";
2-
import { User } from "../../generated/schema";
1+
import { BigInt, log } from "@graphprotocol/graph-ts";
2+
import { User, Dispute } from "../../generated/schema";
33
import { ONE, ZERO } from "../utils";
44

55
export function ensureUser(id: string): User {
@@ -18,6 +18,7 @@ export function createUserFromAddress(id: string): User {
1818
user.totalDelayed = ZERO;
1919
user.activeDisputes = ZERO;
2020
user.disputes = [];
21+
user.rounds = [];
2122
user.resolvedDisputes = [];
2223
user.totalResolvedDisputes = ZERO;
2324
user.totalAppealingDisputes = ZERO;
@@ -34,6 +35,15 @@ export function addUserActiveDispute(id: string, disputeID: string): void {
3435
return;
3536
}
3637
user.disputes = user.disputes.concat([disputeID]);
38+
const dispute = Dispute.load(disputeID);
39+
if (!dispute) {
40+
log.error("Dispute {} not found", [disputeID]);
41+
return;
42+
} else {
43+
dispute.users.push(id);
44+
dispute.save();
45+
}
46+
3747
user.activeDisputes = user.activeDisputes.plus(ONE);
3848
user.totalDisputes = user.totalDisputes.plus(ONE);
3949
user.save();

subgraph/subgraph.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
specVersion: 0.0.4
22
schema:
33
file: ./schema.graphql
4+
features:
5+
- ipfsOnEthereumContracts
46
dataSources:
57
- kind: ethereum
68
name: KlerosCore

0 commit comments

Comments
 (0)