Skip to content

feat: add wallet_id column for per-wallet state isolation#2

Merged
czarcas7ic merged 1 commit into
mainfrom
adam/per-wallet-voting-isolation
Mar 15, 2026
Merged

feat: add wallet_id column for per-wallet state isolation#2
czarcas7ic merged 1 commit into
mainfrom
adam/per-wallet-voting-isolation

Conversation

@czarcas7ic
Copy link
Copy Markdown
Contributor

@czarcas7ic czarcas7ic commented Mar 15, 2026

Summary

Add wallet_id TEXT NOT NULL DEFAULT '' to all voting DB tables so round state is natively scoped per wallet. VotingDb stores the wallet_id on the struct (set once via set_wallet_id()), and all queries filter by it internally. No public API signature changes on VotingDb methods.

Add wallet_id to all voting DB tables so round state is natively
scoped per wallet when both hotkey and keystone are loaded.

- Schema: wallet_id TEXT NOT NULL DEFAULT '' added to rounds (PK
  becomes (round_id, wallet_id)), bundles, cached_tree_state,
  proofs, witnesses, votes with cascading FKs
- VotingDb: stores wallet_id on the struct, set once via
  set_wallet_id(). All operations pass it internally to queries.
  No public API signature changes.
- Migration: v4 drop-and-recreate
- Tests: wallet isolation test verifies two wallets in same round
  don't cross-contaminate
Copy link
Copy Markdown
Contributor

@greg0x greg0x left a comment

Choose a reason for hiding this comment

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

retrospective approve!

Comment on lines +242 to +267
fn test_wallet_isolation() {
let db = test_db();
let conn = db.conn();
let params = test_params();

queries::insert_round(&conn, "wallet-a", &params, None).unwrap();
queries::insert_round(&conn, "wallet-b", &params, None).unwrap();

queries::insert_bundle(&conn, "test-round-1", "wallet-a", 0, &[]).unwrap();
queries::insert_bundle(&conn, "test-round-1", "wallet-b", 0, &[]).unwrap();

let commitment = vec![0xCC; 128];
queries::store_vote(&conn, "test-round-1", "wallet-a", 0, 0, 1, &commitment).unwrap();
queries::store_vote(&conn, "test-round-1", "wallet-b", 0, 0, 2, &commitment).unwrap();

let votes_a = queries::get_votes(&conn, "test-round-1", "wallet-a").unwrap();
let votes_b = queries::get_votes(&conn, "test-round-1", "wallet-b").unwrap();
assert_eq!(votes_a.len(), 1);
assert_eq!(votes_b.len(), 1);
assert_eq!(votes_a[0].choice, 1);
assert_eq!(votes_b[0].choice, 2);

queries::clear_round(&conn, "test-round-1", "wallet-a").unwrap();
let rounds_b = queries::list_rounds(&conn, "wallet-b").unwrap();
assert_eq!(rounds_b.len(), 1, "wallet-b round should survive wallet-a clear");
}
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.

Nice!

@p0mvn p0mvn mentioned this pull request May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants