Skip to content
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

Feat(web): cases filtering #1169

Merged
merged 39 commits into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
410428c
chore(web): make skeleton style global
alcercu Aug 18, 2023
f0264ef
feat(web): modularize cases query and add My cases section to dashboard
alcercu Aug 18, 2023
47223eb
style(web): improve color for light mode skeleton
alcercu Aug 18, 2023
e574146
Merge branch 'dev' into feat(web)/cases-filtering
alcercu Aug 18, 2023
c04e8c7
fix: empty CasesGrid when user has never staked
jaybuidl Aug 22, 2023
465cd8a
feat: implement filtering and search logic
nhestrompia Aug 25, 2023
91351b6
fix(web): dashboard dont show my courts if no staked anymore
kemuru Aug 28, 2023
1bdd14a
chore(web): abstract variables
kemuru Aug 28, 2023
4bed1b3
refactor: clear naming for condition
nhestrompia Aug 28, 2023
a69b335
feat: add court selection filtering and subgraph update
nhestrompia Sep 11, 2023
40ec2ca
refactor: code smell and some refactor
nhestrompia Sep 11, 2023
041c945
fix: page number and query param
nhestrompia Sep 11, 2023
bfe027c
Merge branch 'dev' into feat(web)/cases-filtering
alcercu Sep 12, 2023
23c21d8
refactor(subgraph): avoid contract binding and add numberVotingCases
alcercu Sep 13, 2023
efe8852
feat(subgraph): add blocknumber fields
alcercu Sep 13, 2023
a3b16ed
fix(web): add mainnet to chains, but in second position so it's not t…
alcercu Sep 13, 2023
3045e6c
refactor: fetching at pages
nhestrompia Sep 14, 2023
6f2228d
refactor: query naming
nhestrompia Sep 14, 2023
28547bb
fix: context states resetting
nhestrompia Sep 15, 2023
5127f0f
refactor: clear naming and query params
nhestrompia Sep 15, 2023
a29a3d8
fix: stake amount
nhestrompia Sep 15, 2023
504d5d7
feat(subgraph): add totalAppealingDisputes for user entity
alcercu Sep 15, 2023
41f261d
fix: query update based on subgraph changes
nhestrompia Sep 15, 2023
7a3ea07
refactor(web): move totalAppealingDisputes to useUser query
alcercu Sep 15, 2023
d9ef8f5
fix: dashboard new user problem
nhestrompia Sep 18, 2023
56cb87a
feat(subgraph): add periodDeadline field to dispute entity
alcercu Sep 18, 2023
4ba1cb1
chore(web): use devnet subgraph
alcercu Sep 18, 2023
5740f02
fix: dashboard pagination
nhestrompia Sep 19, 2023
36608f3
feat(web): cases filtering state tracked with url
alcercu Oct 4, 2023
61c67b6
chore(web): remove unused context
alcercu Oct 4, 2023
1596088
Merge branch 'dev' into feat(web)/cases-filtering
alcercu Oct 4, 2023
6211b52
fix(web): finish merging dev
alcercu Oct 4, 2023
0574615
fix(web): fix list view problems
alcercu Oct 5, 2023
9a09569
fix(web): code smells
alcercu Oct 5, 2023
2048cff
fix(web): wrong count and bad filter encoding
alcercu Oct 6, 2023
f29a40d
fix(subgraph): voting and appealing cases count
alcercu Oct 6, 2023
a0411a6
chore: filter ordering
jaybuidl Oct 6, 2023
a1c67ca
chore: dispute period banner more specific
jaybuidl Oct 6, 2023
f42cc14
fix: linter about shadowed variables
jaybuidl Oct 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion subgraph/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ type User @entity {
totalResolvedDisputes: BigInt!
totalDisputes: BigInt!
totalCoherent: BigInt!
totalAppealingDisputes: BigInt!
votes: [Vote!]! @derivedFrom(field: "juror")
contributions: [Contribution!]! @derivedFrom(field: "contributor")
evidences: [Evidence!]! @derivedFrom(field: "sender")
Expand Down Expand Up @@ -128,6 +129,9 @@ type Court @entity {
supportedDisputeKits: [DisputeKit!]!
disputes: [Dispute!]! @derivedFrom(field: "court")
numberDisputes: BigInt!
numberClosedDisputes: BigInt!
numberVotingDisputes: BigInt!
numberAppealingDisputes: BigInt!
stakedJurors: [JurorTokensPerCourt!]! @derivedFrom(field: "court")
numberStakedJurors: BigInt!
stake: BigInt!
Expand All @@ -146,9 +150,12 @@ type Dispute @entity {
tied: Boolean!
overridden: Boolean!
lastPeriodChange: BigInt!
lastPeriodChangeBlockNumber: BigInt!
periodDeadline: BigInt!
rounds: [Round!]! @derivedFrom(field: "dispute")
currentRound: Round!
currentRoundIndex: BigInt!
jurors: [User!]! @derivedFrom(field: "disputes")
shifts: [TokenAndETHShift!]! @derivedFrom(field: "dispute")
disputeKitDispute: DisputeKitDispute @derivedFrom(field: "coreDispute")
}
Expand All @@ -166,8 +173,9 @@ type Round @entity {
feeToken: FeeToken
}

type Draw @entity {
type Draw @entity(immutable: true) {
id: ID! # dispute.id-currentRound-voteID
blockNumber: BigInt!
dispute: Dispute!
round: Round!
juror: User!
Expand Down Expand Up @@ -195,6 +203,7 @@ type Counter @entity {
cases: BigInt!
casesVoting: BigInt!
casesRuled: BigInt!
casesAppealing: BigInt!
}

type FeeToken @entity {
Expand Down
55 changes: 45 additions & 10 deletions subgraph/src/KlerosCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ import {
AcceptedFeeToken,
} from "../generated/KlerosCore/KlerosCore";
import { ZERO, ONE } from "./utils";
import { createCourtFromEvent, getFeeForJuror } from "./entities/Court";
import { createCourtFromEvent } from "./entities/Court";
import { createDisputeKitFromEvent, filterSupportedDisputeKits } from "./entities/DisputeKit";
import { createDisputeFromEvent } from "./entities/Dispute";
import { createRoundFromRoundInfo } from "./entities/Round";
import { updateCases, updateCasesRuled, updateCasesVoting } from "./datapoint";
import { updateCases, updateCasesAppealing, updateCasesRuled, updateCasesVoting } from "./datapoint";
import { addUserActiveDispute, ensureUser } from "./entities/User";
import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt";
import { createDrawFromEvent } from "./entities/Draw";
import { updateTokenAndEthShiftFromEvent } from "./entities/TokenAndEthShift";
import { updateArbitrableCases } from "./entities/Arbitrable";
import { Court, Dispute, FeeToken } from "../generated/schema";
import { Court, Dispute, User } from "../generated/schema";
import { BigInt } from "@graphprotocol/graph-ts";
import { updatePenalty } from "./entities/Penalty";
import { ensureFeeToken } from "./entities/FeeToken";
Expand Down Expand Up @@ -87,31 +87,67 @@ export function handleNewPeriod(event: NewPeriod): void {
const disputeID = event.params._disputeID;
const dispute = Dispute.load(disputeID.toString());
if (!dispute) return;
const newPeriod = getPeriodName(event.params._period);
const court = Court.load(dispute.court);
if (!court) return;

if (dispute.period === "vote") {
court.numberVotingDisputes = court.numberVotingDisputes.minus(ONE);
updateCasesVoting(BigInt.fromI32(-1), event.block.timestamp);
} else if (newPeriod === "vote") {
} else if (dispute.period === "appeal") {
let juror: User;
for (let i = 0; i < dispute.jurors.entries.length; i++) {
juror = ensureUser(dispute.jurors.entries[0].value.toString());
juror.totalAppealingDisputes = juror.totalAppealingDisputes.minus(ONE);
juror.save();
}
court.numberAppealingDisputes = court.numberAppealingDisputes.minus(ONE);
updateCasesAppealing(BigInt.fromI32(-1), event.block.timestamp);
}

const newPeriod = getPeriodName(event.params._period);
if (newPeriod === "vote") {
court.numberVotingDisputes = court.numberVotingDisputes.plus(ONE);
updateCasesVoting(ONE, event.block.timestamp);
} else if (newPeriod === "appeal") {
let juror: User;
for (let i = 0; i < dispute.jurors.entries.length; i++) {
juror = ensureUser(dispute.jurors.entries[0].value.toString());
juror.totalAppealingDisputes = juror.totalAppealingDisputes.plus(ONE);
juror.save();
}
court.numberAppealingDisputes = court.numberAppealingDisputes.plus(ONE);
updateCasesAppealing(ONE, event.block.timestamp);
} else if (newPeriod === "execution") {
const contract = KlerosCore.bind(event.address);
const currentRulingInfo = contract.currentRuling(disputeID);
dispute.currentRuling = currentRulingInfo.getRuling();
dispute.overridden = currentRulingInfo.getOverridden();
dispute.tied = currentRulingInfo.getTied();
dispute.save();
}

dispute.period = newPeriod;
dispute.lastPeriodChange = event.block.timestamp;
dispute.lastPeriodChangeBlockNumber = event.block.number;
if (newPeriod !== "execution") {
dispute.periodDeadline = event.block.timestamp.plus(court.timesPerPeriod[event.params._period]);
} else {
dispute.periodDeadline = BigInt.fromU64(U64.MAX_VALUE);
}
dispute.save();
court.save();
}

export function handleRuling(event: Ruling): void {
const disputeID = event.params._disputeID.toString();
const dispute = Dispute.load(disputeID);
updateCasesRuled(ONE, event.block.timestamp);
const disputeID = event.params._disputeID;
const dispute = Dispute.load(disputeID.toString());
if (!dispute) return;
dispute.ruled = true;
dispute.save();
updateCasesRuled(ONE, event.block.timestamp);
const court = Court.load(dispute.court);
if (!court) return;
court.numberClosedDisputes = court.numberClosedDisputes.plus(ONE);
court.save();
}

export function handleAppealDecision(event: AppealDecision): void {
Expand All @@ -124,7 +160,6 @@ export function handleAppealDecision(event: AppealDecision): void {
dispute.currentRoundIndex = newRoundIndex;
dispute.currentRound = roundID;
dispute.save();
const feeForJuror = getFeeForJuror(dispute.court);
const roundInfo = contract.getRoundInfo(disputeID, newRoundIndex);
createRoundFromRoundInfo(disputeID, newRoundIndex, roundInfo);
}
Expand Down
16 changes: 15 additions & 1 deletion subgraph/src/datapoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ export function getDelta(previousValue: BigInt, newValue: BigInt): BigInt {
return newValue.minus(previousValue);
}

const VARIABLES = ["stakedPNK", "redistributedPNK", "paidETH", "activeJurors", "cases", "casesVoting", "casesRuled"];
const VARIABLES = [
"stakedPNK",
"redistributedPNK",
"paidETH",
"activeJurors",
"cases",
"casesVoting",
"casesRuled",
"casesAppealing",
];

function updateDataPoint(delta: BigInt, timestamp: BigInt, variable: string): void {
checkFirstDayActivity();
Expand All @@ -33,6 +42,7 @@ function checkFirstDayActivity(): void {
counter.cases = ZERO;
counter.casesVoting = ZERO;
counter.casesRuled = ZERO;
counter.casesAppealing = ZERO;
counter.save();
}
}
Expand Down Expand Up @@ -72,3 +82,7 @@ export function updateCasesVoting(delta: BigInt, timestamp: BigInt): void {
export function updateCasesRuled(delta: BigInt, timestamp: BigInt): void {
updateDataPoint(delta, timestamp, "casesRuled");
}

export function updateCasesAppealing(delta: BigInt, timestamp: BigInt): void {
updateDataPoint(delta, timestamp, "casesAppealing");
}
3 changes: 3 additions & 0 deletions subgraph/src/entities/Court.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export function createCourtFromEvent(event: CourtCreated): void {
court.timesPerPeriod = event.params._timesPerPeriod;
court.supportedDisputeKits = event.params._supportedDisputeKits.map<string>((value) => value.toString());
court.numberDisputes = ZERO;
court.numberClosedDisputes = ZERO;
court.numberVotingDisputes = ZERO;
court.numberAppealingDisputes = ZERO;
court.numberStakedJurors = ZERO;
court.stake = ZERO;
court.delayedStake = ZERO;
Expand Down
9 changes: 7 additions & 2 deletions subgraph/src/entities/Dispute.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import { KlerosCore, DisputeCreation } from "../../generated/KlerosCore/KlerosCore";
import { Dispute } from "../../generated/schema";
import { Court, Dispute } from "../../generated/schema";
import { ZERO } from "../utils";

export function createDisputeFromEvent(event: DisputeCreation): void {
const contract = KlerosCore.bind(event.address);
const disputeID = event.params._disputeID;
const disputeContractState = contract.disputes(disputeID);
const dispute = new Dispute(disputeID.toString());
dispute.court = disputeContractState.value0.toString();
const courtID = disputeContractState.value0.toString();
dispute.court = courtID;
dispute.arbitrated = event.params._arbitrable.toHexString();
dispute.period = "evidence";
dispute.ruled = false;
dispute.currentRuling = ZERO;
dispute.tied = true;
dispute.overridden = false;
dispute.lastPeriodChange = event.block.timestamp;
dispute.lastPeriodChangeBlockNumber = event.block.number;
const court = Court.load(courtID);
if (!court) return;
dispute.periodDeadline = event.block.timestamp.plus(court.timesPerPeriod[0]);
dispute.currentRoundIndex = ZERO;
const roundID = `${disputeID.toString()}-${ZERO.toString()}`;
dispute.currentRound = roundID;
Expand Down
1 change: 1 addition & 0 deletions subgraph/src/entities/Draw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export function createDrawFromEvent(event: DrawEvent): void {
const voteID = event.params._voteID;
const drawID = `${disputeID}-${roundIndex.toString()}-${voteID.toString()}`;
const draw = new Draw(drawID);
draw.blockNumber = event.block.number;
draw.dispute = disputeID;
draw.round = roundID;
draw.juror = event.params._address.toHexString();
Expand Down
1 change: 1 addition & 0 deletions subgraph/src/entities/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function createUserFromAddress(id: string): User {
user.disputes = [];
user.resolvedDisputes = [];
user.totalResolvedDisputes = ZERO;
user.totalAppealingDisputes = ZERO;
user.totalDisputes = ZERO;
user.totalCoherent = ZERO;
user.save();
Expand Down
2 changes: 1 addition & 1 deletion subgraph/subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ dataSources:
handler: handleDisputeKitEnabled
- event: StakeSet(indexed address,uint256,uint256)
handler: handleStakeSet
- event: StakeDelayed(indexed address,uint256,uint256)
- event: StakeDelayed(indexed address,uint256,uint256,uint256)
handler: handleStakeDelayed
- event: TokenAndETHShift(indexed address,indexed uint256,indexed uint256,uint256,int256,int256,address)
handler: handleTokenAndETHShift
Expand Down
2 changes: 1 addition & 1 deletion web/.env.devnet.public
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Do not enter sensitive information here.
export REACT_APP_DEPLOYMENT=devnet
export REACT_APP_KLEROS_CORE_SUBGRAPH_DEVNET=https://api.thegraph.com/subgraphs/name/alcercu/kleroscoredev
export REACT_APP_DISPUTE_TEMPLATE_ARBGOERLI_SUBGRAPH_DEVNET=https://api.thegraph.com/subgraphs/name/alcercu/templateregistrydevnet
export REACT_APP_DISPUTE_TEMPLATE_ARBGOERLI_SUBGRAPH_DEVNET=https://api.thegraph.com/subgraphs/name/alcercu/templateregistrydevnet
8 changes: 4 additions & 4 deletions web/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { SentryRoutes } from "./utils/sentry";
import "react-loading-skeleton/dist/skeleton.css";
import "react-toastify/dist/ReactToastify.css";
import Web3Provider from "context/Web3Provider";
import IsListProvider from "context/IsListProvider";
import QueryClientProvider from "context/QueryClientProvider";
import StyledComponentsProvider from "context/StyledComponentsProvider";
import { FilterProvider } from "context/FilterProvider";
import RefetchOnBlock from "context/RefetchOnBlock";
import Layout from "layout/index";
import Home from "./pages/Home";
Expand All @@ -21,18 +21,18 @@ const App: React.FC = () => {
<QueryClientProvider>
<RefetchOnBlock />
<Web3Provider>
<FilterProvider>
<IsListProvider>
<SentryRoutes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="cases/*" element={<Cases />} />
<Route path="courts/*" element={<Courts />} />
<Route path="dashboard" element={<Dashboard />} />
<Route path="dashboard/:page/:order/:filter" element={<Dashboard />} />
<Route path="disputeTemplate" element={<DisputeTemplateView />} />
<Route path="*" element={<h1>Justice not found here ¯\_( ͡° ͜ʖ ͡°)_/¯</h1>} />
</Route>
</SentryRoutes>
</FilterProvider>
</IsListProvider>
</Web3Provider>
</QueryClientProvider>
</StyledComponentsProvider>
Expand Down
Loading