From 316f1f85b143807b4a49c8310b4209e6818dd2df Mon Sep 17 00:00:00 2001 From: alcercu Date: Tue, 17 Jan 2023 16:35:17 +0100 Subject: [PATCH 1/8] feat(subgraph): use numberOfChoices to model the length of arrays --- subgraph/src/DisputeKitClassic.ts | 6 ++++-- subgraph/src/entities/ClassicRound.ts | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/subgraph/src/DisputeKitClassic.ts b/subgraph/src/DisputeKitClassic.ts index 96e019f5d..f89448935 100644 --- a/subgraph/src/DisputeKitClassic.ts +++ b/subgraph/src/DisputeKitClassic.ts @@ -29,7 +29,8 @@ export const DISPUTEKIT_ID = "1"; export function handleDisputeCreation(event: DisputeCreation): void { const disputeID = event.params._coreDisputeID.toString(); createClassicDisputeFromEvent(event); - createClassicRound(disputeID, ZERO); + const numberOfChoices = event.params._numberOfChoices; + createClassicRound(disputeID, numberOfChoices, ZERO); } export function handleEvidenceEvent(event: EvidenceEvent): void { @@ -88,7 +89,8 @@ export function handleChoiceFunded(event: ChoiceFunded): void { ); if (!localDispute) return; const newRoundIndex = localDispute.currentLocalRoundIndex.plus(ONE); - createClassicRound(coreDisputeID, newRoundIndex); + const numberOfChoices = localDispute.numberOfChoices; + createClassicRound(coreDisputeID, numberOfChoices, newRoundIndex); } localRound.save(); diff --git a/subgraph/src/entities/ClassicRound.ts b/subgraph/src/entities/ClassicRound.ts index 9bfbbbd98..ecda3be72 100644 --- a/subgraph/src/entities/ClassicRound.ts +++ b/subgraph/src/entities/ClassicRound.ts @@ -1,23 +1,25 @@ import { BigInt } from "@graphprotocol/graph-ts"; import { Contribution } from "../../generated/DisputeKitClassic/DisputeKitClassic"; import { ClassicRound } from "../../generated/schema"; -import { ZERO } from "../utils"; +import { ONE, ZERO } from "../utils"; export function createClassicRound( disputeID: string, + numberOfChoices: BigInt, roundIndex: BigInt ): void { + const choicesLength = numberOfChoices.plus(ONE); const localDisputeID = `1-${disputeID}`; const id = `${localDisputeID}-${roundIndex.toString()}`; const classicRound = new ClassicRound(id); classicRound.localDispute = localDisputeID; classicRound.votes = []; classicRound.winningChoice = ZERO; - classicRound.counts = []; + classicRound.counts = new Array(choicesLength.toI32()).fill(ZERO); classicRound.tied = true; classicRound.totalVoted = ZERO; classicRound.totalCommited = ZERO; - classicRound.paidFees = []; + classicRound.paidFees = new Array(choicesLength.toI32()).fill(ZERO); classicRound.feeRewards = ZERO; classicRound.fundedChoices = []; classicRound.save(); From 47bb6588d418c64bf5137232d20b6fc163e88a53 Mon Sep 17 00:00:00 2001 From: alcercu Date: Tue, 17 Jan 2023 16:49:34 +0100 Subject: [PATCH 2/8] chore(subgraph): update subgraph.yaml and clean schema --- subgraph/schema.graphql | 16 ---------------- subgraph/subgraph.yaml | 25 +++++++++++++------------ 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index b6d89b846..2cad533d4 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -156,22 +156,6 @@ type DisputeKit @entity { courts: [Court!]! @derivedFrom(field: "supportedDisputeKits") } -type GatewayDispute @entity { - id: ID! - homeDispute: Dispute! - arbitrator: Bytes! - disputeHash: Bytes! - arbitrationCost: BigInt! - relayer: Bytes! -} - -type OutgoingBatch @entity { - id: ID! # messageHash - size: BigInt! - epoch: BigInt! - batchMerkleRoot: String! -} - type Counter @entity { id: ID! # Will be the timestamp except for the counter which will be 0 stakedPNK: BigInt! diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index ac9752492..064578689 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -14,19 +14,16 @@ dataSources: apiVersion: 0.0.6 language: wasm/assemblyscript entities: - - Court - - Juror + - User + - Arbitrable - TokenAndETHShift - JurorTokensPerCourt + - Court + - Dispute - Round - Draw - - Dispute - DisputeKit - - PNKStakedDataPoint - - ETHPaidDataPoint - - PNKRedistributedDataPoint - - ActiveJurorsDataPoint - - CasesDataPoint + - Counter abis: - name: KlerosCore file: ../contracts/deployments/arbitrumGoerli/KlerosCore.json @@ -84,8 +81,12 @@ dataSources: apiVersion: 0.0.6 language: wasm/assemblyscript entities: - - EvidenceGroup - - Evidence + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicEvidenceGroup + - ClassicEvidence + - ClassicContribution abis: - name: DisputeKitClassic file: ../contracts/deployments/arbitrumGoerli/DisputeKitClassic.json @@ -94,8 +95,8 @@ dataSources: handler: handleDisputeCreation - event: Contribution(indexed uint256,indexed uint256,uint256,indexed address,uint256) handler: handleContributionEvent - # - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) - # handler: handleWithdrawal + - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleWithdrawal - event: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) handler: handleChoiceFunded - event: Evidence(indexed address,indexed uint256,indexed address,string) From beedffaaa324e0008382d548a04aeb6e0b35556d Mon Sep 17 00:00:00 2001 From: alcercu Date: Mon, 23 Jan 2023 11:41:09 +0100 Subject: [PATCH 3/8] fix(subgraph): set non-nullable field totalStake when creating user --- subgraph/src/KlerosCore.ts | 2 +- subgraph/src/entities/JurorTokensPerCourt.ts | 2 +- subgraph/src/entities/{Juror.ts => User.ts} | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) rename subgraph/src/entities/{Juror.ts => User.ts} (84%) diff --git a/subgraph/src/KlerosCore.ts b/subgraph/src/KlerosCore.ts index 7a1f8244a..241c48726 100644 --- a/subgraph/src/KlerosCore.ts +++ b/subgraph/src/KlerosCore.ts @@ -26,7 +26,7 @@ import { updateRedistributedPNK, getDelta, } from "./datapoint"; -import { ensureUser } from "./entities/Juror"; +import { ensureUser } from "./entities/User"; import { ensureJurorTokensPerCourt, updateJurorStake, diff --git a/subgraph/src/entities/JurorTokensPerCourt.ts b/subgraph/src/entities/JurorTokensPerCourt.ts index be4d755ee..d4012d668 100644 --- a/subgraph/src/entities/JurorTokensPerCourt.ts +++ b/subgraph/src/entities/JurorTokensPerCourt.ts @@ -2,7 +2,7 @@ import { BigInt, Address } from "@graphprotocol/graph-ts"; import { KlerosCore } from "../../generated/KlerosCore/KlerosCore"; import { Court, JurorTokensPerCourt } from "../../generated/schema"; import { updateActiveJurors, getDelta } from "../datapoint"; -import { ensureUser } from "./Juror"; +import { ensureUser } from "./User"; import { ZERO } from "../utils"; export function ensureJurorTokensPerCourt( diff --git a/subgraph/src/entities/Juror.ts b/subgraph/src/entities/User.ts similarity index 84% rename from subgraph/src/entities/Juror.ts rename to subgraph/src/entities/User.ts index 8db9d3790..83a890c1c 100644 --- a/subgraph/src/entities/Juror.ts +++ b/subgraph/src/entities/User.ts @@ -1,4 +1,5 @@ import { User } from "../../generated/schema"; +import { ZERO } from "../utils"; export function ensureUser(id: string): User { let user = User.load(id); @@ -12,6 +13,7 @@ export function ensureUser(id: string): User { export function createUserFromAddress(id: string): User { const user = new User(id); + user.totalStake = ZERO; user.save(); return user; From e1a6d1d795e596c452683c08470f2eaaf478a6d4 Mon Sep 17 00:00:00 2001 From: alcercu Date: Mon, 23 Jan 2023 12:17:53 +0100 Subject: [PATCH 4/8] fix(subgraph): improve datapoint updates --- subgraph/src/datapoint.ts | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/subgraph/src/datapoint.ts b/subgraph/src/datapoint.ts index e08d8a357..a6e33b1a7 100644 --- a/subgraph/src/datapoint.ts +++ b/subgraph/src/datapoint.ts @@ -20,19 +20,28 @@ function updateDataPoint( timestamp: BigInt, variable: string ): void { - let counter = store.get("Counter", "0"); - if (!counter) { - counter = new Entity(); - for (let i = 0; i < VARIABLES.length; i++) { - counter.set(VARIABLES[i], Value.fromBigInt(ZERO)); + const newCounter = new Entity(); + const counter = store.get("Counter", "0"); + for (let i = 0; i < VARIABLES.length; i++) { + const targetVar = VARIABLES[i]; + if (targetVar === variable) { + newCounter.set( + targetVar, + !counter + ? Value.fromBigInt(delta) + : Value.fromBigInt(counter.get(targetVar)!.toBigInt().plus(delta)) + ); + } else { + newCounter.set( + targetVar, + !counter ? Value.fromBigInt(ZERO) : counter.get(VARIABLES[i])! + ); } } const dayID = timestamp.toI32() / 86400; const dayStartTimestamp = dayID * 86400; - const newValue = counter.get(variable)!.toBigInt().plus(delta); - counter.set(variable, Value.fromBigInt(newValue)); - store.set("Counter", dayStartTimestamp.toString(), counter); - store.set("Counter", "0", counter); + store.set("Counter", dayStartTimestamp.toString(), newCounter); + store.set("Counter", "0", newCounter); } export function updateStakedPNK(delta: BigInt, timestamp: BigInt): void { From 146d46b6c09bd3645515ca808d19619ba8c437f3 Mon Sep 17 00:00:00 2001 From: alcercu Date: Mon, 23 Jan 2023 16:28:38 +0100 Subject: [PATCH 5/8] fix(subgraph): bad argument order --- subgraph/src/entities/JurorTokensPerCourt.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subgraph/src/entities/JurorTokensPerCourt.ts b/subgraph/src/entities/JurorTokensPerCourt.ts index d4012d668..f119a63f0 100644 --- a/subgraph/src/entities/JurorTokensPerCourt.ts +++ b/subgraph/src/entities/JurorTokensPerCourt.ts @@ -61,7 +61,7 @@ export function updateJurorStake( jurorTokens.staked = jurorBalance.value0; jurorTokens.locked = jurorBalance.value1; jurorTokens.save(); - const stakeDelta = getDelta(jurorTokens.staked, previousStake); + const stakeDelta = getDelta(previousStake, jurorTokens.staked); juror.totalStake = juror.totalStake.plus(stakeDelta); court.stake = court.stake.plus(stakeDelta); let activeJurorsDelta: BigInt; From d3f1cbbccfc10b74cefe0dc50a8e970949965acd Mon Sep 17 00:00:00 2001 From: alcercu Date: Mon, 23 Jan 2023 16:51:40 +0100 Subject: [PATCH 6/8] refactor(subgraph): fix code smells --- subgraph/src/datapoint.ts | 34 ++++++++++++++++++++-------------- subgraph/src/entities/User.ts | 2 +- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/subgraph/src/datapoint.ts b/subgraph/src/datapoint.ts index a6e33b1a7..63e8db1ee 100644 --- a/subgraph/src/datapoint.ts +++ b/subgraph/src/datapoint.ts @@ -23,20 +23,11 @@ function updateDataPoint( const newCounter = new Entity(); const counter = store.get("Counter", "0"); for (let i = 0; i < VARIABLES.length; i++) { - const targetVar = VARIABLES[i]; - if (targetVar === variable) { - newCounter.set( - targetVar, - !counter - ? Value.fromBigInt(delta) - : Value.fromBigInt(counter.get(targetVar)!.toBigInt().plus(delta)) - ); - } else { - newCounter.set( - targetVar, - !counter ? Value.fromBigInt(ZERO) : counter.get(VARIABLES[i])! - ); - } + const currentVar = VARIABLES[i]; + newCounter.set( + currentVar, + getNewValue(currentVar, variable, delta, counter) + ); } const dayID = timestamp.toI32() / 86400; const dayStartTimestamp = dayID * 86400; @@ -44,6 +35,21 @@ function updateDataPoint( store.set("Counter", "0", newCounter); } +function getNewValue( + currentVar: string, + targetVar: string, + delta: BigInt, + counter: Entity | null +): Value { + if (currentVar === targetVar) { + return !counter + ? Value.fromBigInt(delta) + : Value.fromBigInt(counter.get(currentVar)!.toBigInt().plus(delta)); + } else { + return !counter ? Value.fromBigInt(ZERO) : counter.get(currentVar)!; + } +} + export function updateStakedPNK(delta: BigInt, timestamp: BigInt): void { updateDataPoint(delta, timestamp, "stakedPNK"); } diff --git a/subgraph/src/entities/User.ts b/subgraph/src/entities/User.ts index 83a890c1c..6d49bb895 100644 --- a/subgraph/src/entities/User.ts +++ b/subgraph/src/entities/User.ts @@ -2,7 +2,7 @@ import { User } from "../../generated/schema"; import { ZERO } from "../utils"; export function ensureUser(id: string): User { - let user = User.load(id); + const user = User.load(id); if (user) { return user; From a29a2558c8deffb49a510722ed6741cb6962677f Mon Sep 17 00:00:00 2001 From: alcercu Date: Fri, 27 Jan 2023 13:08:41 +0100 Subject: [PATCH 7/8] fix(subgraph): wrong court PNK redistribution --- subgraph/src/KlerosCore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subgraph/src/KlerosCore.ts b/subgraph/src/KlerosCore.ts index 241c48726..437fa0314 100644 --- a/subgraph/src/KlerosCore.ts +++ b/subgraph/src/KlerosCore.ts @@ -169,6 +169,6 @@ export function handleTokenAndETHShift(event: TokenAndETHShiftEvent): void { event.block.timestamp ); court.paidETH = court.paidETH.plus(ethAmount); - court.paidPNK = court.paidETH.plus(tokenAmount); + court.paidPNK = court.paidPNK.plus(tokenAmount); court.save(); } From dd619325fb26936931a96a738b60aa557e16f0cb Mon Sep 17 00:00:00 2001 From: alcercu Date: Fri, 27 Jan 2023 13:09:18 +0100 Subject: [PATCH 8/8] fix(subgraph): correctly update counts and winningchoice --- subgraph/src/DisputeKitClassic.ts | 7 ++++--- subgraph/src/entities/ClassicRound.ts | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/subgraph/src/DisputeKitClassic.ts b/subgraph/src/DisputeKitClassic.ts index f89448935..7d3704bea 100644 --- a/subgraph/src/DisputeKitClassic.ts +++ b/subgraph/src/DisputeKitClassic.ts @@ -20,6 +20,7 @@ import { ensureClassicEvidenceGroup } from "./entities/ClassicEvidenceGroup"; import { createClassicRound, updateChoiceFundingFromContributionEvent, + updateCounts, } from "./entities/ClassicRound"; import { createClassicVote } from "./entities/ClassicVote"; import { ONE, ZERO } from "./utils"; @@ -53,9 +54,9 @@ export function handleJustificationEvent(event: JustificationEvent): void { const classicDisputeID = `${DISPUTEKIT_ID}-${coreDisputeID}`; const classicDispute = ClassicDispute.load(classicDisputeID); if (!classicDispute) return; - const currentLocalRoundID = `${ - classicDispute.id - }-${classicDispute.currentLocalRoundIndex.toString()}`; + const currentLocalRoundID = + classicDispute.id + "-" + classicDispute.currentLocalRoundIndex.toString(); + updateCounts(currentLocalRoundID, event.params._choice); createClassicVote(currentLocalRoundID, event); } diff --git a/subgraph/src/entities/ClassicRound.ts b/subgraph/src/entities/ClassicRound.ts index ecda3be72..afed8be9e 100644 --- a/subgraph/src/entities/ClassicRound.ts +++ b/subgraph/src/entities/ClassicRound.ts @@ -25,6 +25,26 @@ export function createClassicRound( classicRound.save(); } +export function updateCounts(id: string, choice: BigInt): void { + const round = ClassicRound.load(id); + if (!round) return; + const choiceNum = choice.toI32(); + const updatedCount = round.counts[choiceNum].plus(ONE); + round.counts[choiceNum] = updatedCount; + const currentWinningCount = round.counts[round.winningChoice.toI32()]; + if (choice.equals(round.winningChoice)) { + if (round.tied) round.tied = false; + } else { + if (updatedCount.equals(currentWinningCount)) { + if (!round.tied) round.tied = true; + } else if (updatedCount.gt(currentWinningCount)) { + round.winningChoice = choice; + round.tied = false; + } + } + round.save(); +} + export function updateChoiceFundingFromContributionEvent( event: Contribution ): void {