From fe34418786fb07bbe554922bfb4ba424e0ec37c3 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Fri, 21 Feb 2025 18:18:46 +0100 Subject: [PATCH 1/5] feat: add stakeset entity and handler --- subgraph/core-neo/subgraph.yaml | 1 + subgraph/core-university/subgraph.yaml | 1 + subgraph/core/schema.graphql | 11 +++++++++++ subgraph/core/src/SortitionModule.ts | 18 ++++++++++++++++-- subgraph/core/subgraph.yaml | 1 + 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/subgraph/core-neo/subgraph.yaml b/subgraph/core-neo/subgraph.yaml index 37feb1f7d..252098b54 100644 --- a/subgraph/core-neo/subgraph.yaml +++ b/subgraph/core-neo/subgraph.yaml @@ -149,6 +149,7 @@ dataSources: language: wasm/assemblyscript entities: - JurorTokensPerCourt + - StakeSet abis: - name: SortitionModule file: ../../contracts/deployments/arbitrum/SortitionModuleNeo.json diff --git a/subgraph/core-university/subgraph.yaml b/subgraph/core-university/subgraph.yaml index 7c95a47e2..7adcb8249 100644 --- a/subgraph/core-university/subgraph.yaml +++ b/subgraph/core-university/subgraph.yaml @@ -149,6 +149,7 @@ dataSources: language: wasm/assemblyscript entities: - JurorTokensPerCourt + - StakeSet abis: - name: SortitionModule file: ../../contracts/deployments/arbitrumSepoliaDevnet/SortitionModuleUniversity.json diff --git a/subgraph/core/schema.graphql b/subgraph/core/schema.graphql index 956d102af..9ff8aca09 100644 --- a/subgraph/core/schema.graphql +++ b/subgraph/core/schema.graphql @@ -354,6 +354,17 @@ type ClassicContribution implements Contribution @entity { rewardWithdrawn: Boolean! } +type StakeSet @entity { + id: ID! # event.transaction.hash.toHex() + - + event.logIndex.toString() + address: Bytes! + courtID: BigInt! + stake: BigInt! + newTotalStake: BigInt! + blocknumber: BigInt! + timestamp: BigInt! + logIndex: BigInt! +} + type _Schema_ @fulltext( name: "evidenceSearch" diff --git a/subgraph/core/src/SortitionModule.ts b/subgraph/core/src/SortitionModule.ts index 1625b6686..efa067b02 100644 --- a/subgraph/core/src/SortitionModule.ts +++ b/subgraph/core/src/SortitionModule.ts @@ -4,8 +4,9 @@ import { StakeDelayedAlreadyTransferredWithdrawn, StakeDelayedNotTransferred, StakeLocked, - StakeSet, + StakeSet as StakeSetEvent, } from "../generated/SortitionModule/SortitionModule"; +import { Court, StakeSet as StakeSetEntity } from "../generated/schema"; import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; import { ensureUser } from "./entities/User"; @@ -23,7 +24,7 @@ export function handleStakeDelayedNotTransferred(event: StakeDelayedNotTransferr updateJurorDelayedStake(event.params._address.toHexString(), event.params._courtID.toString(), event.params._amount); } -export function handleStakeSet(event: StakeSet): void { +export function handleStakeSet(event: StakeSetEvent): void { const jurorAddress = event.params._address.toHexString(); ensureUser(jurorAddress); const courtID = event.params._courtID.toString(); @@ -31,5 +32,18 @@ export function handleStakeSet(event: StakeSet): void { updateJurorStake(jurorAddress, courtID.toString(), SortitionModule.bind(event.address), event.block.timestamp); //stake is updated instantly so no delayed amount, set delay amount to zero updateJurorDelayedStake(jurorAddress, courtID, ZERO); + + const generalCourt = Court.load("1"); + if (!generalCourt) return; + const stakeSet = new StakeSetEntity(event.transaction.hash.toHex() + "-" + event.logIndex.toString()); + stakeSet.address = event.params._address; + stakeSet.courtID = event.params._courtID; + stakeSet.stake = event.params._amount; + stakeSet.newTotalStake = generalCourt.effectiveStake; + stakeSet.blocknumber = event.block.number; + stakeSet.timestamp = event.block.timestamp; + stakeSet.logIndex = event.logIndex; + stakeSet.save(); } + export function handleStakeLocked(event: StakeLocked): void {} diff --git a/subgraph/core/subgraph.yaml b/subgraph/core/subgraph.yaml index ba08525c9..74ff659e8 100644 --- a/subgraph/core/subgraph.yaml +++ b/subgraph/core/subgraph.yaml @@ -149,6 +149,7 @@ dataSources: language: wasm/assemblyscript entities: - JurorTokensPerCourt + - StakeSet abis: - name: SortitionModule file: ../../contracts/deployments/arbitrumSepoliaDevnet/SortitionModule.json From f16a0e2f3bd842f6e329054060568789ca392c5f Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Sat, 22 Feb 2025 14:34:19 +0100 Subject: [PATCH 2/5] fix: newtotalstake is juror specific --- .../core-university/src/SortitionModule.ts | 18 ++++++++++++++++-- subgraph/core/schema.graphql | 2 +- subgraph/core/src/SortitionModule.ts | 10 +++++----- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/subgraph/core-university/src/SortitionModule.ts b/subgraph/core-university/src/SortitionModule.ts index e71103482..592f57eb5 100644 --- a/subgraph/core-university/src/SortitionModule.ts +++ b/subgraph/core-university/src/SortitionModule.ts @@ -1,10 +1,11 @@ -import { SortitionModule, StakeLocked, StakeSet } from "../generated/SortitionModule/SortitionModule"; +import { SortitionModule, StakeLocked, StakeSet as StakeSetEvent } from "../generated/SortitionModule/SortitionModule"; +import { StakeSet as StakeSetEntity, User } from "../generated/schema"; import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; import { ensureUser } from "./entities/User"; import { ZERO } from "./utils"; -export function handleStakeSet(event: StakeSet): void { +export function handleStakeSet(event: StakeSetEvent): void { const jurorAddress = event.params._address.toHexString(); ensureUser(jurorAddress); const courtID = event.params._courtID.toString(); @@ -12,7 +13,20 @@ export function handleStakeSet(event: StakeSet): void { updateJurorStake(jurorAddress, courtID.toString(), SortitionModule.bind(event.address), event.block.timestamp); //stake is updated instantly so no delayed amount, set delay amount to zero updateJurorDelayedStake(jurorAddress, courtID, ZERO); + + const juror = User.load(jurorAddress); + if (!juror) return; + const stakeSet = new StakeSetEntity(event.transaction.hash.toHex() + "-" + event.logIndex.toString()); + stakeSet.address = jurorAddress; + stakeSet.courtID = event.params._courtID; + stakeSet.stake = event.params._amount; + stakeSet.newTotalStake = juror.totalStake; + stakeSet.blocknumber = event.block.number; + stakeSet.timestamp = event.block.timestamp; + stakeSet.logIndex = event.logIndex; + stakeSet.save(); } + export function handleStakeLocked(event: StakeLocked): void { // NOP } diff --git a/subgraph/core/schema.graphql b/subgraph/core/schema.graphql index 9ff8aca09..e031dffd3 100644 --- a/subgraph/core/schema.graphql +++ b/subgraph/core/schema.graphql @@ -356,7 +356,7 @@ type ClassicContribution implements Contribution @entity { type StakeSet @entity { id: ID! # event.transaction.hash.toHex() + - + event.logIndex.toString() - address: Bytes! + address: String! courtID: BigInt! stake: BigInt! newTotalStake: BigInt! diff --git a/subgraph/core/src/SortitionModule.ts b/subgraph/core/src/SortitionModule.ts index efa067b02..57317c3c3 100644 --- a/subgraph/core/src/SortitionModule.ts +++ b/subgraph/core/src/SortitionModule.ts @@ -6,7 +6,7 @@ import { StakeLocked, StakeSet as StakeSetEvent, } from "../generated/SortitionModule/SortitionModule"; -import { Court, StakeSet as StakeSetEntity } from "../generated/schema"; +import { StakeSet as StakeSetEntity, User } from "../generated/schema"; import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; import { ensureUser } from "./entities/User"; @@ -33,13 +33,13 @@ export function handleStakeSet(event: StakeSetEvent): void { //stake is updated instantly so no delayed amount, set delay amount to zero updateJurorDelayedStake(jurorAddress, courtID, ZERO); - const generalCourt = Court.load("1"); - if (!generalCourt) return; + const juror = User.load(jurorAddress); + if (!juror) return; const stakeSet = new StakeSetEntity(event.transaction.hash.toHex() + "-" + event.logIndex.toString()); - stakeSet.address = event.params._address; + stakeSet.address = jurorAddress; stakeSet.courtID = event.params._courtID; stakeSet.stake = event.params._amount; - stakeSet.newTotalStake = generalCourt.effectiveStake; + stakeSet.newTotalStake = juror.totalStake; stakeSet.blocknumber = event.block.number; stakeSet.timestamp = event.block.timestamp; stakeSet.logIndex = event.logIndex; From fb4ab038399dec52dbd419f663b18e02d9acf59f Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Sat, 22 Feb 2025 14:37:03 +0100 Subject: [PATCH 3/5] chore: update package json subgraph version --- subgraph/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subgraph/package.json b/subgraph/package.json index f655b6e86..7f826f24d 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -1,6 +1,6 @@ { "name": "@kleros/kleros-v2-subgraph", - "version": "0.11.0", + "version": "0.12.0", "drtVersion": "0.11.0", "license": "MIT", "scripts": { From 250ac14c2771754cbf105e9fa761eaa9b0328809 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:01:43 +0100 Subject: [PATCH 4/5] fix: bug where newtotalstake was not correct, address feedback --- subgraph/core-university/src/SortitionModule.ts | 13 ++++++------- subgraph/core/schema.graphql | 4 ++-- subgraph/core/src/SortitionModule.ts | 13 ++++++------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/subgraph/core-university/src/SortitionModule.ts b/subgraph/core-university/src/SortitionModule.ts index 592f57eb5..87d126d67 100644 --- a/subgraph/core-university/src/SortitionModule.ts +++ b/subgraph/core-university/src/SortitionModule.ts @@ -1,26 +1,25 @@ import { SortitionModule, StakeLocked, StakeSet as StakeSetEvent } from "../generated/SortitionModule/SortitionModule"; -import { StakeSet as StakeSetEntity, User } from "../generated/schema"; +import { StakeSet as StakeSetEntity } from "../generated/schema"; -import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; +import { ensureJurorTokensPerCourt, updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; import { ensureUser } from "./entities/User"; import { ZERO } from "./utils"; export function handleStakeSet(event: StakeSetEvent): void { const jurorAddress = event.params._address.toHexString(); - ensureUser(jurorAddress); + const juror = ensureUser(jurorAddress); const courtID = event.params._courtID.toString(); updateJurorStake(jurorAddress, courtID.toString(), SortitionModule.bind(event.address), event.block.timestamp); //stake is updated instantly so no delayed amount, set delay amount to zero updateJurorDelayedStake(jurorAddress, courtID, ZERO); - const juror = User.load(jurorAddress); - if (!juror) return; const stakeSet = new StakeSetEntity(event.transaction.hash.toHex() + "-" + event.logIndex.toString()); - stakeSet.address = jurorAddress; + const jurorTokensPerCourt = ensureJurorTokensPerCourt(jurorAddress, "1"); + stakeSet.juror = juror.id; stakeSet.courtID = event.params._courtID; stakeSet.stake = event.params._amount; - stakeSet.newTotalStake = juror.totalStake; + stakeSet.newTotalStake = jurorTokensPerCourt.effectiveStake; stakeSet.blocknumber = event.block.number; stakeSet.timestamp = event.block.timestamp; stakeSet.logIndex = event.logIndex; diff --git a/subgraph/core/schema.graphql b/subgraph/core/schema.graphql index e031dffd3..59fbd76de 100644 --- a/subgraph/core/schema.graphql +++ b/subgraph/core/schema.graphql @@ -354,9 +354,9 @@ type ClassicContribution implements Contribution @entity { rewardWithdrawn: Boolean! } -type StakeSet @entity { +type StakeSet @entity(immutable: true) { id: ID! # event.transaction.hash.toHex() + - + event.logIndex.toString() - address: String! + juror: User! courtID: BigInt! stake: BigInt! newTotalStake: BigInt! diff --git a/subgraph/core/src/SortitionModule.ts b/subgraph/core/src/SortitionModule.ts index 57317c3c3..ed7e38611 100644 --- a/subgraph/core/src/SortitionModule.ts +++ b/subgraph/core/src/SortitionModule.ts @@ -6,9 +6,9 @@ import { StakeLocked, StakeSet as StakeSetEvent, } from "../generated/SortitionModule/SortitionModule"; -import { StakeSet as StakeSetEntity, User } from "../generated/schema"; +import { StakeSet as StakeSetEntity } from "../generated/schema"; -import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; +import { ensureJurorTokensPerCourt, updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; import { ensureUser } from "./entities/User"; import { ZERO } from "./utils"; @@ -26,20 +26,19 @@ export function handleStakeDelayedNotTransferred(event: StakeDelayedNotTransferr export function handleStakeSet(event: StakeSetEvent): void { const jurorAddress = event.params._address.toHexString(); - ensureUser(jurorAddress); + const juror = ensureUser(jurorAddress); const courtID = event.params._courtID.toString(); updateJurorStake(jurorAddress, courtID.toString(), SortitionModule.bind(event.address), event.block.timestamp); //stake is updated instantly so no delayed amount, set delay amount to zero updateJurorDelayedStake(jurorAddress, courtID, ZERO); - const juror = User.load(jurorAddress); - if (!juror) return; const stakeSet = new StakeSetEntity(event.transaction.hash.toHex() + "-" + event.logIndex.toString()); - stakeSet.address = jurorAddress; + const jurorTokensPerCourt = ensureJurorTokensPerCourt(jurorAddress, "1"); + stakeSet.juror = juror.id; stakeSet.courtID = event.params._courtID; stakeSet.stake = event.params._amount; - stakeSet.newTotalStake = juror.totalStake; + stakeSet.newTotalStake = jurorTokensPerCourt.effectiveStake; stakeSet.blocknumber = event.block.number; stakeSet.timestamp = event.block.timestamp; stakeSet.logIndex = event.logIndex; From 809b0857f9b78b0c3ae09e052330f73ace438caa Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Fri, 14 Mar 2025 13:02:29 +0100 Subject: [PATCH 5/5] chore: optimize entity loading by reducing one entity --- subgraph/core-university/src/SortitionModule.ts | 7 +++---- subgraph/core/src/SortitionModule.ts | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/subgraph/core-university/src/SortitionModule.ts b/subgraph/core-university/src/SortitionModule.ts index 87d126d67..aae779fcb 100644 --- a/subgraph/core-university/src/SortitionModule.ts +++ b/subgraph/core-university/src/SortitionModule.ts @@ -1,13 +1,12 @@ import { SortitionModule, StakeLocked, StakeSet as StakeSetEvent } from "../generated/SortitionModule/SortitionModule"; import { StakeSet as StakeSetEntity } from "../generated/schema"; -import { ensureJurorTokensPerCourt, updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; +import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; import { ensureUser } from "./entities/User"; import { ZERO } from "./utils"; export function handleStakeSet(event: StakeSetEvent): void { const jurorAddress = event.params._address.toHexString(); - const juror = ensureUser(jurorAddress); const courtID = event.params._courtID.toString(); updateJurorStake(jurorAddress, courtID.toString(), SortitionModule.bind(event.address), event.block.timestamp); @@ -15,11 +14,11 @@ export function handleStakeSet(event: StakeSetEvent): void { updateJurorDelayedStake(jurorAddress, courtID, ZERO); const stakeSet = new StakeSetEntity(event.transaction.hash.toHex() + "-" + event.logIndex.toString()); - const jurorTokensPerCourt = ensureJurorTokensPerCourt(jurorAddress, "1"); + const juror = ensureUser(jurorAddress); stakeSet.juror = juror.id; stakeSet.courtID = event.params._courtID; stakeSet.stake = event.params._amount; - stakeSet.newTotalStake = jurorTokensPerCourt.effectiveStake; + stakeSet.newTotalStake = juror.totalStake; stakeSet.blocknumber = event.block.number; stakeSet.timestamp = event.block.timestamp; stakeSet.logIndex = event.logIndex; diff --git a/subgraph/core/src/SortitionModule.ts b/subgraph/core/src/SortitionModule.ts index ed7e38611..5fcb150ff 100644 --- a/subgraph/core/src/SortitionModule.ts +++ b/subgraph/core/src/SortitionModule.ts @@ -8,7 +8,7 @@ import { } from "../generated/SortitionModule/SortitionModule"; import { StakeSet as StakeSetEntity } from "../generated/schema"; -import { ensureJurorTokensPerCourt, updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; +import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; import { ensureUser } from "./entities/User"; import { ZERO } from "./utils"; @@ -26,7 +26,6 @@ export function handleStakeDelayedNotTransferred(event: StakeDelayedNotTransferr export function handleStakeSet(event: StakeSetEvent): void { const jurorAddress = event.params._address.toHexString(); - const juror = ensureUser(jurorAddress); const courtID = event.params._courtID.toString(); updateJurorStake(jurorAddress, courtID.toString(), SortitionModule.bind(event.address), event.block.timestamp); @@ -34,11 +33,11 @@ export function handleStakeSet(event: StakeSetEvent): void { updateJurorDelayedStake(jurorAddress, courtID, ZERO); const stakeSet = new StakeSetEntity(event.transaction.hash.toHex() + "-" + event.logIndex.toString()); - const jurorTokensPerCourt = ensureJurorTokensPerCourt(jurorAddress, "1"); + const juror = ensureUser(jurorAddress); stakeSet.juror = juror.id; stakeSet.courtID = event.params._courtID; stakeSet.stake = event.params._amount; - stakeSet.newTotalStake = jurorTokensPerCourt.effectiveStake; + stakeSet.newTotalStake = juror.totalStake; stakeSet.blocknumber = event.block.number; stakeSet.timestamp = event.block.timestamp; stakeSet.logIndex = event.logIndex;