-
Notifications
You must be signed in to change notification settings - Fork 51
feat: subgraph support for shutter disputekit in devnet #1966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
317aed6
05dcdb0
44ea55e
a995e1e
f3f235c
78b2951
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,7 +9,15 @@ import { | |||||||||||||||||||||||||||||||||||||||
| CommitCast, | ||||||||||||||||||||||||||||||||||||||||
| } from "../generated/DisputeKitClassic/DisputeKitClassic"; | ||||||||||||||||||||||||||||||||||||||||
| import { KlerosCore } from "../generated/KlerosCore/KlerosCore"; | ||||||||||||||||||||||||||||||||||||||||
| import { ClassicDispute, ClassicJustification, ClassicRound, ClassicVote, Dispute } from "../generated/schema"; | ||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||
| ClassicDispute, | ||||||||||||||||||||||||||||||||||||||||
| ClassicJustification, | ||||||||||||||||||||||||||||||||||||||||
| ClassicRound, | ||||||||||||||||||||||||||||||||||||||||
| ClassicVote, | ||||||||||||||||||||||||||||||||||||||||
| Dispute, | ||||||||||||||||||||||||||||||||||||||||
| DisputeKit, | ||||||||||||||||||||||||||||||||||||||||
| Round, | ||||||||||||||||||||||||||||||||||||||||
| } from "../generated/schema"; | ||||||||||||||||||||||||||||||||||||||||
| import { ensureClassicContributionFromEvent } from "./entities/ClassicContribution"; | ||||||||||||||||||||||||||||||||||||||||
| import { createClassicDisputeFromEvent } from "./entities/ClassicDispute"; | ||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -19,23 +27,31 @@ import { | |||||||||||||||||||||||||||||||||||||||
| updateCountsAndGetCurrentRuling, | ||||||||||||||||||||||||||||||||||||||||
| } from "./entities/ClassicRound"; | ||||||||||||||||||||||||||||||||||||||||
| import { ensureClassicVote } from "./entities/ClassicVote"; | ||||||||||||||||||||||||||||||||||||||||
| import { ONE, ZERO } from "./utils"; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| export const DISPUTEKIT_ID = "1"; | ||||||||||||||||||||||||||||||||||||||||
| import { ONE, ZERO, extractDisputeKitIDFromExtraData } from "./utils"; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| export function handleDisputeCreation(event: DisputeCreation): void { | ||||||||||||||||||||||||||||||||||||||||
| const disputeID = event.params._coreDisputeID.toString(); | ||||||||||||||||||||||||||||||||||||||||
| createClassicDisputeFromEvent(event); | ||||||||||||||||||||||||||||||||||||||||
| const disputeKitID = extractDisputeKitIDFromExtraData(event.params._extraData); | ||||||||||||||||||||||||||||||||||||||||
| createClassicDisputeFromEvent(event, disputeKitID); | ||||||||||||||||||||||||||||||||||||||||
| const numberOfChoices = event.params._numberOfChoices; | ||||||||||||||||||||||||||||||||||||||||
| createClassicRound(disputeID, numberOfChoices, ZERO); | ||||||||||||||||||||||||||||||||||||||||
| createClassicRound(disputeID, numberOfChoices, ZERO, disputeKitID); | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| export function handleCommitCast(event: CommitCast): void { | ||||||||||||||||||||||||||||||||||||||||
| const coreDisputeID = event.params._coreDisputeID; | ||||||||||||||||||||||||||||||||||||||||
| const coreDispute = Dispute.load(coreDisputeID.toString()); | ||||||||||||||||||||||||||||||||||||||||
| const classicDisputeID = `${DISPUTEKIT_ID}-${coreDisputeID}`; | ||||||||||||||||||||||||||||||||||||||||
| const coreDisputeID = event.params._coreDisputeID.toString(); | ||||||||||||||||||||||||||||||||||||||||
| const coreDispute = Dispute.load(coreDisputeID); | ||||||||||||||||||||||||||||||||||||||||
| if (!coreDispute) return; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const coreCurrentRound = Round.load(coreDispute.currentRound); | ||||||||||||||||||||||||||||||||||||||||
| if (!coreCurrentRound) return; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const disputeKitID = coreCurrentRound.disputeKit; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const classicDisputeID = `${disputeKitID}-${coreDisputeID}`; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const classicDispute = ClassicDispute.load(classicDisputeID); | ||||||||||||||||||||||||||||||||||||||||
| if (!classicDispute || !coreDispute) return; | ||||||||||||||||||||||||||||||||||||||||
| if (!classicDispute) return; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const currentLocalRoundID = classicDispute.id + "-" + classicDispute.currentLocalRoundIndex.toString(); | ||||||||||||||||||||||||||||||||||||||||
| const voteIDs = event.params._voteIDs; | ||||||||||||||||||||||||||||||||||||||||
| for (let i = 0; i < voteIDs.length; i++) { | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -55,9 +71,18 @@ export function handleVoteCast(event: VoteCast): void { | |||||||||||||||||||||||||||||||||||||||
| const juror = event.params._juror.toHexString(); | ||||||||||||||||||||||||||||||||||||||||
| const coreDisputeID = event.params._coreDisputeID.toString(); | ||||||||||||||||||||||||||||||||||||||||
| const coreDispute = Dispute.load(coreDisputeID); | ||||||||||||||||||||||||||||||||||||||||
| const classicDisputeID = `${DISPUTEKIT_ID}-${coreDisputeID}`; | ||||||||||||||||||||||||||||||||||||||||
| if (!coreDispute) return; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const coreCurrentRound = Round.load(coreDispute.currentRound); | ||||||||||||||||||||||||||||||||||||||||
| if (!coreCurrentRound) return; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const disputeKitID = coreCurrentRound.disputeKit; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const classicDisputeID = `${disputeKitID}-${coreDisputeID}`; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const classicDispute = ClassicDispute.load(classicDisputeID); | ||||||||||||||||||||||||||||||||||||||||
| if (!classicDispute || !coreDispute) return; | ||||||||||||||||||||||||||||||||||||||||
| if (!classicDispute) return; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const choice = event.params._choice; | ||||||||||||||||||||||||||||||||||||||||
| const currentLocalRoundID = classicDispute.id + "-" + classicDispute.currentLocalRoundIndex.toString(); | ||||||||||||||||||||||||||||||||||||||||
| const voteIDs = event.params._voteIDs; | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -70,6 +95,7 @@ export function handleVoteCast(event: VoteCast): void { | |||||||||||||||||||||||||||||||||||||||
| justification.transactionHash = event.transaction.hash.toHexString(); | ||||||||||||||||||||||||||||||||||||||||
| justification.timestamp = event.block.timestamp; | ||||||||||||||||||||||||||||||||||||||||
| justification.save(); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const currentRulingInfo = updateCountsAndGetCurrentRuling( | ||||||||||||||||||||||||||||||||||||||||
| currentLocalRoundID, | ||||||||||||||||||||||||||||||||||||||||
| choice, | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -78,6 +104,7 @@ export function handleVoteCast(event: VoteCast): void { | |||||||||||||||||||||||||||||||||||||||
| coreDispute.currentRuling = currentRulingInfo.ruling; | ||||||||||||||||||||||||||||||||||||||||
| coreDispute.tied = currentRulingInfo.tied; | ||||||||||||||||||||||||||||||||||||||||
| coreDispute.save(); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| let classicVote: ClassicVote; | ||||||||||||||||||||||||||||||||||||||||
| for (let i = 0; i < voteIDs.length; i++) { | ||||||||||||||||||||||||||||||||||||||||
| classicVote = ensureClassicVote(currentLocalRoundID, juror, voteIDs[i], coreDispute); | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -97,7 +124,16 @@ export function handleChoiceFunded(event: ChoiceFunded): void { | |||||||||||||||||||||||||||||||||||||||
| const coreDisputeID = event.params._coreDisputeID.toString(); | ||||||||||||||||||||||||||||||||||||||||
| const coreRoundIndex = event.params._coreRoundID.toString(); | ||||||||||||||||||||||||||||||||||||||||
| const choice = event.params._choice; | ||||||||||||||||||||||||||||||||||||||||
| const roundID = `${DISPUTEKIT_ID}-${coreDisputeID}-${coreRoundIndex}`; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const coreDispute = Dispute.load(coreDisputeID); | ||||||||||||||||||||||||||||||||||||||||
| if (!coreDispute) return; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const roundId = `${coreDisputeID}-${coreRoundIndex}`; | ||||||||||||||||||||||||||||||||||||||||
| const coreRound = Round.load(roundId); | ||||||||||||||||||||||||||||||||||||||||
| if (!coreRound) return; | ||||||||||||||||||||||||||||||||||||||||
| const disputeKitID = coreRound.disputeKit; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const localRound = ClassicRound.load(roundID); | ||||||||||||||||||||||||||||||||||||||||
| if (!localRound) return; | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -123,13 +159,13 @@ export function handleChoiceFunded(event: ChoiceFunded): void { | |||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| localRound.feeRewards = localRound.feeRewards.minus(appealCost); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const localDispute = ClassicDispute.load(`${DISPUTEKIT_ID}-${coreDisputeID}`); | ||||||||||||||||||||||||||||||||||||||||
| const localDispute = ClassicDispute.load(`${disputeKitID}-${coreDisputeID}`); | ||||||||||||||||||||||||||||||||||||||||
| if (!localDispute) return; | ||||||||||||||||||||||||||||||||||||||||
| const newRoundIndex = localDispute.currentLocalRoundIndex.plus(ONE); | ||||||||||||||||||||||||||||||||||||||||
| const numberOfChoices = localDispute.numberOfChoices; | ||||||||||||||||||||||||||||||||||||||||
| localDispute.currentLocalRoundIndex = newRoundIndex; | ||||||||||||||||||||||||||||||||||||||||
| localDispute.save(); | ||||||||||||||||||||||||||||||||||||||||
| createClassicRound(coreDisputeID, numberOfChoices, newRoundIndex); | ||||||||||||||||||||||||||||||||||||||||
| createClassicRound(coreDisputeID, numberOfChoices, newRoundIndex, disputeKitID); | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| localRound.save(); | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -144,7 +180,16 @@ export function handleWithdrawal(event: Withdrawal): void { | |||||||||||||||||||||||||||||||||||||||
| // check if all appeal fees have been withdrawn | ||||||||||||||||||||||||||||||||||||||||
| const coreDisputeID = event.params._coreDisputeID.toString(); | ||||||||||||||||||||||||||||||||||||||||
| const coreRoundIndex = event.params._coreRoundID.toString(); | ||||||||||||||||||||||||||||||||||||||||
| const roundID = `${DISPUTEKIT_ID}-${coreDisputeID}-${coreRoundIndex}`; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const coreDispute = Dispute.load(coreDisputeID); | ||||||||||||||||||||||||||||||||||||||||
| if (!coreDispute) return; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const roundId = `${coreDisputeID}-${coreRoundIndex}`; | ||||||||||||||||||||||||||||||||||||||||
| const coreRound = Round.load(roundId); | ||||||||||||||||||||||||||||||||||||||||
| if (!coreRound) return; | ||||||||||||||||||||||||||||||||||||||||
| const disputeKitID = coreRound.disputeKit; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+186
to
+194
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Defensive check for Replicating the guard here avoids malformed IDs during withdrawals. const disputeKitID = coreRound.disputeKit;
-
+ if (!disputeKitID) return;📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+186
to
195
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Missing defensive check in
|
||||||||||||||||||||||||||||||||||||||||
| const localRound = ClassicRound.load(roundID); | ||||||||||||||||||||||||||||||||||||||||
| if (!localRound) return; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,13 +1,23 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { ClassicContribution } from "../../generated/schema"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { ClassicContribution, Dispute, DisputeKit, Round } from "../../generated/schema"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Contribution as ContributionEvent, Withdrawal } from "../../generated/DisputeKitClassic/DisputeKitClassic"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { DISPUTEKIT_ID } from "../DisputeKitClassic"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { ensureUser } from "./User"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| export function ensureClassicContributionFromEvent<T>(event: T): ClassicContribution | null { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!(event instanceof ContributionEvent) && !(event instanceof Withdrawal)) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const coreDisputeID = event.params._coreDisputeID.toString(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const coreRoundIndex = event.params._coreRoundID.toString(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const roundID = `${DISPUTEKIT_ID}-${coreDisputeID}-${coreRoundIndex}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const coreDispute = Dispute.load(coreDisputeID); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!coreDispute) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const roundId = `${coreDisputeID}-${coreRoundIndex}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const coreRound = Round.load(roundId); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!coreRound) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const disputeKitID = coreRound.disputeKit; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+20
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainGuard against a missing
- const disputeKitID = coreRound.disputeKit;
+ const disputeKitID = coreRound.disputeKit;
+ if (!disputeKitID) {
+ // Inconsistent data – abort processing to avoid polluting the store
+ return null;
+ }Fail-fast avoids persisting wrongly-keyed entities and makes the issue visible during indexing. 🏁 Script executed: #!/bin/bash
echo "=== GraphQL schema files ==="
find . -type f -name "*.graphql"
echo ""
echo "=== 'type Round' and 'disputeKit' in GraphQL schemas ==="
rg -n "type Round" -C2 -g "*.graphql" || true
rg -n "disputeKit" -C2 -g "*.graphql" || true
echo ""
echo "=== Locate and inspect Round entity class ==="
round_files=$(rg -l "export class Round" -g "*.ts")
echo "Found Round.ts files:"
echo "$round_files"
for file in $round_files; do
echo ""
echo "------ $file ------"
rg -n "export class Round" -C3 "$file"
rg -n "get disputeKit" -C5 "$file" || true
doneLength of output: 3678 Guard against a missing The GraphQL schema defines • File: - const disputeKitID = coreRound.disputeKit;
+ const disputeKitID = coreRound.disputeKit;
+ if (!disputeKitID) {
+ // Inconsistent data – abort processing to avoid polluting the store
+ return null;
+ }This fail-fast guard ensures any missing 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ensureUser(event.params._contributor.toHexString()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const contributor = event.params._contributor.toHexString(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const choice = event.params._choice; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,10 @@ | ||
| import { BigInt } from "@graphprotocol/graph-ts"; | ||
| import { BigInt, Bytes } from "@graphprotocol/graph-ts"; | ||
|
|
||
| export const ZERO = BigInt.fromI32(0); | ||
| export const ONE = BigInt.fromI32(1); | ||
|
|
||
| export function extractDisputeKitIDFromExtraData(extraData: Bytes): string { | ||
| const start = extraData.length - 32; | ||
| const littleEndian = extraData.subarray(start, extraData.length).reverse(); | ||
| return BigInt.fromUnsignedBytes(Bytes.fromUint8Array(littleEndian)).toString(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Early exit when
disputeKitIDmissingSame defensive check as earlier – without it,
roundIDmay start with"null-".📝 Committable suggestion