diff --git a/Cargo.lock b/Cargo.lock index 2a15b34f..925e42c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "five8" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f76610e969fa1784327ded240f1e28a3fd9520c9cec93b636fcf62dd37f772" +dependencies = [ + "five8_core", +] + [[package]] name = "five8_const" version = "0.1.4" @@ -20,6 +29,15 @@ dependencies = [ "five8_core", ] +[[package]] +name = "five8_const" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a0f1728185f277989ca573a402716ae0beaaea3f76a8ff87ef9dd8fb19436c5" +dependencies = [ + "five8_core", +] + [[package]] name = "five8_core" version = "0.1.2" @@ -36,8 +54,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" name = "pinocchio" version = "0.9.1" dependencies = [ - "five8_const", - "solana-program-error", + "five8_const 0.1.4", + "solana-address", + "solana-program-error 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -45,7 +64,7 @@ name = "pinocchio-associated-token-account" version = "0.2.0" dependencies = [ "pinocchio", - "pinocchio-pubkey", + "solana-address", ] [[package]] @@ -69,16 +88,7 @@ name = "pinocchio-memo" version = "0.2.0" dependencies = [ "pinocchio", - "pinocchio-pubkey", -] - -[[package]] -name = "pinocchio-pubkey" -version = "0.3.0" -dependencies = [ - "five8_const", - "pinocchio", - "sha2-const-stable", + "solana-address", ] [[package]] @@ -86,7 +96,7 @@ name = "pinocchio-system" version = "0.3.0" dependencies = [ "pinocchio", - "pinocchio-pubkey", + "solana-address", ] [[package]] @@ -94,7 +104,7 @@ name = "pinocchio-token" version = "0.4.0" dependencies = [ "pinocchio", - "pinocchio-pubkey", + "solana-address", ] [[package]] @@ -102,7 +112,7 @@ name = "pinocchio-token-2022" version = "0.1.0" dependencies = [ "pinocchio", - "pinocchio-pubkey", + "solana-address", ] [[package]] @@ -153,10 +163,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] -name = "sha2-const-stable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" +name = "solana-address" +version = "1.0.0" +source = "git+https://github.com/febo/solana-sdk.git?branch=copy-feature#c77dbbdecb014b586b24e8a6955419d9b29c3a45" +dependencies = [ + "five8", + "five8_const 1.0.0", + "solana-define-syscall", + "solana-program-error 3.0.0 (git+https://github.com/febo/solana-sdk.git?branch=copy-feature)", +] + +[[package]] +name = "solana-define-syscall" +version = "3.0.0" +source = "git+https://github.com/febo/solana-sdk.git?branch=copy-feature#c77dbbdecb014b586b24e8a6955419d9b29c3a45" [[package]] name = "solana-program-error" @@ -164,6 +184,11 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1af32c995a7b692a915bb7414d5f8e838450cf7c70414e763d8abcae7b51f28" +[[package]] +name = "solana-program-error" +version = "3.0.0" +source = "git+https://github.com/febo/solana-sdk.git?branch=copy-feature#c77dbbdecb014b586b24e8a6955419d9b29c3a45" + [[package]] name = "syn" version = "1.0.109" diff --git a/Cargo.toml b/Cargo.toml index 5a5d337f..cabf633c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ members = [ "sdk/log/crate", "sdk/log/macro", "sdk/pinocchio", - "sdk/pubkey", ] [workspace.package] @@ -22,9 +21,9 @@ rust-version = "1.84" five8_const = "0.1.4" pinocchio = { version = "0.9", path = "sdk/pinocchio" } pinocchio-log-macro = { version = "0.5", path = "sdk/log/macro" } -pinocchio-pubkey = { version = "0.3", path = "sdk/pubkey" } quote = "1.0" regex = "1" +solana-address = { version = "1.0", git = "https://github.com/febo/solana-sdk.git", branch = "copy-feature" } syn = "1.0" [workspace.metadata.cli] diff --git a/README.md b/README.md index 1f16fb20..520f777d 100644 --- a/README.md +++ b/README.md @@ -72,13 +72,13 @@ use pinocchio::{ entrypoint, msg, ProgramResult, - pubkey::Pubkey + Address }; entrypoint!(process_instruction); pub fn process_instruction( - program_id: &Pubkey, + program_id: &Address, accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { @@ -153,7 +153,7 @@ use pinocchio::{ no_allocator, program_entrypoint, ProgramResult, - pubkey::Pubkey + Address }; program_entrypoint!(process_instruction); @@ -161,7 +161,7 @@ default_panic_handler!(); no_allocator!(); pub fn process_instruction( - program_id: &Pubkey, + program_id: &Address, accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { @@ -193,13 +193,13 @@ mod entrypoint { entrypoint, msg, ProgramResult, - pubkey::Pubkey + Address }; entrypoint!(process_instruction); pub fn process_instruction( - program_id: &Pubkey, + program_id: &Address, accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { diff --git a/programs/associated-token-account/Cargo.toml b/programs/associated-token-account/Cargo.toml index 0da0f17a..2b533c97 100644 --- a/programs/associated-token-account/Cargo.toml +++ b/programs/associated-token-account/Cargo.toml @@ -13,4 +13,4 @@ crate-type = ["rlib"] [dependencies] pinocchio = { workspace = true } -pinocchio-pubkey = { workspace = true } +solana-address = { workspace = true, features = ["decode"] } diff --git a/programs/associated-token-account/src/lib.rs b/programs/associated-token-account/src/lib.rs index 320faf39..de3f19c1 100644 --- a/programs/associated-token-account/src/lib.rs +++ b/programs/associated-token-account/src/lib.rs @@ -2,4 +2,4 @@ pub mod instructions; -pinocchio_pubkey::declare_id!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"); +solana_address::declare_id!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"); diff --git a/programs/memo/Cargo.toml b/programs/memo/Cargo.toml index 1ee04bc9..4809ff33 100644 --- a/programs/memo/Cargo.toml +++ b/programs/memo/Cargo.toml @@ -13,4 +13,4 @@ crate-type = ["rlib"] [dependencies] pinocchio = { workspace = true } -pinocchio-pubkey = { workspace = true } +solana-address = { workspace = true, features = ["decode"] } diff --git a/programs/memo/src/lib.rs b/programs/memo/src/lib.rs index bcc06028..fb6e7bd8 100644 --- a/programs/memo/src/lib.rs +++ b/programs/memo/src/lib.rs @@ -4,7 +4,7 @@ pub mod instructions; /// Legacy symbols from Memo version 1 pub mod v1 { - pinocchio_pubkey::declare_id!("Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo"); + solana_address::declare_id!("Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo"); } -pinocchio_pubkey::declare_id!("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"); +solana_address::declare_id!("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"); diff --git a/programs/system/Cargo.toml b/programs/system/Cargo.toml index 19030866..738eb450 100644 --- a/programs/system/Cargo.toml +++ b/programs/system/Cargo.toml @@ -13,4 +13,4 @@ crate-type = ["rlib"] [dependencies] pinocchio = { workspace = true } -pinocchio-pubkey = { workspace = true } +solana-address = { workspace = true, features = ["decode"] } diff --git a/programs/system/src/instructions/allocate_with_seed.rs b/programs/system/src/instructions/allocate_with_seed.rs index 423f85b4..1e28cc75 100644 --- a/programs/system/src/instructions/allocate_with_seed.rs +++ b/programs/system/src/instructions/allocate_with_seed.rs @@ -2,12 +2,11 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Allocate space for and assign an account at an address derived -/// from a base public key and a seed. +/// from a base address and a seed. /// /// ### Accounts: /// 0. `[WRITE]` Allocated account @@ -18,19 +17,19 @@ pub struct AllocateWithSeed<'a, 'b, 'c> { /// Base account. /// - /// The account matching the base Pubkey below must be provided as + /// The account matching the base address below must be provided as /// a signer, but may be the same as the funding account and provided /// as account 0. pub base: &'a AccountInfo, - /// String of ASCII chars, no longer than `Pubkey::MAX_SEED_LEN`. + /// String of ASCII chars, no longer than [`MAX_SEED_LEN`](https://docs.rs/solana-address/latest/solana_address/constant.MAX_SEED_LEN.html). pub seed: &'b str, /// Number of bytes of memory to allocate. pub space: u64, /// Address of program that will own the new account. - pub owner: &'c Pubkey, + pub owner: &'c Address, } impl AllocateWithSeed<'_, '_, '_> { @@ -49,14 +48,14 @@ impl AllocateWithSeed<'_, '_, '_> { // instruction data // - [0..4 ]: instruction discriminator - // - [4..36 ]: base pubkey + // - [4..36 ]: base address // - [36..44]: seed length // - [44.. ]: seed (max 32) // - [.. +8]: account space - // - [.. +32]: owner pubkey + // - [.. +32]: owner address let mut instruction_data = [0; 112]; instruction_data[0] = 9; - instruction_data[4..36].copy_from_slice(self.base.key()); + instruction_data[4..36].copy_from_slice(self.base.key().as_array()); instruction_data[36..44].copy_from_slice(&u64::to_le_bytes(self.seed.len() as u64)); let offset = 44 + self.seed.len(); diff --git a/programs/system/src/instructions/assign.rs b/programs/system/src/instructions/assign.rs index 327a5d3b..84cd7c2e 100644 --- a/programs/system/src/instructions/assign.rs +++ b/programs/system/src/instructions/assign.rs @@ -2,20 +2,19 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Assign account to a program /// /// ### Accounts: -/// 0. `[WRITE, SIGNER]` Assigned account public key +/// 0. `[WRITE, SIGNER]` Assigned account address pub struct Assign<'a, 'b> { /// Account to be assigned. pub account: &'a AccountInfo, /// Program account to assign as owner. - pub owner: &'b Pubkey, + pub owner: &'b Address, } impl Assign<'_, '_> { @@ -31,7 +30,7 @@ impl Assign<'_, '_> { // instruction data // - [0..4 ]: instruction discriminator - // - [4..36]: owner pubkey + // - [4..36]: owner address let mut instruction_data = [0; 36]; instruction_data[0] = 1; instruction_data[4..36].copy_from_slice(self.owner.as_ref()); diff --git a/programs/system/src/instructions/assign_with_seed.rs b/programs/system/src/instructions/assign_with_seed.rs index 97d27e03..0595beb0 100644 --- a/programs/system/src/instructions/assign_with_seed.rs +++ b/programs/system/src/instructions/assign_with_seed.rs @@ -2,8 +2,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Assign account to a program based on a seed. @@ -17,16 +16,16 @@ pub struct AssignWithSeed<'a, 'b, 'c> { /// Base account. /// - /// The account matching the base Pubkey below must be provided as + /// The account matching the base `Address` below must be provided as /// a signer, but may be the same as the funding account and provided /// as account 0. pub base: &'a AccountInfo, - /// String of ASCII chars, no longer than `Pubkey::MAX_SEED_LEN`. + /// String of ASCII chars, no longer than [`MAX_SEED_LEN`](https://docs.rs/solana-address/latest/solana_address/constant.MAX_SEED_LEN.html). pub seed: &'b str, /// Address of program that will own the new account. - pub owner: &'c Pubkey, + pub owner: &'c Address, } impl AssignWithSeed<'_, '_, '_> { @@ -45,13 +44,13 @@ impl AssignWithSeed<'_, '_, '_> { // instruction data // - [0..4 ]: instruction discriminator - // - [4..36 ]: base pubkey + // - [4..36 ]: base address // - [36..44]: seed length // - [44.. ]: seed (max 32) - // - [.. +32]: owner pubkey + // - [.. +32]: owner address let mut instruction_data = [0; 104]; instruction_data[0] = 10; - instruction_data[4..36].copy_from_slice(self.base.key()); + instruction_data[4..36].copy_from_slice(self.base.key().as_array()); instruction_data[36..44].copy_from_slice(&u64::to_le_bytes(self.seed.len() as u64)); let offset = 44 + self.seed.len(); diff --git a/programs/system/src/instructions/authorize_nonce_account.rs b/programs/system/src/instructions/authorize_nonce_account.rs index 3402b1d9..2eab7739 100644 --- a/programs/system/src/instructions/authorize_nonce_account.rs +++ b/programs/system/src/instructions/authorize_nonce_account.rs @@ -2,13 +2,12 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Change the entity authorized to execute nonce instructions on the account. /// -/// The `Pubkey` parameter identifies the entity to authorize. +/// The [`Address`] parameter identifies the entity to authorize. /// /// ### Accounts: /// 0. `[WRITE]` Nonce account @@ -21,7 +20,7 @@ pub struct AuthorizeNonceAccount<'a, 'b> { pub authority: &'a AccountInfo, /// New entity authorized to execute nonce instructions on the account. - pub new_authority: &'b Pubkey, + pub new_authority: &'b Address, } impl AuthorizeNonceAccount<'_, '_> { @@ -43,7 +42,7 @@ impl AuthorizeNonceAccount<'_, '_> { // - [4..12]: lamports let mut instruction_data = [0; 36]; instruction_data[0] = 7; - instruction_data[4..36].copy_from_slice(self.new_authority); + instruction_data[4..36].copy_from_slice(self.new_authority.as_array()); let instruction = Instruction { program_id: &crate::ID, diff --git a/programs/system/src/instructions/create_account.rs b/programs/system/src/instructions/create_account.rs index 6881fd25..5f6c63c3 100644 --- a/programs/system/src/instructions/create_account.rs +++ b/programs/system/src/instructions/create_account.rs @@ -3,9 +3,8 @@ use pinocchio::{ error::ProgramError, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, sysvars::rent::Rent, - ProgramResult, + Address, ProgramResult, }; /// Create a new account. @@ -27,7 +26,7 @@ pub struct CreateAccount<'a> { pub space: u64, /// Address of program that will own the new account. - pub owner: &'a Pubkey, + pub owner: &'a Address, } impl<'a> CreateAccount<'a> { @@ -37,7 +36,7 @@ impl<'a> CreateAccount<'a> { to: &'a AccountInfo, rent_sysvar: &'a AccountInfo, space: u64, - owner: &'a Pubkey, + owner: &'a Address, ) -> Result { let rent = Rent::from_account_info(rent_sysvar)?; let lamports = rent.minimum_balance(space as usize); @@ -68,7 +67,7 @@ impl<'a> CreateAccount<'a> { // - [0..4 ]: instruction discriminator // - [4..12 ]: lamports // - [12..20]: account space - // - [20..52]: owner pubkey + // - [20..52]: owner address let mut instruction_data = [0; 52]; // create account instruction has a '0' discriminator instruction_data[4..12].copy_from_slice(&self.lamports.to_le_bytes()); diff --git a/programs/system/src/instructions/create_account_with_seed.rs b/programs/system/src/instructions/create_account_with_seed.rs index e6414c13..63362fbf 100644 --- a/programs/system/src/instructions/create_account_with_seed.rs +++ b/programs/system/src/instructions/create_account_with_seed.rs @@ -3,17 +3,16 @@ use pinocchio::{ error::ProgramError, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, sysvars::rent::Rent, - ProgramResult, + Address, ProgramResult, }; -/// Create a new account at an address derived from a base pubkey and a seed. +/// Create a new account at an address derived from a base address and a seed. /// /// ### Accounts: /// 0. `[WRITE, SIGNER]` Funding account /// 1. `[WRITE]` Created account -/// 2. `[SIGNER]` (optional) Base account; the account matching the base Pubkey below must be +/// 2. `[SIGNER]` (optional) Base account; the account matching the base address below must be /// provided as a signer, but may be the same as the funding account pub struct CreateAccountWithSeed<'a, 'b, 'c> { /// Funding account. @@ -24,12 +23,12 @@ pub struct CreateAccountWithSeed<'a, 'b, 'c> { /// Base account. /// - /// The account matching the base Pubkey below must be provided as + /// The account matching the base [`Address`] below must be provided as /// a signer, but may be the same as the funding account and provided /// as account 0. pub base: Option<&'a AccountInfo>, - /// String of ASCII chars, no longer than `Pubkey::MAX_SEED_LEN`. + /// String of ASCII chars, no longer than [`MAX_SEED_LEN`](https://docs.rs/solana-address/latest/solana_address/constant.MAX_SEED_LEN.html). pub seed: &'b str, /// Number of lamports to transfer to the new account. @@ -39,7 +38,7 @@ pub struct CreateAccountWithSeed<'a, 'b, 'c> { pub space: u64, /// Address of program that will own the new account. - pub owner: &'c Pubkey, + pub owner: &'c Address, } impl<'a, 'b, 'c> CreateAccountWithSeed<'a, 'b, 'c> { @@ -51,7 +50,7 @@ impl<'a, 'b, 'c> CreateAccountWithSeed<'a, 'b, 'c> { seed: &'b str, rent_sysvar: &'a AccountInfo, space: u64, - owner: &'c Pubkey, + owner: &'c Address, ) -> Result { let rent = Rent::from_account_info(rent_sysvar)?; let lamports = rent.minimum_balance(space as usize); @@ -83,15 +82,15 @@ impl<'a, 'b, 'c> CreateAccountWithSeed<'a, 'b, 'c> { // instruction data // - [0..4 ]: instruction discriminator - // - [4..36 ]: base pubkey + // - [4..36 ]: base address // - [36..44]: seed length // - [44.. ]: seed (max 32) // - [.. +8]: lamports // - [.. +8]: account space - // - [.. +32]: owner pubkey + // - [.. +32]: owner address let mut instruction_data = [0; 120]; instruction_data[0] = 3; - instruction_data[4..36].copy_from_slice(self.base.unwrap_or(self.from).key()); + instruction_data[4..36].copy_from_slice(self.base.unwrap_or(self.from).key().as_array()); instruction_data[36..44].copy_from_slice(&u64::to_le_bytes(self.seed.len() as u64)); let offset = 44 + self.seed.len(); diff --git a/programs/system/src/instructions/initialize_nonce_account.rs b/programs/system/src/instructions/initialize_nonce_account.rs index 738ca1b8..5ab93ac7 100644 --- a/programs/system/src/instructions/initialize_nonce_account.rs +++ b/programs/system/src/instructions/initialize_nonce_account.rs @@ -2,12 +2,14 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Drive state of Uninitialized nonce account to Initialized, setting the nonce value. /// +/// The [`Address`] parameter specifies the entity authorized to execute nonce +/// instruction on the account +/// /// No signatures are required to execute this instruction, enabling derived /// nonce account addresses. /// @@ -27,7 +29,7 @@ pub struct InitializeNonceAccount<'a, 'b> { /// Indicates the entity authorized to execute nonce /// instruction on the account - pub authority: &'b Pubkey, + pub authority: &'b Address, } impl InitializeNonceAccount<'_, '_> { @@ -42,10 +44,10 @@ impl InitializeNonceAccount<'_, '_> { // instruction data // - [0..4 ]: instruction discriminator - // - [4..36]: authority pubkey + // - [4..36]: authority address let mut instruction_data = [0; 36]; instruction_data[0] = 6; - instruction_data[4..36].copy_from_slice(self.authority); + instruction_data[4..36].copy_from_slice(self.authority.as_array()); let instruction = Instruction { program_id: &crate::ID, diff --git a/programs/system/src/instructions/transfer_with_seed.rs b/programs/system/src/instructions/transfer_with_seed.rs index 38581078..0fe6bcce 100644 --- a/programs/system/src/instructions/transfer_with_seed.rs +++ b/programs/system/src/instructions/transfer_with_seed.rs @@ -2,8 +2,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Transfer lamports from a derived address. @@ -18,7 +17,7 @@ pub struct TransferWithSeed<'a, 'b, 'c> { /// Base account. /// - /// The account matching the base Pubkey below must be provided as + /// The account matching the base [`Address`] below must be provided as /// a signer, but may be the same as the funding account and provided /// as account 0. pub base: &'a AccountInfo, @@ -29,11 +28,11 @@ pub struct TransferWithSeed<'a, 'b, 'c> { /// Amount of lamports to transfer. pub lamports: u64, - /// String of ASCII chars, no longer than `Pubkey::MAX_SEED_LEN`. + /// String of ASCII chars, no longer than [`MAX_SEED_LEN`](https://docs.rs/solana-address/latest/solana_address/constant.MAX_SEED_LEN.html). pub seed: &'b str, /// Address of program that will own the new account. - pub owner: &'c Pubkey, + pub owner: &'c Address, } impl TransferWithSeed<'_, '_, '_> { @@ -56,7 +55,7 @@ impl TransferWithSeed<'_, '_, '_> { // - [4..12 ]: lamports amount // - [12..20]: seed length // - [20.. ]: seed (max 32) - // - [.. +32]: owner pubkey + // - [.. +32]: owner address let mut instruction_data = [0; 80]; instruction_data[0] = 11; instruction_data[4..12].copy_from_slice(&self.lamports.to_le_bytes()); diff --git a/programs/system/src/lib.rs b/programs/system/src/lib.rs index 35268bc1..124ce0bb 100644 --- a/programs/system/src/lib.rs +++ b/programs/system/src/lib.rs @@ -2,4 +2,4 @@ pub mod instructions; -pinocchio_pubkey::declare_id!("11111111111111111111111111111111"); +solana_address::declare_id!("11111111111111111111111111111111"); diff --git a/programs/token-2022/Cargo.toml b/programs/token-2022/Cargo.toml index b24c529b..af5d6af8 100644 --- a/programs/token-2022/Cargo.toml +++ b/programs/token-2022/Cargo.toml @@ -12,4 +12,4 @@ crate-type = ["rlib"] [dependencies] pinocchio = { workspace = true } -pinocchio-pubkey = { workspace = true } +solana-address = { workspace = true, features = ["decode"] } diff --git a/programs/token-2022/README.md b/programs/token-2022/README.md index cba28015..e7d31a73 100644 --- a/programs/token-2022/README.md +++ b/programs/token-2022/README.md @@ -27,7 +27,7 @@ Initializing a mint account: ```rust // This example assumes that the instruction receives a writable `mint` -// account; `authority` is a `Pubkey`. +// account; `authority` is an `Address`. // The SPL Token program is being invoked. InitializeMint { mint, @@ -35,7 +35,7 @@ InitializeMint { decimals: 9, mint_authority: authority, freeze_authority: Some(authority), - token_program: Pubkey::from_str("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") + token_program: Address::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") }.invoke()?; ``` @@ -50,7 +50,7 @@ Transfer { to, authority, amount: 10, - token_program: Pubkey::from_str("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb") + token_program: Address::from_str_const("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb") }.invoke()?; ``` diff --git a/programs/token-2022/src/instructions/approve.rs b/programs/token-2022/src/instructions/approve.rs index d926fc24..c7ce517d 100644 --- a/programs/token-2022/src/instructions/approve.rs +++ b/programs/token-2022/src/instructions/approve.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -26,7 +25,7 @@ pub struct Approve<'a, 'b> { /// Amount pub amount: u64, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl Approve<'_, '_> { diff --git a/programs/token-2022/src/instructions/approve_checked.rs b/programs/token-2022/src/instructions/approve_checked.rs index e02bef70..4258063f 100644 --- a/programs/token-2022/src/instructions/approve_checked.rs +++ b/programs/token-2022/src/instructions/approve_checked.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -31,7 +30,7 @@ pub struct ApproveChecked<'a, 'b> { /// Decimals. pub decimals: u8, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl ApproveChecked<'_, '_> { diff --git a/programs/token-2022/src/instructions/burn.rs b/programs/token-2022/src/instructions/burn.rs index 3ea5e398..72396281 100644 --- a/programs/token-2022/src/instructions/burn.rs +++ b/programs/token-2022/src/instructions/burn.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -26,7 +25,7 @@ pub struct Burn<'a, 'b> { /// Amount pub amount: u64, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl Burn<'_, '_> { diff --git a/programs/token-2022/src/instructions/burn_checked.rs b/programs/token-2022/src/instructions/burn_checked.rs index 46b49ef4..cb208ab3 100644 --- a/programs/token-2022/src/instructions/burn_checked.rs +++ b/programs/token-2022/src/instructions/burn_checked.rs @@ -5,8 +5,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Burns tokens by removing them from an account. @@ -27,7 +26,7 @@ pub struct BurnChecked<'a, 'b> { /// Decimals pub decimals: u8, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl BurnChecked<'_, '_> { diff --git a/programs/token-2022/src/instructions/close_account.rs b/programs/token-2022/src/instructions/close_account.rs index f94ad200..4c1a1240 100644 --- a/programs/token-2022/src/instructions/close_account.rs +++ b/programs/token-2022/src/instructions/close_account.rs @@ -2,8 +2,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Close an account by transferring all its SOL to the destination account. @@ -20,7 +19,7 @@ pub struct CloseAccount<'a, 'b> { /// Owner Account pub authority: &'a AccountInfo, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl CloseAccount<'_, '_> { diff --git a/programs/token-2022/src/instructions/freeze_account.rs b/programs/token-2022/src/instructions/freeze_account.rs index 401f1398..e1f18e9c 100644 --- a/programs/token-2022/src/instructions/freeze_account.rs +++ b/programs/token-2022/src/instructions/freeze_account.rs @@ -2,8 +2,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Freeze an Initialized account using the Mint's freeze authority @@ -20,7 +19,7 @@ pub struct FreezeAccount<'a, 'b> { /// Mint Freeze Authority Account pub freeze_authority: &'a AccountInfo, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl FreezeAccount<'_, '_> { diff --git a/programs/token-2022/src/instructions/initialize_account.rs b/programs/token-2022/src/instructions/initialize_account.rs index cfe22f81..00a40310 100644 --- a/programs/token-2022/src/instructions/initialize_account.rs +++ b/programs/token-2022/src/instructions/initialize_account.rs @@ -2,8 +2,7 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Initialize a new Token Account. @@ -23,7 +22,7 @@ pub struct InitializeAccount<'a, 'b> { /// Rent Sysvar Account pub rent_sysvar: &'a AccountInfo, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl InitializeAccount<'_, '_> { diff --git a/programs/token-2022/src/instructions/initialize_account_2.rs b/programs/token-2022/src/instructions/initialize_account_2.rs index e7bacaf2..1474a6df 100644 --- a/programs/token-2022/src/instructions/initialize_account_2.rs +++ b/programs/token-2022/src/instructions/initialize_account_2.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -24,9 +23,9 @@ pub struct InitializeAccount2<'a, 'b> { /// Rent Sysvar Account pub rent_sysvar: &'a AccountInfo, /// Owner of the new Account. - pub owner: &'a Pubkey, + pub owner: &'a Address, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl InitializeAccount2<'_, '_> { @@ -41,13 +40,13 @@ impl InitializeAccount2<'_, '_> { // instruction data // - [0]: instruction discriminator (1 byte, u8) - // - [1..33]: owner (32 bytes, Pubkey) + // - [1..33]: owner (32 bytes, Address) let mut instruction_data = [UNINIT_BYTE; 33]; // Set discriminator as u8 at offset [0] write_bytes(&mut instruction_data, &[16]); // Set owner as [u8; 32] at offset [1..33] - write_bytes(&mut instruction_data[1..], self.owner); + write_bytes(&mut instruction_data[1..], self.owner.as_array()); let instruction = Instruction { program_id: self.token_program, diff --git a/programs/token-2022/src/instructions/initialize_account_3.rs b/programs/token-2022/src/instructions/initialize_account_3.rs index b7ef7a9c..bb7a2f0d 100644 --- a/programs/token-2022/src/instructions/initialize_account_3.rs +++ b/programs/token-2022/src/instructions/initialize_account_3.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -21,9 +20,9 @@ pub struct InitializeAccount3<'a, 'b> { /// Mint Account. pub mint: &'a AccountInfo, /// Owner of the new Account. - pub owner: &'a Pubkey, + pub owner: &'a Address, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl InitializeAccount3<'_, '_> { @@ -37,13 +36,13 @@ impl InitializeAccount3<'_, '_> { // instruction data // - [0]: instruction discriminator (1 byte, u8) - // - [1..33]: owner (32 bytes, Pubkey) + // - [1..33]: owner (32 bytes, Address) let mut instruction_data = [UNINIT_BYTE; 33]; // Set discriminator as u8 at offset [0] write_bytes(&mut instruction_data, &[18]); // Set owner as [u8; 32] at offset [1..33] - write_bytes(&mut instruction_data[1..], self.owner); + write_bytes(&mut instruction_data[1..], self.owner.as_array()); let instruction = Instruction { program_id: self.token_program, diff --git a/programs/token-2022/src/instructions/initialize_mint.rs b/programs/token-2022/src/instructions/initialize_mint.rs index 57563d52..6c14b0ab 100644 --- a/programs/token-2022/src/instructions/initialize_mint.rs +++ b/programs/token-2022/src/instructions/initialize_mint.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -23,11 +22,11 @@ pub struct InitializeMint<'a, 'b> { /// Decimals. pub decimals: u8, /// Mint Authority. - pub mint_authority: &'a Pubkey, + pub mint_authority: &'a Address, /// Freeze Authority. - pub freeze_authority: Option<&'a Pubkey>, + pub freeze_authority: Option<&'a Address>, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl InitializeMint<'_, '_> { @@ -42,9 +41,9 @@ impl InitializeMint<'_, '_> { // Instruction data layout: // - [0]: instruction discriminator (1 byte, u8) // - [1]: decimals (1 byte, u8) - // - [2..34]: mint_authority (32 bytes, Pubkey) + // - [2..34]: mint_authority (32 bytes, Address) // - [34]: freeze_authority presence flag (1 byte, u8) - // - [35..67]: freeze_authority (optional, 32 bytes, Pubkey) + // - [35..67]: freeze_authority (optional, 32 bytes, Address) let mut instruction_data = [UNINIT_BYTE; 67]; let mut length = instruction_data.len(); @@ -52,13 +51,13 @@ impl InitializeMint<'_, '_> { write_bytes(&mut instruction_data, &[0]); // Set decimals as u8 at offset [1] write_bytes(&mut instruction_data[1..2], &[self.decimals]); - // Set mint_authority as Pubkey at offset [2..34] - write_bytes(&mut instruction_data[2..34], self.mint_authority); + // Set mint_authority at offset [2..34] + write_bytes(&mut instruction_data[2..34], self.mint_authority.as_array()); if let Some(freeze_auth) = self.freeze_authority { // Set Option = `true` & freeze_authority at offset [34..67] write_bytes(&mut instruction_data[34..35], &[1]); - write_bytes(&mut instruction_data[35..], freeze_auth); + write_bytes(&mut instruction_data[35..], freeze_auth.as_array()); } else { // Set Option = `false` write_bytes(&mut instruction_data[34..35], &[0]); diff --git a/programs/token-2022/src/instructions/initialize_mint_2.rs b/programs/token-2022/src/instructions/initialize_mint_2.rs index f1d458b8..d3578263 100644 --- a/programs/token-2022/src/instructions/initialize_mint_2.rs +++ b/programs/token-2022/src/instructions/initialize_mint_2.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -20,11 +19,11 @@ pub struct InitializeMint2<'a, 'b> { /// Decimals. pub decimals: u8, /// Mint Authority. - pub mint_authority: &'a Pubkey, + pub mint_authority: &'a Address, /// Freeze Authority. - pub freeze_authority: Option<&'a Pubkey>, + pub freeze_authority: Option<&'a Address>, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl InitializeMint2<'_, '_> { @@ -36,9 +35,9 @@ impl InitializeMint2<'_, '_> { // Instruction data layout: // - [0]: instruction discriminator (1 byte, u8) // - [1]: decimals (1 byte, u8) - // - [2..34]: mint_authority (32 bytes, Pubkey) + // - [2..34]: mint_authority (32 bytes, Address) // - [34]: freeze_authority presence flag (1 byte, u8) - // - [35..67]: freeze_authority (optional, 32 bytes, Pubkey) + // - [35..67]: freeze_authority (optional, 32 bytes, Address) let mut instruction_data = [UNINIT_BYTE; 67]; let mut length = instruction_data.len(); @@ -46,13 +45,13 @@ impl InitializeMint2<'_, '_> { write_bytes(&mut instruction_data, &[20]); // Set decimals as u8 at offset [1] write_bytes(&mut instruction_data[1..2], &[self.decimals]); - // Set mint_authority as Pubkey at offset [2..34] - write_bytes(&mut instruction_data[2..34], self.mint_authority); + // Set mint_authority at offset [2..34] + write_bytes(&mut instruction_data[2..34], self.mint_authority.as_array()); if let Some(freeze_auth) = self.freeze_authority { // Set Option = `true` & freeze_authority at offset [34..67] write_bytes(&mut instruction_data[34..35], &[1]); - write_bytes(&mut instruction_data[35..], freeze_auth); + write_bytes(&mut instruction_data[35..], freeze_auth.as_array()); } else { // Set Option = `false` write_bytes(&mut instruction_data[34..35], &[0]); diff --git a/programs/token-2022/src/instructions/initialize_multisig.rs b/programs/token-2022/src/instructions/initialize_multisig.rs index cc29342a..5ec38c72 100644 --- a/programs/token-2022/src/instructions/initialize_multisig.rs +++ b/programs/token-2022/src/instructions/initialize_multisig.rs @@ -5,8 +5,7 @@ use pinocchio::{ cpi::invoke_with_bounds, error::ProgramError, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Maximum number of multisignature signers. @@ -33,7 +32,7 @@ where /// account. pub m: u8, /// Token Program. - pub token_program: &'c Pubkey, + pub token_program: &'c Address, } impl InitializeMultisig<'_, '_, '_> { diff --git a/programs/token-2022/src/instructions/initialize_multisig_2.rs b/programs/token-2022/src/instructions/initialize_multisig_2.rs index f82bee12..f5fc2c35 100644 --- a/programs/token-2022/src/instructions/initialize_multisig_2.rs +++ b/programs/token-2022/src/instructions/initialize_multisig_2.rs @@ -5,8 +5,7 @@ use pinocchio::{ cpi::invoke_with_bounds, error::ProgramError, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::instructions::MAX_MULTISIG_SIGNERS; @@ -29,7 +28,7 @@ where /// account. pub m: u8, /// Token Program. - pub token_program: &'c Pubkey, + pub token_program: &'c Address, } impl InitializeMultisig2<'_, '_, '_> { diff --git a/programs/token-2022/src/instructions/mint_to.rs b/programs/token-2022/src/instructions/mint_to.rs index ec545d9e..6ac52be2 100644 --- a/programs/token-2022/src/instructions/mint_to.rs +++ b/programs/token-2022/src/instructions/mint_to.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -26,7 +25,7 @@ pub struct MintTo<'a, 'b> { /// Amount pub amount: u64, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl MintTo<'_, '_> { diff --git a/programs/token-2022/src/instructions/mint_to_checked.rs b/programs/token-2022/src/instructions/mint_to_checked.rs index 7402776d..25088fd0 100644 --- a/programs/token-2022/src/instructions/mint_to_checked.rs +++ b/programs/token-2022/src/instructions/mint_to_checked.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -28,7 +27,7 @@ pub struct MintToChecked<'a, 'b> { /// Decimals pub decimals: u8, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl MintToChecked<'_, '_> { diff --git a/programs/token-2022/src/instructions/revoke.rs b/programs/token-2022/src/instructions/revoke.rs index 526c5138..f7c1a72f 100644 --- a/programs/token-2022/src/instructions/revoke.rs +++ b/programs/token-2022/src/instructions/revoke.rs @@ -2,8 +2,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Revokes the delegate's authority. @@ -17,7 +16,7 @@ pub struct Revoke<'a, 'b> { /// Source Owner Account. pub authority: &'a AccountInfo, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl Revoke<'_, '_> { diff --git a/programs/token-2022/src/instructions/set_authority.rs b/programs/token-2022/src/instructions/set_authority.rs index 060771f3..8ae7f969 100644 --- a/programs/token-2022/src/instructions/set_authority.rs +++ b/programs/token-2022/src/instructions/set_authority.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -32,9 +31,9 @@ pub struct SetAuthority<'a, 'b> { /// The type of authority to update. pub authority_type: AuthorityType, /// The new authority - pub new_authority: Option<&'a Pubkey>, + pub new_authority: Option<&'a Address>, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl SetAuthority<'_, '_> { @@ -55,7 +54,7 @@ impl SetAuthority<'_, '_> { // - [0]: instruction discriminator (1 byte, u8) // - [1]: authority_type (1 byte, u8) // - [2]: new_authority presence flag (1 byte, AuthorityType) - // - [3..35] new_authority (optional, 32 bytes, Pubkey) + // - [3..35] new_authority (optional, 32 bytes, Address) let mut instruction_data = [UNINIT_BYTE; 35]; let mut length = instruction_data.len(); @@ -67,7 +66,7 @@ impl SetAuthority<'_, '_> { if let Some(new_authority) = self.new_authority { // Set new_authority as [u8; 32] at offset [2..35] write_bytes(&mut instruction_data[2..3], &[1]); - write_bytes(&mut instruction_data[3..], new_authority); + write_bytes(&mut instruction_data[3..], new_authority.as_array()); } else { write_bytes(&mut instruction_data[2..3], &[0]); // Adjust length if no new authority diff --git a/programs/token-2022/src/instructions/sync_native.rs b/programs/token-2022/src/instructions/sync_native.rs index 4b714ee7..da51abed 100644 --- a/programs/token-2022/src/instructions/sync_native.rs +++ b/programs/token-2022/src/instructions/sync_native.rs @@ -2,8 +2,7 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Given a native token account updates its amount field based @@ -16,7 +15,7 @@ pub struct SyncNative<'a, 'b> { /// Native Token Account pub native_token: &'a AccountInfo, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl SyncNative<'_, '_> { diff --git a/programs/token-2022/src/instructions/thaw_account.rs b/programs/token-2022/src/instructions/thaw_account.rs index 5ebcea19..d14605d8 100644 --- a/programs/token-2022/src/instructions/thaw_account.rs +++ b/programs/token-2022/src/instructions/thaw_account.rs @@ -2,8 +2,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; /// Thaw a Frozen account using the Mint's freeze authority @@ -20,7 +19,7 @@ pub struct ThawAccount<'a, 'b> { /// Mint Freeze Authority Account pub freeze_authority: &'a AccountInfo, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl ThawAccount<'_, '_> { diff --git a/programs/token-2022/src/instructions/transfer.rs b/programs/token-2022/src/instructions/transfer.rs index 2762ae0c..6bd1f2e7 100644 --- a/programs/token-2022/src/instructions/transfer.rs +++ b/programs/token-2022/src/instructions/transfer.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -26,7 +25,7 @@ pub struct Transfer<'a, 'b> { /// Amount of micro-tokens to transfer. pub amount: u64, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl Transfer<'_, '_> { diff --git a/programs/token-2022/src/instructions/transfer_checked.rs b/programs/token-2022/src/instructions/transfer_checked.rs index 6fd1c50c..0028edc7 100644 --- a/programs/token-2022/src/instructions/transfer_checked.rs +++ b/programs/token-2022/src/instructions/transfer_checked.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -31,7 +30,7 @@ pub struct TransferChecked<'a, 'b> { /// Decimal for the Token pub decimals: u8, /// Token Program - pub token_program: &'b Pubkey, + pub token_program: &'b Address, } impl TransferChecked<'_, '_> { diff --git a/programs/token-2022/src/lib.rs b/programs/token-2022/src/lib.rs index 62e593b6..be0c8c3a 100644 --- a/programs/token-2022/src/lib.rs +++ b/programs/token-2022/src/lib.rs @@ -3,10 +3,10 @@ pub mod instructions; pub mod state; -pinocchio_pubkey::declare_id!("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"); - use core::mem::MaybeUninit; +solana_address::declare_id!("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"); + const UNINIT_BYTE: MaybeUninit = MaybeUninit::::uninit(); #[inline(always)] diff --git a/programs/token-2022/src/state/mint.rs b/programs/token-2022/src/state/mint.rs index 61a8d431..4346d0a9 100644 --- a/programs/token-2022/src/state/mint.rs +++ b/programs/token-2022/src/state/mint.rs @@ -1,7 +1,7 @@ use pinocchio::{ account_info::{AccountInfo, Ref}, error::ProgramError, - pubkey::Pubkey, + Address, }; use crate::ID; @@ -16,7 +16,7 @@ pub struct Mint { /// be provided during mint creation. If no mint authority is present /// then the mint has a fixed supply and no further tokens may be /// minted. - mint_authority: Pubkey, + mint_authority: Address, /// Total supply of tokens. supply: [u8; 8], @@ -31,7 +31,7 @@ pub struct Mint { freeze_authority_flag: [u8; 4], /// Optional authority to freeze token accounts. - freeze_authority: Pubkey, + freeze_authority: Address, } impl Mint { @@ -97,7 +97,7 @@ impl Mint { self.mint_authority_flag[0] == 1 } - pub fn mint_authority(&self) -> Option<&Pubkey> { + pub fn mint_authority(&self) -> Option<&Address> { if self.has_mint_authority() { Some(self.mint_authority_unchecked()) } else { @@ -110,7 +110,7 @@ impl Mint { /// This method should be used when the caller knows that the mint will have a mint /// authority set since it skips the `Option` check. #[inline(always)] - pub fn mint_authority_unchecked(&self) -> &Pubkey { + pub fn mint_authority_unchecked(&self) -> &Address { &self.mint_authority } @@ -131,7 +131,7 @@ impl Mint { self.freeze_authority_flag[0] == 1 } - pub fn freeze_authority(&self) -> Option<&Pubkey> { + pub fn freeze_authority(&self) -> Option<&Address> { if self.has_freeze_authority() { Some(self.freeze_authority_unchecked()) } else { @@ -144,7 +144,7 @@ impl Mint { /// This method should be used when the caller knows that the mint will have a freeze /// authority set since it skips the `Option` check. #[inline(always)] - pub fn freeze_authority_unchecked(&self) -> &Pubkey { + pub fn freeze_authority_unchecked(&self) -> &Address { &self.freeze_authority } } diff --git a/programs/token-2022/src/state/multisig.rs b/programs/token-2022/src/state/multisig.rs index a3b3c3ab..747b1a4a 100644 --- a/programs/token-2022/src/state/multisig.rs +++ b/programs/token-2022/src/state/multisig.rs @@ -2,7 +2,7 @@ use core::mem::size_of; use pinocchio::{ account_info::{AccountInfo, Ref}, error::ProgramError, - pubkey::Pubkey, + Address, }; use crate::{instructions::MAX_MULTISIG_SIGNERS, ID}; @@ -17,7 +17,7 @@ pub struct Multisig { /// Is `true` if this structure has been initialized is_initialized: u8, /// Signer public keys - signers: [Pubkey; MAX_MULTISIG_SIGNERS], + signers: [Address; MAX_MULTISIG_SIGNERS], } impl Multisig { @@ -90,8 +90,8 @@ impl Multisig { /// Return the signer addresses of the `Multisig`. #[inline(always)] - pub fn signers(&self) -> &[Pubkey] { - // SAFETY: `self.signers` is an array of `Pubkey` with a fixed size of + pub fn signers(&self) -> &[Address] { + // SAFETY: `self.signers` is an array of `Address` with a fixed size of // `MAX_MULTISIG_SIGNERS`; `self.signers_len` is always `<= MAX_MULTISIG_SIGNERS` // and indicates how many of these signers are valid. unsafe { self.signers.get_unchecked(..self.signers_len()) } diff --git a/programs/token-2022/src/state/token.rs b/programs/token-2022/src/state/token.rs index 3e2aad02..6ad98c07 100644 --- a/programs/token-2022/src/state/token.rs +++ b/programs/token-2022/src/state/token.rs @@ -2,7 +2,7 @@ use super::AccountState; use pinocchio::{ account_info::{AccountInfo, Ref}, error::ProgramError, - pubkey::Pubkey, + Address, }; use crate::ID; @@ -11,10 +11,10 @@ use crate::ID; #[repr(C)] pub struct TokenAccount { /// The mint associated with this account - mint: Pubkey, + mint: Address, /// The owner of this account. - owner: Pubkey, + owner: Address, /// The amount of tokens this account holds. amount: [u8; 8], @@ -24,7 +24,7 @@ pub struct TokenAccount { /// If `delegate` is `Some` then `delegated_amount` represents /// the amount authorized by the delegate. - delegate: Pubkey, + delegate: Address, /// The account's state. state: u8, @@ -45,7 +45,7 @@ pub struct TokenAccount { close_authority_flag: [u8; 4], /// Optional authority to close the account. - close_authority: Pubkey, + close_authority: Address, } impl TokenAccount { @@ -107,11 +107,11 @@ impl TokenAccount { &*(bytes[..Self::BASE_LEN].as_ptr() as *const TokenAccount) } - pub fn mint(&self) -> &Pubkey { + pub fn mint(&self) -> &Address { &self.mint } - pub fn owner(&self) -> &Pubkey { + pub fn owner(&self) -> &Address { &self.owner } @@ -124,7 +124,7 @@ impl TokenAccount { self.delegate_flag[0] == 1 } - pub fn delegate(&self) -> Option<&Pubkey> { + pub fn delegate(&self) -> Option<&Address> { if self.has_delegate() { Some(self.delegate_unchecked()) } else { @@ -134,7 +134,7 @@ impl TokenAccount { /// Use this when you know the account will have a delegate and want to skip the `Option` check. #[inline(always)] - pub fn delegate_unchecked(&self) -> &Pubkey { + pub fn delegate_unchecked(&self) -> &Address { &self.delegate } @@ -174,7 +174,7 @@ impl TokenAccount { self.close_authority_flag[0] == 1 } - pub fn close_authority(&self) -> Option<&Pubkey> { + pub fn close_authority(&self) -> Option<&Address> { if self.has_close_authority() { Some(self.close_authority_unchecked()) } else { @@ -187,7 +187,7 @@ impl TokenAccount { /// This method should be used when the caller knows that the token will have a close /// authority set since it skips the `Option` check. #[inline(always)] - pub fn close_authority_unchecked(&self) -> &Pubkey { + pub fn close_authority_unchecked(&self) -> &Address { &self.close_authority } diff --git a/programs/token/Cargo.toml b/programs/token/Cargo.toml index 0424f922..08a880ce 100644 --- a/programs/token/Cargo.toml +++ b/programs/token/Cargo.toml @@ -13,4 +13,4 @@ crate-type = ["rlib"] [dependencies] pinocchio = { workspace = true } -pinocchio-pubkey = { workspace = true } +solana-address = { workspace = true, features = ["decode"] } diff --git a/programs/token/README.md b/programs/token/README.md index 17fb4f91..1f20a33b 100644 --- a/programs/token/README.md +++ b/programs/token/README.md @@ -24,7 +24,7 @@ This is a `no_std` crate. Initializing a mint account: ```rust // This example assumes that the instruction receives a writable `mint` -// account; `authority` is a `Pubkey`. +// account; `authority` is a `Address`. InitializeMint { mint, rent_sysvar, diff --git a/programs/token/src/instructions/initialize_account_2.rs b/programs/token/src/instructions/initialize_account_2.rs index 26cdfbdb..4b3dee3b 100644 --- a/programs/token/src/instructions/initialize_account_2.rs +++ b/programs/token/src/instructions/initialize_account_2.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -24,7 +23,7 @@ pub struct InitializeAccount2<'a> { /// Rent Sysvar Account pub rent_sysvar: &'a AccountInfo, /// Owner of the new Account. - pub owner: &'a Pubkey, + pub owner: &'a Address, } impl InitializeAccount2<'_> { @@ -39,13 +38,13 @@ impl InitializeAccount2<'_> { // instruction data // - [0]: instruction discriminator (1 byte, u8) - // - [1..33]: owner (32 bytes, Pubkey) + // - [1..33]: owner (32 bytes, Address) let mut instruction_data = [UNINIT_BYTE; 33]; // Set discriminator as u8 at offset [0] write_bytes(&mut instruction_data, &[16]); // Set owner as [u8; 32] at offset [1..33] - write_bytes(&mut instruction_data[1..], self.owner); + write_bytes(&mut instruction_data[1..], self.owner.as_array()); let instruction = Instruction { program_id: &crate::ID, diff --git a/programs/token/src/instructions/initialize_account_3.rs b/programs/token/src/instructions/initialize_account_3.rs index 54f39406..0e46d6a1 100644 --- a/programs/token/src/instructions/initialize_account_3.rs +++ b/programs/token/src/instructions/initialize_account_3.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -21,7 +20,7 @@ pub struct InitializeAccount3<'a> { /// Mint Account. pub mint: &'a AccountInfo, /// Owner of the new Account. - pub owner: &'a Pubkey, + pub owner: &'a Address, } impl InitializeAccount3<'_> { @@ -35,13 +34,13 @@ impl InitializeAccount3<'_> { // instruction data // - [0]: instruction discriminator (1 byte, u8) - // - [1..33]: owner (32 bytes, Pubkey) + // - [1..33]: owner (32 bytes, Address) let mut instruction_data = [UNINIT_BYTE; 33]; // Set discriminator as u8 at offset [0] write_bytes(&mut instruction_data, &[18]); // Set owner as [u8; 32] at offset [1..33] - write_bytes(&mut instruction_data[1..], self.owner); + write_bytes(&mut instruction_data[1..], self.owner.as_array()); let instruction = Instruction { program_id: &crate::ID, diff --git a/programs/token/src/instructions/initialize_mint.rs b/programs/token/src/instructions/initialize_mint.rs index 0a4fbf86..77a299b5 100644 --- a/programs/token/src/instructions/initialize_mint.rs +++ b/programs/token/src/instructions/initialize_mint.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -23,9 +22,9 @@ pub struct InitializeMint<'a> { /// Decimals. pub decimals: u8, /// Mint Authority. - pub mint_authority: &'a Pubkey, + pub mint_authority: &'a Address, /// Freeze Authority. - pub freeze_authority: Option<&'a Pubkey>, + pub freeze_authority: Option<&'a Address>, } impl InitializeMint<'_> { @@ -40,9 +39,9 @@ impl InitializeMint<'_> { // Instruction data layout: // - [0]: instruction discriminator (1 byte, u8) // - [1]: decimals (1 byte, u8) - // - [2..34]: mint_authority (32 bytes, Pubkey) + // - [2..34]: mint_authority (32 bytes, Address) // - [34]: freeze_authority presence flag (1 byte, u8) - // - [35..67]: freeze_authority (optional, 32 bytes, Pubkey) + // - [35..67]: freeze_authority (optional, 32 bytes, Address) let mut instruction_data = [UNINIT_BYTE; 67]; let mut length = instruction_data.len(); @@ -50,13 +49,13 @@ impl InitializeMint<'_> { write_bytes(&mut instruction_data, &[0]); // Set decimals as u8 at offset [1] write_bytes(&mut instruction_data[1..2], &[self.decimals]); - // Set mint_authority as Pubkey at offset [2..34] - write_bytes(&mut instruction_data[2..34], self.mint_authority); + // Set mint_authority as Address at offset [2..34] + write_bytes(&mut instruction_data[2..34], self.mint_authority.as_array()); if let Some(freeze_auth) = self.freeze_authority { // Set Option = `true` & freeze_authority at offset [34..67] write_bytes(&mut instruction_data[34..35], &[1]); - write_bytes(&mut instruction_data[35..], freeze_auth); + write_bytes(&mut instruction_data[35..], freeze_auth.as_array()); } else { // Set Option = `false` write_bytes(&mut instruction_data[34..35], &[0]); diff --git a/programs/token/src/instructions/initialize_mint_2.rs b/programs/token/src/instructions/initialize_mint_2.rs index d8e065c6..c9891620 100644 --- a/programs/token/src/instructions/initialize_mint_2.rs +++ b/programs/token/src/instructions/initialize_mint_2.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, cpi::invoke, instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -20,9 +19,9 @@ pub struct InitializeMint2<'a> { /// Decimals. pub decimals: u8, /// Mint Authority. - pub mint_authority: &'a Pubkey, + pub mint_authority: &'a Address, /// Freeze Authority. - pub freeze_authority: Option<&'a Pubkey>, + pub freeze_authority: Option<&'a Address>, } impl InitializeMint2<'_> { @@ -34,9 +33,9 @@ impl InitializeMint2<'_> { // Instruction data layout: // - [0]: instruction discriminator (1 byte, u8) // - [1]: decimals (1 byte, u8) - // - [2..34]: mint_authority (32 bytes, Pubkey) + // - [2..34]: mint_authority (32 bytes, Address) // - [34]: freeze_authority presence flag (1 byte, u8) - // - [35..67]: freeze_authority (optional, 32 bytes, Pubkey) + // - [35..67]: freeze_authority (optional, 32 bytes, Address) let mut instruction_data = [UNINIT_BYTE; 67]; let mut length = instruction_data.len(); @@ -44,13 +43,13 @@ impl InitializeMint2<'_> { write_bytes(&mut instruction_data, &[20]); // Set decimals as u8 at offset [1] write_bytes(&mut instruction_data[1..2], &[self.decimals]); - // Set mint_authority as Pubkey at offset [2..34] - write_bytes(&mut instruction_data[2..34], self.mint_authority); + // Set mint_authority as Address at offset [2..34] + write_bytes(&mut instruction_data[2..34], self.mint_authority.as_array()); if let Some(freeze_auth) = self.freeze_authority { // Set Option = `true` & freeze_authority at offset [34..67] write_bytes(&mut instruction_data[34..35], &[1]); - write_bytes(&mut instruction_data[35..], freeze_auth); + write_bytes(&mut instruction_data[35..], freeze_auth.as_array()); } else { // Set Option = `false` write_bytes(&mut instruction_data[34..35], &[0]); diff --git a/programs/token/src/instructions/set_authority.rs b/programs/token/src/instructions/set_authority.rs index 94108bb7..c487b953 100644 --- a/programs/token/src/instructions/set_authority.rs +++ b/programs/token/src/instructions/set_authority.rs @@ -4,8 +4,7 @@ use pinocchio::{ account_info::AccountInfo, instruction::{AccountMeta, Instruction, Signer}, program::invoke_signed, - pubkey::Pubkey, - ProgramResult, + Address, ProgramResult, }; use crate::{write_bytes, UNINIT_BYTE}; @@ -32,7 +31,7 @@ pub struct SetAuthority<'a> { /// The type of authority to update. pub authority_type: AuthorityType, /// The new authority - pub new_authority: Option<&'a Pubkey>, + pub new_authority: Option<&'a Address>, } impl SetAuthority<'_> { @@ -53,7 +52,7 @@ impl SetAuthority<'_> { // - [0]: instruction discriminator (1 byte, u8) // - [1]: authority_type (1 byte, u8) // - [2]: new_authority presence flag (1 byte, AuthorityType) - // - [3..35] new_authority (optional, 32 bytes, Pubkey) + // - [3..35] new_authority (optional, 32 bytes, Address) let mut instruction_data = [UNINIT_BYTE; 35]; let mut length = instruction_data.len(); @@ -65,7 +64,7 @@ impl SetAuthority<'_> { if let Some(new_authority) = self.new_authority { // Set new_authority as [u8; 32] at offset [2..35] write_bytes(&mut instruction_data[2..3], &[1]); - write_bytes(&mut instruction_data[3..], new_authority); + write_bytes(&mut instruction_data[3..], new_authority.as_array()); } else { write_bytes(&mut instruction_data[2..3], &[0]); // Adjust length if no new authority diff --git a/programs/token/src/lib.rs b/programs/token/src/lib.rs index 1a8ab22f..651273b3 100644 --- a/programs/token/src/lib.rs +++ b/programs/token/src/lib.rs @@ -3,10 +3,10 @@ pub mod instructions; pub mod state; -pinocchio_pubkey::declare_id!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); - use core::mem::MaybeUninit; +solana_address::declare_id!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); + const UNINIT_BYTE: MaybeUninit = MaybeUninit::::uninit(); #[inline(always)] diff --git a/programs/token/src/state/mint.rs b/programs/token/src/state/mint.rs index 1fba6b48..b2206852 100644 --- a/programs/token/src/state/mint.rs +++ b/programs/token/src/state/mint.rs @@ -1,7 +1,7 @@ use pinocchio::{ account_info::{AccountInfo, Ref}, error::ProgramError, - pubkey::Pubkey, + Address, }; use crate::ID; @@ -16,7 +16,7 @@ pub struct Mint { /// be provided during mint creation. If no mint authority is present /// then the mint has a fixed supply and no further tokens may be /// minted. - mint_authority: Pubkey, + mint_authority: Address, /// Total supply of tokens. supply: [u8; 8], @@ -31,7 +31,7 @@ pub struct Mint { freeze_authority_flag: [u8; 4], /// Optional authority to freeze token accounts. - freeze_authority: Pubkey, + freeze_authority: Address, } impl Mint { @@ -97,7 +97,7 @@ impl Mint { self.mint_authority_flag[0] == 1 } - pub fn mint_authority(&self) -> Option<&Pubkey> { + pub fn mint_authority(&self) -> Option<&Address> { if self.has_mint_authority() { Some(self.mint_authority_unchecked()) } else { @@ -110,7 +110,7 @@ impl Mint { /// This method should be used when the caller knows that the mint will have a mint /// authority set since it skips the `Option` check. #[inline(always)] - pub fn mint_authority_unchecked(&self) -> &Pubkey { + pub fn mint_authority_unchecked(&self) -> &Address { &self.mint_authority } @@ -131,7 +131,7 @@ impl Mint { self.freeze_authority_flag[0] == 1 } - pub fn freeze_authority(&self) -> Option<&Pubkey> { + pub fn freeze_authority(&self) -> Option<&Address> { if self.has_freeze_authority() { Some(self.freeze_authority_unchecked()) } else { @@ -144,7 +144,7 @@ impl Mint { /// This method should be used when the caller knows that the mint will have a freeze /// authority set since it skips the `Option` check. #[inline(always)] - pub fn freeze_authority_unchecked(&self) -> &Pubkey { + pub fn freeze_authority_unchecked(&self) -> &Address { &self.freeze_authority } } diff --git a/programs/token/src/state/multisig.rs b/programs/token/src/state/multisig.rs index a3b3c3ab..747b1a4a 100644 --- a/programs/token/src/state/multisig.rs +++ b/programs/token/src/state/multisig.rs @@ -2,7 +2,7 @@ use core::mem::size_of; use pinocchio::{ account_info::{AccountInfo, Ref}, error::ProgramError, - pubkey::Pubkey, + Address, }; use crate::{instructions::MAX_MULTISIG_SIGNERS, ID}; @@ -17,7 +17,7 @@ pub struct Multisig { /// Is `true` if this structure has been initialized is_initialized: u8, /// Signer public keys - signers: [Pubkey; MAX_MULTISIG_SIGNERS], + signers: [Address; MAX_MULTISIG_SIGNERS], } impl Multisig { @@ -90,8 +90,8 @@ impl Multisig { /// Return the signer addresses of the `Multisig`. #[inline(always)] - pub fn signers(&self) -> &[Pubkey] { - // SAFETY: `self.signers` is an array of `Pubkey` with a fixed size of + pub fn signers(&self) -> &[Address] { + // SAFETY: `self.signers` is an array of `Address` with a fixed size of // `MAX_MULTISIG_SIGNERS`; `self.signers_len` is always `<= MAX_MULTISIG_SIGNERS` // and indicates how many of these signers are valid. unsafe { self.signers.get_unchecked(..self.signers_len()) } diff --git a/programs/token/src/state/token.rs b/programs/token/src/state/token.rs index 27217951..3e36d165 100644 --- a/programs/token/src/state/token.rs +++ b/programs/token/src/state/token.rs @@ -2,7 +2,7 @@ use super::AccountState; use pinocchio::{ account_info::{AccountInfo, Ref}, error::ProgramError, - pubkey::Pubkey, + Address, }; use crate::ID; @@ -11,10 +11,10 @@ use crate::ID; #[repr(C)] pub struct TokenAccount { /// The mint associated with this account - mint: Pubkey, + mint: Address, /// The owner of this account. - owner: Pubkey, + owner: Address, /// The amount of tokens this account holds. amount: [u8; 8], @@ -24,7 +24,7 @@ pub struct TokenAccount { /// If `delegate` is `Some` then `delegated_amount` represents /// the amount authorized by the delegate. - delegate: Pubkey, + delegate: Address, /// The account's state. state: u8, @@ -45,7 +45,7 @@ pub struct TokenAccount { close_authority_flag: [u8; 4], /// Optional authority to close the account. - close_authority: Pubkey, + close_authority: Address, } impl TokenAccount { @@ -107,11 +107,11 @@ impl TokenAccount { &*(bytes.as_ptr() as *const TokenAccount) } - pub fn mint(&self) -> &Pubkey { + pub fn mint(&self) -> &Address { &self.mint } - pub fn owner(&self) -> &Pubkey { + pub fn owner(&self) -> &Address { &self.owner } @@ -124,7 +124,7 @@ impl TokenAccount { self.delegate_flag[0] == 1 } - pub fn delegate(&self) -> Option<&Pubkey> { + pub fn delegate(&self) -> Option<&Address> { if self.has_delegate() { Some(self.delegate_unchecked()) } else { @@ -134,7 +134,7 @@ impl TokenAccount { /// Use this when you know the account will have a delegate and want to skip the `Option` check. #[inline(always)] - pub fn delegate_unchecked(&self) -> &Pubkey { + pub fn delegate_unchecked(&self) -> &Address { &self.delegate } @@ -174,7 +174,7 @@ impl TokenAccount { self.close_authority_flag[0] == 1 } - pub fn close_authority(&self) -> Option<&Pubkey> { + pub fn close_authority(&self) -> Option<&Address> { if self.has_close_authority() { Some(self.close_authority_unchecked()) } else { @@ -187,7 +187,7 @@ impl TokenAccount { /// This method should be used when the caller knows that the token will have a close /// authority set since it skips the `Option` check. #[inline(always)] - pub fn close_authority_unchecked(&self) -> &Pubkey { + pub fn close_authority_unchecked(&self) -> &Address { &self.close_authority } diff --git a/sdk/log/README.md b/sdk/log/README.md index d937b0bd..95ef2057 100644 --- a/sdk/log/README.md +++ b/sdk/log/README.md @@ -28,14 +28,14 @@ This crate defines a lightweight `Logger` type to format log messages and a comp Below is a sample of the improvements observed when formatting log messages, measured in terms of compute units (CU): | Output message | `log!` | `msg!` | Improvement (%) | -|------------------------------------|--------|-----------------|-----------------| -| `"Hello world!"` | 104 | 104 | - | -| `"lamports={}"` + `u64` | 286 | 625 (+339) | 55% | -| `"{}"` + `[&str; 2]` | 119 | 1610 (+1491) | 93% | -| `"{}"` + `[u64; 2]` | 483 | 1154 (+671) | 49% | -| `"lamports={}"` + `i64` | 299 | 659 (+360) | 55% | -| `"{}"` + `[u8; 32]` (pubkey bytes) | 2783 | 8397 (+5614) | 67% | -| `"lamports={:.9}"` + `u64` | 438 | 2656 (+2218)`*` | 84% | +|-------------------------------------|--------|-----------------|-----------------| +| `"Hello world!"` | 104 | 104 | - | +| `"lamports={}"` + `u64` | 286 | 625 (+339) | 55% | +| `"{}"` + `[&str; 2]` | 119 | 1610 (+1491) | 93% | +| `"{}"` + `[u64; 2]` | 483 | 1154 (+671) | 49% | +| `"lamports={}"` + `i64` | 299 | 659 (+360) | 55% | +| `"{}"` + `[u8; 32]` (address bytes) | 2783 | 8397 (+5614) | 67% | +| `"lamports={:.9}"` + `u64` | 438 | 2656 (+2218)`*` | 84% | `*` For `msg!`, the value is logged as a `f64` otherwise the precision formatting is ignored. diff --git a/sdk/pinocchio/Cargo.toml b/sdk/pinocchio/Cargo.toml index 88c772fc..045a5c7f 100644 --- a/sdk/pinocchio/Cargo.toml +++ b/sdk/pinocchio/Cargo.toml @@ -18,9 +18,11 @@ unexpected_cfgs = { level = "warn", check-cfg = [ ] } [features] -std = [] +copy = ["solana-address/copy"] +std = ["solana-address/std"] [dependencies] +solana-address = { workspace = true, features = ["syscalls"] } solana-program-error = "3.0" [dev-dependencies] diff --git a/sdk/pinocchio/src/account_info.rs b/sdk/pinocchio/src/account_info.rs index fc52539a..b130ba41 100644 --- a/sdk/pinocchio/src/account_info.rs +++ b/sdk/pinocchio/src/account_info.rs @@ -10,11 +10,7 @@ use core::{ #[cfg(target_os = "solana")] use crate::syscalls::sol_memset_; -use crate::{ - error::ProgramError, - pubkey::{pubkey_eq, Pubkey}, - ProgramResult, -}; +use crate::{error::ProgramError, Address, ProgramResult}; /// Maximum number of bytes a program may add to an account during a /// single top-level instruction. @@ -22,7 +18,8 @@ pub const MAX_PERMITTED_DATA_INCREASE: usize = 1_024 * 10; /// Represents masks for borrow state of an account. #[repr(u8)] -#[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug)] pub enum BorrowState { /// Mask to check whether an account is already borrowed. /// @@ -44,7 +41,8 @@ pub enum BorrowState { /// This data is wrapped in an `AccountInfo` struct, which provides safe access /// to the data. #[repr(C)] -#[derive(Clone, Copy, Default)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Default)] pub(crate) struct Account { /// Borrow state for lamports and account data. /// @@ -97,11 +95,11 @@ pub(crate) struct Account { /// value is zero at the start of the instruction. resize_delta: i32, - /// Public key of the account. - key: Pubkey, + /// Address of the account. + key: Address, /// Program that owns this account. Modifiable by programs. - owner: Pubkey, + owner: Address, /// The lamports in the account. Modifiable by programs. lamports: u64, @@ -116,7 +114,8 @@ pub(crate) struct Account { /// used to track borrows of the account data and lamports, given that an /// account can be "shared" across multiple `AccountInfo` instances. #[repr(C)] -#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct AccountInfo { /// Raw (pointer to) account data. /// @@ -125,15 +124,15 @@ pub struct AccountInfo { } impl AccountInfo { - /// Public key of the account. + /// Address of the account. #[inline(always)] - pub fn key(&self) -> &Pubkey { + pub fn key(&self) -> &Address { unsafe { &(*self.raw).key } } /// Program that owns this account. #[inline(always)] - pub fn owner(&self) -> &Pubkey { + pub fn owner(&self) -> &Address { unsafe { &(*self.raw).owner } } @@ -189,8 +188,8 @@ impl AccountInfo { /// Checks if the account is owned by the given program. #[inline(always)] - pub fn is_owned_by(&self, program: &Pubkey) -> bool { - pubkey_eq(self.owner(), program) + pub fn is_owned_by(&self, program: &Address) -> bool { + self.owner() == program } /// Changes the owner of the account. @@ -200,8 +199,11 @@ impl AccountInfo { /// It is undefined behavior to use this method while there is an active reference /// to the `owner` returned by [`Self::owner`]. #[inline(always)] - pub unsafe fn assign(&self, new_owner: &Pubkey) { + pub unsafe fn assign(&self, new_owner: &Address) { + #[cfg(feature = "copy")] write(&mut (*self.raw).owner, *new_owner); + #[cfg(not(feature = "copy"))] + write(&mut (*self.raw).owner, new_owner.clone()); } /// Return true if the account borrow state is set to the given state. diff --git a/sdk/pinocchio/src/cpi.rs b/sdk/pinocchio/src/cpi.rs index 9c9325e7..a16351e4 100644 --- a/sdk/pinocchio/src/cpi.rs +++ b/sdk/pinocchio/src/cpi.rs @@ -7,8 +7,7 @@ use crate::{ error::ProgramError, hint::unlikely, instruction::{Account, Instruction, Signer}, - pubkey::{pubkey_eq, Pubkey}, - ProgramResult, + Address, ProgramResult, }; /// Maximum number of accounts that can be passed to a cross-program invocation. @@ -101,7 +100,7 @@ pub fn slice_invoke(instruction: &Instruction, account_infos: &[&AccountInfo]) - /// 1. It has at least as many accounts as the number of accounts expected by /// the instruction. /// 2. The accounts match the expected accounts in the instruction, i.e., their -/// `Pubkey` matches the `pubkey` in the `AccountMeta`. +/// `Address` matches the address in the `AccountMeta`. /// 3. The borrow state of the accounts is compatible with the mutability of the /// accounts in the instruction. /// @@ -144,7 +143,7 @@ pub fn invoke_signed( /// 1. It has at least as many accounts as the number of accounts expected by /// the instruction. /// 2. The accounts match the expected accounts in the instruction, i.e., their -/// `Pubkey` matches the `pubkey` in the `AccountMeta`. +/// `Address` matches the address in the `AccountMeta`. /// 3. The borrow state of the accounts is compatible with the mutability of the /// accounts in the instruction. /// @@ -203,7 +202,7 @@ pub fn invoke_signed_with_bounds( /// 1. It has at least as many accounts as the number of accounts expected by /// the instruction. /// 2. The accounts match the expected accounts in the instruction, i.e., their -/// `Pubkey` matches the `pubkey` in the `AccountMeta`. +/// `Address` matches the address in the `AccountMeta`. /// 3. The borrow state of the accounts is compatible with the mutability of the /// accounts in the instruction. /// @@ -258,7 +257,7 @@ pub fn slice_invoke_signed( /// 1. It has at least as many accounts as the number of accounts expected by /// the instruction. /// 2. The accounts match the expected accounts in the instruction, i.e., their -/// `Pubkey` matches the `pubkey` in the `AccountMeta`. +/// `Address` matches the address in the `AccountMeta`. /// 3. The borrow state of the accounts is compatible with the mutability of the /// accounts in the instruction. /// @@ -300,7 +299,7 @@ unsafe fn inner_invoke_signed_with_bounds( // In order to check whether the borrow state is compatible // with the invocation, we need to check that we have the // correct account info and meta pair. - if unlikely(!pubkey_eq(account_info.key(), account_meta.pubkey)) { + if unlikely(account_info.key() != account_meta.address) { return Err(ProgramError::InvalidArgument); } @@ -395,8 +394,8 @@ pub unsafe fn invoke_signed_unchecked( /// discarded immediately after. #[repr(C)] struct CInstruction<'a> { - /// Public key of the program. - program_id: *const Pubkey, + /// Address of the program. + program_id: *const Address, /// Accounts expected by the program instruction. accounts: *const AccountMeta<'a>, @@ -458,7 +457,7 @@ pub fn set_return_data(data: &[u8]) { /// Get the return data from an invoked program. /// /// For every transaction there is a single buffer with maximum length -/// [`MAX_RETURN_DATA`], paired with a [`Pubkey`] representing the program ID of +/// [`MAX_RETURN_DATA`], paired with an [`Address`] representing the program ID of /// the program that most recently set the return data. Thus the return data is /// a global resource and care must be taken to ensure that it represents what /// is expected: called programs are free to set or not set the return data; and @@ -490,13 +489,13 @@ pub fn get_return_data() -> Option { { const UNINIT_BYTE: core::mem::MaybeUninit = core::mem::MaybeUninit::::uninit(); let mut data = [UNINIT_BYTE; MAX_RETURN_DATA]; - let mut program_id = MaybeUninit::::uninit(); + let mut program_id = MaybeUninit::
::uninit(); let size = unsafe { crate::syscalls::sol_get_return_data( data.as_mut_ptr() as *mut u8, data.len() as u64, - program_id.as_mut_ptr() as *mut Pubkey, + program_id.as_mut_ptr() as *mut Address as *mut u8, ) }; @@ -519,7 +518,7 @@ pub fn get_return_data() -> Option { #[derive(Debug)] pub struct ReturnData { /// Program that most recently set the return data. - program_id: Pubkey, + program_id: Address, /// Return data set by the program. data: [MaybeUninit; MAX_RETURN_DATA], @@ -530,7 +529,7 @@ pub struct ReturnData { impl ReturnData { /// Returns the program that most recently set the return data. - pub fn program_id(&self) -> &Pubkey { + pub fn program_id(&self) -> &Address { &self.program_id } diff --git a/sdk/pinocchio/src/entrypoint/lazy.rs b/sdk/pinocchio/src/entrypoint/lazy.rs index 8c6766b5..3f65938c 100644 --- a/sdk/pinocchio/src/entrypoint/lazy.rs +++ b/sdk/pinocchio/src/entrypoint/lazy.rs @@ -5,8 +5,7 @@ use crate::{ account_info::{Account, AccountInfo}, entrypoint::{NON_DUP_MARKER, STATIC_ACCOUNT_DATA}, error::ProgramError, - pubkey::Pubkey, - BPF_ALIGN_OF_U128, + Address, BPF_ALIGN_OF_U128, }; /// Declare the lazy program entrypoint. @@ -230,7 +229,7 @@ impl InstructionContext { /// This method can only be used after all accounts have been read; otherwise, it will /// return a [`ProgramError::InvalidInstructionData`] error. #[inline(always)] - pub fn program_id(&self) -> Result<&Pubkey, ProgramError> { + pub fn program_id(&self) -> Result<&Address, ProgramError> { if self.remaining > 0 { return Err(ProgramError::InvalidInstructionData); } @@ -245,9 +244,9 @@ impl InstructionContext { /// It is up to the caller to guarantee that all accounts have been read; calling this method /// before reading all accounts will result in undefined behavior. #[inline(always)] - pub unsafe fn program_id_unchecked(&self) -> &Pubkey { + pub unsafe fn program_id_unchecked(&self) -> &Address { let data_len = *(self.buffer as *const usize); - &*(self.buffer.add(core::mem::size_of::() + data_len) as *const Pubkey) + &*(self.buffer.add(core::mem::size_of::() + data_len) as *const Address) } /// Read an account from the input buffer. @@ -277,7 +276,8 @@ impl InstructionContext { } /// Wrapper type around an [`AccountInfo`] that may be a duplicate. -#[derive(Debug, Copy, Clone)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Debug, Clone)] pub enum MaybeAccount { /// An [`AccountInfo`] that is not a duplicate. Account(AccountInfo), diff --git a/sdk/pinocchio/src/entrypoint/mod.rs b/sdk/pinocchio/src/entrypoint/mod.rs index 4f81d25e..cf9235ae 100644 --- a/sdk/pinocchio/src/entrypoint/mod.rs +++ b/sdk/pinocchio/src/entrypoint/mod.rs @@ -19,8 +19,7 @@ use core::{ use crate::{ account_info::{Account, AccountInfo, MAX_PERMITTED_DATA_INCREASE}, - pubkey::Pubkey, - BPF_ALIGN_OF_U128, MAX_TX_ACCOUNTS, + Address, BPF_ALIGN_OF_U128, MAX_TX_ACCOUNTS, }; /// Start address of the memory region used for program heap. @@ -66,7 +65,7 @@ const STATIC_ACCOUNT_DATA: usize = size_of::() + MAX_PERMITTED_DATA_INC /// /// ```ignore /// fn process_instruction( -/// program_id: &Pubkey, // Public key of the account the program was loaded into +/// program_id: &Address, // Address of the account the program was loaded into /// accounts: &[AccountInfo], // All accounts required to process the instruction /// instruction_data: &[u8], // Serialized instruction-specific data /// ) -> ProgramResult; @@ -96,14 +95,14 @@ const STATIC_ACCOUNT_DATA: usize = size_of::() + MAX_PERMITTED_DATA_INC /// account_info::AccountInfo, /// entrypoint, /// msg, -/// pubkey::Pubkey, +/// Address, /// ProgramResult /// }; /// /// entrypoint!(process_instruction); /// /// pub fn process_instruction( -/// program_id: &Pubkey, +/// program_id: &Address, /// accounts: &[AccountInfo], /// instruction_data: &[u8], /// ) -> ProgramResult { @@ -150,7 +149,7 @@ macro_rules! entrypoint { /// /// ```ignore /// fn process_instruction( -/// program_id: &Pubkey, // Public key of the account the program was loaded into +/// program_id: &Address, // Address of the account the program was loaded into /// accounts: &[AccountInfo], // All accounts required to process the instruction /// instruction_data: &[u8], // Serialized instruction-specific data /// ) -> ProgramResult; @@ -310,7 +309,7 @@ unsafe fn clone_account_info( pub unsafe fn deserialize( mut input: *mut u8, accounts: &mut [MaybeUninit; MAX_ACCOUNTS], -) -> (&'static Pubkey, usize, &'static [u8]) { +) -> (&'static Address, usize, &'static [u8]) { // Ensure that MAX_ACCOUNTS is less than or equal to the maximum number of accounts // (MAX_TX_ACCOUNTS) that can be processed in a transaction. const { @@ -431,7 +430,7 @@ pub unsafe fn deserialize( let input = input.add(instruction_data_len); // program id - let program_id: &Pubkey = &*(input as *const Pubkey); + let program_id: &Address = &*(input as *const Address); (program_id, processed, instruction_data) } @@ -639,7 +638,8 @@ mod alloc { }; /// The bump allocator used as the default rust heap when running programs. - #[derive(Clone, Copy, Debug)] + #[cfg_attr(feature = "copy", derive(Copy))] + #[derive(Clone, Debug)] pub struct BumpAllocator { pub start: usize, pub len: usize, @@ -678,7 +678,8 @@ mod alloc { #[cfg(not(feature = "std"))] /// An allocator that does not allocate memory. -#[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug)] pub struct NoAllocator; #[cfg(not(feature = "std"))] @@ -707,7 +708,7 @@ mod tests { use super::*; /// The mock program ID used for testing. - const MOCK_PROGRAM_ID: Pubkey = [5u8; 32]; + const MOCK_PROGRAM_ID: Address = Address::new_from_array([5u8; 32]); /// An uninitialized account info. const UNINIT: MaybeUninit = MaybeUninit::::uninit(); @@ -790,7 +791,7 @@ mod tests { input.write(instruction_data, offset); offset += instruction_data.len(); // Program ID (mock). - input.write(&MOCK_PROGRAM_ID, offset); + input.write(MOCK_PROGRAM_ID.as_array(), offset); input } @@ -853,7 +854,7 @@ mod tests { input.write(instruction_data, offset); offset += instruction_data.len(); // Program ID (mock). - input.write(&MOCK_PROGRAM_ID, offset); + input.write(MOCK_PROGRAM_ID.as_array(), offset); input } @@ -918,7 +919,7 @@ mod tests { unsafe { deserialize(input.as_mut_ptr(), &mut accounts) }; assert_eq!(count, 0); - assert_eq!(program_id, &MOCK_PROGRAM_ID); + assert!(program_id == &MOCK_PROGRAM_ID); assert_eq!(&ix_data, parsed_ix_data); // Input with 3 accounts but the accounts array has only space @@ -931,7 +932,7 @@ mod tests { unsafe { deserialize(input.as_mut_ptr(), &mut accounts) }; assert_eq!(count, 1); - assert_eq!(program_id, &MOCK_PROGRAM_ID); + assert!(program_id == &MOCK_PROGRAM_ID); assert_eq!(&ix_data, parsed_ix_data); assert_accounts(&accounts[..count]); @@ -945,7 +946,7 @@ mod tests { unsafe { deserialize(input.as_mut_ptr(), &mut accounts) }; assert_eq!(count, 64); - assert_eq!(program_id, &MOCK_PROGRAM_ID); + assert!(program_id == &MOCK_PROGRAM_ID); assert_eq!(&ix_data, parsed_ix_data); assert_accounts(&accounts); } @@ -963,7 +964,7 @@ mod tests { unsafe { deserialize(input.as_mut_ptr(), &mut accounts) }; assert_eq!(count, 0); - assert_eq!(program_id, &MOCK_PROGRAM_ID); + assert!(program_id == &MOCK_PROGRAM_ID); assert_eq!(&ix_data, parsed_ix_data); // Input with 3 (1 + 2 duplicated) accounts but the accounts array has only space for 2. The @@ -977,7 +978,7 @@ mod tests { unsafe { deserialize(input.as_mut_ptr(), &mut accounts) }; assert_eq!(count, 2); - assert_eq!(program_id, &MOCK_PROGRAM_ID); + assert!(program_id == &MOCK_PROGRAM_ID); assert_eq!(&ix_data, parsed_ix_data); assert_duplicated_accounts(&accounts[..count], 1); @@ -994,7 +995,7 @@ mod tests { unsafe { deserialize(input.as_mut_ptr(), &mut accounts) }; assert_eq!(count, 64); - assert_eq!(program_id, &MOCK_PROGRAM_ID); + assert!(program_id == &MOCK_PROGRAM_ID); assert_eq!(&ix_data, parsed_ix_data); assert_duplicated_accounts(&accounts, 32); } diff --git a/sdk/pinocchio/src/instruction.rs b/sdk/pinocchio/src/instruction.rs index 7df365f8..5b7d03b7 100644 --- a/sdk/pinocchio/src/instruction.rs +++ b/sdk/pinocchio/src/instruction.rs @@ -2,7 +2,7 @@ use core::{marker::PhantomData, ops::Deref}; -use crate::{account_info::AccountInfo, pubkey::Pubkey}; +use crate::{account_info::AccountInfo, Address}; /// Information about a CPI instruction. #[derive(Debug, Clone)] @@ -10,8 +10,8 @@ pub struct Instruction<'a, 'b, 'c, 'd> where 'a: 'b, { - /// Public key of the program. - pub program_id: &'c Pubkey, + /// Address of the program. + pub program_id: &'c Address, /// Data expected by the program instruction. pub data: &'d [u8], @@ -23,7 +23,8 @@ where /// Use to query and convey information about the sibling instruction components /// when calling the `sol_get_processed_sibling_instruction` syscall. #[repr(C)] -#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct ProcessedSiblingInstruction { /// Length of the instruction data pub data_len: u64, @@ -37,10 +38,11 @@ pub struct ProcessedSiblingInstruction { /// This struct contains the same information as an [`AccountInfo`], but has /// the memory layout as expected by `sol_invoke_signed_c` syscall. #[repr(C)] -#[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug)] pub struct Account<'a> { - // Public key of the account. - key: *const Pubkey, + // Address of the account. + key: *const Address, // Number of lamports owned by this account. lamports: *const u64, @@ -52,7 +54,7 @@ pub struct Account<'a> { data: *const u8, // Program that owns this account. - owner: *const Pubkey, + owner: *const Address, // The epoch at which this account will next owe rent. rent_epoch: u64, @@ -128,8 +130,8 @@ impl<'a> From<&'a AccountInfo> for Account<'a> { #[repr(C)] #[derive(Debug, Clone)] pub struct AccountMeta<'a> { - /// Public key of the account. - pub pubkey: &'a Pubkey, + /// Address of the account. + pub address: &'a Address, /// Indicates whether the account is writable or not. pub is_writable: bool, @@ -141,9 +143,9 @@ pub struct AccountMeta<'a> { impl<'a> AccountMeta<'a> { /// Creates a new `AccountMeta`. #[inline(always)] - pub const fn new(pubkey: &'a Pubkey, is_writable: bool, is_signer: bool) -> Self { + pub const fn new(address: &'a Address, is_writable: bool, is_signer: bool) -> Self { Self { - pubkey, + address, is_writable, is_signer, } @@ -151,26 +153,26 @@ impl<'a> AccountMeta<'a> { /// Creates a new read-only `AccountMeta`. #[inline(always)] - pub const fn readonly(pubkey: &'a Pubkey) -> Self { - Self::new(pubkey, false, false) + pub const fn readonly(address: &'a Address) -> Self { + Self::new(address, false, false) } /// Creates a new writable `AccountMeta`. #[inline(always)] - pub const fn writable(pubkey: &'a Pubkey) -> Self { - Self::new(pubkey, true, false) + pub const fn writable(address: &'a Address) -> Self { + Self::new(address, true, false) } /// Creates a new read-only and signer `AccountMeta`. #[inline(always)] - pub const fn readonly_signer(pubkey: &'a Pubkey) -> Self { - Self::new(pubkey, false, true) + pub const fn readonly_signer(address: &'a Address) -> Self { + Self::new(address, false, true) } /// Creates a new writable and signer `AccountMeta`. #[inline(always)] - pub const fn writable_signer(pubkey: &'a Pubkey) -> Self { - Self::new(pubkey, true, true) + pub const fn writable_signer(address: &'a Address) -> Self { + Self::new(address, true, true) } } @@ -297,13 +299,12 @@ macro_rules! signer { /// /// Creating seeds array and signer for a PDA with a single seed and bump value: /// ``` -/// use pinocchio::{seeds, instruction::Signer}; -/// use pinocchio::pubkey::Pubkey; +/// use pinocchio::{seeds, instruction::Signer, Address}; /// /// let pda_bump = 0xffu8; /// let pda_ref = &[pda_bump]; // prevent temporary value being freed -/// let example_key = Pubkey::default(); -/// let seeds = seeds!(b"seed", &example_key, pda_ref); +/// let example_key = Address::default(); +/// let seeds = seeds!(b"seed", example_key.as_ref(), pda_ref); /// let signer = Signer::from(&seeds); /// ``` #[macro_export] diff --git a/sdk/pinocchio/src/lib.rs b/sdk/pinocchio/src/lib.rs index db234ea7..989d7449 100644 --- a/sdk/pinocchio/src/lib.rs +++ b/sdk/pinocchio/src/lib.rs @@ -34,13 +34,13 @@ //! entrypoint, //! msg, //! ProgramResult, -//! pubkey::Pubkey +//! Address //! }; //! //! entrypoint!(process_instruction); //! //! pub fn process_instruction( -//! program_id: &Pubkey, +//! program_id: &Address, //! accounts: &[AccountInfo], //! instruction_data: &[u8], //! ) -> ProgramResult { @@ -142,7 +142,7 @@ //! no_allocator, //! program_entrypoint, //! ProgramResult, -//! pubkey::Pubkey +//! Address //! }; //! //! program_entrypoint!(process_instruction); @@ -150,7 +150,7 @@ //! no_allocator!(); //! //! pub fn process_instruction( -//! program_id: &Pubkey, +//! program_id: &Address, //! accounts: &[AccountInfo], //! instruction_data: &[u8], //! ) -> ProgramResult { @@ -197,13 +197,13 @@ //! entrypoint, //! msg, //! ProgramResult, -//! pubkey::Pubkey +//! Address //! }; //! //! entrypoint!(process_instruction); //! //! pub fn process_instruction( -//! program_id: &Pubkey, +//! program_id: &Address, //! accounts: &[AccountInfo], //! instruction_data: &[u8], //! ) -> ProgramResult { @@ -217,7 +217,7 @@ //! ```ignore //! cargo build-sbf --features bpf-entrypoint //! ``` -#![warn(missing_copy_implementations, missing_debug_implementations)] + #![no_std] #[cfg(feature = "std")] @@ -233,12 +233,17 @@ pub mod memory; pub mod program { pub use crate::cpi::*; } -pub mod pubkey; pub mod syscalls; pub mod sysvars; #[deprecated(since = "0.7.0", note = "Use the `entrypoint` module instead")] pub use entrypoint::lazy as lazy_entrypoint; + +// Re-export the `solana_address` for downstream use. +pub use solana_address as address; +pub use solana_address::Address; + +// Re-export the `solana_program_error` for downstream use. pub use solana_program_error as error; pub use solana_program_error::ProgramResult; diff --git a/sdk/pinocchio/src/log.rs b/sdk/pinocchio/src/log.rs index d978cbec..d53d9433 100644 --- a/sdk/pinocchio/src/log.rs +++ b/sdk/pinocchio/src/log.rs @@ -27,13 +27,12 @@ //! [`env_logger`]: https://docs.rs/env_logger //! [`RpcClient::get_transaction`]: https://docs.rs/solana-rpc-client/latest/solana_rpc_client/rpc_client/struct.RpcClient.html#method.get_transaction //! -//! While most logging functions are defined in this module, [`Pubkey`]s can -//! also be efficiently logged with the [`pubkey::log`] function. +//! While most logging functions are defined in this module, [`Address`]es can +//! also be efficiently logged with the [`solana_address::Address::log`] function. //! -//! [`Pubkey`]: crate::pubkey::Pubkey -//! [`pubkey::log`]: crate::pubkey::log +//! [`Address`]: solana_address -use crate::{account_info::AccountInfo, pubkey}; +use crate::account_info::AccountInfo; /// Print a message to the log. /// @@ -138,22 +137,28 @@ pub fn sol_log_slice(slice: &[u8]) { /// - `accounts` - A slice of [`AccountInfo`]. /// - `data` - The instruction data. pub fn sol_log_params(accounts: &[AccountInfo], data: &[u8]) { - for (i, account) in accounts.iter().enumerate() { - msg!("AccountInfo"); - sol_log_64(0, 0, 0, 0, i as u64); - msg!("- Is signer"); - sol_log_64(0, 0, 0, 0, account.is_signer() as u64); - msg!("- Key"); - pubkey::log(account.key()); - msg!("- Lamports"); - sol_log_64(0, 0, 0, 0, account.lamports()); - msg!("- Account data length"); - sol_log_64(0, 0, 0, 0, account.data_len() as u64); - msg!("- Owner"); - pubkey::log(account.owner()); + #[cfg(target_os = "solana")] + { + for (i, account) in accounts.iter().enumerate() { + msg!("AccountInfo"); + sol_log_64(0, 0, 0, 0, i as u64); + msg!("- Is signer"); + sol_log_64(0, 0, 0, 0, account.is_signer() as u64); + msg!("- Key"); + account.key().log(); + msg!("- Lamports"); + sol_log_64(0, 0, 0, 0, account.lamports()); + msg!("- Account data length"); + sol_log_64(0, 0, 0, 0, account.data_len() as u64); + msg!("- Owner"); + account.owner().log(); + } + msg!("Instruction data"); + sol_log_slice(data); } - msg!("Instruction data"); - sol_log_slice(data); + + #[cfg(not(target_os = "solana"))] + core::hint::black_box((accounts, data)); } /// Print the remaining compute units available to the program. diff --git a/sdk/pinocchio/src/pubkey.rs b/sdk/pinocchio/src/pubkey.rs deleted file mode 100644 index 756f03ad..00000000 --- a/sdk/pinocchio/src/pubkey.rs +++ /dev/null @@ -1,321 +0,0 @@ -//! Public key type and functions. - -use core::ptr::read_unaligned; - -use crate::error::ProgramError; - -/// Number of bytes in a pubkey. -pub const PUBKEY_BYTES: usize = 32; - -/// maximum length of derived `Pubkey` seed. -pub const MAX_SEED_LEN: usize = 32; - -/// Maximum number of seeds. -pub const MAX_SEEDS: usize = 16; - -/// The marker used to derive [program derived addresses][pda]. -/// -/// [pda]: https://solana.com/docs/core/pda -pub const PDA_MARKER: &[u8; 21] = b"ProgramDerivedAddress"; - -/// The address of a [Solana account][account]. -/// -/// [account]: https://solana.com/docs/core/accounts -pub type Pubkey = [u8; PUBKEY_BYTES]; - -/// Log a `Pubkey` from a program. -#[inline(always)] -pub fn log(pubkey: &Pubkey) { - #[cfg(target_os = "solana")] - unsafe { - crate::syscalls::sol_log_pubkey(pubkey as *const _ as *const u8) - }; - - #[cfg(not(target_os = "solana"))] - core::hint::black_box(pubkey); -} - -/// Compare two `Pubkey`s for equality. -/// -/// The implementation of this function is currently more efficient -/// than `p1 == p2` since it compares 8 bytes at a time instead of -/// byte-by-byte. -#[inline(always)] -pub const fn pubkey_eq(p1: &Pubkey, p2: &Pubkey) -> bool { - let p1_ptr = p1.as_ptr() as *const u64; - let p2_ptr = p2.as_ptr() as *const u64; - - unsafe { - read_unaligned(p1_ptr) == read_unaligned(p2_ptr) - && read_unaligned(p1_ptr.add(1)) == read_unaligned(p2_ptr.add(1)) - && read_unaligned(p1_ptr.add(2)) == read_unaligned(p2_ptr.add(2)) - && read_unaligned(p1_ptr.add(3)) == read_unaligned(p2_ptr.add(3)) - } -} - -/// Find a valid [program derived address][pda] and its corresponding bump seed. -/// -/// [pda]: https://solana.com/docs/core/cpi#program-derived-addresses -/// -/// Program derived addresses (PDAs) are account keys that only the program, -/// `program_id`, has the authority to sign. The address is of the same form -/// as a Solana `Pubkey`, except they are ensured to not be on the ed25519 -/// curve and thus have no associated private key. When performing -/// cross-program invocations the program can "sign" for the key by calling -/// [`invoke_signed`] and passing the same seeds used to generate the -/// address, along with the calculated _bump seed_, which this function -/// returns as the second tuple element. The runtime will verify that the -/// program associated with this address is the caller and thus authorized -/// to be the signer. -/// -/// [`invoke_signed`]: crate::program::invoke_signed -/// -/// The `seeds` are application-specific, and must be carefully selected to -/// uniquely derive accounts per application requirements. It is common to -/// use static strings and other pubkeys as seeds. -/// -/// Because the program address must not lie on the ed25519 curve, there may -/// be seed and program id combinations that are invalid. For this reason, -/// an extra seed (the bump seed) is calculated that results in a -/// point off the curve. The bump seed must be passed as an additional seed -/// when calling `invoke_signed`. -/// -/// The processes of finding a valid program address is by trial and error, -/// and even though it is deterministic given a set of inputs it can take a -/// variable amount of time to succeed across different inputs. This means -/// that when called from an on-chain program it may incur a variable amount -/// of the program's compute budget. Programs that are meant to be very -/// performant may not want to use this function because it could take a -/// considerable amount of time. Programs that are already at risk -/// of exceeding their compute budget should call this with care since -/// there is a chance that the program's budget may be occasionally -/// and unpredictably exceeded. -/// -/// As all account addresses accessed by an on-chain Solana program must be -/// explicitly passed to the program, it is typical for the PDAs to be -/// derived in off-chain client programs, avoiding the compute cost of -/// generating the address on-chain. The address may or may not then be -/// verified by re-deriving it on-chain, depending on the requirements of -/// the program. This verification may be performed without the overhead of -/// re-searching for the bump key by using the [`create_program_address`] -/// function. -/// -/// [`create_program_address`]: crate::pubkey::create_program_address -/// -/// **Warning**: Because of the way the seeds are hashed there is a potential -/// for program address collisions for the same program id. The seeds are -/// hashed sequentially which means that seeds `"abcdef"`, `["abc", "def"]`, -/// and `["ab", "cd", "ef"]` will all result in the same program address given -/// the same program id. Since the chance of collision is local to a given -/// program id, the developer of that program must take care to choose seeds -/// that do not collide with each other. For seed schemes that are susceptible -/// to this type of hash collision, a common remedy is to insert separators -/// between seeds, e.g. transforming `["abc", "def"]` into `["abc", "-", "def"]`. -/// -/// # Panics -/// -/// Panics in the statistically improbable event that a bump seed could not be -/// found. Use [`try_find_program_address`] to handle this case. -/// -/// [`try_find_program_address`]: #try_find_program_address -/// -/// Panics if any of the following are true: -/// -/// - the number of provided seeds is greater than, _or equal to_, [`MAX_SEEDS`], -/// - any individual seed's length is greater than [`MAX_SEED_LEN`]. -#[inline(always)] -pub fn find_program_address(seeds: &[&[u8]], program_id: &Pubkey) -> (Pubkey, u8) { - try_find_program_address(seeds, program_id) - .unwrap_or_else(|| panic!("Unable to find a viable program address bump seed")) -} - -/// Find a valid [program derived address][pda] and its corresponding bump seed. -/// -/// [pda]: https://solana.com/docs/core/cpi#program-derived-addresses -/// -/// The only difference between this method and [`find_program_address`] -/// is that this one returns `None` in the statistically improbable event -/// that a bump seed cannot be found; or if any of `find_program_address`'s -/// preconditions are violated. -/// -/// See the documentation for [`find_program_address`] for a full description. -/// -/// [`find_program_address`]: #find_program_address -#[inline] -pub fn try_find_program_address(seeds: &[&[u8]], program_id: &Pubkey) -> Option<(Pubkey, u8)> { - #[cfg(target_os = "solana")] - { - let mut bytes = core::mem::MaybeUninit::<[u8; PUBKEY_BYTES]>::uninit(); - let mut bump_seed = u8::MAX; - - let result = unsafe { - crate::syscalls::sol_try_find_program_address( - seeds as *const _ as *const u8, - seeds.len() as u64, - program_id as *const _, - bytes.as_mut_ptr() as *mut _, - &mut bump_seed as *mut _, - ) - }; - match result { - // SAFETY: The syscall has initialized the bytes. - crate::SUCCESS => Some((unsafe { bytes.assume_init() }, bump_seed)), - _ => None, - } - } - - #[cfg(not(target_os = "solana"))] - { - core::hint::black_box((seeds, program_id)); - None - } -} - -/// Create a valid [program derived address][pda] without searching for a bump seed. -/// -/// [pda]: https://solana.com/docs/core/cpi#program-derived-addresses -/// -/// Because this function does not create a bump seed, it may unpredictably -/// return an error for any given set of seeds and is not generally suitable -/// for creating program derived addresses. -/// -/// However, it can be used for efficiently verifying that a set of seeds plus -/// bump seed generated by [`find_program_address`] derives a particular -/// address as expected. See the example for details. -/// -/// See the documentation for [`find_program_address`] for a full description -/// of program derived addresses and bump seeds. -/// -/// Note that this function does *not* validate whether the given `seeds` are within -/// the valid length or not. It will return an error in case of invalid seeds length, -/// incurring the cost of the syscall. -/// -/// [`find_program_address`]: #find_program_address -#[inline] -pub fn create_program_address( - seeds: &[&[u8]], - program_id: &Pubkey, -) -> Result { - // Call via a system call to perform the calculation - #[cfg(target_os = "solana")] - { - let mut bytes = core::mem::MaybeUninit::<[u8; PUBKEY_BYTES]>::uninit(); - - let result = unsafe { - crate::syscalls::sol_create_program_address( - seeds as *const _ as *const u8, - seeds.len() as u64, - program_id as *const _ as *const u8, - bytes.as_mut_ptr() as *mut u8, - ) - }; - - match result { - // SAFETY: The syscall has initialized the bytes. - crate::SUCCESS => Ok(unsafe { bytes.assume_init() }), - _ => Err(result.into()), - } - } - - #[cfg(not(target_os = "solana"))] - { - core::hint::black_box((seeds, program_id)); - panic!("create_program_address is only available on target `solana`") - } -} - -/// Create a valid [program derived address][pda] without searching for a bump seed. -/// -/// [pda]: https://solana.com/docs/core/cpi#program-derived-addresses -/// -/// Because this function does not create a bump seed, it may unpredictably -/// return an error for any given set of seeds and is not generally suitable -/// for creating program derived addresses. -/// -/// However, it can be used for efficiently verifying that a set of seeds plus -/// bump seed generated by [`find_program_address`] derives a particular -/// address as expected. See the example for details. -/// -/// See the documentation for [`find_program_address`] for a full description -/// of program derived addresses and bump seeds. -/// -/// Note that this function validates whether the given `seeds` are within the valid -/// length or not, returning an error without incurring the cost of the syscall. -/// -/// [`find_program_address`]: #find_program_address -#[inline(always)] -pub fn checked_create_program_address( - seeds: &[&[u8]], - program_id: &Pubkey, -) -> Result { - if seeds.len() > MAX_SEEDS { - return Err(ProgramError::MaxSeedLengthExceeded); - } - if seeds.iter().any(|seed| seed.len() > MAX_SEED_LEN) { - return Err(ProgramError::MaxSeedLengthExceeded); - } - - create_program_address(seeds, program_id) -} - -/// Derive a Pubkey from another Pubkey, seed, and a program id. -#[inline] -pub fn create_with_seed( - base: &Pubkey, - seed: &[u8], - program_id: &Pubkey, -) -> Result { - if seed.len() > MAX_SEED_LEN { - return Err(ProgramError::MaxSeedLengthExceeded); - } - - if program_id.ends_with(PDA_MARKER) { - return Err(ProgramError::IllegalOwner); - } - - #[cfg(target_os = "solana")] - { - let mut bytes = core::mem::MaybeUninit::<[u8; PUBKEY_BYTES]>::uninit(); - - let vals = &[base, seed, program_id]; - - unsafe { - crate::syscalls::sol_sha256( - vals as *const _ as *const u8, - vals.len() as u64, - bytes.as_mut_ptr() as *mut _, - ); - } - - // SAFETY: The syscall has initialized the bytes. - Ok(unsafe { bytes.assume_init() }) - } - - #[cfg(not(target_os = "solana"))] - { - core::hint::black_box((base, seed, program_id)); - panic!("create_with_seed is only available on target `solana`") - } -} - -#[cfg(test)] -mod tests { - use crate::pubkey::{pubkey_eq, Pubkey, PUBKEY_BYTES}; - - #[test] - fn test_pubkey_eq_matches_default_eq() { - for i in 0..u8::MAX { - let p1: Pubkey = [i; PUBKEY_BYTES]; - let p2: Pubkey = [i; PUBKEY_BYTES]; - - assert_eq!(pubkey_eq(&p1, &p2), p1 == p2); - } - - for i in 0..u8::MAX { - let p1: Pubkey = [i; PUBKEY_BYTES]; - let p2: Pubkey = [u8::MAX - i; PUBKEY_BYTES]; - - assert_eq!(!pubkey_eq(&p1, &p2), p1 != p2); - } - } -} diff --git a/sdk/pinocchio/src/syscalls.rs b/sdk/pinocchio/src/syscalls.rs index d48df695..cb3f7d9b 100644 --- a/sdk/pinocchio/src/syscalls.rs +++ b/sdk/pinocchio/src/syscalls.rs @@ -2,7 +2,7 @@ use crate::{ instruction::{AccountMeta, ProcessedSiblingInstruction}, - pubkey::Pubkey, + Address, }; #[cfg(target_feature = "static-syscalls")] @@ -61,9 +61,9 @@ define_syscall!(fn sol_memset_(s: *mut u8, c: u8, n: u64)); define_syscall!(fn sol_invoke_signed_c(instruction_addr: *const u8, account_infos_addr: *const u8, account_infos_len: u64, signers_seeds_addr: *const u8, signers_seeds_len: u64) -> u64); define_syscall!(fn sol_invoke_signed_rust(instruction_addr: *const u8, account_infos_addr: *const u8, account_infos_len: u64, signers_seeds_addr: *const u8, signers_seeds_len: u64) -> u64); define_syscall!(fn sol_set_return_data(data: *const u8, length: u64)); -define_syscall!(fn sol_get_return_data(data: *mut u8, length: u64, program_id: *mut Pubkey) -> u64); +define_syscall!(fn sol_get_return_data(data: *mut u8, length: u64, program_id: *mut u8) -> u64); define_syscall!(fn sol_log_data(data: *const u8, data_len: u64)); -define_syscall!(fn sol_get_processed_sibling_instruction(index: u64, meta: *mut ProcessedSiblingInstruction, program_id: *mut Pubkey, data: *mut u8, accounts: *mut AccountMeta) -> u64); +define_syscall!(fn sol_get_processed_sibling_instruction(index: u64, meta: *mut ProcessedSiblingInstruction, program_id: *mut Address, data: *mut u8, accounts: *mut AccountMeta) -> u64); define_syscall!(fn sol_get_stack_height() -> u64); define_syscall!(fn sol_curve_validate_point(curve_id: u64, point_addr: *const u8, result: *mut u8) -> u64); define_syscall!(fn sol_curve_group_op(curve_id: u64, group_op: u64, left_input_addr: *const u8, right_input_addr: *const u8, result_point_addr: *mut u8) -> u64); diff --git a/sdk/pinocchio/src/sysvars/clock.rs b/sdk/pinocchio/src/sysvars/clock.rs index 642be91b..99855079 100644 --- a/sdk/pinocchio/src/sysvars/clock.rs +++ b/sdk/pinocchio/src/sysvars/clock.rs @@ -5,15 +5,14 @@ use crate::{ account_info::{AccountInfo, Ref}, error::ProgramError, hint::unlikely, - impl_sysvar_get, - pubkey::{pubkey_eq, Pubkey}, + impl_sysvar_get, Address, }; /// The ID of the clock sysvar. -pub const CLOCK_ID: Pubkey = [ +pub const CLOCK_ID: Address = Address::new_from_array([ 6, 167, 213, 23, 24, 199, 116, 201, 40, 86, 99, 152, 105, 29, 94, 182, 139, 94, 184, 163, 155, 75, 109, 92, 115, 85, 91, 33, 0, 0, 0, 0, -]; +]); /// The unit of time given to a leader for encoding a block. /// @@ -34,7 +33,8 @@ pub type UnixTimestamp = i64; /// /// All members of `Clock` start from 0 upon network boot. #[repr(C)] -#[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug)] pub struct Clock { /// The current `Slot`. pub slot: Slot, @@ -87,7 +87,7 @@ impl Clock { /// This method performs a check on the account info key. #[inline] pub fn from_account_info(account_info: &AccountInfo) -> Result, ProgramError> { - if unlikely(!pubkey_eq(account_info.key(), &CLOCK_ID)) { + if unlikely(account_info.key() != &CLOCK_ID) { return Err(ProgramError::InvalidArgument); } Ok(Ref::map(account_info.try_borrow_data()?, |data| unsafe { @@ -108,7 +108,7 @@ impl Clock { pub unsafe fn from_account_info_unchecked( account_info: &AccountInfo, ) -> Result<&Self, ProgramError> { - if unlikely(!pubkey_eq(account_info.key(), &CLOCK_ID)) { + if unlikely(account_info.key() != &CLOCK_ID) { return Err(ProgramError::InvalidArgument); } Ok(Self::from_bytes_unchecked( diff --git a/sdk/pinocchio/src/sysvars/fees.rs b/sdk/pinocchio/src/sysvars/fees.rs index 1a166426..f7a29ad4 100644 --- a/sdk/pinocchio/src/sysvars/fees.rs +++ b/sdk/pinocchio/src/sysvars/fees.rs @@ -4,7 +4,8 @@ use super::{clock::DEFAULT_MS_PER_SLOT, Sysvar}; use crate::impl_sysvar_get; /// Fee calculator for processing transactions -#[derive(Debug, Clone, Copy)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug)] pub struct FeeCalculator { /// The current cost of a signature in lamports. /// This amount may increase/decrease over time based on cluster processing @@ -22,7 +23,8 @@ impl FeeCalculator { } /// Governs the fee rate for the cluster -#[derive(Debug, Clone, Copy)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug)] pub struct FeeRateGovernor { /// The current cost of a signature pub lamports_per_signature: u64, @@ -74,7 +76,8 @@ impl FeeRateGovernor { } /// Fees sysvar -#[derive(Copy, Clone, Debug)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug)] pub struct Fees { /// Fee calculator for processing transactions pub fee_calculator: FeeCalculator, diff --git a/sdk/pinocchio/src/sysvars/instructions.rs b/sdk/pinocchio/src/sysvars/instructions.rs index 188142eb..66f2a8ef 100644 --- a/sdk/pinocchio/src/sysvars/instructions.rs +++ b/sdk/pinocchio/src/sysvars/instructions.rs @@ -1,19 +1,19 @@ use crate::{ account_info::{AccountInfo, Ref}, + address::{Address, ADDRESS_BYTES}, error::ProgramError, instruction::AccountMeta, - pubkey::{Pubkey, PUBKEY_BYTES}, }; use core::{marker::PhantomData, mem::size_of, ops::Deref}; /// Instructions sysvar ID `Sysvar1nstructions1111111111111111111111111`. -pub const INSTRUCTIONS_ID: Pubkey = [ +pub const INSTRUCTIONS_ID: Address = Address::new_from_array([ 0x06, 0xa7, 0xd5, 0x17, 0x18, 0x7b, 0xd1, 0x66, 0x35, 0xda, 0xd4, 0x04, 0x55, 0xfd, 0xc2, 0xc0, 0xc1, 0x24, 0xc6, 0x8f, 0x21, 0x56, 0x75, 0xa5, 0xdb, 0xba, 0xcb, 0x5f, 0x08, 0x00, 0x00, 0x00, -]; +]); -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Debug)] pub struct Instructions where T: Deref, @@ -126,6 +126,7 @@ impl<'a> TryFrom<&'a AccountInfo> for Instructions> { } #[repr(C)] +#[cfg_attr(feature = "copy", derive(Copy))] #[derive(Clone, Debug, Eq, PartialEq)] pub struct IntrospectedInstruction<'a> { pub raw: *const u8, @@ -171,7 +172,7 @@ impl IntrospectedInstruction<'_> { /// Get the program ID of the `Instruction`. #[inline(always)] - pub fn get_program_id(&self) -> &Pubkey { + pub fn get_program_id(&self) -> &Address { // SAFETY: The first 2 bytes represent the number of accounts in the instruction. let num_accounts = u16::from_le_bytes(unsafe { *(self.raw as *const [u8; 2]) }); @@ -179,7 +180,7 @@ impl IntrospectedInstruction<'_> { unsafe { &*(self.raw.add( size_of::() + num_accounts as usize * size_of::(), - ) as *const Pubkey) + ) as *const Address) } } @@ -189,7 +190,7 @@ impl IntrospectedInstruction<'_> { // SAFETY: The first 2 bytes represent the number of accounts in the instruction. let offset = u16::from_le_bytes(unsafe { *(self.raw as *const [u8; 2]) }) as usize * size_of::() - + PUBKEY_BYTES; + + ADDRESS_BYTES; // SAFETY: The instruction data length is located after the program ID. let data_len = u16::from_le_bytes(unsafe { @@ -213,7 +214,8 @@ const IS_SIGNER: u8 = 0b00000001; const IS_WRITABLE: u8 = 0b00000010; #[repr(C)] -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct IntrospectedAccountMeta { /// Account flags: /// * bit `0`: signer @@ -221,7 +223,7 @@ pub struct IntrospectedAccountMeta { flags: u8, /// The account key. - pub key: Pubkey, + pub key: Address, } impl IntrospectedAccountMeta { diff --git a/sdk/pinocchio/src/sysvars/mod.rs b/sdk/pinocchio/src/sysvars/mod.rs index e252339a..c8d86f1c 100644 --- a/sdk/pinocchio/src/sysvars/mod.rs +++ b/sdk/pinocchio/src/sysvars/mod.rs @@ -1,11 +1,12 @@ //! Provides access to cluster system accounts. -#[cfg(target_os = "solana")] -use crate::syscalls::sol_get_sysvar; -use crate::{error::ProgramError, pubkey::Pubkey}; #[cfg(not(target_os = "solana"))] use core::hint::black_box; +#[cfg(target_os = "solana")] +use crate::syscalls::sol_get_sysvar; +use crate::{error::ProgramError, Address}; + pub mod clock; pub mod fees; pub mod instructions; @@ -76,7 +77,7 @@ macro_rules! impl_sysvar_get { #[inline] pub unsafe fn get_sysvar_unchecked( dst: *mut u8, - sysvar_id: &Pubkey, + sysvar_id: &Address, offset: usize, len: usize, ) -> Result<(), ProgramError> { @@ -110,7 +111,7 @@ pub unsafe fn get_sysvar_unchecked( /// Handler for retrieving a slice of sysvar data from the `sol_get_sysvar` /// syscall. #[inline(always)] -pub fn get_sysvar(dst: &mut [u8], sysvar_id: &Pubkey, offset: usize) -> Result<(), ProgramError> { +pub fn get_sysvar(dst: &mut [u8], sysvar_id: &Address, offset: usize) -> Result<(), ProgramError> { // SAFETY: Use the length of the slice as the length parameter. unsafe { get_sysvar_unchecked(dst.as_mut_ptr(), sysvar_id, offset, dst.len()) } } diff --git a/sdk/pinocchio/src/sysvars/rent.rs b/sdk/pinocchio/src/sysvars/rent.rs index f74c6645..da8c9307 100644 --- a/sdk/pinocchio/src/sysvars/rent.rs +++ b/sdk/pinocchio/src/sysvars/rent.rs @@ -2,20 +2,20 @@ //! //! This is required for the rent sysvar implementation. -use super::Sysvar; use crate::{ account_info::{AccountInfo, Ref}, error::ProgramError, hint::unlikely, impl_sysvar_get, - pubkey::{pubkey_eq, Pubkey}, + sysvars::Sysvar, + Address, }; /// The ID of the rent sysvar. -pub const RENT_ID: Pubkey = [ +pub const RENT_ID: Address = Address::new_from_array([ 6, 167, 213, 23, 25, 44, 92, 81, 33, 140, 201, 76, 61, 74, 241, 127, 88, 218, 238, 8, 155, 161, 253, 68, 227, 219, 217, 138, 0, 0, 0, 0, -]; +]); /// Default rental rate in lamports/byte-year. /// @@ -53,7 +53,8 @@ pub const ACCOUNT_STORAGE_OVERHEAD: u64 = 128; /// Rent sysvar data #[repr(C)] -#[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug)] pub struct Rent { /// Rental rate in lamports per byte-year pub lamports_per_byte_year: u64, @@ -74,7 +75,7 @@ impl Rent { /// This method performs a check on the account info key. #[inline] pub fn from_account_info(account_info: &AccountInfo) -> Result, ProgramError> { - if unlikely(!pubkey_eq(account_info.key(), &RENT_ID)) { + if unlikely(account_info.key() != &RENT_ID) { return Err(ProgramError::InvalidArgument); } Ok(Ref::map(account_info.try_borrow_data()?, |data| unsafe { @@ -95,7 +96,7 @@ impl Rent { pub unsafe fn from_account_info_unchecked( account_info: &AccountInfo, ) -> Result<&Self, ProgramError> { - if unlikely(!pubkey_eq(account_info.key(), &RENT_ID)) { + if unlikely(account_info.key() != &RENT_ID) { return Err(ProgramError::InvalidArgument); } Ok(Self::from_bytes_unchecked( @@ -211,7 +212,8 @@ impl Sysvar for Rent { } /// The return value of [`Rent::due`]. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum RentDue { /// Used to indicate the account is rent exempt. Exempt, diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs b/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs index 0ce462d4..23db76e6 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs @@ -17,18 +17,18 @@ use crate::{ account_info::{AccountInfo, Ref}, error::ProgramError, hint::unlikely, - pubkey::{pubkey_eq, Pubkey}, sysvars::clock::Slot, + Address, }; use core::{mem, ops::Deref, slice::from_raw_parts}; #[cfg(feature = "std")] use std::boxed::Box; /// `SysvarS1otHashes111111111111111111111111111` -pub const SLOTHASHES_ID: Pubkey = [ +pub const SLOTHASHES_ID: Address = Address::new_from_array([ 6, 167, 213, 23, 25, 47, 10, 175, 198, 242, 101, 227, 251, 119, 204, 122, 218, 130, 197, 41, 208, 190, 59, 19, 110, 45, 0, 85, 32, 0, 0, 0, -]; +]); /// Number of bytes in a hash. pub const HASH_BYTES: usize = 32; /// Sysvar data is: @@ -48,7 +48,8 @@ pub const MAX_SIZE: usize = NUM_ENTRIES_SIZE + MAX_ENTRIES * ENTRY_SIZE; pub type Hash = [u8; HASH_BYTES]; /// A single entry in the `SlotHashes` sysvar. -#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Eq, Debug, PartialEq)] #[repr(C)] pub struct SlotHashEntry { /// The slot number stored as little-endian bytes. @@ -68,7 +69,14 @@ pub struct SlotHashes> { /// Log a `Hash` from a program. pub fn log(hash: &Hash) { - crate::pubkey::log(hash); + #[cfg(target_os = "solana")] + // SAFETY: `sol_log_pubkey` expects a valid pointer to a 32-byte array. + unsafe { + solana_address::syscalls::sol_log_pubkey(hash.as_ptr()) + }; + + #[cfg(not(target_os = "solana"))] + core::hint::black_box(hash); } /// Reads the entry count from the first 8 bytes of data. @@ -278,7 +286,7 @@ impl<'a> SlotHashes> { /// - `ProgramError::AccountBorrowFailed` if the account data is already mutably borrowed #[inline(always)] pub fn from_account_info(account_info: &'a AccountInfo) -> Result { - if unlikely(!pubkey_eq(account_info.key(), &SLOTHASHES_ID)) { + if unlikely(account_info.key() != &SLOTHASHES_ID) { return Err(ProgramError::InvalidArgument); } diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/test.rs b/sdk/pinocchio/src/sysvars/slot_hashes/test.rs index 4c15f95b..bf473ada 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/test.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/test.rs @@ -22,12 +22,12 @@ fn test_layout_constants() { assert_eq!(MAX_SIZE, 20_488); assert_eq!(size_of::(), ENTRY_SIZE); assert_eq!(align_of::(), align_of::<[u8; 8]>()); - assert_eq!( - SLOTHASHES_ID, - [ - 6, 167, 213, 23, 25, 47, 10, 175, 198, 242, 101, 227, 251, 119, 204, 122, 218, 130, - 197, 41, 208, 190, 59, 19, 110, 45, 0, 85, 32, 0, 0, 0, - ] + assert!( + SLOTHASHES_ID + == Address::new_from_array([ + 6, 167, 213, 23, 25, 47, 10, 175, 198, 242, 101, 227, 251, 119, 204, 122, 218, 130, + 197, 41, 208, 190, 59, 19, 110, 45, 0, 85, 32, 0, 0, 0, + ]) ); pub fn check_base58(input_bytes: &[u8], expected_b58: &str) { @@ -35,7 +35,7 @@ fn test_layout_constants() { } check_base58( - &SLOTHASHES_ID, + SLOTHASHES_ID.as_array(), "SysvarS1otHashes111111111111111111111111111", ); } @@ -430,7 +430,7 @@ fn test_from_account_info_constructor() { executable: 0, resize_delta: 0, key: SLOTHASHES_ID, - owner: [0u8; 32], + owner: Address::new_from_array([0u8; 32]), lamports: 0, data_len: data.len() as u64, }, diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/test_edge.rs b/sdk/pinocchio/src/sysvars/slot_hashes/test_edge.rs index 55fa5438..8fb18bc8 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/test_edge.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/test_edge.rs @@ -5,8 +5,13 @@ use super::test_utils::{build_slot_hashes_bytes as raw_slot_hashes, make_account #[test] fn test_wrong_key_from_account_info() { let bytes = raw_slot_hashes(0, &[]); - let (info, _backing) = - unsafe { make_account_info([1u8; 32], &bytes, crate::entrypoint::NON_DUP_MARKER) }; + let (info, _backing) = unsafe { + make_account_info( + Address::new_from_array([1u8; 32]), + &bytes, + crate::entrypoint::NON_DUP_MARKER, + ) + }; assert!(matches!( SlotHashes::from_account_info(&info), Err(ProgramError::InvalidArgument) diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/test_utils.rs b/sdk/pinocchio/src/sysvars/slot_hashes/test_utils.rs index 203f1199..8729e880 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/test_utils.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/test_utils.rs @@ -5,7 +5,6 @@ use super::*; extern crate std; use crate::account_info::{Account, AccountInfo}; -use crate::pubkey::Pubkey; use core::{mem, ptr}; use std::vec::Vec; @@ -13,15 +12,16 @@ use std::vec::Vec; /// Account fields are private, so this struct allows more readable /// use of them in tests. #[repr(C)] -#[derive(Clone, Copy)] +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone)] pub struct AccountLayout { pub borrow_state: u8, pub is_signer: u8, pub is_writable: u8, pub executable: u8, pub resize_delta: i32, - pub key: Pubkey, - pub owner: Pubkey, + pub key: Address, + pub owner: Address, pub lamports: u64, pub data_len: u64, } @@ -117,7 +117,7 @@ pub fn create_mock_data(entries: &[(u64, Hash)]) -> Vec { /// or according to borrow rules because the Solana runtime invariants are not /// fully enforced in this hand-rolled representation. pub unsafe fn make_account_info( - key: Pubkey, + key: Address, data: &[u8], borrow_state: u8, ) -> (AccountInfo, Vec) { @@ -140,7 +140,7 @@ pub unsafe fn make_account_info( executable: 0, resize_delta: 0, key, - owner: [0u8; 32], + owner: Address::new_from_array([0u8; 32]), lamports: 0, data_len: data.len() as u64, }, @@ -181,8 +181,8 @@ fn test_account_layout_compatibility() { is_writable: 1, executable: 0, resize_delta: 100, - key: [1u8; 32], - owner: [2u8; 32], + key: Address::new_from_array([1u8; 32]), + owner: Address::new_from_array([2u8; 32]), lamports: 1000, data_len: 256, }; diff --git a/sdk/pubkey/Cargo.toml b/sdk/pubkey/Cargo.toml deleted file mode 100644 index e1528b86..00000000 --- a/sdk/pubkey/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "pinocchio-pubkey" -description = "Companion pubkey helpers for Pinocchio" -version = "0.3.0" -edition = { workspace = true } -license = { workspace = true } -readme = "./README.md" -repository = { workspace = true } -rust-version = { workspace = true } - -[lib] -crate-type = ["rlib"] - -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = [ - 'cfg(target_os, values("solana"))', -] } - -[features] -default = ["const"] -const = ["dep:five8_const", "dep:sha2-const-stable"] - -[dependencies] -five8_const = { workspace = true, optional = true } -sha2-const-stable = { version = "0.1.0", optional = true } -pinocchio = { workspace = true } diff --git a/sdk/pubkey/README.md b/sdk/pubkey/README.md deleted file mode 100644 index 9d3aaf9d..00000000 --- a/sdk/pubkey/README.md +++ /dev/null @@ -1,57 +0,0 @@ -

- pinocchio-pubkey -

-

- pinocchio-pubkey -

-

- Companion Pubkey helpers for pinocchio. -

-

- - -

- -## Overview - -This crate provides two convenience macros to resolve `Pubkey`s at compile time: - -* `pubkey!`: takes a pubkey value as a base58 `&str` and generates its correspondent `Pubkey` (byte array) -* `declare_id!`: takes a pubkey value as a base58 `&str` (usually representing a program address) and generates an `ID` constant, `check_id()` and `id()` helpers - -It also defines a `from_str` helper that takes a `&str` and returns the correspondent `Pubkey` value. - -## Examples - -Once the project is built the first time with `cargo build-sbf`, a new keypair is automatically generated. A public key can be retrieved with: -```bash -solana-keygen pubkey ./target/deploy/your_program-keypair.json -``` - -Instead of the autogenerated keypair, a [vanity key](https://solana.com/developers/cookbook/wallets/generate-vanity-address) can be used. You can move the vanity keypair to `./target/deploy/your_program-keypair.json`. - -Remember to back up the keypair file securely, it is necessary for deploy the program. - -Public keys can be embedded into the program code in the following ways. - -1) Creating a `Pubkey` constant value from a static `&str`: -```rust -use pinocchio::pubkey::Pubkey; - -pub const AUTHORITY: Pubkey = pinocchio_pubkey::pubkey!("7qtAvP4CJuSKauWHtHZJt9wmQRgvcFeUcU3xKrFzxKf1"); -``` - -2) Declaring the program address of a program (usually on your `lib.rs`): -```rust -pinocchio_pubkey::declare_id!("Ping111111111111111111111111111111111111111"); -``` - -3) Creating a `Pubkey` from a `&str`: -```rust -let address = String::from("7qtAvP4CJuSKauWHtHZJt9wmQRgvcFeUcU3xKrFzxKf1"); -let owner = pinocchio_pubkey::from_str(&address); -``` - -## License - -The code is licensed under the [Apache License Version 2.0](../LICENSE) diff --git a/sdk/pubkey/src/lib.rs b/sdk/pubkey/src/lib.rs deleted file mode 100644 index 18f096c4..00000000 --- a/sdk/pubkey/src/lib.rs +++ /dev/null @@ -1,195 +0,0 @@ -#![no_std] - -#[cfg(feature = "const")] -#[doc(hidden)] -// Re-export dependencies used in macros. -pub mod reexport { - pub use pinocchio::pubkey::{pubkey_eq, Pubkey}; -} - -use core::mem::MaybeUninit; -#[cfg(feature = "const")] -pub use five8_const::decode_32_const; -use pinocchio::pubkey::{Pubkey, MAX_SEEDS, PDA_MARKER}; -#[cfg(target_os = "solana")] -use pinocchio::syscalls::sol_sha256; -#[cfg(feature = "const")] -use sha2_const_stable::Sha256; - -/// Derive a [program address][pda] from the given seeds, optional bump and -/// program id. -/// -/// [pda]: https://solana.com/docs/core/pda -/// -/// In general, the derivation uses an optional bump (byte) value to ensure a -/// valid PDA (off-curve) is generated. Even when a program stores a bump to -/// derive a program address, it is necessary to use the -/// [`pinocchio::pubkey::create_program_address`] to validate the derivation. In -/// most cases, the program has the correct seeds for the derivation, so it would -/// be sufficient to just perform the derivation and compare it against the -/// expected resulting address. -/// -/// This function avoids the cost of the `create_program_address` syscall -/// (`1500` compute units) by directly computing the derived address -/// calculating the hash of the seeds, bump and program id using the -/// `sol_sha256` syscall. -/// -/// # Important -/// -/// This function differs from [`pinocchio::pubkey::create_program_address`] in that -/// it does not perform a validation to ensure that the derived address is a valid -/// (off-curve) program derived address. It is intended for use in cases where the -/// seeds, bump, and program id are known to be valid, and the caller wants to derive -/// the address without incurring the cost of the `create_program_address` syscall. -pub fn derive_address( - seeds: &[&[u8]; N], - bump: Option, - program_id: &Pubkey, -) -> Pubkey { - const { - assert!(N < MAX_SEEDS, "number of seeds must be less than MAX_SEEDS"); - } - - const UNINIT: MaybeUninit<&[u8]> = MaybeUninit::<&[u8]>::uninit(); - let mut data = [UNINIT; MAX_SEEDS + 2]; - let mut i = 0; - - while i < N { - // SAFETY: `data` is guaranteed to have enough space for `N` seeds, - // so `i` will always be within bounds. - unsafe { - data.get_unchecked_mut(i).write(seeds.get_unchecked(i)); - } - i += 1; - } - - // TODO: replace this with `as_slice` when the MSRV is upgraded - // to `1.84.0+`. - let bump_seed = [bump.unwrap_or_default()]; - - // SAFETY: `data` is guaranteed to have enough space for `MAX_SEEDS + 2` - // elements, and `MAX_SEEDS` is as large as `N`. - unsafe { - if bump.is_some() { - data.get_unchecked_mut(i).write(&bump_seed); - i += 1; - } - data.get_unchecked_mut(i).write(program_id.as_ref()); - data.get_unchecked_mut(i + 1).write(PDA_MARKER.as_ref()); - } - - #[cfg(target_os = "solana")] - { - let mut pda = MaybeUninit::<[u8; 32]>::uninit(); - - // SAFETY: `data` has `i + 2` elements initialized. - unsafe { - sol_sha256( - data.as_ptr() as *const u8, - (i + 2) as u64, - pda.as_mut_ptr() as *mut u8, - ); - } - - // SAFETY: `pda` has been initialized by the syscall. - unsafe { pda.assume_init() } - } - - #[cfg(not(target_os = "solana"))] - unreachable!("deriving a pda is only available on target `solana`"); -} - -/// Derive a [program address][pda] from the given seeds, optional bump and -/// program id. -/// -/// [pda]: https://solana.com/docs/core/pda -/// -/// In general, the derivation uses an optional bump (byte) value to ensure a -/// valid PDA (off-curve) is generated. -/// -/// This function is intended for use in `const` contexts - i.e., the seeds and -/// bump are known at compile time and the program id is also a constant. It avoids -/// the cost of the `create_program_address` syscall (`1500` compute units) by -/// directly computing the derived address using the SHA-256 hash of the seeds, -/// bump and program id. -/// -/// # Important -/// -/// This function differs from [`pinocchio::pubkey::create_program_address`] in that -/// it does not perform a validation to ensure that the derived address is a valid -/// (off-curve) program derived address. It is intended for use in cases where the -/// seeds, bump, and program id are known to be valid, and the caller wants to derive -/// the address without incurring the cost of the `create_program_address` syscall. -/// -/// This function is a compile-time constant version of [`derive_address`]. -#[cfg(feature = "const")] -pub const fn derive_address_const( - seeds: &[&[u8]; N], - bump: Option, - program_id: &Pubkey, -) -> Pubkey { - const { - assert!(N < MAX_SEEDS, "number of seeds must be less than MAX_SEEDS"); - } - - let mut hasher = Sha256::new(); - let mut i = 0; - - while i < seeds.len() { - hasher = hasher.update(seeds[i]); - i += 1; - } - - // TODO: replace this with `is_some` when the MSRV is upgraded - // to `1.84.0+`. - if let Some(bump) = bump { - hasher - .update(&[bump]) - .update(program_id) - .update(PDA_MARKER) - .finalize() - } else { - hasher.update(program_id).update(PDA_MARKER).finalize() - } -} - -/// Convenience macro to define a static `Pubkey` value. -#[cfg(feature = "const")] -#[macro_export] -macro_rules! pubkey { - ( $id:literal ) => { - $crate::from_str($id) - }; -} - -/// Convenience macro to define a static `Pubkey` value representing the program ID. -/// -/// This macro also defines a helper function to check whether a given pubkey is -/// equal to the program ID. -#[cfg(feature = "const")] -#[macro_export] -macro_rules! declare_id { - ( $id:expr ) => { - #[doc = "The constant program ID."] - pub const ID: $crate::reexport::Pubkey = $crate::from_str($id); - - #[doc = "Returns `true` if given pubkey is the program ID."] - #[inline] - pub fn check_id(id: &$crate::reexport::Pubkey) -> bool { - $crate::reexport::pubkey_eq(id, &ID) - } - - #[doc = "Returns the program ID."] - #[inline] - pub const fn id() -> $crate::reexport::Pubkey { - ID - } - }; -} - -/// Create a `Pubkey` from a `&str`. -#[cfg(feature = "const")] -#[inline(always)] -pub const fn from_str(value: &str) -> Pubkey { - decode_32_const(value) -}