0.5.1-pre.002
This commit is contained in:
165
ks-lib/tests/external_executor_api.rs
Normal file
165
ks-lib/tests/external_executor_api.rs
Normal file
@@ -0,0 +1,165 @@
|
||||
// file: ks-lib/tests/external_executor_api.rs
|
||||
// version: 5
|
||||
|
||||
//! Downstream-style compilation contract for externally implemented executors.
|
||||
|
||||
struct ExternalExecutor;
|
||||
|
||||
struct ExternalTypedExecutor;
|
||||
|
||||
impl ks_lib::ExApiInstructionExecutor for ExternalExecutor {
|
||||
fn executor_name(&self) -> &'static str {
|
||||
return "external_executor";
|
||||
}
|
||||
|
||||
fn executor_version(&self) -> &'static str {
|
||||
return "1";
|
||||
}
|
||||
|
||||
fn program_ids(&self) -> &'static [&'static str] {
|
||||
return &[];
|
||||
}
|
||||
|
||||
fn supports_request(
|
||||
&self,
|
||||
_request: &ks_lib::ExApiExecutionRequest,
|
||||
) -> ks_lib::ExApiExecutionSupport {
|
||||
return ks_lib::ExApiExecutionSupport::No;
|
||||
}
|
||||
|
||||
fn build_plan(
|
||||
&self,
|
||||
request: &ks_lib::ExApiExecutionRequest,
|
||||
) -> ks_core::Result<ks_lib::ExApiExecutionPlan> {
|
||||
return std::result::Result::Ok(ks_lib::ExApiExecutionPlan {
|
||||
executor_name: self.executor_name().to_string(),
|
||||
instruction_count: 0,
|
||||
payload_json: request.payload_json.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl ks_lib::ExApiTypedInstructionExecutor for ExternalTypedExecutor {
|
||||
type Intent = ks_lib::MdPubkey;
|
||||
|
||||
fn capability(
|
||||
&self,
|
||||
_program_id: &ks_lib::MdProgramId,
|
||||
operation_code: &str,
|
||||
) -> ks_lib::ExApiExecutionCapability {
|
||||
return ks_lib::ExApiExecutionCapability::unsupported("external_executor", operation_code);
|
||||
}
|
||||
|
||||
fn build_prepared_plan(
|
||||
&self,
|
||||
intent: &Self::Intent,
|
||||
) -> ks_core::Result<ks_lib::ExApiPreparedExecutionPlan> {
|
||||
return std::result::Result::Ok(ks_lib::ExApiPreparedExecutionPlan {
|
||||
executor_name: "external_typed_executor".to_string(),
|
||||
executor_version: "1".to_string(),
|
||||
intent_id: "external-intent".to_string(),
|
||||
operation_code: "external-operation".to_string(),
|
||||
fee_payer: intent.clone(),
|
||||
instructions: std::vec::Vec::new(),
|
||||
required_signers: std::vec::Vec::new(),
|
||||
policy: ks_lib::ExApiExecutionPolicy::default(),
|
||||
requested_spend_lamports: 0,
|
||||
requested_compute_unit_price_micro_lamports: std::option::Option::None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn external_executor_uses_only_the_public_ks_lib_contract() {
|
||||
let executor: &dyn ks_lib::ExApiInstructionExecutor = &ExternalExecutor;
|
||||
assert_eq!(executor.executor_name(), "external_executor");
|
||||
assert_eq!(executor.executor_version(), "1");
|
||||
assert!(executor.program_ids().is_empty());
|
||||
let typed_executor = ExternalTypedExecutor;
|
||||
let program_id = ks_lib::MdProgramId("external-program".to_string());
|
||||
let capability = ks_lib::ExApiTypedInstructionExecutor::capability(
|
||||
&typed_executor,
|
||||
&program_id,
|
||||
"external-operation",
|
||||
);
|
||||
assert!(!capability.is_supported());
|
||||
let fee_payer = ks_lib::MdPubkey("external-fee-payer".to_string());
|
||||
let plan =
|
||||
ks_lib::ExApiTypedInstructionExecutor::build_prepared_plan(&typed_executor, &fee_payer)
|
||||
.unwrap_or_else(|error| panic!("external typed executor failed: {error}"));
|
||||
assert_eq!(plan.fee_payer, fee_payer);
|
||||
assert!(plan.instructions.is_empty());
|
||||
assert!(plan.required_signers.is_empty());
|
||||
assert_eq!(plan.policy.simulation, ks_lib::ExApiExecutionSimulationPolicy::Required);
|
||||
assert!(plan.policy.dry_run);
|
||||
let solana_core_executor = ks_lib::ExSolanaCoreExecutor;
|
||||
let solana_core_program_id =
|
||||
ks_lib::MdProgramId(ks_program_ids::COMPUTE_BUDGET_PROGRAM_ID.to_string());
|
||||
let solana_core_capability = ks_lib::ExApiTypedInstructionExecutor::capability(
|
||||
&solana_core_executor,
|
||||
&solana_core_program_id,
|
||||
ks_lib::EX_SOLANA_CORE_COMPUTE_BUDGET_SET_UNIT_LIMIT_OPERATION,
|
||||
);
|
||||
assert!(solana_core_capability.is_supported());
|
||||
let solana_core_intent = ks_lib::ExSolanaCoreExecutionIntent {
|
||||
intent_id: "external-solana-core".to_string(),
|
||||
fee_payer: ks_lib::MdPubkey(ks_program_ids::SYSTEM_PROGRAM_ID.to_string()),
|
||||
policy: ks_lib::ExApiExecutionPolicy::default(),
|
||||
operation: ks_lib::ExSolanaCoreOperation::ComputeBudgetSetUnitLimit { units: 500_000 },
|
||||
};
|
||||
let solana_core_plan = ks_lib::ExApiTypedInstructionExecutor::build_prepared_plan(
|
||||
&solana_core_executor,
|
||||
&solana_core_intent,
|
||||
)
|
||||
.unwrap_or_else(|error| panic!("Solana core executor failed: {error}"));
|
||||
assert_eq!(solana_core_plan.instructions.len(), 1);
|
||||
assert_eq!(
|
||||
solana_core_plan.operation_code,
|
||||
ks_lib::EX_SOLANA_CORE_COMPUTE_BUDGET_SET_UNIT_LIMIT_OPERATION
|
||||
);
|
||||
let memo_executor = ks_lib::ExSplMemoExecutor;
|
||||
let memo_program_id = ks_lib::MdProgramId(ks_program_ids::SPL_MEMO_V4_PROGRAM_ID.to_string());
|
||||
let memo_capability = ks_lib::ExApiTypedInstructionExecutor::capability(
|
||||
&memo_executor,
|
||||
&memo_program_id,
|
||||
ks_lib::EX_SPL_MEMO_ADD_MEMO_OPERATION,
|
||||
);
|
||||
assert!(memo_capability.is_supported());
|
||||
let memo_intent = ks_lib::ExSplMemoExecutionIntent {
|
||||
intent_id: "external-spl-memo".to_string(),
|
||||
fee_payer: ks_lib::MdPubkey(ks_program_ids::SYSTEM_PROGRAM_ID.to_string()),
|
||||
policy: ks_lib::ExApiExecutionPolicy {
|
||||
cost_limit: ks_lib::ExApiExecutionCostLimit {
|
||||
max_spend_lamports: std::option::Option::Some(0),
|
||||
max_fee_lamports: std::option::Option::Some(10_000),
|
||||
max_compute_unit_price_micro_lamports: std::option::Option::None,
|
||||
},
|
||||
authorized_signers: vec![ks_lib::MdPubkey(
|
||||
ks_program_ids::SYSTEM_PROGRAM_ID.to_string(),
|
||||
)],
|
||||
post_execution_validation: ks_lib::ExApiPostExecutionValidationPolicy {
|
||||
canonical_insert_required: true,
|
||||
core_extraction_required: true,
|
||||
decode_replay_required: true,
|
||||
materialization_required: true,
|
||||
},
|
||||
..ks_lib::ExApiExecutionPolicy::default()
|
||||
},
|
||||
operation: ks_lib::ExSplMemoOperation::AddMemo {
|
||||
generation: ks_lib::ExSplMemoGeneration::V4,
|
||||
message: "external memo".to_string(),
|
||||
signers: std::vec::Vec::new(),
|
||||
},
|
||||
};
|
||||
let memo_plan =
|
||||
ks_lib::ExApiTypedInstructionExecutor::build_prepared_plan(&memo_executor, &memo_intent)
|
||||
.unwrap_or_else(|error| panic!("SPL Memo executor failed: {error}"));
|
||||
assert_eq!(memo_plan.instructions.len(), 1);
|
||||
assert_eq!(
|
||||
ks_lib::ExSafetyChecker
|
||||
.evaluate_prepared_plan(&memo_plan)
|
||||
.unwrap_or_else(|error| panic!("safety evaluation failed: {error}"))
|
||||
.decision,
|
||||
ks_lib::ExSafetyDecision::Allow
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user