v0.1.1-pre.003
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
# file: Cargo.toml
|
# file: Cargo.toml
|
||||||
# version: 20
|
# version: 21
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = ["crates/ksp-core-lib"]
|
members = ["crates/ksp-core-lib"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.1.1-pre.2.fix.1"
|
version = "0.1.1-pre.3"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# file: crates/ksp-core-lib/Cargo.toml
|
# file: crates/ksp-core-lib/Cargo.toml
|
||||||
# version: 1
|
# version: 2
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "ksp-core-lib"
|
name = "ksp-core-lib"
|
||||||
@@ -7,5 +7,8 @@ version.workspace = true
|
|||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
solana-pubkey = { version = "4.3.0", default-features = false }
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-core-lib/src/lib.rs
|
// file: crates/ksp-core-lib/src/lib.rs
|
||||||
// version: 4
|
// version: 5
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
#![deny(unreachable_pub)]
|
#![deny(unreachable_pub)]
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
//! Core contracts shared by the foundational KSP layers.
|
//! Core contracts shared by the foundational KSP layers.
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
|
mod program_ids;
|
||||||
|
|
||||||
/// Common KSP error type used by higher-level crates.
|
/// Common KSP error type used by higher-level crates.
|
||||||
pub use self::error::Error;
|
pub use self::error::Error;
|
||||||
@@ -16,3 +17,99 @@ pub use self::error::ErrorCode;
|
|||||||
pub use self::error::ErrorContext;
|
pub use self::error::ErrorContext;
|
||||||
/// Common KSP result alias using [`Error`].
|
/// Common KSP result alias using [`Error`].
|
||||||
pub use self::error::Result;
|
pub use self::error::Result;
|
||||||
|
/// Canonical Address Lookup Table Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_ADDRESS_LOOKUP_TABLE;
|
||||||
|
/// Canonical Compute Budget Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_COMPUTE_BUDGET;
|
||||||
|
/// Canonical Config Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_CONFIG;
|
||||||
|
/// Canonical Feature Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_FEATURE;
|
||||||
|
/// Canonical upgradeable BPF Loader Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_LOADER_BPF_UPGRADEABLE;
|
||||||
|
/// Canonical deprecated BPF Loader Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_LOADER_BPF_V1;
|
||||||
|
/// Canonical BPF Loader v2 Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_LOADER_BPF_V2;
|
||||||
|
/// Canonical Native Loader Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_LOADER_NATIVE;
|
||||||
|
/// Canonical Loader v4 Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_LOADER_V4;
|
||||||
|
/// Canonical Ed25519 precompile Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_PRECOMPILE_ED25519;
|
||||||
|
/// Canonical Secp256k1 precompile Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_PRECOMPILE_SECP256K1;
|
||||||
|
/// Canonical Secp256r1 precompile Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_PRECOMPILE_SECP256R1;
|
||||||
|
/// Canonical Slashing Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_SLASHING;
|
||||||
|
/// Canonical Stake Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_STAKE;
|
||||||
|
/// Canonical System Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_SYSTEM;
|
||||||
|
/// Canonical Vote Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_VOTE;
|
||||||
|
/// Canonical ZK ElGamal Proof Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_ZK_ELGAMAL_PROOF;
|
||||||
|
/// Canonical ZK Token Proof Program ID as Base58 text.
|
||||||
|
pub use self::program_ids::PRGID_SOLANA_ZK_TOKEN_PROOF;
|
||||||
|
/// Canonical Address Lookup Table Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_ADDRESS_LOOKUP_TABLE;
|
||||||
|
/// Canonical Compute Budget Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_COMPUTE_BUDGET;
|
||||||
|
/// Canonical Config Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_CONFIG;
|
||||||
|
/// Canonical Feature Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_FEATURE;
|
||||||
|
/// Canonical upgradeable BPF Loader Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_LOADER_BPF_UPGRADEABLE;
|
||||||
|
/// Canonical deprecated BPF Loader Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_LOADER_BPF_V1;
|
||||||
|
/// Canonical BPF Loader v2 Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_LOADER_BPF_V2;
|
||||||
|
/// Canonical Native Loader Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_LOADER_NATIVE;
|
||||||
|
/// Canonical Loader v4 Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_LOADER_V4;
|
||||||
|
/// Canonical Ed25519 precompile Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_PRECOMPILE_ED25519;
|
||||||
|
/// Canonical Secp256k1 precompile Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_PRECOMPILE_SECP256K1;
|
||||||
|
/// Canonical Secp256r1 precompile Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_PRECOMPILE_SECP256R1;
|
||||||
|
/// Canonical Slashing Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_SLASHING;
|
||||||
|
/// Canonical Stake Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_STAKE;
|
||||||
|
/// Canonical System Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_SYSTEM;
|
||||||
|
/// Canonical Vote Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_VOTE;
|
||||||
|
/// Canonical ZK ElGamal Proof Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_ZK_ELGAMAL_PROOF;
|
||||||
|
/// Canonical ZK Token Proof Program ID as a typed [`Pubkey`].
|
||||||
|
pub use self::program_ids::PRGIDPK_SOLANA_ZK_TOKEN_PROOF;
|
||||||
|
/// Immutable descriptor for one registered Program ID.
|
||||||
|
pub use self::program_ids::ProgramIdEntry;
|
||||||
|
/// Borrowed multi-axis filter for the canonical Program ID registry.
|
||||||
|
pub use self::program_ids::ProgramIdFilter;
|
||||||
|
/// Technical classification of one registered Program ID.
|
||||||
|
pub use self::program_ids::ProgramIdKind;
|
||||||
|
/// Returns the canonical Program ID registry.
|
||||||
|
pub use self::program_ids::entries;
|
||||||
|
/// Finds one registered Program ID by its Base58 representation.
|
||||||
|
pub use self::program_ids::find_program_id;
|
||||||
|
/// Finds one registered Program ID by its typed [`Pubkey`] representation.
|
||||||
|
pub use self::program_ids::find_program_pubkey;
|
||||||
|
/// Returns the Solana core/native Program ID view.
|
||||||
|
pub use self::program_ids::native_program_ids;
|
||||||
|
/// Returns Program IDs matching a multi-axis filter.
|
||||||
|
pub use self::program_ids::program_ids;
|
||||||
|
/// Returns Program IDs belonging to one domain.
|
||||||
|
pub use self::program_ids::program_ids_by_domain;
|
||||||
|
/// Returns Program IDs belonging to one family.
|
||||||
|
pub use self::program_ids::program_ids_by_family;
|
||||||
|
/// Returns Program IDs belonging to one protocol or project.
|
||||||
|
pub use self::program_ids::program_ids_by_protocol;
|
||||||
|
/// Solana account address primitive used by KSP Program IDs.
|
||||||
|
pub use solana_pubkey::Pubkey;
|
||||||
|
|||||||
486
crates/ksp-core-lib/src/program_ids.rs
Normal file
486
crates/ksp-core-lib/src/program_ids.rs
Normal file
@@ -0,0 +1,486 @@
|
|||||||
|
// file: crates/ksp-core-lib/src/program_ids.rs
|
||||||
|
// version: 1
|
||||||
|
|
||||||
|
const DOMAIN_SOLANA: &str = "solana";
|
||||||
|
const FAMILY_CONSENSUS: &str = "consensus";
|
||||||
|
const FAMILY_LOADER: &str = "loader";
|
||||||
|
const FAMILY_PRECOMPILE: &str = "precompile";
|
||||||
|
const FAMILY_PROOF: &str = "proof";
|
||||||
|
const FAMILY_RUNTIME: &str = "runtime";
|
||||||
|
const PROTOCOL_SOLANA: &str = "solana";
|
||||||
|
|
||||||
|
/// Declares one KSP-owned Solana Program ID as matching Base58 and typed constants.
|
||||||
|
///
|
||||||
|
/// The Base58 literal is written once and decoded at compile time through [`crate::Pubkey`].
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! declare_program_id {
|
||||||
|
($string_name:ident, $pubkey_name:ident, $value:literal) => {
|
||||||
|
#[doc = concat!("Base58 Program ID declared as `", stringify!($string_name), "`.")]
|
||||||
|
pub const $string_name: &str = $value;
|
||||||
|
#[doc = concat!("Typed Program ID corresponding to `", stringify!($string_name), "`.")]
|
||||||
|
pub const $pubkey_name: $crate::Pubkey = $crate::Pubkey::from_str_const($string_name);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_ADDRESS_LOOKUP_TABLE, PRGIDPK_SOLANA_ADDRESS_LOOKUP_TABLE, "AddressLookupTab1e1111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_LOADER_BPF_V1, PRGIDPK_SOLANA_LOADER_BPF_V1, "BPFLoader1111111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_LOADER_BPF_V2, PRGIDPK_SOLANA_LOADER_BPF_V2, "BPFLoader2111111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_LOADER_BPF_UPGRADEABLE, PRGIDPK_SOLANA_LOADER_BPF_UPGRADEABLE, "BPFLoaderUpgradeab1e11111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_COMPUTE_BUDGET, PRGIDPK_SOLANA_COMPUTE_BUDGET, "ComputeBudget111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_CONFIG, PRGIDPK_SOLANA_CONFIG, "Config1111111111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_PRECOMPILE_ED25519, PRGIDPK_SOLANA_PRECOMPILE_ED25519, "Ed25519SigVerify111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_FEATURE, PRGIDPK_SOLANA_FEATURE, "Feature111111111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_LOADER_V4, PRGIDPK_SOLANA_LOADER_V4, "LoaderV411111111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_LOADER_NATIVE, PRGIDPK_SOLANA_LOADER_NATIVE, "NativeLoader1111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_PRECOMPILE_SECP256K1, PRGIDPK_SOLANA_PRECOMPILE_SECP256K1, "KeccakSecp256k11111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_PRECOMPILE_SECP256R1, PRGIDPK_SOLANA_PRECOMPILE_SECP256R1, "Secp256r1SigVerify1111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_SLASHING, PRGIDPK_SOLANA_SLASHING, "S1ashing11111111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_STAKE, PRGIDPK_SOLANA_STAKE, "Stake11111111111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_SYSTEM, PRGIDPK_SOLANA_SYSTEM, "11111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_VOTE, PRGIDPK_SOLANA_VOTE, "Vote111111111111111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_ZK_ELGAMAL_PROOF, PRGIDPK_SOLANA_ZK_ELGAMAL_PROOF, "ZkE1Gama1Proof11111111111111111111111111111");
|
||||||
|
crate::declare_program_id!(PRGID_SOLANA_ZK_TOKEN_PROOF, PRGIDPK_SOLANA_ZK_TOKEN_PROOF, "ZkTokenProof1111111111111111111111111111111");
|
||||||
|
|
||||||
|
/// Technical classification of a registered Program ID.
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||||
|
pub enum ProgramIdKind {
|
||||||
|
/// A regular executable program belonging to the registered protocol surface.
|
||||||
|
Program,
|
||||||
|
/// A Solana program loader.
|
||||||
|
Loader,
|
||||||
|
/// A runtime precompile exposed through a Program ID.
|
||||||
|
Precompile,
|
||||||
|
/// An enshrined on-chain program deployed as part of the Solana protocol.
|
||||||
|
EnshrinedProgram,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Immutable descriptor for one KSP-owned Program ID.
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
pub struct ProgramIdEntry {
|
||||||
|
code: &'static str,
|
||||||
|
name: &'static str,
|
||||||
|
program_id: &'static str,
|
||||||
|
pubkey: crate::Pubkey,
|
||||||
|
domain: &'static str,
|
||||||
|
family: &'static str,
|
||||||
|
protocol: &'static str,
|
||||||
|
subfamily: std::option::Option<&'static str>,
|
||||||
|
program_version: std::option::Option<&'static str>,
|
||||||
|
kind: crate::ProgramIdKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProgramIdEntry {
|
||||||
|
const fn new(code: &'static str, name: &'static str, program_id: &'static str, pubkey: crate::Pubkey) -> Self {
|
||||||
|
return Self {
|
||||||
|
code,
|
||||||
|
name,
|
||||||
|
program_id,
|
||||||
|
pubkey,
|
||||||
|
domain: "",
|
||||||
|
family: "",
|
||||||
|
protocol: "",
|
||||||
|
subfamily: std::option::Option::None,
|
||||||
|
program_version: std::option::Option::None,
|
||||||
|
kind: crate::ProgramIdKind::Program,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn with_taxonomy(
|
||||||
|
mut self,
|
||||||
|
domain: &'static str,
|
||||||
|
family: &'static str,
|
||||||
|
protocol: &'static str,
|
||||||
|
subfamily: std::option::Option<&'static str>,
|
||||||
|
program_version: std::option::Option<&'static str>,
|
||||||
|
kind: crate::ProgramIdKind,
|
||||||
|
) -> Self {
|
||||||
|
self.domain = domain;
|
||||||
|
self.family = family;
|
||||||
|
self.protocol = protocol;
|
||||||
|
self.subfamily = subfamily;
|
||||||
|
self.program_version = program_version;
|
||||||
|
self.kind = kind;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the stable KSP machine-readable code of this entry.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn code(&self) -> &'static str {
|
||||||
|
return self.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the human-readable program name.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn name(&self) -> &'static str {
|
||||||
|
return self.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the canonical Base58 Program ID.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn program_id(&self) -> &'static str {
|
||||||
|
return self.program_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the typed Solana Program ID.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn pubkey(&self) -> crate::Pubkey {
|
||||||
|
return self.pubkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the broad functional domain.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn domain(&self) -> &'static str {
|
||||||
|
return self.domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the functional family within the domain.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn family(&self) -> &'static str {
|
||||||
|
return self.family;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the owning protocol or project identifier.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn protocol(&self) -> &'static str {
|
||||||
|
return self.protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the optional architectural branch or product subfamily.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn subfamily(&self) -> std::option::Option<&'static str> {
|
||||||
|
return self.subfamily;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the optional public generation of this program lineage.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn program_version(&self) -> std::option::Option<&'static str> {
|
||||||
|
return self.program_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the technical Program ID classification.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn kind(&self) -> crate::ProgramIdKind {
|
||||||
|
return self.kind;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Borrowed filter used to select Program IDs from the canonical KSP registry.
|
||||||
|
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||||
|
pub struct ProgramIdFilter<'a> {
|
||||||
|
domain: std::option::Option<&'a str>,
|
||||||
|
family: std::option::Option<&'a str>,
|
||||||
|
protocol: std::option::Option<&'a str>,
|
||||||
|
subfamily: std::option::Option<&'a str>,
|
||||||
|
program_version: std::option::Option<&'a str>,
|
||||||
|
kind: std::option::Option<crate::ProgramIdKind>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ProgramIdFilter<'a> {
|
||||||
|
/// Creates an empty filter matching every registered Program ID.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
return Self {
|
||||||
|
domain: std::option::Option::None,
|
||||||
|
family: std::option::Option::None,
|
||||||
|
protocol: std::option::Option::None,
|
||||||
|
subfamily: std::option::Option::None,
|
||||||
|
program_version: std::option::Option::None,
|
||||||
|
kind: std::option::Option::None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restricts the filter to one functional domain.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn with_domain(mut self, domain: &'a str) -> Self {
|
||||||
|
self.domain = std::option::Option::Some(domain);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restricts the filter to one functional family.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn with_family(mut self, family: &'a str) -> Self {
|
||||||
|
self.family = std::option::Option::Some(family);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restricts the filter to one protocol or project.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn with_protocol(mut self, protocol: &'a str) -> Self {
|
||||||
|
self.protocol = std::option::Option::Some(protocol);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restricts the filter to one architectural subfamily.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn with_subfamily(mut self, subfamily: &'a str) -> Self {
|
||||||
|
self.subfamily = std::option::Option::Some(subfamily);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restricts the filter to one public program generation.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn with_program_version(mut self, program_version: &'a str) -> Self {
|
||||||
|
self.program_version = std::option::Option::Some(program_version);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restricts the filter to one technical Program ID kind.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn with_kind(mut self, kind: crate::ProgramIdKind) -> Self {
|
||||||
|
self.kind = std::option::Option::Some(kind);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn matches(&self, entry: &crate::ProgramIdEntry) -> bool {
|
||||||
|
if let std::option::Option::Some(domain) = self.domain
|
||||||
|
&& entry.domain() != domain
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if let std::option::Option::Some(family) = self.family
|
||||||
|
&& entry.family() != family
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if let std::option::Option::Some(protocol) = self.protocol
|
||||||
|
&& entry.protocol() != protocol
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if let std::option::Option::Some(subfamily) = self.subfamily
|
||||||
|
&& entry.subfamily() != std::option::Option::Some(subfamily)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if let std::option::Option::Some(program_version) = self.program_version
|
||||||
|
&& entry.program_version() != std::option::Option::Some(program_version)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if let std::option::Option::Some(kind) = self.kind
|
||||||
|
&& entry.kind() != kind
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PROGRAM_ID_ENTRIES: &[crate::ProgramIdEntry] = &[
|
||||||
|
crate::ProgramIdEntry::new(
|
||||||
|
"solana.address_lookup_table",
|
||||||
|
"Address Lookup Table Program",
|
||||||
|
crate::PRGID_SOLANA_ADDRESS_LOOKUP_TABLE,
|
||||||
|
crate::PRGIDPK_SOLANA_ADDRESS_LOOKUP_TABLE,
|
||||||
|
)
|
||||||
|
.with_taxonomy(DOMAIN_SOLANA, FAMILY_RUNTIME, PROTOCOL_SOLANA, std::option::Option::None, std::option::Option::None, crate::ProgramIdKind::Program),
|
||||||
|
crate::ProgramIdEntry::new("solana.loader.bpf.v1", "Deprecated BPF Loader", crate::PRGID_SOLANA_LOADER_BPF_V1, crate::PRGIDPK_SOLANA_LOADER_BPF_V1)
|
||||||
|
.with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_LOADER,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::Some("bpf"),
|
||||||
|
std::option::Option::Some("v1"),
|
||||||
|
crate::ProgramIdKind::Loader,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new("solana.loader.bpf.v2", "BPF Loader v2", crate::PRGID_SOLANA_LOADER_BPF_V2, crate::PRGIDPK_SOLANA_LOADER_BPF_V2).with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_LOADER,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::Some("bpf"),
|
||||||
|
std::option::Option::Some("v2"),
|
||||||
|
crate::ProgramIdKind::Loader,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new(
|
||||||
|
"solana.loader.bpf_upgradeable",
|
||||||
|
"Upgradeable BPF Loader",
|
||||||
|
crate::PRGID_SOLANA_LOADER_BPF_UPGRADEABLE,
|
||||||
|
crate::PRGIDPK_SOLANA_LOADER_BPF_UPGRADEABLE,
|
||||||
|
)
|
||||||
|
.with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_LOADER,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::Some("bpf"),
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Loader,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new("solana.compute_budget", "Compute Budget Program", crate::PRGID_SOLANA_COMPUTE_BUDGET, crate::PRGIDPK_SOLANA_COMPUTE_BUDGET)
|
||||||
|
.with_taxonomy(DOMAIN_SOLANA, FAMILY_RUNTIME, PROTOCOL_SOLANA, std::option::Option::None, std::option::Option::None, crate::ProgramIdKind::Program),
|
||||||
|
crate::ProgramIdEntry::new("solana.config", "Config Program", crate::PRGID_SOLANA_CONFIG, crate::PRGIDPK_SOLANA_CONFIG).with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_RUNTIME,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::None,
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Program,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new(
|
||||||
|
"solana.precompile.ed25519",
|
||||||
|
"Ed25519 Signature Verification Precompile",
|
||||||
|
crate::PRGID_SOLANA_PRECOMPILE_ED25519,
|
||||||
|
crate::PRGIDPK_SOLANA_PRECOMPILE_ED25519,
|
||||||
|
)
|
||||||
|
.with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_PRECOMPILE,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::Some("ed25519"),
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Precompile,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new("solana.feature", "Feature Program", crate::PRGID_SOLANA_FEATURE, crate::PRGIDPK_SOLANA_FEATURE).with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_RUNTIME,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::None,
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Program,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new("solana.loader.v4", "Loader v4", crate::PRGID_SOLANA_LOADER_V4, crate::PRGIDPK_SOLANA_LOADER_V4).with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_LOADER,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::None,
|
||||||
|
std::option::Option::Some("v4"),
|
||||||
|
crate::ProgramIdKind::Loader,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new("solana.loader.native", "Native Loader", crate::PRGID_SOLANA_LOADER_NATIVE, crate::PRGIDPK_SOLANA_LOADER_NATIVE).with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_LOADER,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::Some("native"),
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Loader,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new(
|
||||||
|
"solana.precompile.secp256k1",
|
||||||
|
"Secp256k1 Signature Verification Precompile",
|
||||||
|
crate::PRGID_SOLANA_PRECOMPILE_SECP256K1,
|
||||||
|
crate::PRGIDPK_SOLANA_PRECOMPILE_SECP256K1,
|
||||||
|
)
|
||||||
|
.with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_PRECOMPILE,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::Some("secp256k1"),
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Precompile,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new(
|
||||||
|
"solana.precompile.secp256r1",
|
||||||
|
"Secp256r1 Signature Verification Precompile",
|
||||||
|
crate::PRGID_SOLANA_PRECOMPILE_SECP256R1,
|
||||||
|
crate::PRGIDPK_SOLANA_PRECOMPILE_SECP256R1,
|
||||||
|
)
|
||||||
|
.with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_PRECOMPILE,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::Some("secp256r1"),
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Precompile,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new("solana.slashing", "Slashing Program", crate::PRGID_SOLANA_SLASHING, crate::PRGIDPK_SOLANA_SLASHING).with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_CONSENSUS,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::None,
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::EnshrinedProgram,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new("solana.stake", "Stake Program", crate::PRGID_SOLANA_STAKE, crate::PRGIDPK_SOLANA_STAKE).with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_CONSENSUS,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::None,
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Program,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new("solana.system", "System Program", crate::PRGID_SOLANA_SYSTEM, crate::PRGIDPK_SOLANA_SYSTEM).with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_RUNTIME,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::None,
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Program,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new("solana.vote", "Vote Program", crate::PRGID_SOLANA_VOTE, crate::PRGIDPK_SOLANA_VOTE).with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_CONSENSUS,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::None,
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Program,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new(
|
||||||
|
"solana.proof.zk_elgamal",
|
||||||
|
"ZK ElGamal Proof Program",
|
||||||
|
crate::PRGID_SOLANA_ZK_ELGAMAL_PROOF,
|
||||||
|
crate::PRGIDPK_SOLANA_ZK_ELGAMAL_PROOF,
|
||||||
|
)
|
||||||
|
.with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_PROOF,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::Some("zk_elgamal"),
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Program,
|
||||||
|
),
|
||||||
|
crate::ProgramIdEntry::new("solana.proof.zk_token", "ZK Token Proof Program", crate::PRGID_SOLANA_ZK_TOKEN_PROOF, crate::PRGIDPK_SOLANA_ZK_TOKEN_PROOF)
|
||||||
|
.with_taxonomy(
|
||||||
|
DOMAIN_SOLANA,
|
||||||
|
FAMILY_PROOF,
|
||||||
|
PROTOCOL_SOLANA,
|
||||||
|
std::option::Option::Some("zk_token"),
|
||||||
|
std::option::Option::None,
|
||||||
|
crate::ProgramIdKind::Program,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
/// Returns the canonical KSP Program ID registry.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn entries() -> &'static [crate::ProgramIdEntry] {
|
||||||
|
return PROGRAM_ID_ENTRIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a lazy view of Program IDs matching all configured filter axes.
|
||||||
|
pub fn program_ids<'a>(filter: crate::ProgramIdFilter<'a>) -> impl std::iter::Iterator<Item = &'static crate::ProgramIdEntry> + 'a {
|
||||||
|
return PROGRAM_ID_ENTRIES.iter().filter(move |entry| filter.matches(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns all Solana core/native Program IDs, including loaders, precompiles and enshrined programs.
|
||||||
|
pub fn native_program_ids() -> impl std::iter::Iterator<Item = &'static crate::ProgramIdEntry> {
|
||||||
|
return crate::program_ids(crate::ProgramIdFilter::new().with_domain(DOMAIN_SOLANA).with_protocol(PROTOCOL_SOLANA));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a lazy view of Program IDs belonging to one functional domain.
|
||||||
|
pub fn program_ids_by_domain<'a>(domain: &'a str) -> impl std::iter::Iterator<Item = &'static crate::ProgramIdEntry> + 'a {
|
||||||
|
return crate::program_ids(crate::ProgramIdFilter::new().with_domain(domain));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a lazy view of Program IDs belonging to one functional family.
|
||||||
|
pub fn program_ids_by_family<'a>(family: &'a str) -> impl std::iter::Iterator<Item = &'static crate::ProgramIdEntry> + 'a {
|
||||||
|
return crate::program_ids(crate::ProgramIdFilter::new().with_family(family));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a lazy view of Program IDs belonging to one protocol or project.
|
||||||
|
pub fn program_ids_by_protocol<'a>(protocol: &'a str) -> impl std::iter::Iterator<Item = &'static crate::ProgramIdEntry> + 'a {
|
||||||
|
return crate::program_ids(crate::ProgramIdFilter::new().with_protocol(protocol));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finds one registered Program ID by its canonical Base58 representation.
|
||||||
|
#[must_use]
|
||||||
|
pub fn find_program_id(program_id: &str) -> std::option::Option<&'static crate::ProgramIdEntry> {
|
||||||
|
return PROGRAM_ID_ENTRIES.iter().find(|entry| entry.program_id() == program_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finds one registered Program ID by its typed Solana representation.
|
||||||
|
#[must_use]
|
||||||
|
pub fn find_program_pubkey(program_id: &crate::Pubkey) -> std::option::Option<&'static crate::ProgramIdEntry> {
|
||||||
|
return PROGRAM_ID_ENTRIES.iter().find(|entry| entry.pubkey() == *program_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[path = "../unit_tests/program_ids.rs"]
|
||||||
|
mod tests;
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
// file: crates/ksp-core-lib/tests/public_api.rs
|
// file: crates/ksp-core-lib/tests/public_api.rs
|
||||||
// version: 2
|
// version: 3
|
||||||
|
|
||||||
//! Integration tests for the public `ksp-core-lib` error contract.
|
//! Integration tests for the public `ksp-core-lib` contracts.
|
||||||
|
|
||||||
|
ksp_core_lib::declare_program_id!(TEST_PRGID_SYSTEM, TEST_PRGIDPK_SYSTEM, "11111111111111111111111111111111");
|
||||||
|
|
||||||
fn public_result() -> ksp_core_lib::Result<()> {
|
fn public_result() -> ksp_core_lib::Result<()> {
|
||||||
let error = ksp_core_lib::Error::new(ksp_core_lib::ErrorCode::new("consumer", "failed"), "consumer failure").with_context("operation", "public_api");
|
let error = ksp_core_lib::Error::new(ksp_core_lib::ErrorCode::new("consumer", "failed"), "consumer failure").with_context("operation", "public_api");
|
||||||
@@ -22,3 +24,42 @@ fn error_contract_is_consumable_from_crate_root() {
|
|||||||
assert_eq!(std::string::ToString::to_string(&error), "consumer.failed: consumer failure");
|
assert_eq!(std::string::ToString::to_string(&error), "consumer.failed: consumer failure");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn program_id_contract_is_consumable_from_crate_root() {
|
||||||
|
assert_eq!(TEST_PRGID_SYSTEM, ksp_core_lib::PRGID_SOLANA_SYSTEM);
|
||||||
|
assert_eq!(TEST_PRGIDPK_SYSTEM, ksp_core_lib::PRGIDPK_SOLANA_SYSTEM);
|
||||||
|
assert_eq!(ksp_core_lib::entries().len(), 18);
|
||||||
|
assert_eq!(ksp_core_lib::native_program_ids().count(), 18);
|
||||||
|
let system = ksp_core_lib::find_program_id(ksp_core_lib::PRGID_SOLANA_SYSTEM);
|
||||||
|
let system = match system {
|
||||||
|
std::option::Option::Some(entry) => entry,
|
||||||
|
std::option::Option::None => return,
|
||||||
|
};
|
||||||
|
assert_eq!(system.code(), "solana.system");
|
||||||
|
assert_eq!(system.domain(), "solana");
|
||||||
|
assert_eq!(system.family(), "runtime");
|
||||||
|
assert_eq!(system.protocol(), "solana");
|
||||||
|
assert_eq!(system.pubkey(), ksp_core_lib::PRGIDPK_SOLANA_SYSTEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn program_id_registry_supports_public_taxonomy_filters() {
|
||||||
|
let loader_count = ksp_core_lib::program_ids_by_family("loader").count();
|
||||||
|
let precompile_count = ksp_core_lib::program_ids_by_family("precompile").count();
|
||||||
|
let bpf_v2_count = ksp_core_lib::program_ids(
|
||||||
|
ksp_core_lib::ProgramIdFilter::new()
|
||||||
|
.with_domain("solana")
|
||||||
|
.with_family("loader")
|
||||||
|
.with_protocol("solana")
|
||||||
|
.with_subfamily("bpf")
|
||||||
|
.with_program_version("v2")
|
||||||
|
.with_kind(ksp_core_lib::ProgramIdKind::Loader),
|
||||||
|
)
|
||||||
|
.count();
|
||||||
|
assert_eq!(loader_count, 5);
|
||||||
|
assert_eq!(precompile_count, 3);
|
||||||
|
assert_eq!(bpf_v2_count, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|||||||
89
crates/ksp-core-lib/unit_tests/program_ids.rs
Normal file
89
crates/ksp-core-lib/unit_tests/program_ids.rs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
// file: crates/ksp-core-lib/unit_tests/program_ids.rs
|
||||||
|
// version: 1
|
||||||
|
|
||||||
|
fn assert_program_id_types(program_id: &'static str, pubkey: crate::Pubkey) {
|
||||||
|
assert_eq!(pubkey, crate::Pubkey::from_str_const(program_id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn declared_program_ids_have_matching_text_and_pubkey_forms() {
|
||||||
|
assert_program_id_types(crate::PRGID_SOLANA_SYSTEM, crate::PRGIDPK_SOLANA_SYSTEM);
|
||||||
|
assert_program_id_types(crate::PRGID_SOLANA_STAKE, crate::PRGIDPK_SOLANA_STAKE);
|
||||||
|
assert_program_id_types(crate::PRGID_SOLANA_VOTE, crate::PRGIDPK_SOLANA_VOTE);
|
||||||
|
assert_program_id_types(crate::PRGID_SOLANA_SLASHING, crate::PRGIDPK_SOLANA_SLASHING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn registry_contains_the_eighteen_core_program_ids() {
|
||||||
|
assert_eq!(crate::entries().len(), 18);
|
||||||
|
assert_eq!(crate::native_program_ids().count(), 18);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn registry_codes_program_ids_and_pubkeys_are_unique() {
|
||||||
|
for left_index in 0..crate::entries().len() {
|
||||||
|
for right_index in (left_index + 1)..crate::entries().len() {
|
||||||
|
let left = &crate::entries()[left_index];
|
||||||
|
let right = &crate::entries()[right_index];
|
||||||
|
assert_ne!(left.code(), right.code());
|
||||||
|
assert_ne!(left.program_id(), right.program_id());
|
||||||
|
assert_ne!(left.pubkey(), right.pubkey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn registry_pubkeys_match_their_owned_base58_values() {
|
||||||
|
for entry in crate::entries() {
|
||||||
|
assert_eq!(entry.pubkey(), crate::Pubkey::from_str_const(entry.program_id()));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn filters_combine_domain_family_protocol_subfamily_version_and_kind() {
|
||||||
|
let bpf_v2 = crate::program_ids(
|
||||||
|
crate::ProgramIdFilter::new()
|
||||||
|
.with_domain("solana")
|
||||||
|
.with_family("loader")
|
||||||
|
.with_protocol("solana")
|
||||||
|
.with_subfamily("bpf")
|
||||||
|
.with_program_version("v2")
|
||||||
|
.with_kind(crate::ProgramIdKind::Loader),
|
||||||
|
)
|
||||||
|
.collect::<std::vec::Vec<_>>();
|
||||||
|
assert_eq!(bpf_v2.len(), 1);
|
||||||
|
assert_eq!(bpf_v2[0].program_id(), crate::PRGID_SOLANA_LOADER_BPF_V2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn family_views_cover_expected_core_groups() {
|
||||||
|
assert_eq!(crate::program_ids_by_family("runtime").count(), 5);
|
||||||
|
assert_eq!(crate::program_ids_by_family("consensus").count(), 3);
|
||||||
|
assert_eq!(crate::program_ids_by_family("loader").count(), 5);
|
||||||
|
assert_eq!(crate::program_ids_by_family("precompile").count(), 3);
|
||||||
|
assert_eq!(crate::program_ids_by_family("proof").count(), 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn direct_lookup_supports_text_and_typed_program_ids() {
|
||||||
|
let by_text = crate::find_program_id(crate::PRGID_SOLANA_SLASHING);
|
||||||
|
let by_pubkey = crate::find_program_pubkey(&crate::PRGIDPK_SOLANA_SLASHING);
|
||||||
|
assert_eq!(by_text.map(crate::ProgramIdEntry::code), std::option::Option::Some("solana.slashing"));
|
||||||
|
assert_eq!(by_pubkey.map(crate::ProgramIdEntry::code), std::option::Option::Some("solana.slashing"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn non_program_well_known_accounts_are_absent() {
|
||||||
|
assert!(crate::find_program_id("1nc1nerator11111111111111111111111111111111").is_none());
|
||||||
|
assert!(crate::find_program_id("StakeConfig11111111111111111111111111111111").is_none());
|
||||||
|
assert!(crate::find_program_id("SysvarC1ock11111111111111111111111111111111").is_none());
|
||||||
|
return;
|
||||||
|
}
|
||||||
284
deltas/0.1.1/pre.003.md
Normal file
284
deltas/0.1.1/pre.003.md
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
<!-- file: deltas/0.1.1/pre.003.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta `0.1.1-pre.003` — Pubkey + Program IDs
|
||||||
|
|
||||||
|
## Statut
|
||||||
|
|
||||||
|
Tranche fonctionnelle `0.1.1-pre.003` préparée après validation réussie par le user de `0.1.1-pre.002-fix.001`.
|
||||||
|
|
||||||
|
La base utilisateur observée avant ce delta utilise :
|
||||||
|
|
||||||
|
```text
|
||||||
|
workspace.package.version = "0.1.1-pre.2.fix.1"
|
||||||
|
```
|
||||||
|
|
||||||
|
Le présent delta ouvre :
|
||||||
|
|
||||||
|
```text
|
||||||
|
workspace.package.version = "0.1.1-pre.3"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation de la base précédente
|
||||||
|
|
||||||
|
Le user a exécuté avec succès avant ce delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo fmt --all
|
||||||
|
cargo check --workspace
|
||||||
|
cargo clippy --workspace --all-targets
|
||||||
|
cargo test --workspace
|
||||||
|
```
|
||||||
|
|
||||||
|
Les six tests unitaires Error et le test d'intégration public Error passent sans warning dans cette validation.
|
||||||
|
|
||||||
|
## Audit Solana/Anza revérifié
|
||||||
|
|
||||||
|
Au 2026-08-14 :
|
||||||
|
|
||||||
|
- `solana-pubkey 4.3.0` est la version publiée courante observée sur crates.io ;
|
||||||
|
- son MSRV publié est Rust `1.89.0` ;
|
||||||
|
- la validation précédente du user expose une génération Clippy `rust-1.94.0`, donc la toolchain observée satisfait ce MSRV ;
|
||||||
|
- `Pubkey` reste la façade de compatibilité officielle sur l'`Address` Solana actuel ;
|
||||||
|
- `Pubkey::from_str_const` permet le décodage Base58 compile-time nécessaire à la macro KSP ;
|
||||||
|
- `solana-sdk-ids` est consulté uniquement comme source d'audit et n'entre pas dans le graphe Cargo KSP.
|
||||||
|
|
||||||
|
Sources externes revérifiées pendant cette tranche :
|
||||||
|
|
||||||
|
- crates.io / docs.rs pour `solana-pubkey 4.3.0` ;
|
||||||
|
- `anza-xyz/solana-sdk`, `sdk-ids/src/lib.rs`, pour les identifiants fondamentaux actuellement publiés ;
|
||||||
|
- SIMD-0204 et la documentation Anza pour le Slashing Program `S1ashing11111111111111111111111111111111111`.
|
||||||
|
|
||||||
|
## Dépendance Core
|
||||||
|
|
||||||
|
`crates/ksp-core-lib/Cargo.toml` ajoute uniquement :
|
||||||
|
|
||||||
|
```toml
|
||||||
|
solana-pubkey = { version = "4.3.0", default-features = false }
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun codec wire, client RPC, umbrella SDK ou registre `solana-sdk-ids` n'est ajouté.
|
||||||
|
|
||||||
|
`ksp_core_lib::Pubkey` réexporte `solana_pubkey::Pubkey` depuis la façade Core.
|
||||||
|
|
||||||
|
## Macro KSP de Program ID
|
||||||
|
|
||||||
|
La macro publique :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ksp_core_lib::declare_program_id!
|
||||||
|
```
|
||||||
|
|
||||||
|
possède la chaîne Base58 une seule fois et produit simultanément :
|
||||||
|
|
||||||
|
```text
|
||||||
|
PRGID_* : &'static str
|
||||||
|
PRGIDPK_* : Pubkey
|
||||||
|
```
|
||||||
|
|
||||||
|
La représentation typée est construite avec `Pubkey::from_str_const`, sans parsing runtime, `unwrap`, `expect`, `panic` ni opérateur `?`.
|
||||||
|
|
||||||
|
La macro ne génère pas de symboles génériques `ID`, `id()` ou `check_id()` et peut donc être utilisée plusieurs fois dans une même crate/module.
|
||||||
|
|
||||||
|
## Première surface Program IDs Core
|
||||||
|
|
||||||
|
La tranche fixe le premier registre à 18 Program IDs.
|
||||||
|
|
||||||
|
Les 17 valeurs de la surface officielle actuelle Anza `solana-sdk-ids` sont possédées localement par KSP :
|
||||||
|
|
||||||
|
1. Address Lookup Table ;
|
||||||
|
2. BPF Loader historique v1 ;
|
||||||
|
3. BPF Loader v2 ;
|
||||||
|
4. BPF Loader Upgradeable ;
|
||||||
|
5. Compute Budget ;
|
||||||
|
6. Config ;
|
||||||
|
7. Ed25519 precompile ;
|
||||||
|
8. Feature ;
|
||||||
|
9. Loader v4 ;
|
||||||
|
10. Native Loader ;
|
||||||
|
11. Secp256k1 precompile ;
|
||||||
|
12. Secp256r1 precompile ;
|
||||||
|
13. Stake ;
|
||||||
|
14. System ;
|
||||||
|
15. Vote ;
|
||||||
|
16. ZK ElGamal Proof ;
|
||||||
|
17. ZK Token Proof.
|
||||||
|
|
||||||
|
Le dix-huitième identifiant est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
PRGID_SOLANA_SLASHING = "S1ashing11111111111111111111111111111111111"
|
||||||
|
```
|
||||||
|
|
||||||
|
Son statut de programme enshrined et son adresse sont confirmés séparément par SIMD-0204/Anza ; sa présence ne dépend donc pas de l'ancien registre bot3.
|
||||||
|
|
||||||
|
Les sysvars, `StakeConfig`, l'incinerator et les autres well-known accounts restent exclus du registre Program IDs.
|
||||||
|
|
||||||
|
## Nomenclature publique
|
||||||
|
|
||||||
|
Chaque entrée possède une paire `PRGID_*` / `PRGIDPK_*` au crate-root.
|
||||||
|
|
||||||
|
Exemples :
|
||||||
|
|
||||||
|
```text
|
||||||
|
PRGID_SOLANA_SYSTEM
|
||||||
|
PRGIDPK_SOLANA_SYSTEM
|
||||||
|
|
||||||
|
PRGID_SOLANA_LOADER_BPF_V1
|
||||||
|
PRGIDPK_SOLANA_LOADER_BPF_V1
|
||||||
|
|
||||||
|
PRGID_SOLANA_PRECOMPILE_ED25519
|
||||||
|
PRGIDPK_SOLANA_PRECOMPILE_ED25519
|
||||||
|
|
||||||
|
PRGID_SOLANA_SLASHING
|
||||||
|
PRGIDPK_SOLANA_SLASHING
|
||||||
|
```
|
||||||
|
|
||||||
|
Le suffixe est strictement identique entre les deux représentations.
|
||||||
|
|
||||||
|
## Registre canonique
|
||||||
|
|
||||||
|
`ProgramIdEntry` porte :
|
||||||
|
|
||||||
|
```text
|
||||||
|
code
|
||||||
|
name
|
||||||
|
program_id
|
||||||
|
pubkey
|
||||||
|
domain
|
||||||
|
family
|
||||||
|
protocol
|
||||||
|
subfamily
|
||||||
|
program_version
|
||||||
|
kind
|
||||||
|
```
|
||||||
|
|
||||||
|
Les axes fonctionnels restent extensibles sous forme de chaînes. Aucun enum central fermé des domaines, familles ou protocoles futurs n'est créé.
|
||||||
|
|
||||||
|
`ProgramIdKind` est limité à la classification technique :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Program
|
||||||
|
Loader
|
||||||
|
Precompile
|
||||||
|
EnshrinedProgram
|
||||||
|
```
|
||||||
|
|
||||||
|
La première taxonomie Core utilise :
|
||||||
|
|
||||||
|
```text
|
||||||
|
domain = solana
|
||||||
|
protocol = solana
|
||||||
|
|
||||||
|
family = runtime
|
||||||
|
family = consensus
|
||||||
|
family = loader
|
||||||
|
family = precompile
|
||||||
|
family = proof
|
||||||
|
```
|
||||||
|
|
||||||
|
`program_version` reste distinct de `subfamily`. Les BPF loaders v1/v2 et Loader v4 utilisent l'axe version ; la branche BPF utilise séparément `subfamily = bpf`.
|
||||||
|
|
||||||
|
## API de recherche et vues
|
||||||
|
|
||||||
|
La façade expose :
|
||||||
|
|
||||||
|
```text
|
||||||
|
entries()
|
||||||
|
program_ids(filter)
|
||||||
|
native_program_ids()
|
||||||
|
program_ids_by_domain(...)
|
||||||
|
program_ids_by_family(...)
|
||||||
|
program_ids_by_protocol(...)
|
||||||
|
find_program_id(...)
|
||||||
|
find_program_pubkey(...)
|
||||||
|
```
|
||||||
|
|
||||||
|
`ProgramIdFilter` peut combiner :
|
||||||
|
|
||||||
|
```text
|
||||||
|
domain
|
||||||
|
family
|
||||||
|
protocol
|
||||||
|
subfamily
|
||||||
|
program_version
|
||||||
|
kind
|
||||||
|
```
|
||||||
|
|
||||||
|
Toutes les vues sont construites à partir du registre canonique unique. Elles retournent des iterators paresseux sans dupliquer un tableau statique par catégorie.
|
||||||
|
|
||||||
|
Une future fonction `amm_program_ids()` pourra donc devenir une vue `family = amm` sans changement structurel de `ProgramIdEntry`.
|
||||||
|
|
||||||
|
## Tests ajoutés
|
||||||
|
|
||||||
|
`unit_tests/program_ids.rs` vérifie notamment :
|
||||||
|
|
||||||
|
- cohérence texte/`Pubkey` des déclarations ;
|
||||||
|
- présence exacte des 18 Program IDs Core ;
|
||||||
|
- unicité des codes, Base58 et `Pubkey` ;
|
||||||
|
- correspondance de chaque `Pubkey` avec la Base58 KSP ;
|
||||||
|
- intersection des six axes de filtre ;
|
||||||
|
- tailles attendues des familles Core actuelles ;
|
||||||
|
- recherche texte et `Pubkey` ;
|
||||||
|
- absence de l'incinerator, `StakeConfig` et du Clock sysvar.
|
||||||
|
|
||||||
|
`tests/public_api.rs` vérifie en consommateur externe :
|
||||||
|
|
||||||
|
- la macro `declare_program_id!` ;
|
||||||
|
- les constantes `PRGID_*` / `PRGIDPK_*` ;
|
||||||
|
- `Pubkey` ;
|
||||||
|
- les vues du registre ;
|
||||||
|
- les getters de `ProgramIdEntry` ;
|
||||||
|
- le filtrage public combiné.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
`docs/plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md` passe en version documentaire 6 afin de :
|
||||||
|
|
||||||
|
- fixer l'inventaire Core à 18 IDs ;
|
||||||
|
- tracer la vérification du Slashing Program ;
|
||||||
|
- enregistrer `solana-pubkey 4.3.0` comme dépendance effectivement introduite ;
|
||||||
|
- fermer la question de MSRV de `pre.003` ;
|
||||||
|
- fixer `ProgramIdKind` et les retours iterator des vues ;
|
||||||
|
- compléter l'API publique réellement implémentée.
|
||||||
|
|
||||||
|
## Hors scope préservé
|
||||||
|
|
||||||
|
Cette tranche n'ajoute toujours pas :
|
||||||
|
|
||||||
|
- SPL Token/Token-2022/ATA/Memo ;
|
||||||
|
- Metaplex ou DEX ;
|
||||||
|
- well-known accounts ;
|
||||||
|
- codecs Borsh/Wincode ;
|
||||||
|
- decoder/executor/IDL ;
|
||||||
|
- RPC/WS ;
|
||||||
|
- Wallet ;
|
||||||
|
- Logging ;
|
||||||
|
- Config ;
|
||||||
|
- Store ;
|
||||||
|
- applications.
|
||||||
|
|
||||||
|
## Validations à exécuter sur le dépôt cible
|
||||||
|
|
||||||
|
Cette livraison ne déclare aucune validation Cargo non exécutée dans l'environnement de génération.
|
||||||
|
|
||||||
|
Après application :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo fmt --all
|
||||||
|
cargo check --workspace
|
||||||
|
cargo test --workspace
|
||||||
|
cargo clippy --workspace --all-targets
|
||||||
|
cargo tree -p ksp-core-lib
|
||||||
|
cargo tree -p ksp-core-lib -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Les deux commandes `cargo tree` doivent notamment confirmer l'absence de `solana-sdk-ids` et permettre de contrôler le graphe/features réellement résolus.
|
||||||
|
|
||||||
|
## Suite
|
||||||
|
|
||||||
|
Si les validations sont propres, la tranche suivante reste :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.1.1-pre.004 — intégration Core + audits
|
||||||
|
```
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md -->
|
<!-- file: docs/plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md -->
|
||||||
<!-- version: 5 -->
|
<!-- version: 6 -->
|
||||||
|
|
||||||
# Plan KSP 0.1.1 — Core foundation
|
# Plan KSP 0.1.1 — Core foundation
|
||||||
|
|
||||||
@@ -127,11 +127,18 @@ ksp_core_lib::Result
|
|||||||
ksp_core_lib::Pubkey
|
ksp_core_lib::Pubkey
|
||||||
ksp_core_lib::ProgramIdEntry
|
ksp_core_lib::ProgramIdEntry
|
||||||
ksp_core_lib::ProgramIdFilter
|
ksp_core_lib::ProgramIdFilter
|
||||||
|
ksp_core_lib::ProgramIdKind
|
||||||
ksp_core_lib::entries
|
ksp_core_lib::entries
|
||||||
ksp_core_lib::program_ids
|
ksp_core_lib::program_ids
|
||||||
|
ksp_core_lib::program_ids_by_domain
|
||||||
|
ksp_core_lib::program_ids_by_family
|
||||||
|
ksp_core_lib::program_ids_by_protocol
|
||||||
ksp_core_lib::native_program_ids
|
ksp_core_lib::native_program_ids
|
||||||
ksp_core_lib::find_program_id
|
ksp_core_lib::find_program_id
|
||||||
|
ksp_core_lib::find_program_pubkey
|
||||||
ksp_core_lib::declare_program_id!
|
ksp_core_lib::declare_program_id!
|
||||||
|
ksp_core_lib::PRGID_*
|
||||||
|
ksp_core_lib::PRGIDPK_*
|
||||||
```
|
```
|
||||||
|
|
||||||
Les modules d'implémentation restent privés conformément aux règles Rust du dépôt.
|
Les modules d'implémentation restent privés conformément aux règles Rust du dépôt.
|
||||||
@@ -213,13 +220,13 @@ Ne pas ajouter :
|
|||||||
- crates RPC/client ;
|
- crates RPC/client ;
|
||||||
- Borsh/Wincode/Serde pour une hypothétique future surface wire.
|
- Borsh/Wincode/Serde pour une hypothétique future surface wire.
|
||||||
|
|
||||||
La génération actuelle de `solana-pubkey` requiert Rust 1.89.0. Avant son ajout en `pre.003`, la toolchain réelle du dépôt devra donc être vérifiée. Une toolchain plus ancienne ne doit pas conduire silencieusement à choisir une vieille génération Solana uniquement pour contourner cette exigence.
|
La génération retenue de `solana-pubkey` requiert Rust 1.89.0. La validation `pre.002-fix.001` a été exécutée avec une génération Clippy Rust 1.94.0, donc la toolchain observée satisfait ce MSRV. Une future révision ne devra pas revenir silencieusement à une vieille génération Solana uniquement pour contourner une exigence de toolchain.
|
||||||
|
|
||||||
## Program IDs retenus pour la première surface Core
|
## Program IDs retenus pour la première surface Core
|
||||||
|
|
||||||
Le nombre exact de Program IDs de la première surface Core n'est plus figé à `17`.
|
`pre.003` fixe la première surface Core à **18 Program IDs**.
|
||||||
|
|
||||||
`pre.001` retient les familles fondamentales suivantes comme inventaire de départ à vérifier une dernière fois contre les sources officielles au moment de `pre.003` :
|
Les 17 identifiants fondamentaux exposés par la surface officielle actuelle `solana-sdk-ids` sont recopiés comme valeurs KSP sans créer de dépendance Cargo vers cette crate :
|
||||||
|
|
||||||
- System ;
|
- System ;
|
||||||
- Stake ;
|
- Stake ;
|
||||||
@@ -228,13 +235,16 @@ Le nombre exact de Program IDs de la première surface Core n'est plus figé à
|
|||||||
- Feature ;
|
- Feature ;
|
||||||
- Compute Budget ;
|
- Compute Budget ;
|
||||||
- Address Lookup Table ;
|
- Address Lookup Table ;
|
||||||
- loaders BPF historiques/actuels et Loader v4 ;
|
- BPF Loader historique v1 ;
|
||||||
|
- BPF Loader v2 ;
|
||||||
|
- BPF Loader Upgradeable ;
|
||||||
|
- Loader v4 ;
|
||||||
- Native Loader ;
|
- Native Loader ;
|
||||||
- précompiles Ed25519, Secp256k1 et Secp256r1 ;
|
- précompiles Ed25519, Secp256k1 et Secp256r1 ;
|
||||||
- programmes ZK fondamentaux actuellement exposés par la surface Anza/Solana ;
|
- ZK ElGamal Proof ;
|
||||||
- tout programme natif/historique supplémentaire réellement encore pertinent pour la frontière Core.
|
- ZK Token Proof.
|
||||||
|
|
||||||
L'ancien `ks-program-ids` de bot3 est utilisé comme inventaire historique complémentaire, pas comme source de vérité. Il rappelle notamment une entrée `slashing` dans son ensemble `native_program_ids()`. Sa présence dans la première surface KSP doit être décidée à partir de son statut officiel réel au moment de `pre.003`, plutôt que déduite d'un nombre figé ou d'une ancienne liste.
|
Le dix-huitième identifiant est le Slashing Program `S1ashing11111111111111111111111111111111111`. Il n'est pas encore publié dans `solana-sdk-ids`, mais son statut de programme enshrined et son adresse sont confirmés par SIMD-0204 et la documentation Anza. L'ancien `ks-program-ids` de bot3 avait déjà cette entrée ; `pre.003` ne la conserve toutefois qu'après cette revérification officielle indépendante.
|
||||||
|
|
||||||
### Exclusions volontaires de `0.1.1`
|
### Exclusions volontaires de `0.1.1`
|
||||||
|
|
||||||
@@ -374,7 +384,7 @@ L'audit de l'ancien registre bot3 et des IDLs archivées montre qu'un seul axe h
|
|||||||
- `kind` : classification technique nécessaire aux vues Core telles que les programmes natifs/loaders/précompiles ;
|
- `kind` : classification technique nécessaire aux vues Core telles que les programmes natifs/loaders/précompiles ;
|
||||||
- le code KSP unique, la chaîne Base58 `PRGID_*` et le `Pubkey` `PRGIDPK_*` restent les identités de l'entrée.
|
- le code KSP unique, la chaîne Base58 `PRGID_*` et le `Pubkey` `PRGIDPK_*` restent les identités de l'entrée.
|
||||||
|
|
||||||
Les vocabulaires exacts de `domain`, `family`, `protocol`, `subfamily` et `kind` doivent rester extensibles. Core ne doit pas créer une enum fermée contenant tous les futurs protocoles Solana. Des identifiants statiques/constantes KSP ou des newtypes légers peuvent être utilisés ; le choix syntaxique exact est finalisé en `pre.003`.
|
Les vocabulaires de `domain`, `family`, `protocol`, `subfamily` et `program_version` restent des chaînes extensibles : Core ne crée aucune enum fermée des futurs protocoles Solana. `kind` est volontairement une petite enum technique `ProgramIdKind` (`Program`, `Loader`, `Precompile`, `EnshrinedProgram`) parce qu'elle décrit la nature de l'entrée plutôt qu'un catalogue de protocoles.
|
||||||
|
|
||||||
`family = amm` est retenu comme famille agrégatrice future pour les modèles AMM. Les variantes `cpmm`, `clmm`, `dlmm`, `damm`, `stable_swap`, `weighted_swap`, `gamma`, `ssl` ou équivalentes appartiennent au niveau `subfamily` lorsqu'elles représentent réellement une branche architecturale du protocole. Cela permettra à une future vue `amm_program_ids()` de retrouver l'ensemble de ces programmes au lieu de limiter la recherche à l'ancien préfixe bot3 `AMM_*`.
|
`family = amm` est retenu comme famille agrégatrice future pour les modèles AMM. Les variantes `cpmm`, `clmm`, `dlmm`, `damm`, `stable_swap`, `weighted_swap`, `gamma`, `ssl` ou équivalentes appartiennent au niveau `subfamily` lorsqu'elles représentent réellement une branche architecturale du protocole. Cela permettra à une future vue `amm_program_ids()` de retrouver l'ensemble de ces programmes au lieu de limiter la recherche à l'ancien préfixe bot3 `AMM_*`.
|
||||||
|
|
||||||
@@ -454,7 +464,7 @@ amm_program_ids()
|
|||||||
|
|
||||||
Cette fonction devra être une vue de la classification canonique (`family = amm`) et non un second registre manuel. `0.1.1` ne crée pas un helper AMM vide puisque les Program IDs AMM restent hors scope de la release, mais son ajout futur ne doit nécessiter aucune refonte de `ProgramIdEntry`.
|
Cette fonction devra être une vue de la classification canonique (`family = amm`) et non un second registre manuel. `0.1.1` ne crée pas un helper AMM vide puisque les Program IDs AMM restent hors scope de la release, mais son ajout futur ne doit nécessiter aucune refonte de `ProgramIdEntry`.
|
||||||
|
|
||||||
Les vues filtrées peuvent retourner un iterator/view au lieu d'un `&'static [ProgramIdEntry]` si cela évite de dupliquer des tableaux statiques. Le contrat exact de retour est décidé en `pre.003` en privilégiant une API stable et sans allocation inutile.
|
Les vues filtrées retournent des iterators paresseux sur le registre canonique et n'allouent pas de collection intermédiaire. `entries()` reste la vue exhaustive sous forme de slice statique. `native_program_ids()` et les helpers `program_ids_by_domain(...)`, `program_ids_by_family(...)` et `program_ids_by_protocol(...)` sont des vues de cette même source.
|
||||||
|
|
||||||
`registered_program_ids()` de bot3 reste considéré comme un alias redondant de `entries()` et n'est pas repris automatiquement. Les well-known accounts suivent un registre/naming distinct lorsqu'ils deviennent nécessaires.
|
`registered_program_ids()` de bot3 reste considéré comme un alias redondant de `entries()` et n'est pas repris automatiquement. Les well-known accounts suivent un registre/naming distinct lorsqu'ils deviennent nécessaires.
|
||||||
|
|
||||||
@@ -597,17 +607,17 @@ Aucune dépendance Solana n'est nécessaire à cette tranche.
|
|||||||
Objectifs :
|
Objectifs :
|
||||||
|
|
||||||
- revérifier les versions Solana/Anza au jour de l'implémentation ;
|
- revérifier les versions Solana/Anza au jour de l'implémentation ;
|
||||||
- vérifier `rustc` par rapport au MSRV de la génération retenue ;
|
- vérifier la toolchain observée par rapport au MSRV de la génération retenue ;
|
||||||
- ajouter `solana-pubkey` uniquement au propriétaire `ksp-core-lib` ;
|
- ajouter `solana-pubkey` uniquement au propriétaire `ksp-core-lib` ;
|
||||||
- réexporter `Pubkey` ;
|
- réexporter `Pubkey` ;
|
||||||
- implémenter `declare_program_id!` et la paire `PRGID_*` / `PRGIDPK_*` ;
|
- implémenter `declare_program_id!` et la paire `PRGID_*` / `PRGIDPK_*` ;
|
||||||
- finaliser l'inventaire des Program IDs fondamentaux à partir des sources officielles actuelles ;
|
- finaliser à 18 l'inventaire des Program IDs fondamentaux à partir des sources officielles actuelles ;
|
||||||
- implémenter `ProgramIdEntry`, `ProgramIdFilter`, `entries()`, `program_ids(...)`, `native_program_ids()` et `find_program_id()` ;
|
- implémenter `ProgramIdEntry`, `ProgramIdFilter`, `ProgramIdKind`, `entries()`, `program_ids(...)`, les vues domain/family/protocol, `native_program_ids()`, `find_program_id()` et `find_program_pubkey()` ;
|
||||||
- implémenter la taxonomie extensible `domain` / `family` / `protocol` / `subfamily` / `program_version` / `kind` sans enum centrale fermée des protocoles ;
|
- implémenter la taxonomie extensible `domain` / `family` / `protocol` / `subfamily` / `program_version` / `kind` sans enum centrale fermée des protocoles ;
|
||||||
- garantir que les futurs helpers spécialisés comme `amm_program_ids()` puissent être des vues du registre canonique sans duplication ;
|
- garantir que les futurs helpers spécialisés comme `amm_program_ids()` puissent être des vues du registre canonique sans duplication ;
|
||||||
- ajouter les tests de conformité, d'unicité et de filtrage ;
|
- ajouter les tests de conformité, d'unicité, de filtrage et de façade publique ;
|
||||||
- confirmer l'absence totale de dépendance `solana-sdk-ids` ;
|
- confirmer l'absence totale de dépendance `solana-sdk-ids` ;
|
||||||
- auditer le graphe/features réels.
|
- auditer le graphe/features réels après validation Cargo par le user.
|
||||||
|
|
||||||
### `0.1.1-pre.004` — intégration Core + audits
|
### `0.1.1-pre.004` — intégration Core + audits
|
||||||
|
|
||||||
@@ -657,7 +667,6 @@ Un `pre.NNN-fix.NNN` corrige la tranche correspondante sans réécrire son histo
|
|||||||
|
|
||||||
## Questions ouvertes non bloquantes
|
## Questions ouvertes non bloquantes
|
||||||
|
|
||||||
- Revérifier en `pre.003` la version publiée de `solana-pubkey`, son API compile-time pertinente et le MSRV officiel au jour du code.
|
|
||||||
- Décider en `pre.005`, à partir de l'API réellement stabilisée, si un `README.md`/`USAGE.md` de crate apporte suffisamment de valeur pour être créé maintenant.
|
- Décider en `pre.005`, à partir de l'API réellement stabilisée, si un `README.md`/`USAGE.md` de crate apporte suffisamment de valeur pour être créé maintenant.
|
||||||
|
|
||||||
Aucune de ces questions ne justifie d'élargir le périmètre fonctionnel de `0.1.1`.
|
Aucune de ces questions ne justifie d'élargir le périmètre fonctionnel de `0.1.1`.
|
||||||
|
|||||||
Reference in New Issue
Block a user