11import { useQuery } from "@tanstack/react-query" ;
22
33import { useGraphqlBatcher } from "context/GraphqlBatcher" ;
4- import { useMemo } from "react " ;
4+ import { isUndefined } from "utils/index " ;
55
66import { graphql } from "src/graphql" ;
77import { HomePageBlockQuery } from "src/graphql/graphql" ;
@@ -34,11 +34,32 @@ const homePageBlockQuery = graphql(`
3434 }
3535` ) ;
3636
37- export const useHomePageBlockQuery = ( blockNumber : number | null , allTime : boolean ) => {
38- const isEnabled = blockNumber !== null || allTime ;
37+ type Court = HomePageBlockQuery [ "presentCourts" ] [ number ] ;
38+ type CourtWithTree = Court & {
39+ numberDisputes : number ;
40+ numberVotes : number ;
41+ feeForJuror : bigint ;
42+ effectiveStake : bigint ;
43+ treeNumberDisputes : number ;
44+ treeNumberVotes : number ;
45+ votesPerPnk : number ;
46+ treeVotesPerPnk : number ;
47+ expectedRewardPerPnk : number ;
48+ treeExpectedRewardPerPnk : number ;
49+ } ;
50+
51+ export type HomePageBlockStats = {
52+ mostDisputedCourt : CourtWithTree ;
53+ bestDrawingChancesCourt : CourtWithTree ;
54+ bestExpectedRewardCourt : CourtWithTree ;
55+ courts : CourtWithTree [ ] ;
56+ } ;
57+
58+ export const useHomePageBlockQuery = ( blockNumber : number | undefined , allTime : boolean ) => {
59+ const isEnabled = ! isUndefined ( blockNumber ) || allTime ;
3960 const { graphqlBatcher } = useGraphqlBatcher ( ) ;
4061
41- const usedQuery = useQuery ( {
62+ return useQuery < HomePageBlockStats > ( {
4263 queryKey : [ `homePageBlockQuery${ blockNumber } -${ allTime } ` ] ,
4364 enabled : isEnabled ,
4465 staleTime : Infinity ,
@@ -48,104 +69,100 @@ export const useHomePageBlockQuery = (blockNumber: number | null, allTime: boole
4869 document : homePageBlockQuery ,
4970 variables : { blockNumber } ,
5071 } ) ;
51- return data ;
72+
73+ return processData ( data , allTime ) ;
5274 } ,
5375 } ) ;
76+ } ;
5477
55- const courtActivityStats = useMemo ( ( ) => {
56- if ( usedQuery . data && ! usedQuery . isFetching ) {
57- const diffCourts = allTime
58- ? usedQuery . data . presentCourts . map ( ( presentCourt ) => ( {
59- ...presentCourt ,
60- numberDisputes : presentCourt . numberDisputes ,
61- treeNumberDisputes : presentCourt . numberDisputes ,
62- numberVotes : presentCourt . numberVotes ,
63- treeNumberVotes : presentCourt . numberVotes ,
64- effectiveStake : presentCourt . effectiveStake ,
65- votesPerPnk : Number ( presentCourt . numberVotes ) / ( Number ( presentCourt . effectiveStake ) / 1e18 ) ,
66- treeVotesPerPnk : Number ( presentCourt . numberVotes ) / ( Number ( presentCourt . effectiveStake ) / 1e18 ) ,
67- } ) )
68- : usedQuery . data . presentCourts . map ( ( presentCourt ) => {
69- const pastCourt = usedQuery . data . pastCourts . find ( ( pastCourt ) => pastCourt . id === presentCourt . id ) ;
70-
71- return {
72- ...presentCourt ,
73- numberDisputes : pastCourt
74- ? presentCourt . numberDisputes - pastCourt . numberDisputes
75- : presentCourt . numberDisputes ,
76- treeNumberDisputes : pastCourt
77- ? presentCourt . numberDisputes - pastCourt . numberDisputes
78- : presentCourt . numberDisputes ,
79- numberVotes : pastCourt ? presentCourt . numberVotes - pastCourt . numberVotes : presentCourt . numberVotes ,
80- treeNumberVotes : pastCourt ? presentCourt . numberVotes - pastCourt . numberVotes : presentCourt . numberVotes ,
81- effectiveStake : pastCourt
82- ? ( BigInt ( presentCourt . effectiveStake ) + BigInt ( pastCourt . effectiveStake ) ) / 2n
83- : presentCourt . effectiveStake ,
84- votesPerPnk :
85- Number ( pastCourt ? presentCourt . numberVotes - pastCourt . numberVotes : presentCourt . numberVotes ) /
86- ( Number (
87- pastCourt
88- ? ( BigInt ( presentCourt . effectiveStake ) + BigInt ( pastCourt . effectiveStake ) ) / 2n
89- : presentCourt . effectiveStake
90- ) /
91- 1e18 ) ,
92- treeVotesPerPnk :
93- Number ( pastCourt ? presentCourt . numberVotes - pastCourt . numberVotes : presentCourt . numberVotes ) /
94- ( Number (
95- pastCourt
96- ? ( BigInt ( presentCourt . effectiveStake ) + BigInt ( pastCourt . effectiveStake ) ) / 2n
97- : presentCourt . effectiveStake
98- ) /
99- 1e18 ) ,
100- } ;
101- } ) ;
102-
103- const mostDisputedCourt = diffCourts . toSorted ( ( a , b ) => b . numberDisputes - a . numberDisputes ) [ 0 ] ;
104- // 1. biggest chances of getting drawn
105- // fact: getting drawn in a parent court also subjects you to its rewards
106- // so, rewards/disputes trickle down
107-
108- for ( const parent of diffCourts ) {
109- for ( const child of diffCourts ) {
110- if ( parent . id === child . parent ?. id ) {
111- child . treeNumberVotes = String ( Number ( parent . treeNumberVotes ) + Number ( child . treeNumberVotes ) ) ;
112- }
113- }
114- }
78+ const processData = ( data : HomePageBlockQuery , allTime : boolean ) => {
79+ const presentCourts = data . presentCourts ;
80+ const pastCourts = data . pastCourts ;
81+ const processedCourts : CourtWithTree [ ] = Array ( presentCourts . length ) ;
82+ const processed = new Set ( ) ;
11583
116- for ( const parent of diffCourts ) {
117- for ( const child of diffCourts ) {
118- if ( parent . id === child . parent ?. id ) {
119- child . treeVotesPerPnk += parent . votesPerPnk ;
120- }
121- }
122- }
123- const bestDrawingChancesCourt = diffCourts . toSorted ( ( a , b ) => b . treeVotesPerPnk - a . treeVotesPerPnk ) [ 0 ] ;
124- // 2. expected reward
125- // since we isolated the exclusive disputes from the cumulative disputes
126- // we can calculate the "isolated reward" of every court
127- // after that's done, then just trickle the rewards down
128-
129- for ( const c of diffCourts ) {
130- c . expectedRewardPerPnk = c . votesPerPnk * c . feeForJuror ;
131- c . treeExpectedRewardPerPnk = c . expectedRewardPerPnk ;
132- }
133- for ( const parent of diffCourts ) {
134- for ( const child of diffCourts ) {
135- if ( parent . id === child . parent ?. id ) {
136- child . treeExpectedRewardPerPnk = parent . treeExpectedRewardPerPnk + child . treeExpectedRewardPerPnk ;
137- }
138- }
139- }
140- const bestExpectedRewardCourt = diffCourts . toSorted (
141- ( a , b ) => b . treeExpectedRewardPerPnk - a . treeExpectedRewardPerPnk
142- ) [ 0 ] ;
84+ const processCourt = ( id : number ) : CourtWithTree => {
85+ if ( processed . has ( id ) ) return processedCourts [ id ] ;
86+
87+ processed . add ( id ) ;
88+ const court =
89+ ! allTime && id < data . pastCourts . length
90+ ? addTreeValuesWithDiff ( presentCourts [ id ] , pastCourts [ id ] )
91+ : addTreeValues ( presentCourts [ id ] ) ;
92+ const parentIndex = court . parent ? Number ( court . parent . id ) - 1 : 0 ;
14393
144- return { mostDisputedCourt , bestDrawingChancesCourt , bestExpectedRewardCourt , diffCourts } ;
145- } else {
146- return undefined ;
94+ if ( id === parentIndex ) {
95+ processedCourts [ id ] = court ;
96+ return court ;
14797 }
148- } , [ usedQuery ] ) ;
14998
150- return courtActivityStats ;
99+ processedCourts [ id ] = {
100+ ...court ,
101+ treeNumberDisputes : court . treeNumberDisputes + processCourt ( parentIndex ) . treeNumberDisputes ,
102+ treeNumberVotes : court . treeNumberVotes + processCourt ( parentIndex ) . treeNumberVotes ,
103+ treeVotesPerPnk : court . treeVotesPerPnk + processCourt ( parentIndex ) . treeVotesPerPnk ,
104+ treeExpectedRewardPerPnk : court . treeExpectedRewardPerPnk + processCourt ( parentIndex ) . treeExpectedRewardPerPnk ,
105+ } ;
106+
107+ return processedCourts [ id ] ;
108+ } ;
109+
110+ for ( const court of presentCourts . toReversed ( ) ) {
111+ processCourt ( Number ( court . id ) - 1 ) ;
112+ }
113+
114+ processedCourts . reverse ( ) ;
115+
116+ return {
117+ mostDisputedCourt : getCourtMostDisputes ( processedCourts ) ,
118+ bestDrawingChancesCourt : getCourtBestDrawingChances ( processedCourts ) ,
119+ bestExpectedRewardCourt : getBestExpectedRewardCourt ( processedCourts ) ,
120+ courts : processedCourts ,
121+ } ;
151122} ;
123+
124+ const addTreeValues = ( court : Court ) : CourtWithTree => {
125+ const votesPerPnk = Number ( court . numberVotes ) / ( Number ( court . effectiveStake ) / 1e18 ) ;
126+ const expectedRewardPerPnk = votesPerPnk * ( Number ( court . feeForJuror ) / 1e18 ) ;
127+ return {
128+ ...court ,
129+ numberDisputes : Number ( court . numberDisputes ) ,
130+ numberVotes : Number ( court . numberVotes ) ,
131+ feeForJuror : BigInt ( court . feeForJuror ) / BigInt ( 1e18 ) ,
132+ effectiveStake : BigInt ( court . effectiveStake ) ,
133+ treeNumberDisputes : Number ( court . numberDisputes ) ,
134+ treeNumberVotes : Number ( court . numberVotes ) ,
135+ votesPerPnk,
136+ treeVotesPerPnk : votesPerPnk ,
137+ expectedRewardPerPnk,
138+ treeExpectedRewardPerPnk : expectedRewardPerPnk ,
139+ } ;
140+ } ;
141+
142+ const addTreeValuesWithDiff = ( presentCourt : Court , pastCourt : Court ) : CourtWithTree => {
143+ const presentCourtWithTree = addTreeValues ( presentCourt ) ;
144+ const pastCourtWithTree = addTreeValues ( pastCourt ) ;
145+ const diffNumberVotes = presentCourtWithTree . numberVotes - pastCourtWithTree . numberVotes ;
146+ const avgEffectiveStake = ( presentCourtWithTree . effectiveStake + pastCourtWithTree . effectiveStake ) / 2n ;
147+ const votesPerPnk = diffNumberVotes / Number ( avgEffectiveStake ) ;
148+ const expectedRewardPerPnk = votesPerPnk * Number ( presentCourt . feeForJuror ) ;
149+ return {
150+ ...presentCourt ,
151+ numberDisputes : presentCourtWithTree . numberDisputes - pastCourtWithTree . numberDisputes ,
152+ treeNumberDisputes : presentCourtWithTree . treeNumberDisputes - pastCourtWithTree . treeNumberDisputes ,
153+ numberVotes : diffNumberVotes ,
154+ treeNumberVotes : presentCourtWithTree . treeNumberVotes - pastCourtWithTree . treeNumberVotes ,
155+ effectiveStake : avgEffectiveStake ,
156+ votesPerPnk,
157+ treeVotesPerPnk : votesPerPnk ,
158+ expectedRewardPerPnk,
159+ treeExpectedRewardPerPnk : expectedRewardPerPnk ,
160+ } ;
161+ } ;
162+
163+ const getCourtMostDisputes = ( courts : CourtWithTree [ ] ) =>
164+ courts . toSorted ( ( a : CourtWithTree , b : CourtWithTree ) => b . numberDisputes - a . numberDisputes ) [ 0 ] ;
165+ const getCourtBestDrawingChances = ( courts : CourtWithTree [ ] ) =>
166+ courts . toSorted ( ( a , b ) => b . treeVotesPerPnk - a . treeVotesPerPnk ) [ 0 ] ;
167+ const getBestExpectedRewardCourt = ( courts : CourtWithTree [ ] ) =>
168+ courts . toSorted ( ( a , b ) => b . treeExpectedRewardPerPnk - a . treeExpectedRewardPerPnk ) [ 0 ] ;
0 commit comments