-
Notifications
You must be signed in to change notification settings - Fork 83
feat(scripts): add wallet-operator mapper for consolidation analysis #3840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Add comprehensive wallet-operator mapping toolset for beta staker consolidation analysis. Enables identification of wallets containing deprecated operators and BTC distribution calculations. Core functionality: - query-dkg-events.js: Extracts operator membership from on-chain DKG events - analyze-per-operator.js: Calculates BTC distribution by provider - validate-operator-list.js: Verifies operator list completeness Configuration: - operators.json: Defines KEEP (4 active) vs DISABLE (16 deprecated) operators - Contract ABIs for Bridge and WalletRegistry interactions - Archive node RPC support for historical event queries Documentation: - README: Usage guide and integration points - Manual sweep procedures and execution scripts - Operator consolidation communication guidelines Integration: - Provides data source for monitoring dashboard - Supports draining progress assessment - Enables manual sweep decision-making Technical details: - Uses threshold cryptography (51/100 signatures) - Queries sortition pool for operator address resolution - Classifies operators by provider (STAKED, P2P, BOAR, NUCO)
| const path = require('path'); | ||
|
|
||
| const MAPPING_FILE = path.join(__dirname, 'wallet-operator-mapping.json'); | ||
| const CSV_PATH = '/Users/leonardosaturnino/Documents/GitHub/memory-bank/20250809-beta-staker-consolidation/knowledge/threshold_stakers_may_2025.csv'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we commit this file to the repo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit hash 6461451
| } | ||
|
|
||
| // File paths | ||
| const PROOF_OF_FUNDS_PATH = '/Users/leonardosaturnino/Documents/GitHub/memory-bank/20250809-beta-staker-consolidation/knowledge/20251006-tbtc-proof-of-funds.json'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we commit this file to the repo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit hash 6461451
| if (providerShares[data.provider]) { | ||
| if (data.status === 'KEEP') { | ||
| providerShares[data.provider].keep += data.totalShare; | ||
| providerShares[data.provider].keepWallets = data.walletCount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure this is = and not +=?
| providerShares[data.provider].keepWallets = data.walletCount; | |
| providerShares[data.provider].keepWallets += data.walletCount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit hash 6461451
| providerShares[data.provider].keepWallets = data.walletCount; | ||
| } else { | ||
| providerShares[data.provider].disable += data.totalShare; | ||
| providerShares[data.provider].disableWallets = data.walletCount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
| providerShares[data.provider].disableWallets = data.walletCount; | |
| providerShares[data.provider].disableWallets += data.walletCount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit hash 6461451
Fix critical bugs and configuration issues identified in code review: Bug Fixes: - Fix wallet count aggregation in analyze-per-operator.js - Changed assignment operator from = to += on lines 122, 125 - Now correctly sums wallet counts across all operators per provider - Previously only recorded last operator's count, causing incorrect analysis Configuration: - Externalize hard-coded file paths to environment variables - query-dkg-events.js: Use PROOF_OF_FUNDS_PATH with ./data/ fallback - validate-operator-list.js: Use THRESHOLD_STAKERS_CSV_PATH with ./data/ fallback - Scripts now portable across team members and environments Documentation: - Add data file setup section to README.md - Document two setup options: default directory and env variables - Create data/README.md with file requirements and sources - Update .env.example with new configuration variables - Add data/ directory to .gitignore All review comments from piotr-roslaniec addressed.
Add gitignore rules for wallet-operator-mapper script working files: - .env for local configuration - data/ directory for analysis outputs - JSON mapping files generated during execution - package-lock.json for npm dependency lock These files are runtime artifacts that should not be tracked.
|
Looks solid overall! Since these queries archive nodes for historical DKG events, have you run into any RPC rate limting issues? scanning large block ranges can sometimes be flaky depending on the provider. As a nice to have in the future, might be worth adding some retry logic or at least documenting the expected runtime and which RPC providers work well (I'm guessing this needs archive node access, so not all Infura/Alchemy tiers will work). Also curious... what's the typical execution time for a full analysis run? |
Remove single-purpose investigation scripts and add general-purpose query utilities for ongoing operator management. Removed: - calculate-all-beta-staker-weights.js (governance task complete) - calculate-allowlist-weights.js (superseded) - generate-allowlist-weights-final.js (output saved) - check-current-pool-weights.js (investigation complete) - check-sortition-pool-divisor.js (findings incorporated) - investigate-unknown-operator.js (one-time investigation) - verify-missing-wallets.js (specific verification done) Added utility scripts: - query-proof-of-funds.js: Generate proof-of-funds reports - query-sortition-pool.js: Check operator pool status - query-all-pool-operators.js: Discover all pool operators - query-all-stakers.js: Verify staker documentation completeness Updated README to document all remaining scripts in Main and Utility sections.
piotr-roslaniec
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just a couple of questions
| console.log(`\nTotal unique staking providers: ${allStakingProviders.size}\n`); | ||
|
|
||
| // Load our known list | ||
| const stakersJson = require('/Users/leonardosaturnino/Documents/GitHub/memory-bank/20250809-beta-staker-consolidation/knowledge/threshold_stakers_may_2025.json'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add this JSON to repo or use a permalink to fetch it
| ); | ||
| const walletRegistry = new ethers.Contract(WALLET_REGISTRY_ADDRESS, walletRegistryAbi, provider); | ||
|
|
||
| for (const provider of unknownProviders) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: We are shadowing const provider = new ethers.JsonRpcProvider(...) from before
| for (const provider of unknownProviders) { | |
| for (const stakingProvider of unknownProviders) { |
| totalBalance += BigInt(balanceSats); | ||
|
|
||
| // Convert satoshis to BTC as integer string (truncated, no decimals) | ||
| const balanceBTCInt = Math.floor(balanceSats / 100000000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about whether or not this will lead to some significant loss in precision
| const balanceBTCInt = Math.floor(balanceSats / 100000000); | |
| const balanceBTCInt = (balanceSats / 100000000).toFixed(8); |
| providers.forEach(provider => { | ||
| if (summary.byProvider[provider]) { | ||
| summary.byProvider[provider].wallets++; | ||
| summary.byProvider[provider].btc += wallet.btcBalance; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if wallet has operators from multiple deprecated providers? Is that possible? If yes, is it going to be counted multiple times?
| summary.byProvider[provider].btc += wallet.btcBalance; | |
| summary.byProvider[provider].btc += wallet.btcBalance / providers.size |
Add comprehensive wallet-operator mapping toolset for beta staker consolidation analysis. Enables identification of wallets containing deprecated operators and BTC distribution calculations.
Core functionality:
Configuration:
Documentation:
Integration:
Technical details: