// file: kb_pipeline/src/solana_ata_execution.rs // version: 5 //! Devnet ATA execution with stateful and canonical post-validation. /// Complete request for one Devnet SPL Associated Token Account execution. #[derive(Clone, Debug, Eq, PartialEq)] pub struct DevnetSplAssociatedTokenAccountExecutionRequest { /// Stable caller-provided execution identifier. pub intent_id: std::string::String, /// Endpoint role used for state, balance, blockhash, fee and hydration calls. pub query_role: std::string::String, /// Endpoint role used for simulation, submission and confirmation polling. pub transaction_role: std::string::String, /// Exact typed SPL Associated Token Account operation. pub operation: kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation, /// Explicitly authorizes signing and submission after successful simulation. pub submit: bool, /// Explicit operator confirmation required by the active profile. pub operator_confirmed: bool, /// Number of `getTransaction` retries after the first hydration attempt. pub post_validation_max_retries: u32, /// Replaces existing core and decode outputs for the submitted signature. pub force_post_validation_replay: bool, } impl crate::solana_ata_execution::DevnetSplAssociatedTokenAccountExecutionRequest { /// Creates a conservative simulation-only request. pub fn new( intent_id: impl std::convert::Into, operation: kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation, ) -> Self { return Self { intent_id: intent_id.into(), query_role: "http_queries".to_string(), transaction_role: "http_transactions".to_string(), operation, submit: false, operator_confirmed: false, post_validation_max_retries: 10, force_post_validation_replay: false, }; } /// Validates request-local bounds independently from one profile. pub fn validate(&self) -> kb_core::Result<()> { if self.intent_id.trim().is_empty() { return std::result::Result::Err(kb_core::Error::config( "Devnet SPL Associated Token Account execution intent id must not be empty", )); } if self.query_role.trim().is_empty() || self.transaction_role.trim().is_empty() { return std::result::Result::Err(kb_core::Error::config( "Devnet SPL Associated Token Account execution endpoint roles must not be empty", )); } if self.post_validation_max_retries > 20 { return std::result::Result::Err(kb_core::Error::config( "post-execution getTransaction retries must not exceed 20", )); } return std::result::Result::Ok(()); } } /// Complete result of one Devnet SPL Associated Token Account execution. #[derive(Clone, Debug, PartialEq)] pub struct DevnetSplAssociatedTokenAccountExecutionSummary { /// Profile used by the orchestration. pub profile_name: std::string::String, /// Exact classified cluster. pub cluster: kb_execution_api::ExecutionCluster, /// Genesis hash returned by the selected endpoint. pub genesis_hash: std::string::String, /// Non-secret persistent wallet description. pub wallet: kb_wallet::WalletSummary, /// Wallet balance observed before planning. pub balance_lamports: u64, /// Stateful readiness report produced before plan simulation. pub stateful_readiness: crate::SplAssociatedTokenAccountStatefulReadinessReport, /// Exact prepared Token plan. pub plan: kb_execution_api::PreparedExecutionPlan, /// Recent blockhash used by the exact transaction. pub latest_blockhash: kb_rpc::LatestBlockhashResult, /// Fee estimate for the exact compiled message. pub fee: kb_rpc::FeeForMessageResult, /// Exact simulation result bound to the compiled message. pub simulation: kb_execution_api::ExecutionSimulationResult, /// Submission result when explicitly authorized. pub send_result: std::option::Option, /// Confirmation result when submitted. pub confirmation: std::option::Option, /// Stateful account relationships observed after confirmation. pub post_state_validation: std::option::Option, /// Canonical hydration result for the exact signature. pub backfill: std::option::Option, /// Core extraction result for the exact signature. pub core_extraction: std::option::Option, /// First Token decode and materialization replay. pub decode_replay: std::option::Option, /// Second replay proving idempotence for the same decoder version and input. pub idempotence_replay: std::option::Option, /// Exact materialized rows produced for the submitted Token transaction. pub materializations: std::vec::Vec, /// Aggregated post-execution validation diagnostic. pub post_execution: std::option::Option, } struct PreparedAtaExecution { wallet: kb_wallet::TemporaryWallet, unsigned: kb_execution_solana::UnsignedSolanaTransaction, evidence: kb_execution_solana::SolanaSimulationEvidence, summary: crate::solana_ata_execution::DevnetSplAssociatedTokenAccountExecutionSummary, } /// Simulates one Devnet SPL Associated Token Account operation after stateful preflight. pub async fn simulate_devnet_spl_associated_token_account( http_pool: &kb_rpc::HttpEndpointPool, profile: &kb_config::ProfileConfig, workspace_root: &std::path::Path, request: &crate::solana_ata_execution::DevnetSplAssociatedTokenAccountExecutionRequest, observer: &O, ) -> kb_core::Result where O: crate::SolanaExecutionObserver, { if request.submit { return std::result::Result::Err(kb_core::Error::config( "simulate_devnet_spl_associated_token_account requires submit=false", )); } let prepared = match crate::solana_ata_execution::prepare_execution( http_pool, profile, workspace_root, request, observer, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; return std::result::Result::Ok(prepared.summary); } /// Executes one Devnet SPL Associated Token Account simulation or authorized submission. #[allow(clippy::too_many_arguments)] pub async fn execute_devnet_spl_associated_token_account( http_pool: &kb_rpc::HttpEndpointPool, store: &S, profile: &kb_config::ProfileConfig, workspace_root: &std::path::Path, request: &crate::solana_ata_execution::DevnetSplAssociatedTokenAccountExecutionRequest, decoders: &[std::sync::Arc], materializers: &[std::sync::Arc], observer: &O, ) -> kb_core::Result where S: kb_store_core::RawTransactionStore + kb_store_core::CoreExtractionStore + kb_store_core::DecodePipelineStore + Sync, O: crate::SolanaExecutionObserver, { let prepared = match crate::solana_ata_execution::prepare_execution( http_pool, profile, workspace_root, request, observer, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; if !request.submit { return std::result::Result::Ok(prepared.summary); } if !prepared.summary.simulation.success { return std::result::Result::Err(kb_core::Error::new( "execution_simulation_failed", crate::solana_execution::simulation_failure_message(&prepared.summary.simulation), )); } if let std::result::Result::Err(error) = crate::solana_ata_execution::validate_profile_wallet_signers( prepared.unsigned.required_signer_pubkeys(), prepared.summary.wallet.public_key.as_str(), ) { return std::result::Result::Err(error); } let send_evaluation = match kb_execution_safety::ExecutionSafetyChecker .evaluate_send(&prepared.summary.plan, &prepared.summary.simulation) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; if send_evaluation.decision == kb_execution_safety::ExecutionSafetyDecision::Deny { return std::result::Result::Err(kb_core::Error::new( "execution_send_denied", crate::solana_execution::violation_message(send_evaluation.violations.as_slice()), )); } let signed = match prepared .unsigned .sign_after_simulation(&prepared.evidence, &[prepared.wallet.as_signer()]) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; if let std::result::Result::Err(error) = signed.verify_signatures() { return std::result::Result::Err(error); } let signature = signed.primary_signature().clone(); let mut summary = prepared.summary; let mut diagnostic = kb_execution_api::PostExecutionDiagnostic { signature: signature.clone(), canonical_inserted: false, core_extracted: false, decode_replayed: false, materialized: false, diagnostics: std::vec::Vec::new(), }; let send_config = match kb_rpc::SendTransactionConfig::from_execution_config( &profile.execution, std::option::Option::Some(summary.latest_blockhash.context.slot), ) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let sent = match http_pool .send_transaction_for_role( request.transaction_role.as_str(), signed.transaction_base64().as_str(), &signature, &send_config, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => { diagnostic .diagnostics .push(format!("SPL Associated Token Account submission failed: {error}")); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); }, }; summary.send_result = std::option::Option::Some( sent.to_execution_result(kb_execution_api::ExecutionCluster::Devnet), ); let confirmation_config = match kb_rpc::ConfirmTransactionConfig::from_execution_config( &profile.execution, std::option::Option::Some(summary.latest_blockhash.last_valid_block_height), std::option::Option::Some(summary.latest_blockhash.context.slot), ) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let confirmation = match http_pool .confirm_transaction_for_roles( request.transaction_role.as_str(), request.query_role.as_str(), kb_execution_api::ExecutionCluster::Devnet, &signature, &confirmation_config, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => { diagnostic .diagnostics .push(format!("SPL Associated Token Account confirmation failed: {error}")); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); }, }; let confirmation_status = confirmation.status; summary.confirmation = std::option::Option::Some(confirmation); if !matches!( confirmation_status, kb_execution_api::ExecutionConfirmationStatus::Confirmed | kb_execution_api::ExecutionConfirmationStatus::Finalized ) { diagnostic.diagnostics.push(format!("SPL Associated Token Account post-validation stopped at confirmation status {confirmation_status:?}")); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); } let post_state = match crate::solana_ata_execution::validate_post_state_with_retries( http_pool, profile, request.query_role.as_str(), request.post_validation_max_retries, &request.operation, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => { diagnostic.diagnostics.push(format!( "SPL Associated Token Account post-state validation failed: {error}" )); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); }, }; let post_state_ready = post_state.status == crate::SplAssociatedTokenAccountStatefulReadinessStatus::Ready; summary.post_state_validation = std::option::Option::Some(post_state); if !post_state_ready { diagnostic.diagnostics.push("confirmed SPL Associated Token Account execution did not satisfy final account relationships".to_string()); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); } let backfill = match crate::solana_token_execution::hydrate_signature( http_pool, store, profile, request.query_role.as_str(), request.post_validation_max_retries, observer, &signature, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => { diagnostic .diagnostics .push(format!("SPL Associated Token Account hydration failed: {error}")); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); }, }; diagnostic.canonical_inserted = crate::solana_token_execution::canonical_available(&backfill); summary.backfill = std::option::Option::Some(backfill); if !diagnostic.canonical_inserted { diagnostic.diagnostics.push("confirmed SPL Associated Token Account transaction was unavailable for canonical hydration".to_string()); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); } let extraction = match crate::execute_core_extraction( store, &crate::CoreExtractionRequest { source: crate::CoreExtractionSource::Signatures(std::vec![signature.0.clone()]), limit: 1, max_concurrent_extractions: 1, force_replay: request.force_post_validation_replay, }, observer, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => { diagnostic .diagnostics .push(format!("SPL Associated Token Account core extraction failed: {error}")); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); }, }; diagnostic.core_extracted = extraction.failed == 0 && !extraction.cancelled && extraction.selected == 1 && extraction.extracted.saturating_add(extraction.skipped) >= 1; summary.core_extraction = std::option::Option::Some(extraction); if !diagnostic.core_extracted { diagnostic .diagnostics .push("SPL Associated Token Account core extraction did not complete".to_string()); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); } let replay_program_ids = crate::solana_ata_execution::replay_program_ids(&request.operation); let first_replay = match crate::solana_token_execution::replay_program( store, &signature, false, request.force_post_validation_replay, replay_program_ids.as_slice(), decoders, materializers, observer, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => { diagnostic .diagnostics .push(format!("SPL Associated Token Account decode replay failed: {error}")); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); }, }; diagnostic.decode_replayed = crate::solana_token_execution::decode_completed(&first_replay); summary.decode_replay = std::option::Option::Some(first_replay); let filter = match kb_store_core::MaterializedEventFilter::new( std::option::Option::None, std::option::Option::None, std::option::Option::Some(signature.0.clone()), 64, ) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let rows = match kb_store_core::DecodePipelineStore::list_materialized_events(store, &filter).await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => { diagnostic.diagnostics.push(format!( "SPL Associated Token Account materialization query failed: {error}" )); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); }, }; summary.materializations = rows .into_iter() .filter(|row| return row.source_decoder_name == "spl_associated_token_account") .collect(); diagnostic.materialized = !summary.plan.policy.post_execution_validation.materialization_required || !summary.materializations.is_empty(); let second_replay = match crate::solana_token_execution::replay_program( store, &signature, true, request.force_post_validation_replay, replay_program_ids.as_slice(), decoders, materializers, observer, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => { diagnostic .diagnostics .push(format!("SPL Associated Token Account idempotence replay failed: {error}")); summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); }, }; let idempotent = second_replay.failed_inputs == 0 && second_replay.processors.iter().all(|processor| { return processor.failed == 0 && processor.materialized_outputs == 0 && processor.materialization_refused == 0; }); summary.idempotence_replay = std::option::Option::Some(second_replay); if !idempotent { diagnostic.diagnostics.push( "second SPL Associated Token Account replay did not prove a clean idempotent skip" .to_string(), ); } else if diagnostic.canonical_inserted && diagnostic.core_extracted && diagnostic.decode_replayed && diagnostic.materialized { diagnostic.diagnostics.push("SPL Associated Token Account completed canonical hydration, core extraction, decode, materialization and idempotence validation".to_string()); } summary.post_execution = std::option::Option::Some(diagnostic); return std::result::Result::Ok(summary); } async fn prepare_execution( http_pool: &kb_rpc::HttpEndpointPool, profile: &kb_config::ProfileConfig, workspace_root: &std::path::Path, request: &crate::solana_ata_execution::DevnetSplAssociatedTokenAccountExecutionRequest, observer: &O, ) -> kb_core::Result where O: crate::SolanaExecutionObserver, { if let std::result::Result::Err(error) = request.validate() { return std::result::Result::Err(error); } if let std::result::Result::Err(error) = crate::solana_ata_execution::validate_profile(profile, request) { return std::result::Result::Err(error); } if let std::result::Result::Err(error) = crate::solana_execution::ensure_not_cancelled(observer, "ata_validate") { return std::result::Result::Err(error); } let genesis = match http_pool.get_genesis_hash_for_role(request.query_role.as_str()).await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; if genesis.classified_cluster != std::option::Option::Some(kb_execution_api::ExecutionCluster::Devnet) { return std::result::Result::Err(kb_core::Error::new( "execution_cluster_mismatch", format!( "expected Devnet genesis hash but endpoint returned {} classified as {:?}", genesis.genesis_hash, genesis.classified_cluster ), )); } let wallet = match crate::solana_execution::load_profile_wallet(profile, workspace_root).await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let wallet_summary = wallet.summary(); let fee_payer = kb_model::Pubkey(wallet_summary.public_key.clone()); let balance = match http_pool .get_balance_for_role( request.query_role.as_str(), &fee_payer, &kb_rpc::GetBalanceConfig::confirmed(), ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; if balance.lamports < profile.execution.max_fee_lamports { return std::result::Result::Err(kb_core::Error::new( "execution_balance_insufficient", format!( "Devnet wallet balance {} is below the configured fee ceiling {}", balance.lamports, profile.execution.max_fee_lamports ), )); } let intent = crate::solana_ata_execution::build_intent(profile, request, fee_payer.clone()); let intent = match intent { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let plan = match kb_execution_api::TypedInstructionExecutor::build_prepared_plan( &kb_executor_spl_associated_token_account::SplAssociatedTokenAccountExecutor, &intent, ) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let readiness = match crate::inspect_spl_associated_token_account_stateful_readiness( http_pool, &crate::SplAssociatedTokenAccountStatefulReadinessRequest { query_role: request.query_role.clone(), cluster: kb_execution_api::ExecutionCluster::Devnet, intent, available_signers: std::vec![fee_payer.clone()], }, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; if readiness.status != crate::SplAssociatedTokenAccountStatefulReadinessStatus::Ready { return std::result::Result::Err(kb_core::Error::new( "execution_spl_associated_token_account_stateful_blocked", crate::solana_ata_execution::failed_readiness_message(&readiness), )); } let plan_evaluation = match kb_execution_safety::ExecutionSafetyChecker.evaluate_prepared_plan(&plan) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; if plan_evaluation.decision == kb_execution_safety::ExecutionSafetyDecision::Deny { return std::result::Result::Err(kb_core::Error::new( "execution_plan_denied", crate::solana_execution::violation_message(plan_evaluation.violations.as_slice()), )); } let latest_blockhash = match http_pool .get_latest_blockhash_for_role( request.query_role.as_str(), &kb_rpc::GetLatestBlockhashConfig::confirmed(), ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let unsigned = match kb_execution_solana::build_legacy_transaction( &plan, latest_blockhash.blockhash.as_str(), ) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let fee = match http_pool .get_fee_for_message_for_role( request.query_role.as_str(), unsigned.message_base64().as_str(), &kb_rpc::GetFeeForMessageConfig::new( kb_rpc::RpcCommitmentLevel::Confirmed, std::option::Option::Some(latest_blockhash.context.slot), ), ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; if fee.fee_lamports.is_none() { return std::result::Result::Err(kb_core::Error::new( "execution_fee_unavailable", "getFeeForMessage returned null for the selected recent blockhash", )); } let unsigned_base64 = match unsigned.transaction_base64() { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let simulation_config = match kb_rpc::SimulateTransactionConfig::new( kb_rpc::RpcCommitmentLevel::Confirmed, false, false, std::option::Option::Some(latest_blockhash.context.slot), true, std::option::Option::None, ) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; crate::solana_execution::emit( observer, crate::SolanaExecutionProgressLevel::Info, "spl_associated_token_account_simulation", format!( "simulating exact SPL Associated Token Account message {}", unsigned.message_hash() ), std::option::Option::None, ); let simulation_rpc = match http_pool .simulate_transaction_for_role( request.transaction_role.as_str(), unsigned_base64.as_str(), &simulation_config, ) .await { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let simulation = simulation_rpc.to_execution_result( kb_execution_api::ExecutionCluster::Devnet, kb_execution_api::ExecutionBlockhashKind::Latest, std::option::Option::Some( simulation_rpc.context.slot.saturating_sub(latest_blockhash.context.slot), ), std::option::Option::None, std::option::Option::None, std::option::Option::Some(&fee), ); let evidence = unsigned.bind_simulation(simulation.clone()); let summary = crate::solana_ata_execution::DevnetSplAssociatedTokenAccountExecutionSummary { profile_name: profile.name.clone(), cluster: kb_execution_api::ExecutionCluster::Devnet, genesis_hash: genesis.genesis_hash, wallet: wallet_summary, balance_lamports: balance.lamports, stateful_readiness: readiness, plan, latest_blockhash, fee, simulation, send_result: std::option::Option::None, confirmation: std::option::Option::None, post_state_validation: std::option::Option::None, backfill: std::option::Option::None, core_extraction: std::option::Option::None, decode_replay: std::option::Option::None, idempotence_replay: std::option::Option::None, materializations: std::vec::Vec::new(), post_execution: std::option::Option::None, }; return std::result::Result::Ok(crate::solana_ata_execution::PreparedAtaExecution { wallet, unsigned, evidence, summary, }); } fn validate_profile( profile: &kb_config::ProfileConfig, request: &crate::solana_ata_execution::DevnetSplAssociatedTokenAccountExecutionRequest, ) -> kb_core::Result<()> { if profile.wallet.cluster != "devnet" { return std::result::Result::Err(kb_core::Error::config( "SPL Associated Token Account Devnet orchestration requires a Devnet wallet profile", )); } if !profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist { return std::result::Result::Err(kb_core::Error::config( "SPL Associated Token Account Devnet orchestration requires an enabled persistent temporary wallet", )); } if !profile.execution.require_simulation { return std::result::Result::Err(kb_core::Error::config( "SPL Associated Token Account Devnet orchestration requires simulation", )); } if request.submit && !profile.wallet.devnet_send_enabled { return std::result::Result::Err(kb_core::Error::config( "Devnet transaction submission is disabled by the wallet profile", )); } if request.submit && profile.execution.require_operator_confirmation && !request.operator_confirmed { return std::result::Result::Err(kb_core::Error::config( "SPL Associated Token Account Devnet submission requires explicit operator confirmation", )); } return std::result::Result::Ok(()); } fn build_intent( profile: &kb_config::ProfileConfig, request: &crate::solana_ata_execution::DevnetSplAssociatedTokenAccountExecutionRequest, fee_payer: kb_model::Pubkey, ) -> kb_core::Result< kb_executor_spl_associated_token_account::SplAssociatedTokenAccountExecutionIntent, > { let max_rent_lamports = if matches!(&request.operation, kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation::RecoverNested { .. }) { 0 } else { profile.execution.devnet_max_spend_lamports }; let mut authorized_signers = std::vec![fee_payer.clone()]; if let kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation::RecoverNested { wallet_owner, .. } = &request.operation { if !authorized_signers.contains(wallet_owner) { authorized_signers.push(wallet_owner.clone()); } } let intent = kb_executor_spl_associated_token_account::SplAssociatedTokenAccountExecutionIntent { intent_id: request.intent_id.clone(), fee_payer, max_rent_lamports, policy: kb_execution_api::ExecutionPolicy { cluster: kb_execution_api::ExecutionClusterPolicy { expected_cluster: kb_execution_api::ExecutionCluster::Devnet, allow_mainnet: false, mainnet_confirmation: false, }, simulation: kb_execution_api::ExecutionSimulationPolicy::Required, blockhash: kb_execution_api::ExecutionBlockhashPolicy { kind: kb_execution_api::ExecutionBlockhashKind::Latest, max_age_slots: std::option::Option::Some( profile.execution.recent_blockhash_max_age_slots, ), nonce_account: std::option::Option::None, nonce_authority: std::option::Option::None, }, cost_limit: kb_execution_api::ExecutionCostLimit { max_spend_lamports: std::option::Option::Some(max_rent_lamports), max_fee_lamports: std::option::Option::Some(profile.execution.max_fee_lamports), max_compute_unit_price_micro_lamports: std::option::Option::Some( profile.execution.max_compute_unit_price_micro_lamports, ), }, authorized_signers, dry_run: !request.submit, post_execution_validation: kb_execution_api::PostExecutionValidationPolicy { canonical_insert_required: true, core_extraction_required: true, decode_replay_required: true, materialization_required: true, }, }, operation: request.operation.clone(), }; return std::result::Result::Ok(intent); } fn failed_readiness_message( readiness: &crate::SplAssociatedTokenAccountStatefulReadinessReport, ) -> std::string::String { let failures = readiness .checks .iter() .filter(|check| return !check.passed) .take(8) .map(|check| return format!("{}: {}", check.code, check.message)) .collect::>(); if failures.is_empty() { return "SPL Associated Token Account stateful readiness returned Blocked without diagnostics".to_string(); } return failures.join("; "); } fn replay_program_ids( operation: &kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation, ) -> std::vec::Vec<&'static str> { let mut output = std::vec![kb_program_ids::ASSOCIATED_TOKEN_PROGRAM_ID]; if operation.token_program() == kb_executor_spl_associated_token_account::SplAssociatedTokenProgram::Classic { output.push(kb_program_ids::SPL_TOKEN_PROGRAM_ID); } return output; } async fn validate_post_state_with_retries( http_pool: &kb_rpc::HttpEndpointPool, profile: &kb_config::ProfileConfig, query_role: &str, maximum_retries: u32, operation: &kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation, ) -> kb_core::Result { let mut retry = 0_u32; loop { let result = crate::inspect_spl_associated_token_account_post_execution( http_pool, query_role, kb_execution_api::ExecutionCluster::Devnet, operation, ) .await; match result { std::result::Result::Ok(report) if report.status == crate::SplAssociatedTokenAccountStatefulReadinessStatus::Ready || retry >= maximum_retries => { return std::result::Result::Ok(report); }, std::result::Result::Err(error) if retry >= maximum_retries => { return std::result::Result::Err(error); }, std::result::Result::Ok(_) | std::result::Result::Err(_) => {}, } retry = retry.saturating_add(1); tokio::time::sleep(std::time::Duration::from_millis(std::cmp::max( profile.execution.confirmation_poll_interval_ms, 500, ))) .await; } } fn validate_profile_wallet_signers( required_signers: &[std::string::String], wallet_pubkey: &str, ) -> kb_core::Result<()> { if required_signers.iter().any(|value| return value.as_str() != wallet_pubkey) { return std::result::Result::Err(kb_core::Error::new( "execution_spl_associated_token_account_external_signer_unavailable", format!( "the Devnet ATA orchestrator can sign only with profile wallet {}; required signers are {}", wallet_pubkey, required_signers.join(",") ), )); } return std::result::Result::Ok(()); } #[cfg(test)] mod tests { fn required_environment_value(name: &str) -> std::string::String { return match std::env::var(name) { std::result::Result::Ok(value) if !value.trim().is_empty() => value, std::result::Result::Ok(_) | std::result::Result::Err(_) => { panic!("{name} is required") }, }; } fn local_devnet_profile() -> kb_config::ProfileConfig { let config = match kb_config::parse_config_json(include_str!("../../config/example.config.json")) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => panic!("example config parse failed: {error}"), }; for profile in config.profiles { if profile.name == "local_devnet" { return profile; } } panic!("local_devnet profile missing"); } fn create_operation( wallet: &str, ) -> kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation { return kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation::CreateIdempotent { wallet_owner: kb_model::Pubkey(wallet.to_string()), mint: kb_model::Pubkey(kb_program_ids::VOTE_PROGRAM_ID.to_string()), token_program: kb_executor_spl_associated_token_account::SplAssociatedTokenProgram::Classic, }; } #[test] fn request_is_simulation_only_and_bounded_by_default() { let request = crate::DevnetSplAssociatedTokenAccountExecutionRequest::new( "ata-1", crate::solana_ata_execution::tests::create_operation(kb_program_ids::SYSTEM_PROGRAM_ID), ); assert!(!request.submit); assert!(request.validate().is_ok()); let mut invalid = request; invalid.post_validation_max_retries = 21; assert!(invalid.validate().is_err()); } #[test] fn creation_and_recovery_intents_preserve_exact_spend_and_signers() { let profile = crate::solana_ata_execution::tests::local_devnet_profile(); let fee_payer = kb_model::Pubkey(kb_program_ids::SYSTEM_PROGRAM_ID.to_string()); let create = crate::DevnetSplAssociatedTokenAccountExecutionRequest::new( "ata-2", crate::solana_ata_execution::tests::create_operation(fee_payer.0.as_str()), ); let create_intent = crate::solana_ata_execution::build_intent(&profile, &create, fee_payer.clone()) .unwrap_or_else(|error| panic!("create intent failed: {error}")); assert_eq!(create_intent.max_rent_lamports, profile.execution.devnet_max_spend_lamports); assert!(create_intent.policy.dry_run); assert_eq!(create_intent.policy.authorized_signers, std::vec![fee_payer.clone()]); let recovery = crate::DevnetSplAssociatedTokenAccountExecutionRequest::new( "ata-3", kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation::RecoverNested { wallet_owner: kb_model::Pubkey(kb_program_ids::STAKE_PROGRAM_ID.to_string()), owner_mint: kb_model::Pubkey(kb_program_ids::VOTE_PROGRAM_ID.to_string()), nested_mint: kb_model::Pubkey(kb_program_ids::CONFIG_PROGRAM_ID.to_string()), token_program: kb_executor_spl_associated_token_account::SplAssociatedTokenProgram::Token2022, }, ); let recovery_intent = crate::solana_ata_execution::build_intent(&profile, &recovery, fee_payer) .unwrap_or_else(|error| panic!("recovery intent failed: {error}")); assert_eq!(recovery_intent.max_rent_lamports, 0); assert_eq!(recovery_intent.policy.authorized_signers.len(), 2); } #[test] fn submission_signers_must_resolve_to_the_profile_wallet() { let wallet = kb_program_ids::SYSTEM_PROGRAM_ID.to_string(); assert!( crate::solana_ata_execution::validate_profile_wallet_signers( std::slice::from_ref(&wallet), wallet.as_str(), ) .is_ok() ); let error = crate::solana_ata_execution::validate_profile_wallet_signers( &[wallet.clone(), kb_program_ids::VOTE_PROGRAM_ID.to_string()], wallet.as_str(), ); assert!(error.is_err()); } #[tokio::test] async fn optional_devnet_operation_from_env() { if std::env::var("KB_DEVNET_SPL_ATA_EXECUTION_TEST").ok().as_deref() != std::option::Option::Some("1") { return; } let operation_code = std::env::var("KB_DEVNET_SPL_ATA_OPERATION") .unwrap_or_else(|_| return "create_idempotent".to_string()); let token_program = match std::env::var("KB_DEVNET_SPL_ATA_TOKEN_PROGRAM").ok().as_deref() { std::option::Option::Some("token_2022") => { kb_executor_spl_associated_token_account::SplAssociatedTokenProgram::Token2022 }, std::option::Option::Some("classic") | std::option::Option::None => { kb_executor_spl_associated_token_account::SplAssociatedTokenProgram::Classic }, std::option::Option::Some(value) => panic!("unsupported Token Program {value}"), }; let submit = std::env::var("KB_DEVNET_SPL_ATA_SUBMIT").ok().as_deref() == std::option::Option::Some("1"); let profile = crate::solana_ata_execution::tests::local_devnet_profile(); let workspace_root = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) .parent() .map(std::path::Path::to_path_buf) .unwrap_or_else(|| panic!("workspace root missing")); let wallet = crate::solana_execution::load_profile_wallet(&profile, workspace_root.as_path()) .await .unwrap_or_else(|error| panic!("profile wallet failed: {error}")); let wallet_pubkey = wallet.public_key(); let operation = match operation_code.as_str() { "create_idempotent" => kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation::CreateIdempotent { wallet_owner: kb_model::Pubkey(wallet_pubkey), mint: kb_model::Pubkey(crate::solana_ata_execution::tests::required_environment_value("KB_DEVNET_SPL_ATA_MINT")), token_program, }, "recover_nested" => kb_executor_spl_associated_token_account::SplAssociatedTokenAccountOperation::RecoverNested { wallet_owner: kb_model::Pubkey(wallet_pubkey), owner_mint: kb_model::Pubkey(crate::solana_ata_execution::tests::required_environment_value("KB_DEVNET_SPL_ATA_OWNER_MINT")), nested_mint: kb_model::Pubkey(crate::solana_ata_execution::tests::required_environment_value("KB_DEVNET_SPL_ATA_NESTED_MINT")), token_program, }, value => panic!("unsupported ATA operation {value}"), }; let mut request = crate::DevnetSplAssociatedTokenAccountExecutionRequest::new( "optional-devnet-ata", operation, ); request.submit = submit; request.operator_confirmed = submit; request.post_validation_max_retries = 20; let pool = kb_rpc::HttpEndpointPool::from_profile(&profile) .unwrap_or_else(|error| panic!("HTTP pool failed: {error}")); let store = kb_store_pg::PostgresStore::connect_from_profile_config(&profile) .await .unwrap_or_else(|error| panic!("PostgreSQL connection failed: {error}")); store .initialize_store_schema() .await .unwrap_or_else(|error| panic!("schema initialization failed: {error}")); let decoders: std::vec::Vec> = std::vec![ std::sync::Arc::new( kb_decoder_spl_associated_token_account::SplAssociatedTokenAccountDecoder ), std::sync::Arc::new(kb_decoder_spl_token::SplTokenDecoder), ]; let materializers: std::vec::Vec< std::sync::Arc, > = std::vec![ std::sync::Arc::new(kb_materializer_token_accounts::TokenAccountsMaterializer), std::sync::Arc::new(kb_materializer_risk::RiskMaterializer), ]; let summary = crate::execute_devnet_spl_associated_token_account( &pool, &store, &profile, workspace_root.as_path(), &request, decoders.as_slice(), materializers.as_slice(), &crate::NoopSolanaExecutionObserver, ) .await .unwrap_or_else(|error| panic!("Devnet ATA execution failed: {error}")); assert_eq!( summary.stateful_readiness.status, crate::SplAssociatedTokenAccountStatefulReadinessStatus::Ready ); assert!(summary.simulation.success, "{:?}", summary.simulation.error); if submit { let send_result = match summary.send_result.as_ref() { std::option::Option::Some(value) => value, std::option::Option::None => { panic!("submitted ATA execution returned no signature") }, }; println!( "Devnet ATA operation={} signature={} materializations={}", operation_code, send_result.signature.0, summary.materializations.len() ); assert!(summary.post_execution.as_ref().is_some_and(|value| { return value.canonical_inserted && value.core_extracted && value.decode_replayed && value.materialized; })); assert!(summary.idempotence_replay.as_ref().is_some_and(|value| { return value.failed_inputs == 0 && value.processors.iter().all(|processor| { return processor.failed == 0 && processor.materialized_outputs == 0 && processor.materialization_refused == 0; }); })); if operation_code == "recover_nested" { assert!(summary.materializations.iter().any(|row| { return row.materialized_family == "token_account" && row.payload_json["lifecycleKind"] == "nested_ata_recovered"; })); assert!(summary.materializations.iter().any(|row| { return row.materialized_family == "risk" && row.payload_json["riskKind"] == "nested_ata_anti_pattern_recovered"; })); } } } }