-
Notifications
You must be signed in to change notification settings - Fork 21
Solana Head Detection: slotSubscribe #772
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
Conversation
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.
Pull request overview
This PR migrates Solana head detection from the expensive blockSubscribe WebSocket API to the lightweight slotSubscribe API. The change significantly reduces bandwidth usage (by ~93% according to benchmarks) while maintaining real-time performance through throttled HTTP calls to retrieve actual block heights.
Changes:
- Replaced
blockSubscribe/blockUnsubscribewithslotSubscribe/slotUnsubscribefor WebSocket subscriptions - Implemented throttled HTTP calls (every 5 slots) to retrieve actual block heights via
getBlockHeight - Introduced synthetic hash generation based on slot numbers for ForkChoice deduplication
- Added caching mechanism for block heights per upstream to minimize HTTP calls
- Simplified data models: replaced
SolanaWrapper/SolanaContext/SolanaResultwithSolanaSlotNotification
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
| src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt | Core implementation of slotSubscribe-based head detection with throttled HTTP calls, synthetic hash generation, and per-upstream caching |
| src/test/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecificTest.kt | Comprehensive test coverage for slot parsing, throttling logic, synthetic hashes, and error handling scenarios |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt
Show resolved
Hide resolved
src/test/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecificTest.kt
Show resolved
Hide resolved
src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt
Outdated
Show resolved
Hide resolved
src/test/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecificTest.kt
Show resolved
Hide resolved
src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt
Show resolved
Hide resolved
src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt
Show resolved
Hide resolved
src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt
Show resolved
Hide resolved
0783c77 to
7fa4e77
Compare
src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaChainSpecific.kt
Show resolved
Hide resolved
… strategy, remove BlockSubscribe tests, and enhance caching logic. Delete SolanaStrategyBenchmark for performance comparison.
Replace two separate RPC calls (getSlot + getBlockHeight) with a single getEpochInfo call that returns both absoluteSlot and blockHeight
…imistic height estimation and improve error handling for RPC failures. Update tests to validate new behavior.
7fa4e77 to
08d9fe6
Compare
…Height with getEpochInfo for improved efficiency and accuracy in height estimation. Update logic to handle actual slot and height retrieval.
Solana Head Detection: slotSubscribe vs blockSubscribe
Summary
This PR replaces the expensive
blockSubscribeWebSocket subscription with the lightweightslotSubscribeapproach for Solana head detection. The change reduces WebSocket bandwidth by 95% while maintaining the same real-time performance.Problem
The
blockSubscribeAPI has significant drawbacks:--rpc-pubsub-enable-block-subscriptionnode flagSolution
Use
slotSubscribewith throttledgetBlockHeightHTTP calls:Benchmark Results
Synthetic Benchmark (100 slots)
Real Production Test (Solana Mainnet, ~11 minutes each)
Daily Extrapolation (24 hours)
Implementation Details
slotSubscribe Notification Format
{"slot": 112301554, "parent": 112301553, "root": 112301500}~50 bytes per notification
Throttling Logic
Synthetic Hash
Since slotSubscribe doesn't provide block hash, we generate a deterministic synthetic hash from slot:
This ensures ForkChoice deduplication works correctly.
Conclusion
slotSubscribe is the recommended approach because:
The trade-off of ~46K HTTP calls/day is acceptable: