Skip to content

Commit bfe6e45

Browse files
committed
feat: compute vote fiat value
feat: add index to vp_value
1 parent 228bf79 commit bfe6e45

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

src/helpers/actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export async function getProposal(space, id) {
9292
params: {}
9393
};
9494
proposal.choices = jsonParse(proposal.choices);
95+
proposal.vp_value_by_strategy = jsonParse(proposal.vp_value_by_strategy, []);
9596

9697
return proposal;
9798
}

src/helpers/utils.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,41 @@ export function getSpaceController(space: string, network = NETWORK) {
266266

267267
return snapshot.utils.getSpaceController(space, networkId, { broviderUrl });
268268
}
269+
270+
/**
271+
* Computes the dot product of two arrays by multiplying corresponding elements and summing the results.
272+
*
273+
* This function performs a dot product calculation between two arrays of numbers.
274+
* Both arrays are flattened to handle nested structures of unlimited depth before
275+
* calculation using Array.flat(Infinity).
276+
*
277+
* @param arrayA - First array of numbers. Can contain deeply nested arrays of any depth
278+
* @param arrayB - Second array of numbers. Must have the same structure as arrayA after flattening
279+
* @returns The computed dot product as a number. Returns 0 if arrays are invalid or mismatched.
280+
*
281+
* @example
282+
* // Simple arrays
283+
* dotProduct([1, 2, 3], [10, 20, 30]) // Returns 140 (1*10 + 2*20 + 3*30)
284+
*
285+
* @example
286+
* // Nested arrays (2 levels)
287+
* dotProduct([1, [2, 3]], [10, [20, 30]]) // Returns 140 (1*10 + 2*20 + 3*30)
288+
*
289+
* @example
290+
* // Deep nested arrays (unlimited depth)
291+
* dotProduct([1, [2, [3, 4]]], [10, [20, [30, 40]]]) // Returns 340 (1*10 + 2*20 + 3*30 + 4*40)
292+
*/
293+
export function dotProduct(arrayA: any[], arrayB: any[]): number {
294+
if (!Array.isArray(arrayA) || !Array.isArray(arrayB)) {
295+
return 0;
296+
}
297+
298+
const flatArrayA = arrayA.flat(Infinity).map(val => Number(val) || 0);
299+
const flatArrayB = arrayB.flat(Infinity).map(val => Number(val) || 0);
300+
301+
if (flatArrayA.length !== flatArrayB.length) {
302+
return 0;
303+
}
304+
305+
return flatArrayA.reduce((sum, val, i) => sum + val * flatArrayB[i], 0);
306+
}

src/writer/vote.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import snapshot from '@snapshot-labs/snapshot.js';
22
import { getProposal } from '../helpers/actions';
33
import log from '../helpers/log';
44
import db from '../helpers/mysql';
5-
import { captureError, hasStrategyOverride, jsonParse } from '../helpers/utils';
5+
import { captureError, dotProduct, hasStrategyOverride, jsonParse } from '../helpers/utils';
66
import { updateProposalAndVotes } from '../scores';
77

88
const scoreAPIUrl = process.env.SCORE_API_URL || 'https://score.snapshot.org';
@@ -116,6 +116,9 @@ export async function action(body, ipfs, receipt, id, context): Promise<void> {
116116
const withOverride = hasStrategyOverride(context.proposal.strategies);
117117
if (vpState === 'final' && withOverride) vpState = 'pending';
118118

119+
// Compute vote value
120+
const voteValue = dotProduct(context.proposal.vp_value_by_strategy, context.vp.vp_by_strategy);
121+
119122
const params = {
120123
id,
121124
ipfs,
@@ -130,6 +133,7 @@ export async function action(body, ipfs, receipt, id, context): Promise<void> {
130133
vp: context.vp.vp,
131134
vp_by_strategy: JSON.stringify(context.vp.vp_by_strategy),
132135
vp_state: vpState,
136+
vp_value: voteValue,
133137
cb: 0
134138
};
135139

@@ -152,7 +156,7 @@ export async function action(body, ipfs, receipt, id, context): Promise<void> {
152156
await db.queryAsync(
153157
`
154158
UPDATE votes
155-
SET id = ?, ipfs = ?, created = ?, choice = ?, reason = ?, metadata = ?, app = ?, vp = ?, vp_by_strategy = ?, vp_state = ?
159+
SET id = ?, ipfs = ?, created = ?, choice = ?, reason = ?, metadata = ?, app = ?, vp = ?, vp_by_strategy = ?, vp_state = ?, vp_value = ?
156160
WHERE voter = ? AND proposal = ? AND space = ?;
157161
UPDATE leaderboard SET last_vote = ? WHERE user = ? AND space = ? LIMIT 1;
158162
`,
@@ -167,6 +171,7 @@ export async function action(body, ipfs, receipt, id, context): Promise<void> {
167171
params.vp,
168172
params.vp_by_strategy,
169173
params.vp_state,
174+
params.vp_value,
170175
voter,
171176
proposalId,
172177
msg.space,

test/schema.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ CREATE TABLE votes (
100100
vp DECIMAL(64,30) NOT NULL,
101101
vp_by_strategy JSON NOT NULL,
102102
vp_state VARCHAR(24) NOT NULL,
103+
vp_value DECIMAL(8,3) NOT NULL DEFAULT '0.000',
103104
cb INT(11) NOT NULL,
104105
PRIMARY KEY (voter, space, proposal),
105106
UNIQUE KEY id (id),
@@ -111,6 +112,7 @@ CREATE TABLE votes (
111112
INDEX app (app),
112113
INDEX vp (vp),
113114
INDEX vp_state (vp_state),
115+
INDEX vp_value (vp_value),
114116
INDEX cb (cb)
115117
);
116118

0 commit comments

Comments
 (0)