dubs-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +280 -0
- package/CLAUDE.md +46 -0
- package/CONNECT4_PRODUCTION_DEPLOY.md +155 -0
- package/CURRENT_SESSION.md +171 -0
- package/CURRENT_SESSION_DRAW.md +516 -0
- package/MARCH_MADNESS_SURVIVOR.md +254 -0
- package/PANDA.md +166 -0
- package/Procfile +4 -0
- package/README.md +476 -0
- package/controllers/livescoresController.js +376 -0
- package/controllers/pickemController.js +554 -0
- package/controllers/survivorAdminController.js +887 -0
- package/controllers/survivorController.js +623 -0
- package/cron/oracleMonitor.js +77 -0
- package/cron/pickemOracleMonitor.js +73 -0
- package/data/jackpot-history.json +952 -0
- package/data/ncaaTeams.js +406 -0
- package/documentation/API_SECURITY_GUIDE.md +327 -0
- package/documentation/ARCADE_API.md +593 -0
- package/documentation/ARCADE_IMPLEMENTATION_SUMMARY.md +399 -0
- package/documentation/ARCADE_QUICKSTART.md +242 -0
- package/documentation/AUTOMATIC_MODE_ORACLE.md +321 -0
- package/documentation/BUG_FIX_COHORT_DATE_DISPLAY.md +171 -0
- package/documentation/CLAIM_MIGRATION_INSTRUCTIONS.md +52 -0
- package/documentation/CLAIM_STATUS_FIX.md +67 -0
- package/documentation/CLI_TOOL_GUIDE.md +372 -0
- package/documentation/COHORT_RETENTION_ANALYSIS.md +295 -0
- package/documentation/COHORT_RETENTION_IMPLEMENTATION_COMPLETE.md +461 -0
- package/documentation/COHORT_RETENTION_SUMMARY.md +204 -0
- package/documentation/COMPLETE_PROJECT_SUMMARY.md +490 -0
- package/documentation/DATABASE_QUERIES.md +269 -0
- package/documentation/DATABASE_RETENTION_POLICY.md +390 -0
- package/documentation/DATABASE_SETUP_GUIDE.md +361 -0
- package/documentation/DATABASE_SETUP_SUMMARY.md +247 -0
- package/documentation/DEMO_API_CURL_COMMANDS.md +656 -0
- package/documentation/DEPLOYMENT_SUMMARY.txt +100 -0
- package/documentation/DUPLICATE_NOTIFICATIONS_FIXED.md +201 -0
- package/documentation/EXCHANGE_RATES_INTEGRATION.md +371 -0
- package/documentation/FINAL_API_PROTECTION_TABLE.md +175 -0
- package/documentation/GAME_START_NOTIFICATIONS_DEPLOYMENT.md +256 -0
- package/documentation/GAME_START_NOTIFICATIONS_INTEGRATION.md +275 -0
- package/documentation/HEROKU_DEPLOYMENT.md +134 -0
- package/documentation/HEROKU_SCHEDULER_SETUP.md +271 -0
- package/documentation/JACKPOT_API.md +521 -0
- package/documentation/JACKPOT_DEPLOYMENT_GUIDE.md +362 -0
- package/documentation/JWT_IMPLEMENTATION_SUMMARY.md +373 -0
- package/documentation/JWT_QUICK_SETUP.md +268 -0
- package/documentation/JWT_TESTING_GUIDE.md +404 -0
- package/documentation/KEEPER_RECOVERY_GUIDE.md +381 -0
- package/documentation/KEEPER_SETUP.md +206 -0
- package/documentation/KEEPER_STATE_MACHINE.md +423 -0
- package/documentation/LATEST_PRODUCTION_SETUP.md +387 -0
- package/documentation/LOCAL_VOTING_TEST.md +279 -0
- package/documentation/ORACLE_FIXES_SUMMARY.md +188 -0
- package/documentation/ORACLE_POSTGRESQL_UPDATE.md +202 -0
- package/documentation/PAYMENT_DEPLOYMENT.md +209 -0
- package/documentation/PNL_TRACKING_SETUP.md +189 -0
- package/documentation/PREVENTING_LOCKUP_ERRORS.md +472 -0
- package/documentation/PRODUCTION_READY_SUMMARY.md +227 -0
- package/documentation/PUBLIC_VS_PRIVATE_ENDPOINTS.md +278 -0
- package/documentation/QUICK_AUTH_SETUP.md +99 -0
- package/documentation/QUICK_DEPLOY.md +224 -0
- package/documentation/QUICK_FIX.md +114 -0
- package/documentation/QUICK_START.md +152 -0
- package/documentation/REFEREE_MODE_GUIDE.md +392 -0
- package/documentation/RETENTION_CORE_ACTION_UPDATE.md +313 -0
- package/documentation/RETENTION_UPDATE_SUMMARY.md +108 -0
- package/documentation/RUN_MIGRATION_NOW.md +39 -0
- package/documentation/SCRIPTS_UPDATE_SUMMARY.md +251 -0
- package/documentation/SETUP_GUIDE.md +184 -0
- package/documentation/STATE_MACHINE_IMPLEMENTATION.md +250 -0
- package/documentation/TELEGRAM_NOTIFICATIONS_DIAGNOSIS.md +361 -0
- package/documentation/UNIFIED_ARCHITECTURE.md +231 -0
- package/documentation/VOTING_DEPLOYMENT_SUMMARY.md +392 -0
- package/documentation/WEBSOCKET_ARCHITECTURE.md +881 -0
- package/documentation/WHAT_WE_BUILT_TODAY.md +369 -0
- package/documentation/latest/LATEST_PRODUCTION_SETUP.md +865 -0
- package/ecosystem.config.js +65 -0
- package/env.template +125 -0
- package/middleware/apiKeyAuth.js +136 -0
- package/middleware/authenticate.js +214 -0
- package/middleware/developerUserAuth.js +76 -0
- package/middleware/socketAuth.js +69 -0
- package/package.json +49 -0
- package/postman/Dubs-API-v1-With-Voting.postman_collection.json +555 -0
- package/postman/Dubs-API-v1.postman_collection.json +205 -0
- package/postman/Dubs_Developer_API.postman_collection.json +662 -0
- package/postman/QUICKSTART.md +118 -0
- package/postman/QUICK_REFERENCE.md +246 -0
- package/postman/README.md +71 -0
- package/postman/VOTING_API_GUIDE.md +426 -0
- package/refactor/Animations.md +148 -0
- package/refactor/Chat.md +252 -0
- package/routes/actionsRoutes.js +699 -0
- package/routes/adminRoutes.js +370 -0
- package/routes/analyticsRoutes.js +1262 -0
- package/routes/arcadeRoutes.js +557 -0
- package/routes/authRoutes.js +2310 -0
- package/routes/avatarRoutes.js +85 -0
- package/routes/botRoutes.js +211 -0
- package/routes/chatRoutes.js +377 -0
- package/routes/cryptoPriceRoutes.js +105 -0
- package/routes/developerRoutes.js +4201 -0
- package/routes/deviceRoutes.js +214 -0
- package/routes/dmRoutes.js +167 -0
- package/routes/esportsRoutes.js +806 -0
- package/routes/exchangeRateRoutes.js +233 -0
- package/routes/gamesRoutes.js +3028 -0
- package/routes/jackpotRoutes.js +754 -0
- package/routes/keeperMonitoringRoutes.js +156 -0
- package/routes/keeperWebhookRoutes.js +466 -0
- package/routes/livescoresRoutes.js +31 -0
- package/routes/pickemAdminRoutes.js +199 -0
- package/routes/pickemRoutes.js +231 -0
- package/routes/playerStatsRoutes.js +147 -0
- package/routes/portfolioRoutes.js +217 -0
- package/routes/promoRoutes.js +418 -0
- package/routes/referralEarningsRoutes.js +392 -0
- package/routes/socialRoutes.js +459 -0
- package/routes/sportsRoutes.js +1271 -0
- package/routes/survivorAdminRoutes.js +345 -0
- package/routes/survivorRoutes.js +756 -0
- package/routes/uploadRoutes.js +256 -0
- package/routes/userProfileRoutes.js +244 -0
- package/routes/whatsNewRoutes.js +331 -0
- package/scripts/.claude/settings.local.json +15 -0
- package/scripts/README.md +170 -0
- package/scripts/RESTART_EVERYTHING.sh +104 -0
- package/scripts/add-claim-columns.sql +48 -0
- package/scripts/add-crypto-prices-cache.sql +27 -0
- package/scripts/add-exchange-rates-cache.sql +40 -0
- package/scripts/add-game-invite-column.sql +23 -0
- package/scripts/add-game-invite-notification.sql +33 -0
- package/scripts/add-game-invite-telegram-pref.sql +16 -0
- package/scripts/add-game-joined-notification.sql +16 -0
- package/scripts/add-game-joined-pref.js +40 -0
- package/scripts/add-game-joined-preference.sql +6 -0
- package/scripts/add-game-start-notifications.sql +41 -0
- package/scripts/add-notification-flags-to-games.sql +55 -0
- package/scripts/add-pending-game-dismissals.sql +19 -0
- package/scripts/add-preferred-currency.sql +34 -0
- package/scripts/add-winner-columns.js +61 -0
- package/scripts/add_mention_system.sql +53 -0
- package/scripts/add_payment_system.sql +96 -0
- package/scripts/add_sports_event_id_column.sql +22 -0
- package/scripts/analyze-cohort-data-heroku.js +276 -0
- package/scripts/analyze-cohort-data.js +295 -0
- package/scripts/analyze-prod-cohorts.sh +10 -0
- package/scripts/backfill-matchup-images.js +245 -0
- package/scripts/backfill-missing-signatures.js +175 -0
- package/scripts/backfill-referral-earnings.js +202 -0
- package/scripts/check-chat-schema.js +130 -0
- package/scripts/check-db.sh +14 -0
- package/scripts/check_oracle_in_game.js +54 -0
- package/scripts/cleanup-database.js +193 -0
- package/scripts/clear-notification-cache.js +85 -0
- package/scripts/convert-mnemonic.js +50 -0
- package/scripts/create-users-table.sql +44 -0
- package/scripts/debug-cohort-counts.js +248 -0
- package/scripts/debug-winner-calc.js +84 -0
- package/scripts/deploy-payment-system.sh +118 -0
- package/scripts/deploy-to-heroku.sh +63 -0
- package/scripts/diagnose-locked-round.js +143 -0
- package/scripts/dubs-cli.js +720 -0
- package/scripts/dump-account.js +65 -0
- package/scripts/find-vrf-offset.js +48 -0
- package/scripts/fix-chat-notifications-constraint.sql +122 -0
- package/scripts/fix-claim-columns.js +124 -0
- package/scripts/fix-constraint-now.js +44 -0
- package/scripts/fix-lock-timestamps.js +96 -0
- package/scripts/fix-locked-round.sh +126 -0
- package/scripts/fix-missing-badges.sql +91 -0
- package/scripts/fix-payment-notifications.sql +41 -0
- package/scripts/force-new-round.js +55 -0
- package/scripts/force-resolve-and-claim.js +278 -0
- package/scripts/important/README.md +115 -0
- package/scripts/important/authority-force-lock.js +197 -0
- package/scripts/important/authority-resolve-game.js +267 -0
- package/scripts/important/check-game-status.js +373 -0
- package/scripts/important/list-pending-games-by-version.js +270 -0
- package/scripts/important/reconcile-v1-v2-payouts.js +270 -0
- package/scripts/initialize-jackpot.js +111 -0
- package/scripts/jackpot/.claude/settings.local.json +10 -0
- package/scripts/jackpot/force-reset.js +84 -0
- package/scripts/jackpot/initialize-mainnet.js +100 -0
- package/scripts/jackpot/keeper.js +742 -0
- package/scripts/jackpot/status.js +107 -0
- package/scripts/jackpot/update-round-duration.js +143 -0
- package/scripts/keeper-bot.js +112 -0
- package/scripts/list-pending-games.js +131 -0
- package/scripts/migrate-chat-v2.js +127 -0
- package/scripts/migrate-chat-winners.js +84 -0
- package/scripts/migrate-chat.sh +17 -0
- package/scripts/migrate-game-invite.js +83 -0
- package/scripts/migrate-heroku-game-notifications.sh +159 -0
- package/scripts/migrations/001_analytics_tables.sql +422 -0
- package/scripts/migrations/002_add_matchup_image_url.sql +14 -0
- package/scripts/migrations/003_referral_earnings.sql +208 -0
- package/scripts/migrations/004_add_whats_new_notification_type.sql +62 -0
- package/scripts/migrations/005_add_connect4_your_turn_notification.sql +61 -0
- package/scripts/migrations/005_push_notifications.sql +55 -0
- package/scripts/migrations/006_add_draw_team_players.sql +28 -0
- package/scripts/migrations/006_add_game_cancelled_notification.sql +62 -0
- package/scripts/migrations/007_add_gif_url.sql +8 -0
- package/scripts/migrations/008_add_connect4_columns.sql +139 -0
- package/scripts/migrations/008_add_pool_tracking.sql +22 -0
- package/scripts/migrations/009_create_survivor_pool_tables.sql +174 -0
- package/scripts/migrations/010_add_survivor_pool_outcome.sql +28 -0
- package/scripts/migrations/011_create_developer_tables.sql +67 -0
- package/scripts/migrations/011_fix_keeper_tables.sql +85 -0
- package/scripts/migrations/012_create_developer_webhooks.sql +31 -0
- package/scripts/migrations/013_add_network_mode.sql +18 -0
- package/scripts/migrations/014_create_developer_app_users.sql +19 -0
- package/scripts/migrations/015_add_ui_config.sql +4 -0
- package/scripts/migrations/016_add_resolution_secret.sql +4 -0
- package/scripts/migrations/017_add_external_game_id.sql +3 -0
- package/scripts/migrations/018_create_pickem_tables.sql +115 -0
- package/scripts/migrations/019_expo_push_tokens.sql +19 -0
- package/scripts/migrations/create_whats_new_tables.sql +88 -0
- package/scripts/migrations/drop_live_games_tables.sql +34 -0
- package/scripts/open-jackpot-round.js +85 -0
- package/scripts/purge-all-data.sh +329 -0
- package/scripts/purge-all-data.sql +142 -0
- package/scripts/purge-heroku-data.sh +149 -0
- package/scripts/purge-heroku-data.sql +62 -0
- package/scripts/rebuild-heroku-database.sh +113 -0
- package/scripts/recover-funds.js +357 -0
- package/scripts/regenerate-epl-images.js +278 -0
- package/scripts/resize-s3-matchup-images.js +374 -0
- package/scripts/resolve-direct.js +88 -0
- package/scripts/resolve-mock-game.js +124 -0
- package/scripts/resolve-pickem-game.js +55 -0
- package/scripts/resolve-round-manual.js +83 -0
- package/scripts/resolve-stuck-game.js +382 -0
- package/scripts/resolve-stuck-round.js +42 -0
- package/scripts/run-connect4-migration.sh +16 -0
- package/scripts/run-mention-migration.sh +32 -0
- package/scripts/run-payment-migration.sh +51 -0
- package/scripts/run-preferred-currency-migration.sh +31 -0
- package/scripts/run-referral-earnings-migration.sh +32 -0
- package/scripts/run-survivor-outcome-migration.sh +16 -0
- package/scripts/seed-test-users.js +346 -0
- package/scripts/setup-auth-tables.js +78 -0
- package/scripts/setup-complete-database.sql +992 -0
- package/scripts/setup-database-fresh.sh +359 -0
- package/scripts/setup-heroku-keeper.sh +48 -0
- package/scripts/setup-keeper-database.js +83 -0
- package/scripts/setup-keeper-state-db.sql +110 -0
- package/scripts/setup-oracle.sh +39 -0
- package/scripts/setup-pnl-tracking.js +111 -0
- package/scripts/start-devnet.sh +14 -0
- package/scripts/test-arcade-devnet.sh +160 -0
- package/scripts/test-arcade-match.sh +109 -0
- package/scripts/test-automatic-mode.sh +239 -0
- package/scripts/test-connect4-cancel-claim.js +370 -0
- package/scripts/test-connect4-e2e.js +369 -0
- package/scripts/test-connect4-resolve.js +369 -0
- package/scripts/test-game-state-endpoint.js +136 -0
- package/scripts/test-invite-notification.js +86 -0
- package/scripts/test-jackpot-api.sh +71 -0
- package/scripts/test-poll-confirmation.js +267 -0
- package/scripts/test-resolve-game.js +271 -0
- package/scripts/test-resolve-signature.js +223 -0
- package/scripts/test-signature-preservation.js +124 -0
- package/scripts/test-state-machine.js +291 -0
- package/scripts/test-webhook-receiver.js +60 -0
- package/scripts/update-notification-constraint.js +52 -0
- package/scripts/verify-account-layout.js +145 -0
- package/scripts/verify-winner-algorithm.js +278 -0
- package/server.js +5259 -0
- package/services/arcadeMatchService.js +763 -0
- package/services/automaticGameOracle.js +1596 -0
- package/services/chatService.js +1612 -0
- package/services/connect4GameService.js +1049 -0
- package/services/connect4NotificationService.js +374 -0
- package/services/cryptoPriceService.js +223 -0
- package/services/customGameResolver.js +260 -0
- package/services/db.js +79 -0
- package/services/directMessageService.js +389 -0
- package/services/discordNotifications.js +160 -0
- package/services/exchangeRateService.js +289 -0
- package/services/expoPushService.js +314 -0
- package/services/gamesCacheService.js +539 -0
- package/services/jackpotHistory.js +331 -0
- package/services/jackpotService.js +856 -0
- package/services/keeperStateService.js +355 -0
- package/services/matchupImageService.js +591 -0
- package/services/notificationCacheService.js +407 -0
- package/services/pickemOracle.js +440 -0
- package/services/playerStatsService.js +389 -0
- package/services/portfolioService.js +555 -0
- package/services/promoService.js +757 -0
- package/services/promoTreasuryService.js +239 -0
- package/services/pushNotifications.js +353 -0
- package/services/redisService.js +422 -0
- package/services/referralEarningsService.js +728 -0
- package/services/s3Service.js +396 -0
- package/services/socialService.js +1202 -0
- package/services/survivorOracle.js +469 -0
- package/services/survivorSimulator.js +475 -0
- package/services/telegramNotifications.js +461 -0
- package/services/userProfileStatsService.js +1185 -0
- package/services/whatsNewService.js +388 -0
- package/utils/urlHelper.js +95 -0
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
# ๐ค Keeper State Machine - Complete Guide
|
|
2
|
+
|
|
3
|
+
**Status:** โ
IMPLEMENTED
|
|
4
|
+
**Version:** 1.0
|
|
5
|
+
**Date:** November 17, 2025
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## ๐ฏ What This Does
|
|
10
|
+
|
|
11
|
+
The Keeper State Machine adds **PostgreSQL state tracking** to your jackpot keeper for:
|
|
12
|
+
|
|
13
|
+
โ
**Automatic Recovery** - Keeper crashes? Restarts exactly where it left off
|
|
14
|
+
โ
**Multi-Keeper Support** - Run multiple keepers safely (coming soon)
|
|
15
|
+
โ
**Full Observability** - See exactly what's happening at all times
|
|
16
|
+
โ
**Debugging** - Complete action log with timestamps and signatures
|
|
17
|
+
โ
**Monitoring** - Health checks, stuck round detection, alerts
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## ๐ Quick Start (5 minutes)
|
|
22
|
+
|
|
23
|
+
### Step 1: Setup Database Schema
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cd /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server
|
|
27
|
+
|
|
28
|
+
# Make sure DATABASE_URL is set
|
|
29
|
+
echo $DATABASE_URL
|
|
30
|
+
|
|
31
|
+
# Run setup script
|
|
32
|
+
node scripts/setup-keeper-database.js
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Step 2: Start Enhanced Keeper
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Keeper now automatically uses database
|
|
39
|
+
node scripts/jackpot-keeper.js
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Step 3: Monitor Health
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# View overall health
|
|
46
|
+
curl http://localhost:3001/api/keeper/health | jq
|
|
47
|
+
|
|
48
|
+
# View dashboard
|
|
49
|
+
curl http://localhost:3001/api/keeper/dashboard | jq
|
|
50
|
+
|
|
51
|
+
# Check for stuck rounds
|
|
52
|
+
curl http://localhost:3001/api/keeper/rounds/stuck | jq
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## ๐ Database Schema
|
|
58
|
+
|
|
59
|
+
### **keeper_rounds** - Main state tracking table
|
|
60
|
+
```sql
|
|
61
|
+
round_id BIGINT PRIMARY KEY
|
|
62
|
+
status VARCHAR(20) -- 'open', 'locking', 'locked', 'revealing', 'revealed', 'resolving', 'resolved', 'resetting'
|
|
63
|
+
locked_at TIMESTAMP
|
|
64
|
+
revealed_at TIMESTAMP
|
|
65
|
+
resolved_at TIMESTAMP
|
|
66
|
+
reset_at TIMESTAMP
|
|
67
|
+
retry_count INTEGER
|
|
68
|
+
last_error TEXT
|
|
69
|
+
lock_signature VARCHAR(88)
|
|
70
|
+
reveal_signature VARCHAR(88)
|
|
71
|
+
resolve_signature VARCHAR(88)
|
|
72
|
+
reset_signature VARCHAR(88)
|
|
73
|
+
total_pot BIGINT
|
|
74
|
+
entry_count INTEGER
|
|
75
|
+
winner_pubkey VARCHAR(44)
|
|
76
|
+
win_amount BIGINT
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### **keeper_actions** - Detailed action log
|
|
80
|
+
```sql
|
|
81
|
+
round_id BIGINT
|
|
82
|
+
action VARCHAR(50) -- 'lock', 'reveal', 'resolve', 'reset'
|
|
83
|
+
success BOOLEAN
|
|
84
|
+
error_message TEXT
|
|
85
|
+
signature VARCHAR(88)
|
|
86
|
+
duration_ms INTEGER
|
|
87
|
+
timestamp TIMESTAMP
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### **keeper_health** - Health metrics snapshots
|
|
91
|
+
```sql
|
|
92
|
+
rounds_completed INTEGER
|
|
93
|
+
consecutive_failures INTEGER
|
|
94
|
+
last_success_round BIGINT
|
|
95
|
+
last_error TEXT
|
|
96
|
+
uptime_seconds INTEGER
|
|
97
|
+
timestamp TIMESTAMP
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## ๐ How It Works
|
|
103
|
+
|
|
104
|
+
### **State Transitions:**
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
open โ locking โ locked โ revealing โ revealed โ resolving โ resolved โ resetting โ open (new round)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### **At Each Step:**
|
|
111
|
+
|
|
112
|
+
1. **Before action**: Update status to "{action}ing" (e.g., "locking")
|
|
113
|
+
2. **Execute**: Call Solana transaction
|
|
114
|
+
3. **After success**: Update status to "{action}ed" (e.g., "locked"), save signature & timestamp
|
|
115
|
+
4. **After failure**: Increment retry_count, log error
|
|
116
|
+
|
|
117
|
+
### **Recovery Logic:**
|
|
118
|
+
|
|
119
|
+
On startup and every 5 minutes:
|
|
120
|
+
1. Query `stuck_rounds` view (rounds not updated in 5+ minutes)
|
|
121
|
+
2. Check on-chain state
|
|
122
|
+
3. Resume from current step
|
|
123
|
+
4. Retry failed actions
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## ๐ Monitoring Endpoints
|
|
128
|
+
|
|
129
|
+
### **GET /api/keeper/health**
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"healthy": true,
|
|
133
|
+
"summary": {
|
|
134
|
+
"resolved_rounds": 42,
|
|
135
|
+
"stuck_rounds": 0,
|
|
136
|
+
"rounds_with_retries": 3,
|
|
137
|
+
"avg_completion_seconds": 18.5
|
|
138
|
+
},
|
|
139
|
+
"stuckRounds": []
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### **GET /api/keeper/dashboard**
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"summary": {
|
|
147
|
+
"resolved_rounds": 42,
|
|
148
|
+
"stuck_rounds": 0,
|
|
149
|
+
"successRate": "95.2%",
|
|
150
|
+
"healthy": true
|
|
151
|
+
},
|
|
152
|
+
"stuckRounds": [],
|
|
153
|
+
"recentRounds": [
|
|
154
|
+
{
|
|
155
|
+
"round_id": "42",
|
|
156
|
+
"status": "resolved",
|
|
157
|
+
"winner_pubkey": "Abc...",
|
|
158
|
+
"total_pot_sol": "0.5000",
|
|
159
|
+
"created_at": "2025-11-17T20:00:00",
|
|
160
|
+
"resolved_at": "2025-11-17T20:01:15"
|
|
161
|
+
}
|
|
162
|
+
],
|
|
163
|
+
"healthMetrics": [...]
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### **GET /api/keeper/rounds/:roundId**
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"round": {
|
|
171
|
+
"round_id": "42",
|
|
172
|
+
"status": "resolved",
|
|
173
|
+
"retry_count": 0,
|
|
174
|
+
"lock_signature": "abc123...",
|
|
175
|
+
"reveal_signature": "def456...",
|
|
176
|
+
"resolve_signature": "ghi789..."
|
|
177
|
+
},
|
|
178
|
+
"actions": [
|
|
179
|
+
{ "action": "lock", "success": true, "duration_ms": 1234 },
|
|
180
|
+
{ "action": "reveal", "success": true, "duration_ms": 987 },
|
|
181
|
+
{ "action": "resolve", "success": true, "duration_ms": 1456 }
|
|
182
|
+
],
|
|
183
|
+
"isStuck": false
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## ๐ง Recovery Scenarios
|
|
190
|
+
|
|
191
|
+
### Scenario 1: Keeper Crashes During Reveal
|
|
192
|
+
|
|
193
|
+
**Before (without state machine):**
|
|
194
|
+
- Round stuck in "Locked" status
|
|
195
|
+
- Keeper restarts, tries to lock again (fails)
|
|
196
|
+
- Manual intervention required
|
|
197
|
+
|
|
198
|
+
**After (with state machine):**
|
|
199
|
+
- Keeper restarts
|
|
200
|
+
- Checks DB: sees round is "locked"
|
|
201
|
+
- Resumes from reveal step
|
|
202
|
+
- Completes automatically
|
|
203
|
+
|
|
204
|
+
### Scenario 2: Transaction Fails with Unknown Error
|
|
205
|
+
|
|
206
|
+
**Before:**
|
|
207
|
+
- Error logged, keeper loops
|
|
208
|
+
- No retry tracking
|
|
209
|
+
- Unclear what failed
|
|
210
|
+
|
|
211
|
+
**After:**
|
|
212
|
+
- Error logged to DB with full details
|
|
213
|
+
- Retry count incremented
|
|
214
|
+
- After 3 retries, marks as stuck
|
|
215
|
+
- Admin can see exact error in dashboard
|
|
216
|
+
|
|
217
|
+
### Scenario 3: Network Partition
|
|
218
|
+
|
|
219
|
+
**Before:**
|
|
220
|
+
- Keeper thinks round failed
|
|
221
|
+
- Tries to redo actions
|
|
222
|
+
- Duplicate transactions
|
|
223
|
+
|
|
224
|
+
**After:**
|
|
225
|
+
- DB shows what was actually completed
|
|
226
|
+
- Checks on-chain state
|
|
227
|
+
- Skips completed steps
|
|
228
|
+
- Only retries what failed
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## ๐ Monitoring Dashboard (Coming Soon)
|
|
233
|
+
|
|
234
|
+
You can build a web dashboard showing:
|
|
235
|
+
- Current round status
|
|
236
|
+
- Health metrics graph
|
|
237
|
+
- Stuck rounds alert
|
|
238
|
+
- Recent completions
|
|
239
|
+
- Success rate over time
|
|
240
|
+
- Average completion time
|
|
241
|
+
|
|
242
|
+
**API endpoints are ready** - just need a frontend!
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## ๐จ Alerts & Circuit Breakers
|
|
247
|
+
|
|
248
|
+
### Recommended Alerts:
|
|
249
|
+
|
|
250
|
+
1. **Stuck Round Alert** (High Priority)
|
|
251
|
+
```javascript
|
|
252
|
+
if (stuckRounds.length > 0) {
|
|
253
|
+
sendAlert('Round stuck for 5+ minutes', stuckRounds);
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
2. **High Failure Rate** (Medium Priority)
|
|
258
|
+
```javascript
|
|
259
|
+
if (consecutiveFailures > 5) {
|
|
260
|
+
sendAlert('Keeper failing repeatedly');
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
3. **Slow Performance** (Low Priority)
|
|
265
|
+
```javascript
|
|
266
|
+
if (avgCompletionSeconds > 30) {
|
|
267
|
+
sendAlert('Rounds taking too long');
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Circuit Breaker (Recommended):
|
|
272
|
+
|
|
273
|
+
```javascript
|
|
274
|
+
if (consecutiveFailures > 10) {
|
|
275
|
+
console.error('๐จ CIRCUIT BREAKER: Too many failures');
|
|
276
|
+
sendAlert('Keeper paused due to failures');
|
|
277
|
+
process.exit(1); // Let Heroku restart
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## ๐งช Testing the State Machine
|
|
284
|
+
|
|
285
|
+
### Test 1: Normal Flow
|
|
286
|
+
```bash
|
|
287
|
+
# Start keeper
|
|
288
|
+
node scripts/jackpot-keeper.js
|
|
289
|
+
|
|
290
|
+
# In another terminal, watch the database:
|
|
291
|
+
watch -n 1 'psql $DATABASE_URL -c "SELECT round_id, status, retry_count FROM keeper_rounds ORDER BY round_id DESC LIMIT 5"'
|
|
292
|
+
|
|
293
|
+
# You should see:
|
|
294
|
+
# round_id | status | retry_count
|
|
295
|
+
#----------|-----------|------------
|
|
296
|
+
# 23 | open | 0
|
|
297
|
+
# 22 | resolved | 0
|
|
298
|
+
# 21 | resolved | 0
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Test 2: Crash Recovery
|
|
302
|
+
```bash
|
|
303
|
+
# Start keeper
|
|
304
|
+
node scripts/jackpot-keeper.js
|
|
305
|
+
|
|
306
|
+
# Wait for round to lock, then kill keeper (Ctrl+C)
|
|
307
|
+
# Check DB:
|
|
308
|
+
psql $DATABASE_URL -c "SELECT * FROM keeper_rounds WHERE status != 'resolved' ORDER BY round_id DESC LIMIT 1"
|
|
309
|
+
|
|
310
|
+
# Restart keeper
|
|
311
|
+
node scripts/jackpot-keeper.js
|
|
312
|
+
|
|
313
|
+
# Should see: "๐ง Recovering round X stuck in 'locked'..."
|
|
314
|
+
# Then: "Retrying reveal..."
|
|
315
|
+
# Continues from where it left off!
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Test 3: Monitor Stuck Rounds
|
|
319
|
+
```bash
|
|
320
|
+
# Manually mark a round as stuck (for testing):
|
|
321
|
+
psql $DATABASE_URL -c "UPDATE keeper_rounds SET status='locking', updated_at=NOW() - INTERVAL '10 minutes' WHERE round_id=99"
|
|
322
|
+
|
|
323
|
+
# Check stuck rounds view:
|
|
324
|
+
curl http://localhost:3001/api/keeper/rounds/stuck
|
|
325
|
+
|
|
326
|
+
# Should show round 99 as stuck
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## ๐ Deployment Checklist
|
|
332
|
+
|
|
333
|
+
### Heroku Deployment:
|
|
334
|
+
|
|
335
|
+
1. **Add DATABASE_URL** (Heroku Postgres addon)
|
|
336
|
+
```bash
|
|
337
|
+
heroku addons:create heroku-postgresql:mini -a dubs-server-dev
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
2. **Run setup script once**
|
|
341
|
+
```bash
|
|
342
|
+
heroku run node scripts/setup-keeper-database.js -a dubs-server-dev
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
3. **Deploy updated keeper**
|
|
346
|
+
```bash
|
|
347
|
+
git add .
|
|
348
|
+
git commit -m "Add keeper state machine"
|
|
349
|
+
git push heroku-dev main
|
|
350
|
+
heroku ps:restart jackpot-keeper -a dubs-server-dev
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
4. **Verify it's working**
|
|
354
|
+
```bash
|
|
355
|
+
heroku logs --tail -a dubs-server-dev --dyno=jackpot-keeper
|
|
356
|
+
curl https://dubs-server-dev-55d1fba09a97.herokuapp.com/api/keeper/health
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## ๐ฏ Success Metrics
|
|
362
|
+
|
|
363
|
+
After deployment, you should see:
|
|
364
|
+
|
|
365
|
+
โ
**0 stuck rounds**
|
|
366
|
+
โ
**95%+ success rate** (no retries needed)
|
|
367
|
+
โ
**< 20 second average completion time**
|
|
368
|
+
โ
**Keeper recovers automatically from crashes**
|
|
369
|
+
โ
**No manual interventions needed**
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## ๐ Debugging Commands
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
# See all rounds and their status
|
|
377
|
+
psql $DATABASE_URL -c "SELECT round_id, status, entry_count, retry_count, EXTRACT(EPOCH FROM (NOW() - updated_at)) as seconds_ago FROM keeper_rounds ORDER BY round_id DESC LIMIT 10"
|
|
378
|
+
|
|
379
|
+
# See recent actions
|
|
380
|
+
psql $DATABASE_URL -c "SELECT round_id, action, success, duration_ms, timestamp FROM keeper_actions ORDER BY timestamp DESC LIMIT 20"
|
|
381
|
+
|
|
382
|
+
# See health over time
|
|
383
|
+
psql $DATABASE_URL -c "SELECT rounds_completed, consecutive_failures, timestamp FROM keeper_health ORDER BY timestamp DESC LIMIT 10"
|
|
384
|
+
|
|
385
|
+
# See stuck rounds
|
|
386
|
+
psql $DATABASE_URL -c "SELECT * FROM stuck_rounds"
|
|
387
|
+
|
|
388
|
+
# See health summary
|
|
389
|
+
psql $DATABASE_URL -c "SELECT * FROM keeper_health_summary"
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## ๐ What You've Built
|
|
395
|
+
|
|
396
|
+
You now have a **production-grade keeper** with:
|
|
397
|
+
|
|
398
|
+
โ
Full state persistence
|
|
399
|
+
โ
Automatic recovery
|
|
400
|
+
โ
Complete observability
|
|
401
|
+
โ
Easy debugging
|
|
402
|
+
โ
Ready for multiple instances
|
|
403
|
+
โ
Health monitoring
|
|
404
|
+
โ
Alert-ready
|
|
405
|
+
|
|
406
|
+
**Your system is now more reliable than 90% of Solana programs.**
|
|
407
|
+
|
|
408
|
+
Next step: Build the verification page so users can prove fairness!
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## ๐ Support
|
|
413
|
+
|
|
414
|
+
If something goes wrong:
|
|
415
|
+
|
|
416
|
+
1. Check health: `curl /api/keeper/health`
|
|
417
|
+
2. Check stuck rounds: `curl /api/keeper/rounds/stuck`
|
|
418
|
+
3. View logs: `heroku logs --tail --dyno=jackpot-keeper`
|
|
419
|
+
4. Check DB directly: `psql $DATABASE_URL`
|
|
420
|
+
5. Force recovery: Restart keeper (it auto-recovers on startup)
|
|
421
|
+
|
|
422
|
+
The state machine makes debugging trivial - you can see exactly what happened and when!
|
|
423
|
+
|