Skip to content
This repository was archived by the owner on May 11, 2026. It is now read-only.

feat: add vp value to leaderboard#571

Merged
wa0x6e merged 15 commits into
masterfrom
feat-add-vp-value-to-leaderboard
Apr 17, 2026
Merged

feat: add vp value to leaderboard#571
wa0x6e merged 15 commits into
masterfrom
feat-add-vp-value-to-leaderboard

Conversation

@wa0x6e

@wa0x6e wa0x6e commented Aug 6, 2025

Copy link
Copy Markdown
Contributor

Summary

Adds vp_value tracking to the leaderboard table and defers vote deletion to an async background script. Leaderboard updates use idempotent SUM/COUNT queries from the votes table instead of fragile delta-based increments, preventing drift from re-votes, race conditions, or missed updates.

Background workers (votesVpValue, scores, shutter) now guard against overwriting cb=PENDING_DELETE set by delete-proposal, preventing a race condition where votes marked for deletion could be orphaned.

Changes

  • ✨ Add vp_value column to the leaderboard table
  • ✨ Add PENDING_DELETE constant (cb = -3) for soft-deleting votes
  • ✨ Add deleteProposalVotes async script to process pending vote deletions in batches
  • ♻️ delete-proposal writer: mark votes as PENDING_DELETE instead of deleting inline
  • ♻️ votesVpValue: refresh leaderboard vp_value using SUM(vp_value) from votes table (idempotent)
  • ♻️ deleteProposalVotes: refresh leaderboard vote_count and vp_value using COUNT(*)/SUM() via single JOIN subquery (idempotent)
  • 🐛 votesVpValue: guard vote cb update with AND cb = PENDING_COMPUTE to prevent overwriting PENDING_DELETE
  • 🐛 scores: guard vote update with AND cb != PENDING_DELETE to prevent overwriting deletion state
  • 🐛 shutter: skip PENDING_DELETE votes during decryption to avoid wasted work and inconsistency

Benchmark

Tested against production database (68M+ votes). All queries use the PRIMARY KEY (voter, space, proposal) index.

Query Time
SUM(vp_value) WHERE voter+space (single pair) ~500ms
Batch leaderboard refresh (50 pairs) 1,123ms
Batch leaderboard refresh (200 pairs) 797ms
Batch leaderboard refresh (500 pairs) 1,355ms

~500ms is mostly network latency to PlanetScale. The query itself is near-instant (PK index lookup).

Test plan

  • Verify vp_value column is added to leaderboard table
  • Verify votes are marked cb = -3 on proposal deletion instead of being deleted inline
  • Verify deleteProposalVotes script picks up and deletes pending votes
  • Verify leaderboard vp_value is refreshed correctly after vote vp_value computation
  • Verify leaderboard vote_count and vp_value are correct after vote deletion
  • Verify background workers do not overwrite PENDING_DELETE on votes mid-deletion

🤖 Generated with Claude Code

@wa0x6e
wa0x6e requested a review from Copilot August 6, 2025 20:33

This comment was marked as outdated.

@wa0x6e
wa0x6e changed the base branch from master to feat-assign-fiat-value-to-vote August 6, 2025 20:33
@wa0x6e
wa0x6e requested a review from Copilot August 7, 2025 17:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds voting power value tracking to the leaderboard system by introducing a new vp_value column that accumulates the total voting power value for each user across spaces and proposals.

  • Adds vp_value column to the leaderboard table schema with appropriate indexing
  • Updates vote creation logic to increment the user's voting power value in the leaderboard
  • Implements voting power value decrementation when proposals are deleted

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
test/schema.sql Adds vp_value DECIMAL column and index to leaderboard table
src/writer/vote.ts Updates vote creation to track and increment voting power values in leaderboard
src/writer/delete-proposal.ts Implements batch processing to decrement voting power values when proposals are deleted
src/helpers/entityValue.ts Refactors vote value calculation using reduce for better readability

Comment thread src/writer/delete-proposal.ts Outdated
Comment thread src/writer/delete-proposal.ts Outdated
Base automatically changed from feat-assign-fiat-value-to-vote to master September 3, 2025 07:14
@wa0x6e
wa0x6e force-pushed the feat-add-vp-value-to-leaderboard branch 2 times, most recently from 748e75e to c313e29 Compare January 29, 2026 11:43
@wa0x6e
wa0x6e requested review from ChaituVR and bonustrack January 29, 2026 12:04
Comment thread src/writer/delete-proposal.ts Outdated
@ChaituVR

This comment was marked as outdated.

Comment thread src/writer/delete-proposal.ts Outdated
@wa0x6e
wa0x6e force-pushed the feat-add-vp-value-to-leaderboard branch from a76dbb9 to 19c7502 Compare March 2, 2026 04:25
@wa0x6e
wa0x6e requested a review from Copilot March 2, 2026 05:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/helpers/deleteProposalVotes.ts Outdated
Comment thread src/helpers/leaderboardQuery.ts Outdated
Comment thread src/helpers/votesVpValue.ts Outdated
Comment thread src/helpers/deleteProposalVotes.ts
@wa0x6e
wa0x6e force-pushed the feat-add-vp-value-to-leaderboard branch from 206780c to 50e4e82 Compare March 2, 2026 06:58
@wa0x6e
wa0x6e requested a review from Copilot March 2, 2026 06:59
…ript

- Add vp_value column to leaderboard table, updated asynchronously
  by votesVpValue when votes are finalized
- Add PENDING_DELETE cb status for deferred vote deletion
- Add deleteProposalVotes async script to process flagged votes in
  batches (update leaderboard/spaces counters, then delete)
- Simplify delete-proposal writer: flags votes instead of deleting inline
- Initialize vp_value to 0 on leaderboard row creation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@wa0x6e
wa0x6e force-pushed the feat-add-vp-value-to-leaderboard branch from 50e4e82 to db2a9a6 Compare March 2, 2026 07:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/writer/delete-proposal.ts
Comment thread src/helpers/votesVpValue.ts Outdated
Comment thread src/helpers/deleteProposalVotes.ts
Comment thread src/index.ts
Comment thread src/helpers/votesVpValue.ts Outdated
…nting on re-votes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@wa0x6e
wa0x6e requested a review from ChaituVR March 12, 2026 13:24
Comment thread src/helpers/votesVpValue.ts Outdated
Comment thread src/helpers/votesVpValue.ts
… deltas

Replace delta-based vp_value leaderboard updates with idempotent SUM
queries from the votes table. Benchmarked at ~500ms per (voter, space)
pair on 68M+ votes, using the PRIMARY KEY index.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@wa0x6e
wa0x6e requested a review from Copilot March 19, 2026 13:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread test/schema.sql
Comment thread src/helpers/votesVpValue.ts Outdated
Comment thread src/helpers/votesVpValue.ts Outdated
Comment thread src/helpers/deleteProposalVotes.ts Outdated
Comment thread src/helpers/deleteProposalVotes.ts Outdated
wa0x6e and others added 5 commits March 19, 2026 22:08
…letion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…te deletion

Single UPDATE query with COUNT/SUM correlated subqueries instead of
per-pair JOIN loop. Benchmarked fastest at ~500ms for 100 pairs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/helpers/deleteProposalVotes.ts
Comment thread src/helpers/deleteProposalVotes.ts
Comment thread src/helpers/votesVpValue.ts
Comment thread src/helpers/deleteProposalVotes.ts Outdated
@wa0x6e
wa0x6e requested a review from ChaituVR March 20, 2026 05:05
@ChaituVR

Copy link
Copy Markdown
Member

Claude says this: (But i didn't verify code myself but it sounds reasonable)

The Orphaned Vote Bug — Step by Step

Setup: Alice voted on Proposal P1 in space aave.eth. Her vote has cb = PENDING_COMPUTE, vp_value = 0.

Step 0: votesVpValue wakes up, starts its cycle.
Step 1: getPendingVotes() runs:

SELECT id, voter, space, proposal FROM votes WHERE cb = -1 LIMIT 500
Returns: { id: 'vote_abc', voter: 'alice', space: 'aave.eth', proposal: 'P1' }

Steps 2: getProposalVpValues() runs:

SELECT id, cb, vp_value_by_strategy FROM proposals WHERE cb IN (-1,-2,1,-10) AND votes > 0
Returns: { id: 'P1', vpValueByStrategy: [0.5, 1.2] } — proposal exists, all good.

Step 3: A moderator deletes Proposal P1. delete-proposal.ts runs atomically:

DELETE FROM proposals WHERE id = 'P1';
UPDATE votes SET cb = -3 WHERE proposal = 'P1';  -- PENDING_DELETE
UPDATE leaderboard SET proposal_count = GREATEST(proposal_count - 1, 0) WHERE user = 'mod' AND space = 'aave.eth';
UPDATE spaces SET proposal_count = GREATEST(proposal_count - 1, 0) WHERE id = 'aave.eth';
Alice's vote is now cb = -3 (PENDING_DELETE) in the database.

Step 4: votesVpValue doesn't know any of this happened. It still has the old data from Time 1-2. It computes vp_value = 100 and runs refreshVotesVpValues():

UPDATE votes SET vp_value = 100, cb = 1 WHERE id IN ('vote_abc');
UPDATE leaderboard l SET vp_value = COALESCE((
  SELECT SUM(v.vp_value) FROM votes v WHERE v.voter = l.user AND v.space = l.space
), 0) WHERE (l.user, l.space) IN (('alice', 'aave.eth'));

This overwrites cb = -3 (PENDING_DELETE) with cb = 1 (FINAL).

Background workers (votesVpValue, scores) could overwrite cb=PENDING_DELETE
set by delete-proposal, orphaning votes that should be cleaned up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@wa0x6e

wa0x6e commented Mar 24, 2026

Copy link
Copy Markdown
Contributor Author

Claude says this: (But i didn't verify code myself but it sounds reasonable)

The Orphaned Vote Bug — Step by Step

Setup: Alice voted on Proposal P1 in space aave.eth. Her vote has cb = PENDING_COMPUTE, vp_value = 0.

Step 0: votesVpValue wakes up, starts its cycle. Step 1: getPendingVotes() runs:

SELECT id, voter, space, proposal FROM votes WHERE cb = -1 LIMIT 500
Returns: { id: 'vote_abc', voter: 'alice', space: 'aave.eth', proposal: 'P1' }

Steps 2: getProposalVpValues() runs:

SELECT id, cb, vp_value_by_strategy FROM proposals WHERE cb IN (-1,-2,1,-10) AND votes > 0
Returns: { id: 'P1', vpValueByStrategy: [0.5, 1.2] } — proposal exists, all good.

Step 3: A moderator deletes Proposal P1. delete-proposal.ts runs atomically:

DELETE FROM proposals WHERE id = 'P1';
UPDATE votes SET cb = -3 WHERE proposal = 'P1';  -- PENDING_DELETE
UPDATE leaderboard SET proposal_count = GREATEST(proposal_count - 1, 0) WHERE user = 'mod' AND space = 'aave.eth';
UPDATE spaces SET proposal_count = GREATEST(proposal_count - 1, 0) WHERE id = 'aave.eth';
Alice's vote is now cb = -3 (PENDING_DELETE) in the database.

Step 4: votesVpValue doesn't know any of this happened. It still has the old data from Time 1-2. It computes vp_value = 100 and runs refreshVotesVpValues():

UPDATE votes SET vp_value = 100, cb = 1 WHERE id IN ('vote_abc');
UPDATE leaderboard l SET vp_value = COALESCE((
  SELECT SUM(v.vp_value) FROM votes v WHERE v.voter = l.user AND v.space = l.space
), 0) WHERE (l.user, l.space) IN (('alice', 'aave.eth'));

This overwrites cb = -3 (PENDING_DELETE) with cb = 1 (FINAL).

A valid concern, now fixed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/helpers/deleteProposalVotes.ts
Comment thread src/helpers/deleteProposalVotes.ts
Comment thread src/writer/delete-proposal.ts
wa0x6e and others added 2 commits March 24, 2026 22:22
Prevent shutter from decrypting and scoring votes that are
mid-deletion, avoiding wasted work and potential inconsistency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@wa0x6e

wa0x6e commented Mar 24, 2026

Copy link
Copy Markdown
Contributor Author

@ChaituVR Race conditions should be fixed now

@ChaituVR ChaituVR left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utAck, but haven't tested 🙈

Comment thread src/helpers/deleteProposalVotes.ts Outdated
Comment thread src/helpers/deleteProposalVotes.ts Outdated
@wa0x6e
wa0x6e merged commit caa0625 into master Apr 17, 2026
2 checks passed
@wa0x6e
wa0x6e deleted the feat-add-vp-value-to-leaderboard branch April 17, 2026 10:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants