1+ import { capture } from '@snapshot-labs/snapshot-sentry' ;
12import snapshot from '@snapshot-labs/snapshot.js' ;
3+ import { z } from 'zod' ;
24import db from './mysql' ;
35import { CB } from '../constants' ;
46
7+ type Datum = {
8+ id : string ;
9+ vpState : string ;
10+ vpByStrategy : number [ ] ;
11+ vpValueByStrategy : number [ ] ;
12+ } ;
13+
514const REFRESH_INTERVAL = 10 * 1000 ;
615const BATCH_SIZE = 100 ;
716
8- /**
9- * Calculates the total vote value based on the voting power and the proposal's value per strategy.
10- * @returns The total vote value, in the currency unit specified by the proposal's vp_value_by_strategy values
11- **/
12- export function getVoteValue ( vp_value_by_strategy : number [ ] , vp_by_strategy : number [ ] ) : number {
13- if ( ! vp_value_by_strategy . length ) return 0 ;
14-
15- if ( vp_value_by_strategy . length !== vp_by_strategy . length ) {
16- throw new Error ( 'invalid data to compute vote value' ) ;
17- }
17+ const datumSchema = z
18+ . object ( {
19+ id : z . string ( ) ,
20+ vpState : z . string ( ) ,
21+ vpValueByStrategy : z . array ( z . number ( ) . finite ( ) ) ,
22+ vpByStrategy : z . array ( z . number ( ) . finite ( ) )
23+ } )
24+ . refine ( data => data . vpValueByStrategy . length === data . vpByStrategy . length , {
25+ message : 'Array length mismatch: vpValueByStrategy and vpByStrategy must have the same length'
26+ } ) ;
1827
19- return vp_value_by_strategy . reduce ( ( sum , value , index ) => sum + value * vp_by_strategy [ index ] , 0 ) ;
28+ export function getVoteValue ( datum : Pick < Datum , 'vpValueByStrategy' | 'vpByStrategy' > ) : number {
29+ return datum . vpValueByStrategy . reduce (
30+ ( sum , value , index ) => sum + value * datum . vpByStrategy [ index ] ,
31+ 0
32+ ) ;
2033}
2134
22- type Datum = {
23- id : string ;
24- vp_state : string ;
25- vp_by_strategy : number [ ] ;
26- vp_value_by_strategy : number [ ] ;
27- } ;
28-
2935async function getVotes ( ) : Promise < Datum [ ] > {
3036 const query = `
3137 SELECT votes.id, votes.vp_state, votes.vp_by_strategy, proposals.vp_value_by_strategy
3238 FROM votes
3339 JOIN proposals ON votes.proposal = proposals.id
34- WHERE proposals.cb IN (?) AND votes.cb IN (?)
40+ WHERE proposals.cb IN (?) AND votes.cb = ?
3541 ORDER BY votes.created ASC
3642 LIMIT ?` ;
3743 const results = await db . queryAsync ( query , [
3844 [ CB . PENDING_FINAL , CB . PENDING_COMPUTE , CB . FINAL ] ,
39- [ CB . PENDING_SYNC , CB . PENDING_COMPUTE ] ,
45+ CB . PENDING_COMPUTE ,
4046 BATCH_SIZE
4147 ] ) ;
4248
4349 return results . map ( ( r : any ) => {
44- r . vp_value_by_strategy = JSON . parse ( r . vp_value_by_strategy ) ;
45- r . vp_by_strategy = JSON . parse ( r . vp_by_strategy ) ;
46- return r ;
50+ return {
51+ id : r . id ,
52+ vpState : r . vp_state ,
53+ vpValueByStrategy : JSON . parse ( r . vp_value_by_strategy ) ,
54+ vpByStrategy : JSON . parse ( r . vp_by_strategy )
55+ } ;
4756 } ) ;
4857}
4958
@@ -55,11 +64,16 @@ async function refreshVotesVpValues(data: Datum[]) {
5564 query . push ( 'UPDATE votes SET vp_value = ?, cb = ? WHERE id = ? LIMIT 1' ) ;
5665
5766 try {
58- const value = getVoteValue ( datum . vp_value_by_strategy , datum . vp_by_strategy ) ;
67+ const validatedDatum = datumSchema . parse ( datum ) ;
68+ const value = getVoteValue ( validatedDatum ) ;
5969
60- params . push ( value , datum . vp_state === 'final' ? CB . FINAL : CB . PENDING_FINAL , datum . id ) ;
70+ params . push (
71+ value ,
72+ validatedDatum . vpState === 'final' ? CB . FINAL : CB . PENDING_FINAL ,
73+ validatedDatum . id
74+ ) ;
6175 } catch ( e ) {
62- console . log ( e ) ;
76+ capture ( e ) ;
6377 params . push ( 0 , CB . INELIGIBLE , datum . id ) ;
6478 }
6579 }
0 commit comments