// file: crates/ksp-program-api/tests/external_implementation.rs // version: 1 //! Downstream-style implementation canary for the open Program decoder contract. const EXTERNAL_PROGRAM_ID_BYTES: [u8; 32] = [0xE7_u8; 32]; const FOREIGN_PROGRAM_ID_BYTES: [u8; 32] = [0xE8_u8; 32]; const SUPPORTED_OPCODE: u8 = 0x2A_u8; struct ExternalDecodedInstruction { opcode: u8, } struct ExternalProgramDecoder { program_ids: [ksp_program_api::Pubkey; 1], } impl ExternalProgramDecoder { fn new() -> Self { return Self { program_ids: [ksp_program_api::Pubkey::new_from_array(EXTERNAL_PROGRAM_ID_BYTES)] }; } } impl ksp_program_api::ProgramInstructionDecoder for ExternalProgramDecoder { type Decoded = ExternalDecodedInstruction; fn program_ids(&self) -> &[ksp_program_api::Pubkey] { return &self.program_ids; } fn recognize(&self, instruction: &ksp_program_api::ProgramInstruction) -> ksp_program_api::ProgramInstructionRecognition { if instruction.program_id() != &self.program_ids[0] { return ksp_program_api::ProgramInstructionRecognition::NoMatch; } if instruction.data().first() == std::option::Option::Some(&SUPPORTED_OPCODE) { return ksp_program_api::ProgramInstructionRecognition::ExactMatch; } return ksp_program_api::ProgramInstructionRecognition::ProgramMatch; } fn decode( &self, instruction: &ksp_program_api::ProgramInstruction, ) -> ksp_program_api::Result> { if instruction.program_id() != &self.program_ids[0] { return std::result::Result::Ok(ksp_program_api::ProgramInstructionDecodeOutcome::Unsupported); } let opcode = match instruction.data().first() { std::option::Option::Some(value) if *value == SUPPORTED_OPCODE => *value, _ => return std::result::Result::Ok(ksp_program_api::ProgramInstructionDecodeOutcome::Unsupported), }; return std::result::Result::Ok(ksp_program_api::ProgramInstructionDecodeOutcome::Decoded(ExternalDecodedInstruction { opcode })); } } fn assert_send_sync(_value: &T) { return; } #[test] fn pre_004_external_decoder_uses_unregistered_pubkey_and_implementation_owned_output() { let decoder = ExternalProgramDecoder::new(); assert_send_sync(&decoder); let external_program_id = ksp_program_api::Pubkey::new_from_array(EXTERNAL_PROGRAM_ID_BYTES); assert!(ksp_core_lib::find_program_pubkey(&external_program_id).is_none()); assert_eq!(ksp_program_api::ProgramInstructionDecoder::program_ids(&decoder), &[external_program_id]); let exact = ksp_program_api::ProgramInstruction::try_new(external_program_id, std::vec![], std::vec![SUPPORTED_OPCODE]); assert!(exact.is_ok()); let exact = match exact { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; assert_eq!(ksp_program_api::ProgramInstructionDecoder::recognize(&decoder, &exact), ksp_program_api::ProgramInstructionRecognition::ExactMatch); let outcome = ksp_program_api::ProgramInstructionDecoder::decode(&decoder, &exact); assert!(outcome.is_ok()); let outcome = match outcome { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let decoded = match outcome { ksp_program_api::ProgramInstructionDecodeOutcome::Decoded(value) => value, _ => return, }; assert_eq!(decoded.opcode, SUPPORTED_OPCODE); return; } #[test] fn pre_004_external_decoder_distinguishes_program_match_unsupported_and_no_match() { let decoder = ExternalProgramDecoder::new(); let external_program_id = ksp_program_api::Pubkey::new_from_array(EXTERNAL_PROGRAM_ID_BYTES); let program_only = ksp_program_api::ProgramInstruction::try_new(external_program_id, std::vec![], std::vec![0x11_u8]); assert!(program_only.is_ok()); let program_only = match program_only { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; assert_eq!(ksp_program_api::ProgramInstructionDecoder::recognize(&decoder, &program_only), ksp_program_api::ProgramInstructionRecognition::ProgramMatch); let unsupported = ksp_program_api::ProgramInstructionDecoder::decode(&decoder, &program_only); assert!(unsupported.is_ok()); let unsupported = match unsupported { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; assert!(matches!(unsupported, ksp_program_api::ProgramInstructionDecodeOutcome::Unsupported)); let foreign_program_id = ksp_program_api::Pubkey::new_from_array(FOREIGN_PROGRAM_ID_BYTES); let foreign = ksp_program_api::ProgramInstruction::try_new(foreign_program_id, std::vec![], std::vec![SUPPORTED_OPCODE]); assert!(foreign.is_ok()); let foreign = match foreign { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; assert_eq!(ksp_program_api::ProgramInstructionDecoder::recognize(&decoder, &foreign), ksp_program_api::ProgramInstructionRecognition::NoMatch); return; }