Files
khadhroony-bot3/ks-pipeline/src/spl_token_2022_execution_orchestration.rs
2026-08-09 19:34:08 +02:00

332 lines
14 KiB
Rust

// file: ks-pipeline/src/spl_token_2022_execution_orchestration.rs
// version: 5
//! Final Token-2022 execution-readiness and stateful postcondition contracts.
/// Maximum number of distinct transaction signers accepted by one Token-2022 execution envelope.
pub const MAX_TOKEN_2022_EXECUTION_SIGNERS: usize = 16;
/// Result of one stateful postcondition checked after a confirmed Token-2022 transaction.
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Token2022ExecutionPostconditionStatus {
/// The observed final state confirms the expected operation effect.
Confirmed,
/// The observed final state contradicts the expected operation effect.
Contradicted,
/// The operation has no supported stateful postcondition in the current contract.
NotApplicable,
}
/// One explicit stateful postcondition retained by the execution orchestrator.
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct Token2022ExecutionPostcondition {
/// Stable semantic role such as `mint`, `source`, `destination`, or `registry`.
pub role: std::string::String,
/// Canonical account whose final state was inspected.
pub account: ks_lib::MdPubkey,
/// Explicit result of the postcondition.
pub status: crate::Token2022ExecutionPostconditionStatus,
/// Bounded diagnostic explaining the result without retaining complete account data.
pub diagnostic: std::string::String,
}
/// Complete deterministic request checked before Token-2022 transaction signing.
#[derive(Clone, Debug, PartialEq)]
pub struct Token2022ExecutionReadinessRequest {
/// Exact prepared executor plan.
pub plan: ks_lib::ExApiPreparedExecutionPlan,
/// Exact hash of the compiled Solana message.
pub message_hash: std::string::String,
/// Hash retained by the simulation evidence.
pub simulated_message_hash: std::string::String,
/// Whether the exact compiled message was simulated.
pub simulated: bool,
/// Whether the exact simulation succeeded.
pub simulation_succeeded: bool,
/// Stateful Token-2022 account preflight report.
pub stateful_preflight: crate::Token2022PreflightReport,
/// Cryptographic proof context-state preflight report.
pub cryptographic_preflight: crate::Token2022CryptographicPreflightReport,
/// Ordered proof orchestration report.
pub proof_orchestration: crate::Token2022ProofOrchestrationReport,
/// Public keys actually available to sign the transaction.
pub resolved_signers: std::vec::Vec<ks_lib::MdPubkey>,
/// Whether submission was explicitly requested.
pub submit: bool,
/// Whether submission received explicit operator confirmation.
pub operator_confirmed: bool,
}
/// Deterministic execution-readiness report produced before signing.
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct Token2022ExecutionReadinessReport {
/// Stable operation code.
pub operation_code: std::string::String,
/// Exact compiled message hash bound to simulation.
pub message_hash: std::string::String,
/// Highest RPC context slot across stateful and cryptographic preflights.
pub context_slot: u64,
/// Ordered signer public keys required by the plan.
pub required_signers: std::vec::Vec<ks_lib::MdPubkey>,
/// Whether transaction signing and submission are authorized.
pub send_authorized: bool,
/// Ordered successful checks.
pub checks: std::vec::Vec<std::string::String>,
}
/// Validates the complete Token-2022 execution envelope before transaction signing.
pub fn validate_token_2022_execution_readiness(
request: &crate::Token2022ExecutionReadinessRequest,
) -> ks_core::Result<crate::Token2022ExecutionReadinessReport> {
if request.plan.operation_code.trim().is_empty() {
return std::result::Result::Err(ks_core::Error::config(
"Token-2022 execution plan operation_code must not be empty",
));
}
if request.plan.operation_code != request.proof_orchestration.operation_code {
return std::result::Result::Err(ks_core::Error::new(
"token_2022_execution_operation_mismatch",
"Token-2022 plan and proof orchestration operation codes must match",
));
}
if request.message_hash.trim().is_empty()
|| request.simulated_message_hash.trim().is_empty()
|| request.message_hash != request.simulated_message_hash
{
return std::result::Result::Err(ks_core::Error::new(
"token_2022_execution_simulation_message_mismatch",
"Token-2022 simulation must be bound to the exact compiled message hash",
));
}
if !request.simulated || !request.simulation_succeeded {
return std::result::Result::Err(ks_core::Error::new(
"token_2022_execution_simulation_required",
"Token-2022 execution requires one successful exact-message simulation",
));
}
if !request.proof_orchestration.simulation_required {
return std::result::Result::Err(ks_core::Error::new(
"token_2022_execution_proof_policy_mismatch",
"Token-2022 proof orchestration must require simulation",
));
}
if request.stateful_preflight.commitment != "confirmed"
|| request.cryptographic_preflight.commitment != "confirmed"
{
return std::result::Result::Err(ks_core::Error::new(
"token_2022_execution_preflight_commitment_mismatch",
"Token-2022 stateful and cryptographic preflights must use confirmed commitment",
));
}
let required_signers = match validate_signers(
request.plan.required_signers.as_slice(),
request.resolved_signers.as_slice(),
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
if request.submit && !request.operator_confirmed {
return std::result::Result::Err(ks_core::Error::new(
"token_2022_execution_confirmation_required",
"Token-2022 submission requires explicit operator confirmation",
));
}
if request.submit && !request.proof_orchestration.send_authorized {
return std::result::Result::Err(ks_core::Error::new(
"token_2022_execution_proof_send_not_authorized",
"Token-2022 proof orchestration did not authorize submission",
));
}
if request.submit && request.plan.policy.dry_run {
return std::result::Result::Err(ks_core::Error::new(
"token_2022_execution_dry_run_blocks_submission",
"Token-2022 plan remains dry-run and cannot be submitted",
));
}
let context_slot = request
.stateful_preflight
.context_slot
.max(request.cryptographic_preflight.context_slot);
return std::result::Result::Ok(crate::Token2022ExecutionReadinessReport {
operation_code: request.plan.operation_code.clone(),
message_hash: request.message_hash.clone(),
context_slot,
required_signers,
send_authorized: request.submit
&& request.operator_confirmed
&& request.proof_orchestration.send_authorized
&& !request.plan.policy.dry_run,
checks: vec![
"operation_matches_proof_orchestration".to_string(),
"simulation_bound_to_exact_message".to_string(),
"confirmed_stateful_preflight".to_string(),
"confirmed_cryptographic_preflight".to_string(),
"all_required_signers_resolved".to_string(),
"submission_policy_consistent".to_string(),
],
});
}
/// Aggregates explicit postconditions without converting unsupported checks into success.
pub fn summarize_token_2022_postconditions(
postconditions: &[crate::Token2022ExecutionPostcondition],
) -> crate::Token2022ExecutionPostconditionStatus {
if postconditions.iter().any(|item| {
return item.status == crate::Token2022ExecutionPostconditionStatus::Contradicted;
}) {
return crate::Token2022ExecutionPostconditionStatus::Contradicted;
}
if postconditions.iter().any(|item| {
return item.status == crate::Token2022ExecutionPostconditionStatus::Confirmed;
}) {
return crate::Token2022ExecutionPostconditionStatus::Confirmed;
}
return crate::Token2022ExecutionPostconditionStatus::NotApplicable;
}
fn validate_signers(
required: &[ks_lib::ExApiRequiredSigner],
resolved: &[ks_lib::MdPubkey],
) -> ks_core::Result<std::vec::Vec<ks_lib::MdPubkey>> {
if required.len() > crate::MAX_TOKEN_2022_EXECUTION_SIGNERS
|| resolved.len() > crate::MAX_TOKEN_2022_EXECUTION_SIGNERS
{
return std::result::Result::Err(ks_core::Error::new(
"token_2022_execution_signer_limit_exceeded",
format!(
"Token-2022 execution accepts at most {} signers",
crate::MAX_TOKEN_2022_EXECUTION_SIGNERS
),
));
}
let mut required_unique =
std::collections::BTreeMap::<std::string::String, ks_lib::MdPubkey>::new();
for signer in required {
required_unique
.entry(signer.pubkey.0.clone())
.or_insert_with(|| return signer.pubkey.clone());
}
let resolved_set = resolved
.iter()
.map(|signer| return signer.0.clone())
.collect::<std::collections::BTreeSet<std::string::String>>();
for signer in required_unique.values() {
if !resolved_set.contains(signer.0.as_str()) {
return std::result::Result::Err(ks_core::Error::new(
"token_2022_execution_signer_unresolved",
format!("Token-2022 required signer {} is unresolved", signer.0),
));
}
}
return std::result::Result::Ok(required_unique.into_values().collect());
}
#[cfg(test)]
mod tests {
fn pubkey(byte: u8) -> ks_lib::MdPubkey {
return ks_lib::MdPubkey(bs58::encode([byte; 32]).into_string());
}
fn request() -> crate::Token2022ExecutionReadinessRequest {
let signer = pubkey(1);
let policy = ks_lib::ExApiExecutionPolicy {
dry_run: false,
..std::default::Default::default()
};
let plan = ks_lib::ExApiPreparedExecutionPlan {
executor_name: "kb-lib.executor.spl.token_2022".to_string(),
executor_version: "0.4.6".to_string(),
intent_id: "intent".to_string(),
operation_code: "spl.token_2022.confidential_transfer".to_string(),
fee_payer: signer.clone(),
instructions: vec![],
required_signers: vec![ks_lib::ExApiRequiredSigner {
pubkey: signer.clone(),
role: "authority".to_string(),
}],
policy,
requested_spend_lamports: 0,
requested_compute_unit_price_micro_lamports: std::option::Option::None,
};
return crate::Token2022ExecutionReadinessRequest {
plan,
message_hash: "message-hash".to_string(),
simulated_message_hash: "message-hash".to_string(),
simulated: true,
simulation_succeeded: true,
stateful_preflight: crate::Token2022PreflightReport {
commitment: "confirmed".to_string(),
context_slot: 100,
requested_data_bytes: 0,
accounts: vec![],
elgamal_registry_validated: false,
},
cryptographic_preflight: crate::Token2022CryptographicPreflightReport {
commitment: "confirmed".to_string(),
context_slot: 101,
proof_contexts: vec![],
},
proof_orchestration: crate::Token2022ProofOrchestrationReport {
operation_code: "spl.token_2022.confidential_transfer".to_string(),
instructions_sysvar_required: true,
inline_offsets: vec![1],
context_requirements: vec![],
simulation_required: true,
send_authorized: true,
checks: vec![],
},
resolved_signers: vec![signer],
submit: true,
operator_confirmed: true,
};
}
#[test]
fn exact_message_preflights_and_signers_authorize_submission() {
let report = super::validate_token_2022_execution_readiness(&request())
.expect("complete Token-2022 readiness must succeed");
assert!(report.send_authorized);
assert_eq!(report.context_slot, 101);
assert_eq!(report.required_signers.len(), 1);
}
#[test]
fn message_mismatch_missing_signer_and_dry_run_fail_closed() {
let mut mismatched = request();
mismatched.simulated_message_hash = "other".to_string();
assert!(super::validate_token_2022_execution_readiness(&mismatched).is_err());
let mut missing = request();
missing.resolved_signers.clear();
assert!(super::validate_token_2022_execution_readiness(&missing).is_err());
let mut dry_run = request();
dry_run.plan.policy.dry_run = true;
assert!(super::validate_token_2022_execution_readiness(&dry_run).is_err());
}
#[test]
fn postcondition_summary_preserves_contradicted_and_not_applicable() {
let account = pubkey(2);
let not_applicable = crate::Token2022ExecutionPostcondition {
role: "mint".to_string(),
account: account.clone(),
status: crate::Token2022ExecutionPostconditionStatus::NotApplicable,
diagnostic: "no supported final-state assertion".to_string(),
};
assert_eq!(
super::summarize_token_2022_postconditions(&[not_applicable]),
crate::Token2022ExecutionPostconditionStatus::NotApplicable
);
let contradicted = crate::Token2022ExecutionPostcondition {
role: "source".to_string(),
account,
status: crate::Token2022ExecutionPostconditionStatus::Contradicted,
diagnostic: "final extension inventory contradicts the expected effect".to_string(),
};
assert_eq!(
super::summarize_token_2022_postconditions(&[contradicted]),
crate::Token2022ExecutionPostconditionStatus::Contradicted
);
}
}