1
1
import { useQuery } from "@tanstack/react-query" ;
2
2
3
3
import { useGraphqlBatcher } from "context/GraphqlBatcher" ;
4
- import { useMemo } from "react " ;
4
+ import { isUndefined } from "utils/index " ;
5
5
6
6
import { graphql } from "src/graphql" ;
7
7
import { HomePageBlockQuery } from "src/graphql/graphql" ;
@@ -34,11 +34,32 @@ const homePageBlockQuery = graphql(`
34
34
}
35
35
` ) ;
36
36
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 ;
39
60
const { graphqlBatcher } = useGraphqlBatcher ( ) ;
40
61
41
- const usedQuery = useQuery ( {
62
+ return useQuery < HomePageBlockStats > ( {
42
63
queryKey : [ `homePageBlockQuery${ blockNumber } -${ allTime } ` ] ,
43
64
enabled : isEnabled ,
44
65
staleTime : Infinity ,
@@ -48,104 +69,100 @@ export const useHomePageBlockQuery = (blockNumber: number | null, allTime: boole
48
69
document : homePageBlockQuery ,
49
70
variables : { blockNumber } ,
50
71
} ) ;
51
- return data ;
72
+
73
+ return processData ( data , allTime ) ;
52
74
} ,
53
75
} ) ;
76
+ } ;
54
77
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 ( ) ;
115
83
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 ;
143
93
144
- return { mostDisputedCourt , bestDrawingChancesCourt , bestExpectedRewardCourt , diffCourts } ;
145
- } else {
146
- return undefined ;
94
+ if ( id === parentIndex ) {
95
+ processedCourts [ id ] = court ;
96
+ return court ;
147
97
}
148
- } , [ usedQuery ] ) ;
149
98
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
+ } ;
151
122
} ;
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