Skip to content

Feat(subgraph): Add more datapoints #391

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

Merged
merged 18 commits into from
Nov 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

## Reporting a Vulnerability

You can privately disclose vulnerabilities to us at any time, by sending an email to clement@kleros.io and contact@kleros.io.
You can privately disclose vulnerabilities to us at any time, by sending an email to clement@kleros.io and contact@kleros.io.
We can then discuss the best way to handle things on a case by case basis.
29 changes: 9 additions & 20 deletions contracts/src/arbitration/KlerosGovernor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,10 @@ contract KlerosGovernor is IArbitrable, IMetaEvidence {
* @param _arbitrator The new trusted arbitrator.
* @param _arbitratorExtraData The extra data used by the new arbitrator.
*/
function changeArbitrator(IArbitrator _arbitrator, bytes memory _arbitratorExtraData)
external
onlyByGovernor
duringSubmissionPeriod
{
function changeArbitrator(
IArbitrator _arbitrator,
bytes memory _arbitratorExtraData
) external onlyByGovernor duringSubmissionPeriod {
arbitrator = _arbitrator;
arbitratorExtraData = _arbitratorExtraData;
}
Expand Down Expand Up @@ -334,11 +333,7 @@ contract KlerosGovernor is IArbitrable, IMetaEvidence {
* @param _cursor Index of the transaction from which to start executing.
* @param _count Number of transactions to execute. Executes until the end if set to "0" or number higher than number of transactions in the list.
*/
function executeTransactionList(
uint256 _listID,
uint256 _cursor,
uint256 _count
) external {
function executeTransactionList(uint256 _listID, uint256 _cursor, uint256 _count) external {
Submission storage submission = submissions[_listID];
require(submission.approved, "Should be approved");
require(block.timestamp - submission.approvalTime <= executionTimeout, "Time to execute has passed");
Expand Down Expand Up @@ -376,16 +371,10 @@ contract KlerosGovernor is IArbitrable, IMetaEvidence {
* @return executed Whether the transaction was executed or not.

*/
function getTransactionInfo(uint256 _listID, uint256 _transactionIndex)
external
view
returns (
address target,
uint256 value,
bytes memory data,
bool executed
)
{
function getTransactionInfo(
uint256 _listID,
uint256 _transactionIndex
) external view returns (address target, uint256 value, bytes memory data, bool executed) {
Submission storage submission = submissions[_listID];
Transaction storage transaction = submission.txs[_transactionIndex];
return (transaction.target, transaction.value, transaction.data, transaction.executed);
Expand Down
39 changes: 39 additions & 0 deletions subgraph/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ enum Period {

type Court @entity {
id: ID!
policy: String
hiddenVotes: Boolean!
parent: Court
children: [Court!]! @derivedFrom(field: "parent")
Expand All @@ -27,6 +28,7 @@ type Juror @entity {
tokens: [JurorTokensPerSubcourt!]! @derivedFrom(field: "juror")
shifts: [TokenAndETHShift!]! @derivedFrom(field: "juror")
draws: [Draw!]! @derivedFrom(field: "juror")
votes: [Vote!]! @derivedFrom(field: "juror")
}

type TokenAndETHShift @entity {
Expand All @@ -45,16 +47,41 @@ type JurorTokensPerSubcourt @entity {
locked: BigInt!
}

type EvidenceGroup @entity {
id: ID!
evidences: [Evidence!]! @derivedFrom(field: "evidenceGroup")
lastEvidenceID: BigInt!
}

type Evidence @entity {
id: ID! # Set to `${evidenceGroupID}-${id}`
evidence: String!
evidenceGroup: EvidenceGroup!
sender: Bytes!
}

type Round @entity {
id: ID! # Set to `${dispute.id}-${currentRound}`
dispute: Dispute!
disputeKitID: DisputeKit!
tokensAtStakePerJuror: BigInt!
totalFeesForJurors: BigInt!
nbVotes: BigInt!
totalVoted: BigInt!
repartitions: BigInt!
penalties: BigInt!
drawnJurors: [Draw!]! @derivedFrom(field: "round")
votes: [Vote!]! @derivedFrom(field: "round")
currentDecision: BigInt
}

type Vote @entity {
id: ID! # Set to `${coreDisputeID}-${coreRoundID}-${jurorAddress}`
dispute: Dispute!
round: Round!
juror: Juror!
choice: BigInt
justification: String
}

type Draw @entity {
Expand All @@ -74,6 +101,7 @@ type Dispute @entity {
lastPeriodChange: BigInt!
rounds: [Round!]! @derivedFrom(field: "dispute")
draws: [Draw!]! @derivedFrom(field: "dispute")
votes: [Vote!]! @derivedFrom(field: "dispute")
currentRound: Int!
shifts: [TokenAndETHShift!]! @derivedFrom(field: "dispute")
gatewayDispute: GatewayDispute! @derivedFrom(field: "homeDispute")
Expand Down Expand Up @@ -130,3 +158,14 @@ type CasesDataPoint @entity {
id: ID! # Will be the timestamp except for the counter which will be 0
value: BigInt!
}

type Counter @entity {
id: ID! # Always 0
stakedPNK: BigInt!
redistributedPNK: BigInt!
paidETH: BigInt!
activeJurors: BigInt!
cases: BigInt!
casesVoting: BigInt!
casesRuled: BigInt!
}
61 changes: 61 additions & 0 deletions subgraph/src/DisputeKitClassic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { BigInt } from "@graphprotocol/graph-ts";
import {
DisputeKitClassic,
Evidence as EvidenceEvent,
Justification as JustificationEvent,
} from "../generated/DisputeKitClassic/DisputeKitClassic";
import {
Dispute,
Round,
Evidence,
EvidenceGroup,
Vote,
} from "../generated/schema";

export function handleEvidenceEvent(event: EvidenceEvent): void {
const evidenceGroupID = event.params._evidenceGroupID;
let evidenceGroup = EvidenceGroup.load(evidenceGroupID.toString());
if (!evidenceGroup) {
evidenceGroup = new EvidenceGroup(evidenceGroupID.toString());
evidenceGroup.lastEvidenceID = BigInt.fromI32(0);
}
const evidenceID = evidenceGroup.lastEvidenceID.plus(BigInt.fromI32(1));
const evidence = new Evidence(`${evidenceGroupID}-${evidenceID}`);
evidence.evidence = event.params._evidence;
evidence.evidenceGroup = evidenceGroupID.toString();
evidence.sender = event.params._party;
evidenceGroup.lastEvidenceID = evidenceID;
evidenceGroup.save();
evidence.save();
}

export function handleJustificationEvent(event: JustificationEvent): void {
const disputeID = event.params._coreDisputeID;
const dispute = Dispute.load(disputeID.toString());
if (dispute) {
const currentRoundIndex = dispute.currentRound;
const currentRound = Round.load(
`${disputeID.toString()}-${currentRoundIndex.toString()}`
);
if (currentRound) {
const contract = DisputeKitClassic.bind(event.address);
currentRound.totalVoted = contract.getRoundInfo(
disputeID,
BigInt.fromI32(dispute.currentRound),
BigInt.fromI32(0)
).value2;
currentRound.currentDecision = contract.currentRuling(disputeID);
currentRound.save();
const juror = event.params._juror.toHexString();
const vote = new Vote(
`${disputeID.toString()}-${currentRoundIndex.toString()}-${juror}`
);
vote.dispute = disputeID.toString();
vote.round = `${disputeID.toString()}-${currentRoundIndex.toString()}`;
vote.juror = juror;
vote.choice = event.params._choice;
vote.justification = event.params._justification;
vote.save();
}
}
}
84 changes: 25 additions & 59 deletions subgraph/src/KlerosCore.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
Address,
BigInt,
Entity,
Value,
store,
BigDecimal,
} from "@graphprotocol/graph-ts";
import { Address, BigInt } from "@graphprotocol/graph-ts";
import {
KlerosCore,
AppealDecision,
Expand All @@ -29,6 +22,16 @@ import {
DisputeKit,
Court,
} from "../generated/schema";
import {
updateCases,
updateActiveJurors,
updatePaidETH,
updateStakedPNK,
updateCasesRuled,
updateCasesVoting,
updateRedistributedPNK,
getDelta,
} from "./datapoint";

function getPeriodName(index: i32): string {
const periodArray = ["Evidence", "Commit", "Vote", "Appeal", "Execution"];
Expand Down Expand Up @@ -114,11 +117,16 @@ export function handleAppealDecision(event: AppealDecision): void {
disputeID,
BigInt.fromI64(newRoundIndex)
);
const subcourtID = dispute.subcourtID;
const subcourtStorage = contract.courts(BigInt.fromString(subcourtID));
round.dispute = disputeID.toString();
round.tokensAtStakePerJuror = roundInfo.value0;
round.totalFeesForJurors = roundInfo.value1;
round.nbVotes = roundInfo.value1.div(subcourtStorage.getFeeForJuror());
round.totalVoted = BigInt.fromI32(0);
round.repartitions = roundInfo.value2;
round.penalties = roundInfo.value3;
round.disputeKitID = roundInfo.value5.toString();
dispute.currentRound = newRoundIndex;
round.save();
dispute.save();
Expand All @@ -130,20 +138,24 @@ export function handleDisputeCreation(event: DisputeCreation): void {
const disputeID = event.params._disputeID;
const dispute = new Dispute(disputeID.toString());
const disputeStorage = contract.disputes(disputeID);
const subcourtID = disputeStorage.value0.toString();
const subcourtID = disputeStorage.value0;
dispute.arbitrated = event.params._arbitrable;
dispute.subcourtID = subcourtID;
dispute.subcourtID = subcourtID.toString();
dispute.period = "Evidence";
dispute.ruled = false;
dispute.lastPeriodChange = disputeStorage.value4;
dispute.currentRound = 0;
const roundInfo = contract.getRoundInfo(disputeID, BigInt.fromString("0"));
const round = new Round(`${disputeID.toString()}-0`);
const subcourtStorage = contract.courts(subcourtID);
round.dispute = disputeID.toString();
round.tokensAtStakePerJuror = roundInfo.value0;
round.totalFeesForJurors = roundInfo.value1;
round.nbVotes = roundInfo.value1.div(subcourtStorage.getFeeForJuror());
round.totalVoted = BigInt.fromI32(0);
round.repartitions = roundInfo.value2;
round.penalties = roundInfo.value3;
round.disputeKitID = roundInfo.value5.toString();
dispute.save();
round.save();
updateCases(BigInt.fromI32(1), event.block.timestamp);
Expand Down Expand Up @@ -217,10 +229,7 @@ export function handleStakeSet(event: StakeSet): void {
} else previousStake = jurorTokens.staked;
jurorTokens.staked = amountStaked;
jurorTokens.save();
updateTotalPNKStaked(
getDelta(previousStake, amountStaked),
event.block.timestamp
);
updateStakedPNK(getDelta(previousStake, amountStaked), event.block.timestamp);
}

export function handleTokenAndETHShift(event: TokenAndETHShiftEvent): void {
Expand All @@ -231,55 +240,12 @@ export function handleTokenAndETHShift(event: TokenAndETHShiftEvent): void {
const ethAmount = event.params._ethAmount;
const shift = new TokenAndETHShift(shiftID);
if (tokenAmount.gt(BigInt.fromI32(0))) {
updatePNKRedistributed(tokenAmount, event.block.timestamp);
updateRedistributedPNK(tokenAmount, event.block.timestamp);
}
updateETHPaid(ethAmount, event.block.timestamp);
updatePaidETH(ethAmount, event.block.timestamp);
shift.juror = jurorAddress;
shift.dispute = disputeID.toString();
shift.tokenAmount = tokenAmount;
shift.ethAmount = ethAmount;
shift.save();
}

function getDelta(previousValue: BigInt, newValue: BigInt): BigInt {
return newValue.minus(previousValue);
}

function updateDataPoint(
delta: BigInt,
timestamp: BigInt,
entityName: string
): void {
let counter = store.get(entityName, "0");
if (!counter) {
counter = new Entity();
counter.set("value", Value.fromBigInt(BigInt.fromI32(0)));
}
const dayID = timestamp.toI32() / 86400;
const dayStartTimestamp = dayID * 86400;
const newValue = counter.get("value")!.toBigInt().plus(delta);
const newDataPoint = new Entity();
newDataPoint.set("value", Value.fromBigInt(newValue));
store.set(entityName, dayStartTimestamp.toString(), newDataPoint);
store.set(entityName, "0", newDataPoint);
}

function updateTotalPNKStaked(delta: BigInt, timestamp: BigInt): void {
updateDataPoint(delta, timestamp, "PNKStakedDataPoint");
}

function updatePNKRedistributed(delta: BigInt, timestamp: BigInt): void {
updateDataPoint(delta, timestamp, "PNKRedistributedDataPoint");
}

function updateETHPaid(delta: BigInt, timestamp: BigInt): void {
updateDataPoint(delta, timestamp, "ETHPaidDataPoint");
}

function updateActiveJurors(delta: BigInt, timestamp: BigInt): void {
updateDataPoint(delta, timestamp, "ActiveJurorsDataPoint");
}

function updateCases(delta: BigInt, timestamp: BigInt): void {
updateDataPoint(delta, timestamp, "CasesDataPoint");
}
11 changes: 11 additions & 0 deletions subgraph/src/PolicyRegistry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { PolicyUpdate } from "../generated/PolicyRegistry/PolicyRegistry";
import { Court } from "../generated/schema";

export function handlePolicyUpdate(event: PolicyUpdate): void {
const courtID = event.params._subcourtID.toString();
const court = Court.load(courtID);
if (court) {
court.policy = event.params._policy;
court.save();
}
}
Loading