82 lines
3.2 KiB
Rust
82 lines
3.2 KiB
Rust
// file: crates/ksp-interface-lib/src/program_instruction.rs
|
|
// version: 1
|
|
|
|
/// Maximum opaque data payload admitted by one passive Program instruction contract.
|
|
pub const MAX_PROGRAM_INSTRUCTION_DATA_LEN: usize = 10 * 1024;
|
|
|
|
/// Passive, bounded Program instruction wire contract.
|
|
///
|
|
/// The instruction preserves the caller-provided Program identity, ordered
|
|
/// account metas and opaque data bytes without applying Program-specific
|
|
/// semantics. Construction enforces only the Interface-owned admission bounds.
|
|
pub struct ProgramInstruction {
|
|
program_id: crate::Pubkey,
|
|
accounts: std::vec::Vec<crate::ProgramAccountMeta>,
|
|
data: std::vec::Vec<u8>,
|
|
}
|
|
|
|
impl ProgramInstruction {
|
|
/// Creates one passive Program instruction after enforcing Interface admission bounds.
|
|
///
|
|
/// The provided vectors are consumed directly. Their account order and duplicates
|
|
/// are preserved exactly when construction succeeds.
|
|
pub fn try_new(program_id: crate::Pubkey, accounts: std::vec::Vec<crate::ProgramAccountMeta>, data: std::vec::Vec<u8>) -> ksp_core_lib::Result<Self> {
|
|
if accounts.len() > crate::MAX_PROGRAM_INSTRUCTION_ACCOUNTS {
|
|
return std::result::Result::Err(
|
|
ksp_core_lib::Error::new(
|
|
crate::ERROR_CODE_PROGRAM_INSTRUCTION_LIMIT_EXCEEDED,
|
|
"Program instruction account count exceeds the Interface admission limit",
|
|
)
|
|
.with_context("field", "accounts")
|
|
.with_context("actual_len", accounts.len().to_string())
|
|
.with_context("maximum_len", crate::MAX_PROGRAM_INSTRUCTION_ACCOUNTS.to_string()),
|
|
);
|
|
}
|
|
if data.len() > crate::MAX_PROGRAM_INSTRUCTION_DATA_LEN {
|
|
return std::result::Result::Err(
|
|
ksp_core_lib::Error::new(
|
|
crate::ERROR_CODE_PROGRAM_INSTRUCTION_LIMIT_EXCEEDED,
|
|
"Program instruction data length exceeds the Interface admission limit",
|
|
)
|
|
.with_context("field", "data")
|
|
.with_context("actual_len", data.len().to_string())
|
|
.with_context("maximum_len", crate::MAX_PROGRAM_INSTRUCTION_DATA_LEN.to_string()),
|
|
);
|
|
}
|
|
return std::result::Result::Ok(Self { program_id, accounts, data });
|
|
}
|
|
|
|
/// Returns the ordered account metas exactly as admitted at construction.
|
|
#[must_use]
|
|
pub fn accounts(&self) -> &[crate::ProgramAccountMeta] {
|
|
return self.accounts.as_slice();
|
|
}
|
|
|
|
/// Returns the opaque Program instruction data bytes.
|
|
#[must_use]
|
|
pub fn data(&self) -> &[u8] {
|
|
return self.data.as_slice();
|
|
}
|
|
|
|
/// Returns the Program identity.
|
|
#[must_use]
|
|
pub const fn program_id(&self) -> &crate::Pubkey {
|
|
return &self.program_id;
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Debug for ProgramInstruction {
|
|
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
return formatter
|
|
.debug_struct("ProgramInstruction")
|
|
.field("program_id", &self.program_id)
|
|
.field("account_count", &self.accounts.len())
|
|
.field("data_len", &self.data.len())
|
|
.finish();
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
#[path = "../unit_tests/program_instruction.rs"]
|
|
mod tests;
|