sol-mcp 0.2.0__py3-none-any.whl

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.
@@ -0,0 +1,452 @@
1
+ """Expert guidance system for curated Solana interpretations.
2
+
3
+ This module provides curated expert knowledge that goes beyond
4
+ what's explicitly stated in the runtime code. It captures nuances,
5
+ gotchas, and insights from Anza research and community discussions.
6
+ """
7
+
8
+ from dataclasses import dataclass
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class GuidanceEntry:
13
+ """A curated guidance entry."""
14
+
15
+ topic: str
16
+ summary: str
17
+ key_points: list[str]
18
+ gotchas: list[str]
19
+ references: list[str]
20
+
21
+
22
+ # Guidance database - populated incrementally
23
+ GUIDANCE_DB: dict[str, GuidanceEntry] = {
24
+ "staking": GuidanceEntry(
25
+ topic="Stake Delegation and Rewards",
26
+ summary="Solana uses delegated PoS with warmup/cooldown periods and NO slashing.",
27
+ key_points=[
28
+ "No minimum stake requirement - any amount can be delegated",
29
+ "Warmup period: ~2 epochs for stake to become active",
30
+ "Cooldown period: ~2 epochs for stake to become withdrawable after deactivation",
31
+ "Rewards distributed per-epoch based on vote credits earned by validator",
32
+ "Stakers delegate to validators, not run validators themselves (unlike Ethereum)",
33
+ "Stake accounts are separate from vote accounts",
34
+ ],
35
+ gotchas=[
36
+ "NO SLASHING - Solana does not slash validators for misbehavior",
37
+ "Indirect penalties only: missed leader slots, lost delegations, delinquency",
38
+ "Warmup is proportional - large stakes take longer to fully activate",
39
+ "Stake must be fully cooled down before withdrawal (can't partial withdraw active stake)",
40
+ "Rewards compound automatically if not withdrawn",
41
+ ],
42
+ references=[
43
+ "programs/stake/src/stake_state.rs",
44
+ "programs/stake/src/stake_instruction.rs",
45
+ "runtime/src/bank.rs - epoch reward distribution",
46
+ ],
47
+ ),
48
+ "voting": GuidanceEntry(
49
+ topic="Vote Accounts and Tower Sync",
50
+ summary="Validators vote on blocks using vote accounts; TowerBFT provides consensus.",
51
+ key_points=[
52
+ "Vote accounts track validator's votes and lockouts",
53
+ "Each vote has a lockout that doubles with confirmation depth",
54
+ "32 confirmation levels = 2^32 slots lockout (~centuries)",
55
+ "Vote credits earned for correct votes, used for reward calculation",
56
+ "Tower sync ensures validators don't vote on conflicting forks",
57
+ "Vote transaction fees paid by validator from vote account",
58
+ ],
59
+ gotchas=[
60
+ "Vote accounts need SOL balance for transaction fees",
61
+ "Delinquent validators (missing votes) still in validator set but earn no rewards",
62
+ "Vote latency matters - late votes may not count for credits",
63
+ "Tower state persisted to disk - losing it can cause safety violations",
64
+ "Commission changes take effect next epoch",
65
+ ],
66
+ references=[
67
+ "programs/vote/src/vote_state.rs",
68
+ "programs/vote/src/vote_instruction.rs",
69
+ ],
70
+ ),
71
+ "slashing": GuidanceEntry(
72
+ topic="Why Solana Doesn't Slash (Yet)",
73
+ summary="Solana has NO protocol-level slashing; penalties are indirect market-based.",
74
+ key_points=[
75
+ "No double-sign slashing like Ethereum",
76
+ "No surround vote slashing",
77
+ "No attestation penalties for missed votes",
78
+ "Delinquent validators just don't earn rewards",
79
+ "Market handles bad actors: stakers withdraw and delegate elsewhere",
80
+ "Leader schedule skips validators not producing blocks",
81
+ ],
82
+ gotchas=[
83
+ "This may change - SIMDs could introduce slashing in future",
84
+ "Economic security relies on delegation markets, not protocol punishment",
85
+ "Validators CAN vote on conflicting forks without immediate penalty",
86
+ "TowerBFT lockouts prevent this in practice, but no slashing if violated",
87
+ "Alpenglow (Q1 2026) may introduce new safety mechanisms",
88
+ ],
89
+ references=[
90
+ "N/A - slashing not implemented",
91
+ "SIMD discussions on potential future slashing",
92
+ ],
93
+ ),
94
+ "alpenglow": GuidanceEntry(
95
+ topic="Alpenglow: New Consensus Protocol (Q1 2026)",
96
+ summary="Alpenglow replaces TowerBFT with Votor/Rotor for 100x faster finality.",
97
+ key_points=[
98
+ "Finality: 12.8s (TowerBFT) → ~150ms median, sometimes 100ms",
99
+ "Votor: replaces TowerBFT for voting and block finalization",
100
+ "Rotor: replaces/refines Turbine for data dissemination",
101
+ "Based on Martin-Alvisi Fast Byzantine Consensus (5f+1 bound)",
102
+ "Adversary tolerance: 33% → 20% for fast path",
103
+ "Proof of History (PoH) still used as cryptographic clock",
104
+ "SIMD-0326 approved by validator governance",
105
+ ],
106
+ gotchas=[
107
+ "Testnet expected by Breakpoint (Dec 2025), mainnet Q1 2026",
108
+ "Migration from TowerBFT will require careful coordination",
109
+ "Lower adversary tolerance (20% vs 33%) is tradeoff for speed",
110
+ "PoH is NOT being removed - still provides ordering",
111
+ "Research led by Prof. Wattenhofer (ETH Zurich) who found TowerBFT vulnerabilities",
112
+ ],
113
+ references=[
114
+ "SIMD-0326: proposals/0326-alpenglow.md",
115
+ "https://www.anza.xyz/blog/alpenglow-a-new-consensus-for-solana",
116
+ "https://www.helius.dev/blog/alpenglow",
117
+ ],
118
+ ),
119
+ "poh": GuidanceEntry(
120
+ topic="Proof of History",
121
+ summary="PoH is a cryptographic clock providing ordering, NOT consensus.",
122
+ key_points=[
123
+ "Sequential SHA-256 hashing creates verifiable passage of time",
124
+ "Each hash depends on previous - can't be parallelized",
125
+ "Provides global ordering without communication",
126
+ "Leader produces PoH stream, validators verify",
127
+ "NOT a consensus mechanism - TowerBFT/Alpenglow handle consensus",
128
+ "Enables high throughput by reducing coordination overhead",
129
+ ],
130
+ gotchas=[
131
+ "PoH is often misunderstood as Solana's consensus - it's not",
132
+ "PoH generator is a single point of failure during leader slot",
133
+ "Verification is parallelizable, generation is not",
134
+ "Time assumptions matter - clock drift can cause issues",
135
+ "Alpenglow keeps PoH, only replaces the consensus layer",
136
+ ],
137
+ references=[
138
+ "poh/src/poh_recorder.rs",
139
+ "poh/src/poh_service.rs",
140
+ ],
141
+ ),
142
+ "accounts": GuidanceEntry(
143
+ topic="Account Model",
144
+ summary="Solana uses flat account model with ownership and rent.",
145
+ key_points=[
146
+ "Accounts are flat key-value pairs, not a state trie",
147
+ "Each account has: lamports, data, owner, executable, rent_epoch",
148
+ "Programs (smart contracts) own accounts they create",
149
+ "Only the owner program can modify account data",
150
+ "System program owns native SOL accounts",
151
+ "Rent: accounts must maintain minimum balance or be garbage collected",
152
+ ],
153
+ gotchas=[
154
+ "Account data size is fixed at creation (can't resize easily)",
155
+ "Rent-exempt threshold: ~2 years of rent paid upfront",
156
+ "Cross-program invocations (CPI) pass accounts explicitly",
157
+ "PDAs (Program Derived Addresses) for deterministic account addresses",
158
+ "Account lookup tables (ALTs) for transaction size optimization",
159
+ ],
160
+ references=[
161
+ "runtime/src/accounts.rs",
162
+ "sdk/src/account.rs",
163
+ ],
164
+ ),
165
+ "svm": GuidanceEntry(
166
+ topic="Solana Virtual Machine",
167
+ summary="SVM executes BPF/SBF bytecode with parallel transaction processing.",
168
+ key_points=[
169
+ "Programs compile to BPF (Berkeley Packet Filter) bytecode",
170
+ "SBF (Solana BPF) is Solana's extended BPF variant",
171
+ "Parallel execution: transactions touching different accounts run concurrently",
172
+ "Compute units: each instruction costs CUs, capped per transaction",
173
+ "Native programs (vote, stake, system) run directly, not in VM",
174
+ "Upgradeable programs use BPF Loader v3",
175
+ ],
176
+ gotchas=[
177
+ "Account locking determines parallelism - overlapping accounts = sequential",
178
+ "Compute budget can be increased with priority fees",
179
+ "Stack size limited - deep recursion will fail",
180
+ "Heap size limited to 32KB by default",
181
+ "Cross-program invocations have depth limit (4)",
182
+ ],
183
+ references=[
184
+ "svm/src/",
185
+ "program-runtime/src/",
186
+ "programs/bpf_loader/",
187
+ ],
188
+ ),
189
+ "turbine": GuidanceEntry(
190
+ topic="Turbine Block Propagation",
191
+ summary="Turbine uses erasure coding and tree structure for efficient block propagation.",
192
+ key_points=[
193
+ "Blocks split into shreds (data fragments)",
194
+ "Reed-Solomon erasure coding for redundancy",
195
+ "Tree structure: leader → root → branches → leaves",
196
+ "Each node forwards to small fanout, not broadcast",
197
+ "Reduces leader bandwidth from O(n) to O(log n)",
198
+ "Retransmit stage handles missing shreds",
199
+ ],
200
+ gotchas=[
201
+ "Tree structure means propagation latency varies by position",
202
+ "Stake-weighted tree assignment - higher stake = earlier in tree",
203
+ "Network partitions can cause shred loss cascades",
204
+ "Rotor (Alpenglow) refines but doesn't fully replace Turbine concepts",
205
+ "Repair protocol handles missing shreds after propagation",
206
+ ],
207
+ references=[
208
+ "turbine/src/",
209
+ "ledger/src/shred.rs",
210
+ ],
211
+ ),
212
+ "towerbft": GuidanceEntry(
213
+ topic="TowerBFT: Current Consensus (Pre-Alpenglow)",
214
+ summary="TowerBFT is Solana's CURRENT consensus mechanism - a PBFT variant optimized for PoH.",
215
+ key_points=[
216
+ "CURRENT CONSENSUS (Jan 2026) - Alpenglow not yet live on mainnet",
217
+ "PBFT-like consensus optimized to leverage Proof of History",
218
+ "Validators vote on blocks; votes have exponential lockouts",
219
+ "Lockout doubles with each confirmation: 2, 4, 8, 16... slots",
220
+ "32 confirmations = 2^32 slots lockout (effectively permanent)",
221
+ "Fork choice: pick fork with most stake-weighted votes",
222
+ "Finality: ~12.8 seconds (32 confirmations at 400ms slots)",
223
+ "Optimistic confirmation: ~2.5 seconds for high-confidence",
224
+ ],
225
+ gotchas=[
226
+ "TowerBFT is NOT being replaced until Alpenglow ships (expected Q1 2026)",
227
+ "PoH provides ordering, TowerBFT provides consensus - they work together",
228
+ "Lockouts prevent validators from easily switching forks (Byzantine resistance)",
229
+ "Tower state must be persisted - losing it risks voting on conflicting forks",
230
+ "No explicit slashing for safety violations, but lockouts make violations expensive",
231
+ "Wattenhofer et al. found theoretical liveness vulnerabilities (epsilon stake attack)",
232
+ "In practice, TowerBFT has been reliable since mainnet launch",
233
+ ],
234
+ references=[
235
+ "programs/vote/src/vote_state.rs - VoteState, lockouts",
236
+ "core/src/consensus.rs - Tower, fork choice",
237
+ "core/src/replay_stage.rs - block replay and voting",
238
+ "https://docs.solanalabs.com/consensus/tower-bft",
239
+ ],
240
+ ),
241
+ "consensus": GuidanceEntry(
242
+ topic="Solana Consensus Overview",
243
+ summary="Solana consensus = PoH (ordering) + TowerBFT (agreement). Alpenglow coming Q1 2026.",
244
+ key_points=[
245
+ "TWO components work together: PoH for ordering, TowerBFT for consensus",
246
+ "PoH is NOT consensus - it's a cryptographic clock for ordering",
247
+ "TowerBFT is the ACTUAL consensus mechanism (PBFT variant)",
248
+ "Leader rotation: stake-weighted schedule, ~4 slots per leader",
249
+ "Blocks confirmed via vote transactions from validators",
250
+ "Finality: ~12.8s (TowerBFT) → ~150ms (Alpenglow, not yet live)",
251
+ "Fork choice: heaviest subtree by stake-weighted votes",
252
+ ],
253
+ gotchas=[
254
+ "Common misconception: 'PoH is Solana's consensus' - FALSE",
255
+ "PoH reduces communication overhead, TowerBFT provides BFT agreement",
256
+ "Alpenglow (SIMD-0326) approved but NOT YET LIVE as of Jan 2026",
257
+ "Expected timeline: testnet late 2025, mainnet Q1 2026",
258
+ "Current mainnet still runs TowerBFT + PoH",
259
+ ],
260
+ references=[
261
+ "See 'towerbft' for current consensus details",
262
+ "See 'alpenglow' for future consensus details",
263
+ "See 'poh' for Proof of History details",
264
+ ],
265
+ ),
266
+ "leader_schedule": GuidanceEntry(
267
+ topic="Leader Schedule and Block Production",
268
+ summary="Validators take turns producing blocks based on stake-weighted schedule.",
269
+ key_points=[
270
+ "Leader schedule computed per epoch from stake distribution",
271
+ "Each leader gets ~4 consecutive slots (1.6 seconds)",
272
+ "Higher stake = more leader slots = more block rewards",
273
+ "Leader produces blocks containing transactions",
274
+ "Blocks signed by leader and include PoH hashes",
275
+ "Missed leader slots: no block produced, network continues",
276
+ ],
277
+ gotchas=[
278
+ "Leader schedule is deterministic - everyone computes the same schedule",
279
+ "Schedule based on stake at epoch boundary (2 epochs ahead)",
280
+ "Validators can be 'delinquent' if they miss too many slots",
281
+ "No penalty for missed slots except lost rewards",
282
+ "Jito and other MEV infrastructure can affect leader slot value",
283
+ ],
284
+ references=[
285
+ "runtime/src/bank.rs - leader_schedule_epoch",
286
+ "ledger/src/leader_schedule.rs",
287
+ ],
288
+ ),
289
+ "epochs": GuidanceEntry(
290
+ topic="Epochs and Timing",
291
+ summary="Epochs are ~2-3 day periods for stake activation, rewards, and schedule changes.",
292
+ key_points=[
293
+ "Epoch = 432,000 slots = ~2-3 days (at 400ms/slot)",
294
+ "Stake changes (activation/deactivation) take effect at epoch boundaries",
295
+ "Rewards distributed at end of each epoch",
296
+ "Leader schedule computed for epoch N+2 at start of epoch N",
297
+ "Rent collection happens per-epoch",
298
+ "Vote account commission changes effective next epoch",
299
+ ],
300
+ gotchas=[
301
+ "Slot duration is 400ms TARGET but can vary",
302
+ "Epoch duration varies with actual slot times",
303
+ "Stake warmup/cooldown spans epoch boundaries",
304
+ "'Current epoch' for stake purposes is when it becomes active",
305
+ "First epoch after activation only gets partial rewards",
306
+ ],
307
+ references=[
308
+ "sdk/src/clock.rs - Epoch, Slot, Clock",
309
+ "runtime/src/bank.rs - epoch transitions",
310
+ ],
311
+ ),
312
+ # ===================
313
+ # MEV / Jito
314
+ # ===================
315
+ "mev": GuidanceEntry(
316
+ topic="MEV on Solana (Jito)",
317
+ summary="Jito provides MEV infrastructure for Solana - bundles, block engine, and tip distribution.",
318
+ key_points=[
319
+ "Jito-Agave: MEV-enabled fork of Agave, runs ~70% of mainnet stake",
320
+ "Block Engine: off-chain service that receives bundles from searchers",
321
+ "Bundles: atomic transaction groups that execute all-or-nothing",
322
+ "Tips: searchers pay validators directly for bundle inclusion",
323
+ "Tip distribution: tips split between validator and stakers",
324
+ "MEV sources: DEX arbitrage, liquidations, NFT mints",
325
+ "No mempool: Solana's no-mempool design changes MEV dynamics",
326
+ ],
327
+ gotchas=[
328
+ "Solana MEV is different from Ethereum - no mempool means no traditional frontrunning",
329
+ "Searchers connect to block engine, not directly to validators",
330
+ "Bundles land at end of block (not beginning like Ethereum)",
331
+ "Tip accounts: special accounts that receive and distribute tips",
332
+ "Jito dominance (~70%) is a centralization concern",
333
+ "Jito temporarily paused mempool feature in 2024 due to sandwich concerns",
334
+ "Validators can run without Jito but lose MEV revenue",
335
+ ],
336
+ references=[
337
+ "jito-solana/bundle/",
338
+ "jito-solana/tip-distributor/",
339
+ "https://jito-labs.gitbook.io/",
340
+ ],
341
+ ),
342
+ "jito": GuidanceEntry(
343
+ topic="Jito Infrastructure",
344
+ summary="Jito Labs provides the dominant MEV infrastructure for Solana validators.",
345
+ key_points=[
346
+ "Jito-Agave: forked Agave client with block engine integration",
347
+ "Block Engine: receives bundles, simulates, forwards to validators",
348
+ "Bundles: 1-5 transactions that execute atomically",
349
+ "Tips: SOL payments from searchers to validators for inclusion",
350
+ "Tip Distribution Program: on-chain program for tip accounting",
351
+ "MEV Dashboard: jito.wtf shows MEV statistics",
352
+ "~70% of mainnet validators run Jito-Agave",
353
+ ],
354
+ gotchas=[
355
+ "Jito is a company, not a protocol - centralization risk",
356
+ "Block engine is off-chain and closed-source",
357
+ "Validators trust Jito to forward bundles fairly",
358
+ "Tip distribution happens on-chain (verifiable)",
359
+ "Jito foundation (non-profit) governs JTO token",
360
+ "JTO token launched Dec 2023 - governance + staking",
361
+ "Frankendancer integration coming - Jito + Firedancer networking",
362
+ ],
363
+ references=[
364
+ "jito-foundation/jito-solana",
365
+ "jito-foundation/jito-programs",
366
+ "https://www.jito.network/",
367
+ ],
368
+ ),
369
+ "bundles": GuidanceEntry(
370
+ topic="Jito Bundles",
371
+ summary="Bundles are atomic transaction groups for MEV extraction on Solana.",
372
+ key_points=[
373
+ "Bundle = 1-5 transactions that execute all-or-nothing",
374
+ "Atomic: all succeed or all fail (no partial execution)",
375
+ "Ordered: transactions execute in specified order",
376
+ "Tip required: bundles include tip transaction to validator",
377
+ "Simulation: block engine simulates bundles before forwarding",
378
+ "Landing: bundles placed at END of block (after normal txs)",
379
+ "Priority: higher tip = higher priority in block engine queue",
380
+ ],
381
+ gotchas=[
382
+ "Bundles land at BLOCK END, not beginning (unlike Ethereum)",
383
+ "This means bundles can't frontrun normal transactions",
384
+ "Bundles CAN backrun - execute after a target transaction",
385
+ "Sandwich attacks harder but not impossible",
386
+ "Bundle simulation can fail - no guarantee of landing",
387
+ "Tip is paid even if bundle reverts (validator gets tip)",
388
+ "Multiple bundles can conflict - block engine handles conflicts",
389
+ ],
390
+ references=[
391
+ "jito-solana/bundle/",
392
+ "https://jito-labs.gitbook.io/mev/",
393
+ ],
394
+ ),
395
+ "tips": GuidanceEntry(
396
+ topic="Jito Tip Distribution",
397
+ summary="Tips are SOL payments from searchers to validators, distributed to stakers.",
398
+ key_points=[
399
+ "Tip accounts: 8 special accounts that receive tips",
400
+ "Searchers send tip transaction as part of bundle",
401
+ "Tips collected per-block, distributed per-epoch",
402
+ "Distribution: validator commission + staker rewards",
403
+ "Tip Distribution Program: on-chain, verifiable distribution",
404
+ "NCN (Node Consensus Network): upcoming decentralized tip routing",
405
+ "Average tips: varies widely, ~0.001-0.1 SOL per block",
406
+ ],
407
+ gotchas=[
408
+ "Tips are NOT transaction fees - separate mechanism",
409
+ "Tip accounts rotate - don't hardcode addresses",
410
+ "Validator can set custom tip commission (separate from vote commission)",
411
+ "Stakers receive tip rewards proportional to stake",
412
+ "Tips visible on-chain but searcher identity often hidden",
413
+ "Large tips often indicate high-value MEV (big arb, liquidation)",
414
+ ],
415
+ references=[
416
+ "jito-solana/tip-distributor/",
417
+ "jito-foundation/jito-programs",
418
+ ],
419
+ ),
420
+ }
421
+
422
+
423
+ def get_expert_guidance(topic: str) -> GuidanceEntry | None:
424
+ """
425
+ Get expert guidance for a topic.
426
+
427
+ Searches for exact match first, then partial matches.
428
+ """
429
+ topic_lower = topic.lower()
430
+
431
+ # Exact match
432
+ if topic_lower in GUIDANCE_DB:
433
+ return GUIDANCE_DB[topic_lower]
434
+
435
+ # Partial match
436
+ for key, entry in GUIDANCE_DB.items():
437
+ if topic_lower in key or key in topic_lower:
438
+ return entry
439
+ if topic_lower in entry.summary.lower():
440
+ return entry
441
+
442
+ return None
443
+
444
+
445
+ def list_guidance_topics() -> list[str]:
446
+ """List all available guidance topics."""
447
+ return list(GUIDANCE_DB.keys())
448
+
449
+
450
+ def add_guidance(entry: GuidanceEntry) -> None:
451
+ """Add a new guidance entry."""
452
+ GUIDANCE_DB[entry.topic.lower()] = entry
@@ -0,0 +1,8 @@
1
+ """Indexer components for Solana MCP."""
2
+
3
+ from .chunker import chunk_content
4
+ from .compiler import compile_rust
5
+ from .downloader import download_repos
6
+ from .embedder import build_index
7
+
8
+ __all__ = ["download_repos", "compile_rust", "chunk_content", "build_index"]