v0.2.13-pre.004

This commit is contained in:
2026-08-28 05:11:44 +02:00
parent 900444bff5
commit 0ee28eeb95
9 changed files with 582 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-interface-lib/src/lib.rs
// version: 2
// version: 3
#![warn(missing_docs)]
#![deny(unreachable_pub)]
@@ -14,6 +14,7 @@
mod error;
mod program_account_meta;
mod program_instruction;
/// Error code used when an Interface-owned Program instruction admission limit is exceeded.
pub use self::error::ERROR_CODE_PROGRAM_INSTRUCTION_LIMIT_EXCEEDED;
@@ -21,5 +22,9 @@ pub use self::error::ERROR_CODE_PROGRAM_INSTRUCTION_LIMIT_EXCEEDED;
pub use self::program_account_meta::MAX_PROGRAM_INSTRUCTION_ACCOUNTS;
/// Passive account metadata attached to one Program instruction.
pub use self::program_account_meta::ProgramAccountMeta;
/// Maximum opaque data payload admitted by one passive Program instruction contract.
pub use self::program_instruction::MAX_PROGRAM_INSTRUCTION_DATA_LEN;
/// Passive, bounded Program instruction wire contract.
pub use self::program_instruction::ProgramInstruction;
/// Canonical Solana account address primitive owned by `ksp-core-lib`.
pub use ksp_core_lib::Pubkey;

View File

@@ -0,0 +1,81 @@
// 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;