tribewarez_pot_o/lib.rs
1//! # tribewarez-pot-o
2//!
3//! Proof of Tensor Optimizations (PoT-O) on-chain program for Solana.
4//!
5//! This crate implements the PoT-O blockchain validation system, which combines proof-of-work
6//! concepts with tensor network analysis to optimize mining rewards. It manages miner accounts,
7//! validates cryptographic proofs submitted by off-chain validators, and distributes rewards
8//! with optional tensor-aware enhancements.
9//!
10//! ## Core Features
11//!
12//! - **Proof Validation**: Validates mining proofs submitted by the off-chain PoT-O validator
13//! - **Miner Management**: Creates and maintains miner accounts with proof history tracking
14//! - **Reward Distribution**: Distributes mining rewards with support for tensor-weighted bonuses
15//! - **Difficulty Adjustment**: Automatically adjusts mining difficulty based on network conditions
16//! - **Tensor Network Support**: v0.2.0 feature for enhanced reward calculations using tensor metrics
17//!
18//! ## Key Instructions
19//!
20//! - `initialize`: Set up the PoT-O configuration (admin-only)
21//! - `register_miner`: Register a new miner account
22//! - `submit_proof`: Submit a mining proof for validation and reward distribution
23//! - `update_pool_config`: Update configuration parameters (admin-only)
24//! - `create_tensor_pool`: Create a tensor network pool for enhanced rewards (admin-only)
25//!
26//! ## Events
27//!
28//! This program emits events for proof submissions, reward distributions, and configuration changes.
29//! See the [`events`] module for detailed event documentation.
30//!
31//! ## Services
32//!
33//! The [`services`] module provides trait implementations for proof validation and reward distribution,
34//! supporting both legacy (v0.1.x) and tensor-aware (v0.2.0) configurations.
35
36use anchor_lang::prelude::*;
37
38// Module declarations
39pub mod events;
40pub mod services;
41
42// Re-export services for use in instructions
43use events::{ProofSubmitted, RewardDistributed};
44use services::{ProofData, ServiceRegistry};
45
46declare_id!("1PoToVa1idator11111111111111111111111111111");
47
48/// PoT-O: Proof of Tensor Optimizations on-chain program.
49/// Validates mining proofs submitted by the off-chain PoT-O validator,
50/// manages miner accounts, distributes rewards, and adjusts difficulty.
51#[program]
52pub mod tribewarez_pot_o {
53 use super::*;
54
55 /// Initialize the PoT-O config. Called once by the admin.
56 ///
57 /// Sets up both v0.1.x and v0.2.0 configuration. Tensor network features
58 /// are disabled by default but can be enabled via update_pool_config.
59 pub fn initialize(ctx: Context<Initialize>, params: InitParams) -> Result<()> {
60 let config = &mut ctx.accounts.config;
61 config.admin = ctx.accounts.admin.key();
62 config.difficulty = params.difficulty;
63 config.mml_threshold = params.mml_threshold;
64 config.path_distance_max = params.path_distance_max;
65 config.reward_per_proof = params.reward_per_proof;
66 config.total_proofs = 0;
67 config.pool_type = params.pool_type;
68 config.swap_program_id = params.swap_program_id;
69 config.bump = ctx.bumps.config;
70
71 // Initialize tensor network fields (v0.2.0)
72 config.tensor_enabled = 0; // Disabled by default, enable via update_pool_config
73 config.s_max = 1_000_000; // 1e6 scale
74 config.bond_dimension = 2; // Default: 2 bonds per vertex
75 config.max_pool_size = 128; // Max 128 miners per entanglement pool
76 config.entropy_weight_factor = 500_000; // 0.5x entropy weight
77 config.network_entropy = 0;
78 config.total_miners = 0;
79 config.active_pools = 0;
80 config.average_coherence = 0;
81
82 Ok(())
83 }
84
85 /// Register a new miner.
86 ///
87 /// Initializes miner account with device type and computes initial coherence
88 /// based on device type if tensor network is enabled.
89 pub fn register_miner(ctx: Context<RegisterMiner>, device_type: u8) -> Result<()> {
90 let miner = &mut ctx.accounts.miner_account;
91 miner.authority = ctx.accounts.authority.key();
92 miner.device_type = device_type;
93 miner.total_proofs = 0;
94 miner.total_rewards = 0;
95 miner.pending_rewards = 0;
96 miner.reputation_score = 0;
97 miner.last_proof_slot = 0;
98 miner.pool_id = Pubkey::default();
99 miner.bump = ctx.bumps.miner_account;
100
101 // Initialize tensor fields (v0.2.0)
102 miner.vertex_id = 0; // Will be assigned by pool service
103 miner.entropy_score = 0; // Will be calculated on first proof
104 miner.coherence = compute_device_coherence(device_type);
105 miner.last_entropy_update = 0;
106 miner.entanglement_count = 0;
107 miner.pool_generation = 0;
108 miner.unlock_probability = 0; // Will be calculated from entropy
109
110 // Emit event
111 let clock = Clock::get()?;
112 emit!(events::MinerRegistered {
113 authority: ctx.accounts.authority.key(),
114 device_type,
115 timestamp: clock.unix_timestamp,
116 });
117
118 Ok(())
119 }
120
121 /// Submit a PoT-O proof. Validates on-chain using ServiceRegistry and distributes rewards.
122 ///
123 /// This instruction delegates validation and reward calculation to the service layer,
124 /// enabling both legacy (v0.1.x) and tensor-aware (v0.2.0) modes based on config.
125 ///
126 /// Flow:
127 /// 1. Instantiate ServiceRegistry based on config.tensor_enabled
128 /// 2. Use ProofValidator to validate proof (standard or tensor-aware)
129 /// 3. Use RewardDistributor to calculate rewards with bonuses
130 /// 4. Update miner stats and emit events
131 pub fn submit_proof(ctx: Context<SubmitProof>, params: ProofParams) -> Result<()> {
132 let config = &ctx.accounts.config;
133 let clock = Clock::get()?;
134
135 // Instantiate appropriate ServiceRegistry based on config
136 let registry = if config.tensor_enabled != 0 {
137 // Tensor-aware mode (v0.2.0)
138 ServiceRegistry::new_tensor_aware(
139 config.s_max,
140 config.bond_dimension,
141 (config.entropy_weight_factor as f64) / 1_000_000.0,
142 config.max_pool_size,
143 )
144 } else {
145 // Legacy mode (v0.1.x)
146 ServiceRegistry::new_legacy()
147 };
148
149 // Prepare proof data for validation
150 let proof_data = ProofData {
151 challenge_id: params.challenge_id,
152 challenge_slot: params.challenge_slot,
153 tensor_result_hash: params.tensor_result_hash,
154 mml_score: params.mml_score,
155 path_signature: params.path_signature,
156 path_distance: params.path_distance,
157 computation_nonce: params.computation_nonce,
158 computation_hash: params.computation_hash,
159 };
160
161 // 1. Validate proof using service
162 let validator = registry.proof_validator();
163 let validated_proof = validator
164 .validate(
165 &proof_data,
166 clock.slot,
167 config.mml_threshold,
168 config.path_distance_max,
169 )
170 .map_err(|e| match e {
171 services::ValidationError::ChallengeExpired => PotOError::ChallengeExpired,
172 services::ValidationError::MmlThresholdNotMet => PotOError::MmlThresholdNotMet,
173 services::ValidationError::PathDistanceTooLarge => PotOError::PathDistanceTooLarge,
174 services::ValidationError::InvalidComputationHash => {
175 PotOError::InvalidComputationHash
176 }
177 _ => PotOError::InvalidComputationHash, // Other errors map to generic
178 })?;
179
180 // 2. Calculate reward using service
181 let miner_account = &mut ctx.accounts.miner_account;
182 let distributor = registry.reward_distributor();
183 let reward_allocation = distributor.calculate_reward(
184 config.reward_per_proof,
185 miner_account.reputation_score,
186 miner_account.pool_id,
187 miner_account.device_type,
188 );
189
190 // 3. Record proof with tensor data
191 let proof_record = &mut ctx.accounts.proof_record;
192 proof_record.miner = ctx.accounts.miner.key();
193 proof_record.challenge_id = params.challenge_id;
194 proof_record.mml_score = params.mml_score;
195 proof_record.path_signature = params.path_signature;
196 proof_record.slot = clock.slot;
197 proof_record.timestamp = clock.unix_timestamp;
198 proof_record.reward_distributed = reward_allocation.total_reward;
199 proof_record.bump = ctx.bumps.proof_record;
200
201 // New fields in v0.2.0
202 proof_record.entropy_score = validated_proof.entropy_score;
203 proof_record.is_tensor_aware = if registry.is_tensor_aware() { 1 } else { 0 };
204 proof_record.path_distance = params.path_distance;
205 proof_record.device_type = miner_account.device_type;
206
207 // 4. Update miner stats
208 miner_account.total_proofs += 1;
209 miner_account.pending_rewards += reward_allocation.total_reward;
210 miner_account.last_proof_slot = clock.slot;
211 miner_account.reputation_score += 1;
212
213 // Update tensor fields
214 miner_account.entropy_score = validated_proof.entropy_score;
215 if registry.is_tensor_aware() {
216 miner_account.last_entropy_update = clock.slot;
217 }
218
219 // 5. Update global stats
220 let cfg = &mut ctx.accounts.config;
221 cfg.total_proofs += 1;
222 if registry.is_tensor_aware() {
223 cfg.network_entropy = cfg
224 .network_entropy
225 .saturating_add(validated_proof.entropy_score);
226 }
227
228 // 6. Emit events
229 emit!(ProofSubmitted {
230 miner: ctx.accounts.miner.key(),
231 challenge_id: params.challenge_id,
232 mml_score: params.mml_score,
233 slot: clock.slot,
234 timestamp: clock.unix_timestamp,
235 entropy_score: validated_proof.entropy_score,
236 is_tensor_aware: registry.is_tensor_aware(),
237 });
238
239 emit!(RewardDistributed {
240 miner: ctx.accounts.miner.key(),
241 base_reward: reward_allocation.base_reward,
242 bonus_reward: reward_allocation.bonus_reward,
243 total_reward: reward_allocation.total_reward,
244 multiplier: (reward_allocation.multiplier * 1_000_000.0) as u64, // Convert f64 to u64
245 timestamp: clock.unix_timestamp,
246 });
247
248 Ok(())
249 }
250
251 /// Adjust difficulty (admin or time-gated crank).
252 ///
253 /// Can also adjust entropy weight factor and other tensor parameters.
254 pub fn adjust_difficulty(
255 ctx: Context<AdjustDifficulty>,
256 new_difficulty: u64,
257 new_mml_threshold: u64,
258 new_path_distance_max: u32,
259 ) -> Result<()> {
260 let config = &mut ctx.accounts.config;
261 config.difficulty = new_difficulty;
262 config.mml_threshold = new_mml_threshold;
263 config.path_distance_max = new_path_distance_max;
264 Ok(())
265 }
266
267 /// Claim accumulated rewards.
268 ///
269 /// Transfers accumulated pending rewards to the miner's authority.
270 /// In production, this would include CPI to SPL token program.
271 pub fn claim_rewards(ctx: Context<ClaimRewards>) -> Result<()> {
272 let miner = &mut ctx.accounts.miner_account;
273 let pending = miner.pending_rewards;
274 require!(pending > 0, PotOError::NoRewardsToClaim);
275
276 miner.total_rewards += pending;
277 miner.pending_rewards = 0;
278
279 // In production: CPI transfer of PTtC/NMTC tokens here.
280 // For now, reward accounting is on-chain only.
281
282 let _clock = Clock::get()?;
283 msg!("Rewards claimed: {} tokens", pending);
284
285 Ok(())
286 }
287
288 /// Update pool configuration (admin only).
289 ///
290 /// Can enable/disable tensor network features and configure pool parameters.
291 pub fn update_pool_config(
292 ctx: Context<UpdatePoolConfig>,
293 pool_type: u8,
294 swap_program_id: Pubkey,
295 ) -> Result<()> {
296 let config = &mut ctx.accounts.config;
297 config.pool_type = pool_type;
298 config.swap_program_id = swap_program_id;
299 Ok(())
300 }
301
302 /// Enable or update tensor network configuration (admin only).
303 ///
304 /// Called to enable tensor network features and set entropy parameters.
305 /// Parameters:
306 /// - enable: 1 to enable, 0 to disable tensor network
307 /// - s_max: Maximum entropy (1e6 scale)
308 /// - bond_dimension: Quantum bond dimension (typically 2-4)
309 /// - max_pool_size: Maximum miners per entanglement pool
310 /// - entropy_weight: Entropy weight factor (in 1e6 scale)
311 pub fn configure_tensor_network(
312 ctx: Context<UpdatePoolConfig>,
313 enable: u8,
314 s_max: u64,
315 bond_dimension: u32,
316 max_pool_size: u32,
317 entropy_weight: u64,
318 ) -> Result<()> {
319 let config = &mut ctx.accounts.config;
320 config.tensor_enabled = enable;
321 if enable != 0 {
322 config.s_max = s_max.max(1_000_000); // Minimum 1e6
323 config.bond_dimension = bond_dimension.clamp(2, 8); // Between 2 and 8
324 config.max_pool_size = max_pool_size.clamp(2, 512); // Between 2 and 512
325 config.entropy_weight_factor = entropy_weight;
326 }
327 Ok(())
328 }
329
330 /// Request a token swap via CPI to tribewarez-swap (extension point).
331 pub fn request_swap(
332 _ctx: Context<RequestSwap>,
333 _from_token_mint: Pubkey,
334 _to_token_mint: Pubkey,
335 _amount: u64,
336 ) -> Result<()> {
337 // Extension point: CPI into tribewarez-swap program.
338 // Stub: log and succeed for now.
339 msg!("Swap request received (CPI to tribewarez-swap pending)");
340 Ok(())
341 }
342}
343
344// ---------------------------------------------------------------------------
345// Helper
346// ---------------------------------------------------------------------------
347
348/// Compute initial coherence factor for a device type.
349///
350/// Coherence preservation capabilities (1e6 scale):
351/// - Device 0 (CPU): 0.6 - moderate decoherence
352/// - Device 1 (GPU): 0.8 - good coherence
353/// - Device 2 (ASIC): 1.0 - excellent coherence (baseline)
354/// - Device 3 (Mobile): 0.4 - significant decoherence
355fn compute_device_coherence(device_type: u8) -> u64 {
356 match device_type {
357 0 => 600_000, // CPU: 0.6x
358 1 => 800_000, // GPU: 0.8x
359 2 => 1_000_000, // ASIC: 1.0x (baseline)
360 3 => 400_000, // Mobile: 0.4x
361 _ => 500_000, // Unknown: 0.5x (conservative)
362 }
363}
364
365// ---------------------------------------------------------------------------
366// Accounts
367// ---------------------------------------------------------------------------
368
369/// Parameters for initializing the PoT-O configuration.
370/// These values are set once during program initialization and can be updated via `update_pool_config`.
371#[derive(AnchorSerialize, AnchorDeserialize)]
372pub struct InitParams {
373 /// Base difficulty threshold for mining proofs
374 pub difficulty: u64,
375 /// Minimum MML (Merkle Merkle Linkage) score required for valid proofs
376 pub mml_threshold: u64,
377 /// Maximum neural path distance allowed in tensor network validation
378 pub path_distance_max: u32,
379 /// Base reward amount distributed per validated proof
380 pub reward_per_proof: u64,
381 /// Pool type (0 = legacy, 1 = tensor-aware v0.2.0)
382 pub pool_type: u8,
383 /// Swap program ID for fee collection functionality
384 pub swap_program_id: Pubkey,
385}
386
387#[derive(AnchorSerialize, AnchorDeserialize)]
388/// Parameters for submitting and validating mining proofs.
389/// Contains cryptographic commitments and validation data for the proof.
390pub struct ProofParams {
391 /// Unique challenge identifier for this mining round
392 pub challenge_id: [u8; 32],
393 /// Solana slot number when the challenge was issued
394 pub challenge_slot: u64,
395 /// Hash of the tensor computation result
396 pub tensor_result_hash: [u8; 32],
397 /// Merkle Merkle Linkage score derived from the proof
398 pub mml_score: u64,
399 /// Signature proving path through the neural network
400 pub path_signature: [u8; 32],
401 /// Distance traveled in the neural path (must be <= path_distance_max)
402 pub path_distance: u32,
403 /// Nonce used in the computation
404 pub computation_nonce: u64,
405 /// Hash of the complete computation (verified against submitted hash)
406 pub computation_hash: [u8; 32],
407}
408
409/// Global PoT-O configuration account.
410/// Stores network-wide settings for proof validation, reward distribution, and tensor network parameters.
411/// This is a singleton account (one per program) created by the admin during initialization.
412#[account]
413pub struct PotOConfig {
414 /// Admin/authority account that can update configuration
415 pub admin: Pubkey,
416 /// Base difficulty threshold for mining proofs
417 pub difficulty: u64,
418 /// Minimum MML score required for valid proofs
419 pub mml_threshold: u64,
420 /// Maximum neural path distance allowed
421 pub path_distance_max: u32,
422 /// Base reward amount per validated proof
423 pub reward_per_proof: u64,
424 /// Total number of proofs submitted since inception
425 pub total_proofs: u64,
426 /// Pool type: 0 = legacy v0.1.x, 1 = tensor-aware v0.2.0
427 pub pool_type: u8,
428 /// Program ID of the swap program for fee collection
429 pub swap_program_id: Pubkey,
430 /// PDA bump seed for this account
431 pub bump: u8,
432
433 // --- v0.2.0 Tensor Network Extensions ---
434 // New fields added at end for ABI compatibility
435 /// Whether tensor network enhancements are enabled
436 pub tensor_enabled: u8, // 0 = disabled, 1 = enabled
437 /// Maximum entropy (1e6 scale)
438 pub s_max: u64, // Maximum entropy (1e6 scale)
439 /// Quantum bond dimension for tensor network calculations
440 pub bond_dimension: u32, // Quantum bond dimension
441 /// Maximum miners allowed per entanglement pool
442 pub max_pool_size: u32, // Maximum miners per pool
443 /// Weight factor for entropy in reward calculations (1e6 scale)
444 pub entropy_weight_factor: u64, // Entropy weight in 1e6 scale
445 /// Current network-wide entropy measurement
446 pub network_entropy: u64, // Current network entropy
447 /// Total number of active miners in the network
448 pub total_miners: u32, // Number of active miners
449 /// Number of active entanglement pools
450 pub active_pools: u32, // Number of entanglement pools
451 /// Average coherence score across all devices (1e6 scale)
452 pub average_coherence: u64, // Average device coherence (1e6 scale)
453
454 // Reserved for future expansion (256 bytes total)
455 /// Reserved space for future updates without breaking ABI compatibility
456 pub reserved: [u8; 200],
457}
458
459/// Per-miner account storing mining history and statistics.
460/// Created when a miner first registers. Updated each time a proof is submitted.
461#[account]
462pub struct MinerAccount {
463 /// Public key of the miner who owns this account
464 pub authority: Pubkey,
465 /// Type of hardware used by this miner
466 pub device_type: u8,
467 /// Total number of valid proofs submitted by this miner
468 pub total_proofs: u64,
469 /// Total rewards distributed to this miner
470 pub total_rewards: u64,
471 /// Pending rewards awaiting claim
472 pub pending_rewards: u64,
473 /// Reputation score based on submission quality (higher is better)
474 pub reputation_score: u64,
475 /// Solana slot of the last valid proof submission
476 pub last_proof_slot: u64,
477 /// ID of the tensor pool this miner is associated with (if any)
478 pub pool_id: Pubkey,
479 /// PDA bump seed for this account
480 pub bump: u8,
481
482 // --- v0.2.0 Tensor Network Extensions ---
483 // New fields added at end for ABI compatibility
484 /// Vertex position in the tensor network graph
485 pub vertex_id: u32, // Position in tensor network graph
486 /// Miner's contribution to network entropy (1e6 scale)
487 pub entropy_score: u64, // Miner's entropy contribution (1e6 scale)
488 /// Device's ability to preserve quantum coherence (1e6 scale, 0-1000000)
489 pub coherence: u64, // Device coherence preservation (1e6 scale)
490 /// Last slot when this miner's entropy metrics were updated
491 pub last_entropy_update: u64, // Last slot when entropy was updated
492 /// Number of other miners this miner is entangled with
493 pub entanglement_count: u32, // Number of entangled connections
494 /// Current pool generation/epoch
495 pub pool_generation: u64, // Generation/epoch of current pool
496 /// Probability of unlock based on entropy (1e6 scale, 0-1000000)
497 pub unlock_probability: u64, // P(unlock) calculated from entropy (1e6 scale)
498
499 // Reserved for future expansion (256 bytes total)
500 /// Reserved space for future updates without breaking ABI compatibility
501 pub reserved: [u8; 192],
502}
503
504/// Proof record account storing details of a submitted mining proof.
505/// Created each time a miner submits a valid proof.
506#[account]
507pub struct ProofRecord {
508 /// Miner who submitted this proof
509 pub miner: Pubkey,
510 /// Unique challenge ID for this proof
511 pub challenge_id: [u8; 32],
512 /// Merkle Merkle Linkage score for this proof
513 pub mml_score: u64,
514 /// Cryptographic signature proving path through neural network
515 pub path_signature: [u8; 32],
516 /// Solana slot when the proof was submitted
517 pub slot: u64,
518 /// Timestamp when the proof was submitted
519 pub timestamp: i64,
520 /// Reward amount that was distributed for this proof
521 pub reward_distributed: u64,
522 /// PDA bump seed for this account
523 pub bump: u8,
524
525 // --- v0.2.0 Tensor Network Extensions ---
526 /// Entropy score calculated from this proof (1e6 scale)
527 pub entropy_score: u64, // Calculated entropy for this proof
528 /// Whether this proof was validated using tensor-aware logic
529 pub is_tensor_aware: u8, // 0 = standard, 1 = tensor-aware validation
530 /// Distance traveled in the neural path
531 pub path_distance: u32, // Neural path distance
532 /// Type of device that submitted this proof
533 pub device_type: u8, // Device type that submitted proof
534}
535
536// ---------------------------------------------------------------------------
537// Contexts
538// ---------------------------------------------------------------------------
539
540#[derive(Accounts)]
541pub struct Initialize<'info> {
542 #[account(
543 init,
544 payer = admin,
545 space = 8 + 32 + 8 + 8 + 4 + 8 + 8 + 1 + 32 + 1 + 1 + 8 + 4 + 4 + 8 + 8 + 4 + 4 + 8 + 200,
546 seeds = [b"pot_o_config"],
547 bump
548 )]
549 pub config: Account<'info, PotOConfig>,
550 #[account(mut)]
551 pub admin: Signer<'info>,
552 pub system_program: Program<'info, System>,
553}
554
555#[derive(Accounts)]
556pub struct RegisterMiner<'info> {
557 #[account(
558 init,
559 payer = authority,
560 space = 8 + 32 + 1 + 8 + 8 + 8 + 8 + 8 + 32 + 1 + 4 + 8 + 8 + 8 + 4 + 8 + 8 + 192,
561 seeds = [b"miner", authority.key().as_ref()],
562 bump
563 )]
564 pub miner_account: Account<'info, MinerAccount>,
565 #[account(mut)]
566 pub authority: Signer<'info>,
567 pub system_program: Program<'info, System>,
568}
569
570#[derive(Accounts)]
571#[instruction(params: ProofParams)]
572pub struct SubmitProof<'info> {
573 #[account(
574 mut,
575 seeds = [b"pot_o_config"],
576 bump = config.bump,
577 )]
578 pub config: Account<'info, PotOConfig>,
579 /// CHECK: miner pubkey used for PDA derivation; identity is in instruction data
580 pub miner: AccountInfo<'info>,
581 #[account(
582 mut,
583 seeds = [b"miner", miner.key().as_ref()],
584 bump = miner_account.bump,
585 )]
586 pub miner_account: Account<'info, MinerAccount>,
587 #[account(
588 init,
589 payer = relayer,
590 space = 8 + 32 + 32 + 8 + 32 + 8 + 8 + 8 + 1 + 8 + 1 + 4 + 1,
591 seeds = [b"proof", params.challenge_id.as_ref()],
592 bump
593 )]
594 pub proof_record: Account<'info, ProofRecord>,
595 #[account(mut)]
596 pub relayer: Signer<'info>,
597 pub system_program: Program<'info, System>,
598}
599
600#[derive(Accounts)]
601pub struct AdjustDifficulty<'info> {
602 #[account(
603 mut,
604 seeds = [b"pot_o_config"],
605 bump = config.bump,
606 has_one = admin,
607 )]
608 pub config: Account<'info, PotOConfig>,
609 pub admin: Signer<'info>,
610}
611
612#[derive(Accounts)]
613pub struct ClaimRewards<'info> {
614 #[account(
615 mut,
616 seeds = [b"miner", authority.key().as_ref()],
617 bump = miner_account.bump,
618 )]
619 pub miner_account: Account<'info, MinerAccount>,
620 pub authority: Signer<'info>,
621}
622
623#[derive(Accounts)]
624pub struct UpdatePoolConfig<'info> {
625 #[account(
626 mut,
627 seeds = [b"pot_o_config"],
628 bump = config.bump,
629 has_one = admin,
630 )]
631 pub config: Account<'info, PotOConfig>,
632 pub admin: Signer<'info>,
633}
634
635#[derive(Accounts)]
636pub struct RequestSwap<'info> {
637 #[account(
638 seeds = [b"pot_o_config"],
639 bump = config.bump,
640 )]
641 pub config: Account<'info, PotOConfig>,
642 #[account(mut)]
643 pub authority: Signer<'info>,
644}
645
646// ---------------------------------------------------------------------------
647// Errors
648// ---------------------------------------------------------------------------
649
650#[error_code]
651pub enum PotOError {
652 #[msg("Challenge has expired (> 256 slots old)")]
653 ChallengeExpired,
654 #[msg("MML score does not meet the required threshold")]
655 MmlThresholdNotMet,
656 #[msg("Neural path distance exceeds maximum allowed")]
657 PathDistanceTooLarge,
658 #[msg("Computation hash does not match expected value")]
659 InvalidComputationHash,
660 #[msg("No rewards available to claim")]
661 NoRewardsToClaim,
662}