diff --git a/Cargo.lock b/Cargo.lock index faa8e1f2..a96f0a1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,6 +57,7 @@ dependencies = [ "five8_const 0.1.4", "solana-account-view", "solana-address", + "solana-instruction-view", "solana-program-error", ] @@ -64,8 +65,10 @@ dependencies = [ name = "pinocchio-associated-token-account" version = "0.2.0" dependencies = [ - "pinocchio", + "solana-account-view", "solana-address", + "solana-instruction-view", + "solana-program-error", ] [[package]] @@ -88,8 +91,10 @@ dependencies = [ name = "pinocchio-memo" version = "0.2.0" dependencies = [ - "pinocchio", + "solana-account-view", "solana-address", + "solana-instruction-view", + "solana-program-error", ] [[package]] @@ -97,23 +102,30 @@ name = "pinocchio-system" version = "0.3.0" dependencies = [ "pinocchio", + "solana-account-view", "solana-address", + "solana-instruction-view", + "solana-program-error", ] [[package]] name = "pinocchio-token" version = "0.4.0" dependencies = [ - "pinocchio", + "solana-account-view", "solana-address", + "solana-instruction-view", + "solana-program-error", ] [[package]] name = "pinocchio-token-2022" version = "0.1.0" dependencies = [ - "pinocchio", + "solana-account-view", "solana-address", + "solana-instruction-view", + "solana-program-error", ] [[package]] @@ -166,7 +178,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "solana-account-view" version = "0.0.0" -source = "git+https://github.com/febo/solana-sdk.git?branch=solana-account-view#7d4d8b0f2f484a68901bf148f53e1c9552596057" +source = "git+https://github.com/febo/solana-sdk.git?branch=solana-instruction-view#88a90e9c5144dbab669d670c158277326dce118d" dependencies = [ "solana-address", "solana-program-error", @@ -175,7 +187,7 @@ dependencies = [ [[package]] name = "solana-address" version = "1.0.0" -source = "git+https://github.com/febo/solana-sdk.git?branch=solana-account-view#117e66ac2874fbfa119ef650e06f57b94e98482d" +source = "git+https://github.com/febo/solana-sdk.git?branch=solana-instruction-view#88a90e9c5144dbab669d670c158277326dce118d" dependencies = [ "five8", "five8_const 1.0.0", @@ -186,12 +198,23 @@ dependencies = [ [[package]] name = "solana-define-syscall" version = "3.0.0" -source = "git+https://github.com/febo/solana-sdk.git?branch=solana-account-view#117e66ac2874fbfa119ef650e06f57b94e98482d" +source = "git+https://github.com/febo/solana-sdk.git?branch=solana-instruction-view#88a90e9c5144dbab669d670c158277326dce118d" + +[[package]] +name = "solana-instruction-view" +version = "0.0.0" +source = "git+https://github.com/febo/solana-sdk.git?branch=solana-instruction-view#88a90e9c5144dbab669d670c158277326dce118d" +dependencies = [ + "solana-account-view", + "solana-address", + "solana-define-syscall", + "solana-program-error", +] [[package]] name = "solana-program-error" version = "3.0.0" -source = "git+https://github.com/febo/solana-sdk.git?branch=solana-account-view#117e66ac2874fbfa119ef650e06f57b94e98482d" +source = "git+https://github.com/febo/solana-sdk.git?branch=solana-instruction-view#88a90e9c5144dbab669d670c158277326dce118d" [[package]] name = "syn" diff --git a/Cargo.toml b/Cargo.toml index b1e68741..3002b4b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,10 @@ pinocchio = { version = "0.9", path = "sdk/pinocchio" } pinocchio-log-macro = { version = "0.5", path = "sdk/log/macro" } quote = "1.0" regex = "1" -solana-account-view = { version = "0.0.0", git = "https://github.com/febo/solana-sdk.git", branch = "solana-account-view" } -solana-address = { version = "1.0", git = "https://github.com/febo/solana-sdk.git", branch = "solana-account-view" } +solana-account-view = { version = "0.0.0", git = "https://github.com/febo/solana-sdk.git", branch = "solana-instruction-view" } +solana-address = { version = "1.0", git = "https://github.com/febo/solana-sdk.git", branch = "solana-instruction-view" } +solana-instruction-view = { version = "0.0.0", git = "https://github.com/febo/solana-sdk.git", branch = "solana-instruction-view" } +solana-program-error = { version = "3.0.0", git = "https://github.com/febo/solana-sdk.git", branch = "solana-instruction-view" } syn = "1.0" [workspace.metadata.cli] diff --git a/programs/associated-token-account/Cargo.toml b/programs/associated-token-account/Cargo.toml index 2b533c97..7949c16b 100644 --- a/programs/associated-token-account/Cargo.toml +++ b/programs/associated-token-account/Cargo.toml @@ -12,5 +12,7 @@ rust-version = { workspace = true } crate-type = ["rlib"] [dependencies] -pinocchio = { workspace = true } +solana-account-view = { workspace = true } solana-address = { workspace = true, features = ["decode"] } +solana-instruction-view = { workspace = true, features = ["cpi"] } +solana-program-error = { workspace = true } diff --git a/programs/associated-token-account/src/instructions/create.rs b/programs/associated-token-account/src/instructions/create.rs index 2d9c05ee..1d073634 100644 --- a/programs/associated-token-account/src/instructions/create.rs +++ b/programs/associated-token-account/src/instructions/create.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Creates an associated token account for the given wallet address and token mint. /// Returns an error if the account exists. @@ -39,13 +39,13 @@ impl Create<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 6] = [ - AccountMeta::writable_signer(self.funding_account.address()), - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.wallet.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly(self.system_program.address()), - AccountMeta::readonly(self.token_program.address()), + let account_metas: [AccountRole; 6] = [ + AccountRole::writable_signer(self.funding_account.address()), + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.wallet.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly(self.system_program.address()), + AccountRole::readonly(self.token_program.address()), ]; // Instruction data: @@ -53,7 +53,7 @@ impl Create<'_> { let instruction_data = [0u8]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data, diff --git a/programs/associated-token-account/src/instructions/create_idempotent.rs b/programs/associated-token-account/src/instructions/create_idempotent.rs index 6d6a293b..23ce728a 100644 --- a/programs/associated-token-account/src/instructions/create_idempotent.rs +++ b/programs/associated-token-account/src/instructions/create_idempotent.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Creates an associated token account for the given wallet address and /// token mint, if it doesn't already exist. Returns an error if the @@ -40,13 +40,13 @@ impl CreateIdempotent<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 6] = [ - AccountMeta::writable_signer(self.funding_account.address()), - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.wallet.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly(self.system_program.address()), - AccountMeta::readonly(self.token_program.address()), + let account_metas: [AccountRole; 6] = [ + AccountRole::writable_signer(self.funding_account.address()), + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.wallet.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly(self.system_program.address()), + AccountRole::readonly(self.token_program.address()), ]; // Instruction data: @@ -54,7 +54,7 @@ impl CreateIdempotent<'_> { let instruction_data = [1u8]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data, diff --git a/programs/associated-token-account/src/instructions/recover_nested.rs b/programs/associated-token-account/src/instructions/recover_nested.rs index b4f70e0e..eeac22ad 100644 --- a/programs/associated-token-account/src/instructions/recover_nested.rs +++ b/programs/associated-token-account/src/instructions/recover_nested.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Transfers from and closes a nested associated token account: an /// associated token account owned by an associated token account. @@ -50,14 +50,14 @@ impl RecoverNested<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 7] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::writable(self.destination_account.address()), - AccountMeta::readonly(self.owner_account.address()), - AccountMeta::readonly(self.owner_mint.address()), - AccountMeta::writable_signer(self.wallet.address()), - AccountMeta::readonly(self.token_program.address()), + let account_metas: [AccountRole; 7] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::writable(self.destination_account.address()), + AccountRole::readonly(self.owner_account.address()), + AccountRole::readonly(self.owner_mint.address()), + AccountRole::writable_signer(self.wallet.address()), + AccountRole::readonly(self.token_program.address()), ]; // Instruction data: @@ -65,7 +65,7 @@ impl RecoverNested<'_> { let instruction_data = [2u8]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data, diff --git a/programs/memo/Cargo.toml b/programs/memo/Cargo.toml index 4809ff33..647fc5ae 100644 --- a/programs/memo/Cargo.toml +++ b/programs/memo/Cargo.toml @@ -12,5 +12,7 @@ rust-version = { workspace = true } crate-type = ["rlib"] [dependencies] -pinocchio = { workspace = true } +solana-account-view = { workspace = true } solana-address = { workspace = true, features = ["decode"] } +solana-instruction-view = { workspace = true, features = ["cpi"] } +solana-program-error = { workspace = true } diff --git a/programs/memo/src/instructions/mod.rs b/programs/memo/src/instructions/mod.rs index a1ac9d27..f75d81b2 100644 --- a/programs/memo/src/instructions/mod.rs +++ b/programs/memo/src/instructions/mod.rs @@ -1,12 +1,11 @@ use core::mem::MaybeUninit; -use pinocchio::{ - account::AccountView, - cpi::{slice_invoke_signed, MAX_CPI_ACCOUNTS}, - error::ProgramError, - instruction::{AccountMeta, Instruction, Signer}, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{slice_invoke_signed, Signer, MAX_CPI_ACCOUNTS}, + AccountRole, InstructionView, }; +use solana_program_error::{ProgramError, ProgramResult}; /// Memo instruction. /// @@ -27,7 +26,7 @@ impl Memo<'_, '_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers_seeds: &[Signer]) -> ProgramResult { - const UNINIT_META: MaybeUninit = MaybeUninit::::uninit(); + const UNINIT_META: MaybeUninit = MaybeUninit::::uninit(); // We don't know num_accounts at compile time, so we use MAX_CPI_ACCOUNTS let mut account_metas = [UNINIT_META; MAX_CPI_ACCOUNTS]; @@ -43,14 +42,14 @@ impl Memo<'_, '_, '_> { // SAFETY: i is less than len(self.signers) account_metas .get_unchecked_mut(i) - .write(AccountMeta::readonly_signer( + .write(AccountRole::readonly_signer( self.signers.get_unchecked(i).address(), )); } } // SAFETY: len(account_metas) <= MAX_CPI_ACCOUNTS - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: unsafe { core::slice::from_raw_parts(account_metas.as_ptr() as _, num_accounts) diff --git a/programs/system/Cargo.toml b/programs/system/Cargo.toml index 738eb450..b49b27dc 100644 --- a/programs/system/Cargo.toml +++ b/programs/system/Cargo.toml @@ -13,4 +13,7 @@ crate-type = ["rlib"] [dependencies] pinocchio = { workspace = true } +solana-account-view = { workspace = true } solana-address = { workspace = true, features = ["decode"] } +solana-instruction-view = { workspace = true, features = ["cpi"] } +solana-program-error = { workspace = true } diff --git a/programs/system/src/instructions/advance_nonce_account.rs b/programs/system/src/instructions/advance_nonce_account.rs index c6e30777..11f7a374 100644 --- a/programs/system/src/instructions/advance_nonce_account.rs +++ b/programs/system/src/instructions/advance_nonce_account.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Consumes a stored nonce, replacing it with a successor. /// @@ -31,14 +31,14 @@ impl AdvanceNonceAccount<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.recent_blockhashes_sysvar.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.recent_blockhashes_sysvar.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // instruction - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &[4], diff --git a/programs/system/src/instructions/allocate.rs b/programs/system/src/instructions/allocate.rs index aa783d7e..6821da1e 100644 --- a/programs/system/src/instructions/allocate.rs +++ b/programs/system/src/instructions/allocate.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Allocate space in a (possibly new) account without funding. /// @@ -26,8 +26,8 @@ impl Allocate<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 1] = - [AccountMeta::writable_signer(self.account.address())]; + let account_metas: [AccountRole; 1] = + [AccountRole::writable_signer(self.account.address())]; // instruction data // - [0..4 ]: instruction discriminator @@ -36,7 +36,7 @@ impl Allocate<'_> { instruction_data[0] = 8; instruction_data[4..12].copy_from_slice(&self.space.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data, diff --git a/programs/system/src/instructions/allocate_with_seed.rs b/programs/system/src/instructions/allocate_with_seed.rs index fd145b82..a6fd30a0 100644 --- a/programs/system/src/instructions/allocate_with_seed.rs +++ b/programs/system/src/instructions/allocate_with_seed.rs @@ -1,9 +1,10 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Allocate space for and assign an account at an address derived /// from a base address and a seed. @@ -41,9 +42,9 @@ impl AllocateWithSeed<'_, '_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly_signer(self.base.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly_signer(self.base.address()), ]; // instruction data @@ -63,7 +64,7 @@ impl AllocateWithSeed<'_, '_, '_> { instruction_data[offset..offset + 8].copy_from_slice(&self.space.to_le_bytes()); instruction_data[offset + 8..offset + 40].copy_from_slice(self.owner.as_ref()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data[..offset + 40], diff --git a/programs/system/src/instructions/assign.rs b/programs/system/src/instructions/assign.rs index 5ca5f753..6a2a5a10 100644 --- a/programs/system/src/instructions/assign.rs +++ b/programs/system/src/instructions/assign.rs @@ -1,9 +1,10 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Assign account to a program /// @@ -26,8 +27,8 @@ impl Assign<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 1] = - [AccountMeta::writable_signer(self.account.address())]; + let account_metas: [AccountRole; 1] = + [AccountRole::writable_signer(self.account.address())]; // instruction data // - [0..4 ]: instruction discriminator @@ -36,7 +37,7 @@ impl Assign<'_, '_> { instruction_data[0] = 1; instruction_data[4..36].copy_from_slice(self.owner.as_ref()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data, diff --git a/programs/system/src/instructions/assign_with_seed.rs b/programs/system/src/instructions/assign_with_seed.rs index 7a37bbaf..82de5443 100644 --- a/programs/system/src/instructions/assign_with_seed.rs +++ b/programs/system/src/instructions/assign_with_seed.rs @@ -1,9 +1,10 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Assign account to a program based on a seed. /// @@ -37,9 +38,9 @@ impl AssignWithSeed<'_, '_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly_signer(self.base.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly_signer(self.base.address()), ]; // instruction data @@ -57,7 +58,7 @@ impl AssignWithSeed<'_, '_, '_> { instruction_data[44..offset].copy_from_slice(self.seed.as_bytes()); instruction_data[offset..offset + 32].copy_from_slice(self.owner.as_ref()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data[..offset + 32], diff --git a/programs/system/src/instructions/authorize_nonce_account.rs b/programs/system/src/instructions/authorize_nonce_account.rs index 4b880901..00d2fb63 100644 --- a/programs/system/src/instructions/authorize_nonce_account.rs +++ b/programs/system/src/instructions/authorize_nonce_account.rs @@ -1,9 +1,10 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Change the entity authorized to execute nonce instructions on the account. /// @@ -32,9 +33,9 @@ impl AuthorizeNonceAccount<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // instruction data @@ -44,7 +45,7 @@ impl AuthorizeNonceAccount<'_, '_> { instruction_data[0] = 7; instruction_data[4..36].copy_from_slice(self.new_authority.as_array()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data, diff --git a/programs/system/src/instructions/create_account.rs b/programs/system/src/instructions/create_account.rs index e92b78f7..e034559a 100644 --- a/programs/system/src/instructions/create_account.rs +++ b/programs/system/src/instructions/create_account.rs @@ -1,11 +1,11 @@ -use pinocchio::{ - account::AccountView, - error::ProgramError, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - sysvars::rent::Rent, - Address, ProgramResult, +use pinocchio::sysvars::rent::Rent; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::{ProgramError, ProgramResult}; /// Create a new account. /// @@ -58,9 +58,9 @@ impl<'a> CreateAccount<'a> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable_signer(self.from.address()), - AccountMeta::writable_signer(self.to.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable_signer(self.from.address()), + AccountRole::writable_signer(self.to.address()), ]; // instruction data @@ -74,7 +74,7 @@ impl<'a> CreateAccount<'a> { instruction_data[12..20].copy_from_slice(&self.space.to_le_bytes()); instruction_data[20..52].copy_from_slice(self.owner.as_ref()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data, diff --git a/programs/system/src/instructions/create_account_with_seed.rs b/programs/system/src/instructions/create_account_with_seed.rs index d2ac492e..fd57c7b5 100644 --- a/programs/system/src/instructions/create_account_with_seed.rs +++ b/programs/system/src/instructions/create_account_with_seed.rs @@ -1,11 +1,11 @@ -use pinocchio::{ - account::AccountView, - error::ProgramError, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - sysvars::rent::Rent, - Address, ProgramResult, +use pinocchio::sysvars::rent::Rent; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::{ProgramError, ProgramResult}; /// Create a new account at an address derived from a base address and a seed. /// @@ -74,10 +74,10 @@ impl<'a, 'b, 'c> CreateAccountWithSeed<'a, 'b, 'c> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable_signer(self.from.address()), - AccountMeta::writable(self.to.address()), - AccountMeta::readonly_signer(self.base.unwrap_or(self.from).address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable_signer(self.from.address()), + AccountRole::writable(self.to.address()), + AccountRole::readonly_signer(self.base.unwrap_or(self.from).address()), ]; // instruction data @@ -100,7 +100,7 @@ impl<'a, 'b, 'c> CreateAccountWithSeed<'a, 'b, 'c> { instruction_data[offset + 8..offset + 16].copy_from_slice(&self.space.to_le_bytes()); instruction_data[offset + 16..offset + 48].copy_from_slice(self.owner.as_ref()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data[..offset + 48], diff --git a/programs/system/src/instructions/initialize_nonce_account.rs b/programs/system/src/instructions/initialize_nonce_account.rs index 9ddf3ea7..d1571330 100644 --- a/programs/system/src/instructions/initialize_nonce_account.rs +++ b/programs/system/src/instructions/initialize_nonce_account.rs @@ -1,9 +1,7 @@ -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; /// Drive state of Uninitialized nonce account to Initialized, setting the nonce value. /// @@ -36,10 +34,10 @@ impl InitializeNonceAccount<'_, '_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.recent_blockhashes_sysvar.address()), - AccountMeta::readonly(self.rent_sysvar.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.recent_blockhashes_sysvar.address()), + AccountRole::readonly(self.rent_sysvar.address()), ]; // instruction data @@ -49,7 +47,7 @@ impl InitializeNonceAccount<'_, '_> { instruction_data[0] = 6; instruction_data[4..36].copy_from_slice(self.authority.as_array()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data, diff --git a/programs/system/src/instructions/transfer.rs b/programs/system/src/instructions/transfer.rs index ac2c0418..63f86ac8 100644 --- a/programs/system/src/instructions/transfer.rs +++ b/programs/system/src/instructions/transfer.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Transfer lamports. /// @@ -30,9 +30,9 @@ impl Transfer<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable_signer(self.from.address()), - AccountMeta::writable(self.to.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable_signer(self.from.address()), + AccountRole::writable(self.to.address()), ]; // instruction data @@ -42,7 +42,7 @@ impl Transfer<'_> { instruction_data[0] = 2; instruction_data[4..12].copy_from_slice(&self.lamports.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data, diff --git a/programs/system/src/instructions/transfer_with_seed.rs b/programs/system/src/instructions/transfer_with_seed.rs index e050a2b0..fd0f072c 100644 --- a/programs/system/src/instructions/transfer_with_seed.rs +++ b/programs/system/src/instructions/transfer_with_seed.rs @@ -1,9 +1,10 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Transfer lamports from a derived address. /// @@ -44,10 +45,10 @@ impl TransferWithSeed<'_, '_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.from.address()), - AccountMeta::readonly_signer(self.base.address()), - AccountMeta::writable(self.to.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.from.address()), + AccountRole::readonly_signer(self.base.address()), + AccountRole::writable(self.to.address()), ]; // instruction data @@ -65,7 +66,7 @@ impl TransferWithSeed<'_, '_, '_> { instruction_data[20..offset].copy_from_slice(self.seed.as_bytes()); instruction_data[offset..offset + 32].copy_from_slice(self.owner.as_ref()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data[..offset + 32], diff --git a/programs/system/src/instructions/upgrade_nonce_account.rs b/programs/system/src/instructions/upgrade_nonce_account.rs index eadbbc0c..dae1d59e 100644 --- a/programs/system/src/instructions/upgrade_nonce_account.rs +++ b/programs/system/src/instructions/upgrade_nonce_account.rs @@ -1,9 +1,6 @@ -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - ProgramResult, -}; +use solana_account_view::AccountView; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; /// One-time idempotent upgrade of legacy nonce versions in order to bump /// them out of chain blockhash domain. @@ -19,10 +16,10 @@ impl UpgradeNonceAccount<'_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 1] = [AccountMeta::writable(self.account.address())]; + let account_metas: [AccountRole; 1] = [AccountRole::writable(self.account.address())]; // instruction - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &[12], diff --git a/programs/system/src/instructions/withdraw_nonce_account.rs b/programs/system/src/instructions/withdraw_nonce_account.rs index b82e1d21..90629aa0 100644 --- a/programs/system/src/instructions/withdraw_nonce_account.rs +++ b/programs/system/src/instructions/withdraw_nonce_account.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Withdraw funds from a nonce account. /// @@ -48,12 +48,12 @@ impl WithdrawNonceAccount<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 5] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::writable(self.recipient.address()), - AccountMeta::readonly(self.recent_blockhashes_sysvar.address()), - AccountMeta::readonly(self.rent_sysvar.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 5] = [ + AccountRole::writable(self.account.address()), + AccountRole::writable(self.recipient.address()), + AccountRole::readonly(self.recent_blockhashes_sysvar.address()), + AccountRole::readonly(self.rent_sysvar.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // instruction data @@ -63,7 +63,7 @@ impl WithdrawNonceAccount<'_> { instruction_data[0] = 5; instruction_data[4..12].copy_from_slice(&self.lamports.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &instruction_data, diff --git a/programs/token-2022/Cargo.toml b/programs/token-2022/Cargo.toml index af5d6af8..1588a39b 100644 --- a/programs/token-2022/Cargo.toml +++ b/programs/token-2022/Cargo.toml @@ -11,5 +11,7 @@ repository = { workspace = true } crate-type = ["rlib"] [dependencies] -pinocchio = { workspace = true } +solana-account-view = { workspace = true } solana-address = { workspace = true, features = ["decode"] } +solana-instruction-view = { workspace = true, features = ["cpi"] } +solana-program-error = { workspace = true } diff --git a/programs/token-2022/src/instructions/approve.rs b/programs/token-2022/src/instructions/approve.rs index e3d91d5c..eba23c8a 100644 --- a/programs/token-2022/src/instructions/approve.rs +++ b/programs/token-2022/src/instructions/approve.rs @@ -1,11 +1,12 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -37,10 +38,10 @@ impl Approve<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.source.address()), - AccountMeta::readonly(self.delegate.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.source.address()), + AccountRole::readonly(self.delegate.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data @@ -53,7 +54,7 @@ impl Approve<'_, '_> { // Set amount as u64 at offset [1..9] write_bytes(&mut instruction_data[1..], &self.amount.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 9) }, diff --git a/programs/token-2022/src/instructions/approve_checked.rs b/programs/token-2022/src/instructions/approve_checked.rs index d98b849f..8a34fa3c 100644 --- a/programs/token-2022/src/instructions/approve_checked.rs +++ b/programs/token-2022/src/instructions/approve_checked.rs @@ -1,11 +1,12 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -42,11 +43,11 @@ impl ApproveChecked<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 4] = [ - AccountMeta::writable(self.source.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly(self.delegate.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 4] = [ + AccountRole::writable(self.source.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly(self.delegate.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data @@ -62,7 +63,7 @@ impl ApproveChecked<'_, '_> { // Set decimals as u8 at offset [9] write_bytes(&mut instruction_data[9..], &[self.decimals]); - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) }, diff --git a/programs/token-2022/src/instructions/burn.rs b/programs/token-2022/src/instructions/burn.rs index 93104bc2..ba2636b4 100644 --- a/programs/token-2022/src/instructions/burn.rs +++ b/programs/token-2022/src/instructions/burn.rs @@ -1,11 +1,12 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -37,10 +38,10 @@ impl Burn<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::writable(self.mint.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::writable(self.mint.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data @@ -53,7 +54,7 @@ impl Burn<'_, '_> { // Set amount as u64 at offset [1..9] write_bytes(&mut instruction_data[1..], &self.amount.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 9) }, diff --git a/programs/token-2022/src/instructions/burn_checked.rs b/programs/token-2022/src/instructions/burn_checked.rs index 026b88d9..b0710111 100644 --- a/programs/token-2022/src/instructions/burn_checked.rs +++ b/programs/token-2022/src/instructions/burn_checked.rs @@ -1,12 +1,14 @@ use core::slice::from_raw_parts; -use crate::{write_bytes, UNINIT_BYTE}; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; + +use crate::{write_bytes, UNINIT_BYTE}; /// Burns tokens by removing them from an account. /// @@ -38,10 +40,10 @@ impl BurnChecked<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::writable(self.mint.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::writable(self.mint.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data @@ -57,7 +59,7 @@ impl BurnChecked<'_, '_> { // Set decimals as u8 at offset [9] write_bytes(&mut instruction_data[9..], &[self.decimals]); - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) }, diff --git a/programs/token-2022/src/instructions/close_account.rs b/programs/token-2022/src/instructions/close_account.rs index 11d0fc4d..1b872133 100644 --- a/programs/token-2022/src/instructions/close_account.rs +++ b/programs/token-2022/src/instructions/close_account.rs @@ -1,9 +1,10 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Close an account by transferring all its SOL to the destination account. /// @@ -31,13 +32,13 @@ impl CloseAccount<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::writable(self.destination.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::writable(self.destination.address()), + AccountRole::readonly_signer(self.authority.address()), ]; - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: &[9], diff --git a/programs/token-2022/src/instructions/freeze_account.rs b/programs/token-2022/src/instructions/freeze_account.rs index 78ea2ab1..2beb0fef 100644 --- a/programs/token-2022/src/instructions/freeze_account.rs +++ b/programs/token-2022/src/instructions/freeze_account.rs @@ -1,9 +1,10 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Freeze an Initialized account using the Mint's freeze authority /// @@ -31,13 +32,13 @@ impl FreezeAccount<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly_signer(self.freeze_authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly_signer(self.freeze_authority.address()), ]; - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: &[10], diff --git a/programs/token-2022/src/instructions/initialize_account.rs b/programs/token-2022/src/instructions/initialize_account.rs index 46df3f05..0cb7d772 100644 --- a/programs/token-2022/src/instructions/initialize_account.rs +++ b/programs/token-2022/src/instructions/initialize_account.rs @@ -1,9 +1,7 @@ -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; /// Initialize a new Token Account. /// @@ -29,14 +27,14 @@ impl InitializeAccount<'_, '_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 4] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly(self.owner.address()), - AccountMeta::readonly(self.rent_sysvar.address()), + let account_metas: [AccountRole; 4] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly(self.owner.address()), + AccountRole::readonly(self.rent_sysvar.address()), ]; - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: &[1], diff --git a/programs/token-2022/src/instructions/initialize_account_2.rs b/programs/token-2022/src/instructions/initialize_account_2.rs index 6913bce1..83dc16de 100644 --- a/programs/token-2022/src/instructions/initialize_account_2.rs +++ b/programs/token-2022/src/instructions/initialize_account_2.rs @@ -1,11 +1,9 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -32,10 +30,10 @@ impl InitializeAccount2<'_, '_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly(self.rent_sysvar.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly(self.rent_sysvar.address()), ]; // instruction data @@ -48,7 +46,7 @@ impl InitializeAccount2<'_, '_> { // Set owner as [u8; 32] at offset [1..33] write_bytes(&mut instruction_data[1..], self.owner.as_array()); - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 33) }, diff --git a/programs/token-2022/src/instructions/initialize_account_3.rs b/programs/token-2022/src/instructions/initialize_account_3.rs index 41417ad5..1c4c7e79 100644 --- a/programs/token-2022/src/instructions/initialize_account_3.rs +++ b/programs/token-2022/src/instructions/initialize_account_3.rs @@ -1,11 +1,9 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -29,9 +27,9 @@ impl InitializeAccount3<'_, '_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), ]; // instruction data @@ -44,7 +42,7 @@ impl InitializeAccount3<'_, '_> { // Set owner as [u8; 32] at offset [1..33] write_bytes(&mut instruction_data[1..], self.owner.as_array()); - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 33) }, diff --git a/programs/token-2022/src/instructions/initialize_mint.rs b/programs/token-2022/src/instructions/initialize_mint.rs index 30eed6fe..ddfa2968 100644 --- a/programs/token-2022/src/instructions/initialize_mint.rs +++ b/programs/token-2022/src/instructions/initialize_mint.rs @@ -1,11 +1,9 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -33,9 +31,9 @@ impl InitializeMint<'_, '_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.mint.address()), - AccountMeta::readonly(self.rent_sysvar.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.mint.address()), + AccountRole::readonly(self.rent_sysvar.address()), ]; // Instruction data layout: @@ -65,7 +63,7 @@ impl InitializeMint<'_, '_> { length = 35; } - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, length) }, diff --git a/programs/token-2022/src/instructions/initialize_mint_2.rs b/programs/token-2022/src/instructions/initialize_mint_2.rs index a959807f..ffbd2939 100644 --- a/programs/token-2022/src/instructions/initialize_mint_2.rs +++ b/programs/token-2022/src/instructions/initialize_mint_2.rs @@ -1,11 +1,9 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -30,7 +28,7 @@ impl InitializeMint2<'_, '_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 1] = [AccountMeta::writable(self.mint.address())]; + let account_metas: [AccountRole; 1] = [AccountRole::writable(self.mint.address())]; // Instruction data layout: // - [0]: instruction discriminator (1 byte, u8) @@ -59,7 +57,7 @@ impl InitializeMint2<'_, '_> { length = 35; } - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, length) }, diff --git a/programs/token-2022/src/instructions/initialize_multisig.rs b/programs/token-2022/src/instructions/initialize_multisig.rs index c0bc0f72..ac46fdc4 100644 --- a/programs/token-2022/src/instructions/initialize_multisig.rs +++ b/programs/token-2022/src/instructions/initialize_multisig.rs @@ -1,12 +1,9 @@ use core::{mem::MaybeUninit, slice}; -use pinocchio::{ - account::AccountView, - cpi::invoke_with_bounds, - error::ProgramError, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke_with_bounds, AccountRole, InstructionView}; +use solana_program_error::{ProgramError, ProgramResult}; /// Maximum number of multisignature signers. pub const MAX_MULTISIG_SIGNERS: usize = 11; @@ -53,7 +50,7 @@ impl InitializeMultisig<'_, '_, '_> { let num_accounts = 2 + signers.len(); // Account metadata - const UNINIT_META: MaybeUninit = MaybeUninit::::uninit(); + const UNINIT_META: MaybeUninit = MaybeUninit::::uninit(); let mut acc_metas = [UNINIT_META; 2 + MAX_MULTISIG_SIGNERS]; unsafe { @@ -62,14 +59,14 @@ impl InitializeMultisig<'_, '_, '_> { // - Index 0 and 1 are always present acc_metas .get_unchecked_mut(0) - .write(AccountMeta::writable(multisig.address())); + .write(AccountRole::writable(multisig.address())); acc_metas .get_unchecked_mut(1) - .write(AccountMeta::readonly(rent_sysvar.address())); + .write(AccountRole::readonly(rent_sysvar.address())); } for (account_meta, signer) in acc_metas[2..].iter_mut().zip(signers.iter()) { - account_meta.write(AccountMeta::readonly(signer.address())); + account_meta.write(AccountRole::readonly(signer.address())); } // Instruction data layout: @@ -77,7 +74,7 @@ impl InitializeMultisig<'_, '_, '_> { // - [1]: m (1 byte, u8) let data = &[2, m]; - let instruction = Instruction { + let instruction = InstructionView { program_id: token_program, accounts: unsafe { slice::from_raw_parts(acc_metas.as_ptr() as _, num_accounts) }, data, diff --git a/programs/token-2022/src/instructions/initialize_multisig_2.rs b/programs/token-2022/src/instructions/initialize_multisig_2.rs index 07b23859..5295a7dc 100644 --- a/programs/token-2022/src/instructions/initialize_multisig_2.rs +++ b/programs/token-2022/src/instructions/initialize_multisig_2.rs @@ -1,12 +1,9 @@ use core::{mem::MaybeUninit, slice}; -use pinocchio::{ - account::AccountView, - cpi::invoke_with_bounds, - error::ProgramError, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke_with_bounds, AccountRole, InstructionView}; +use solana_program_error::{ProgramError, ProgramResult}; use crate::instructions::MAX_MULTISIG_SIGNERS; @@ -48,7 +45,7 @@ impl InitializeMultisig2<'_, '_, '_> { let num_accounts = 1 + signers.len(); // Account metadata - const UNINIT_META: MaybeUninit = MaybeUninit::::uninit(); + const UNINIT_META: MaybeUninit = MaybeUninit::::uninit(); let mut acc_metas = [UNINIT_META; 1 + MAX_MULTISIG_SIGNERS]; unsafe { @@ -57,11 +54,11 @@ impl InitializeMultisig2<'_, '_, '_> { // - Index 0 is always present acc_metas .get_unchecked_mut(0) - .write(AccountMeta::writable(multisig.address())); + .write(AccountRole::writable(multisig.address())); } for (account_meta, signer) in acc_metas[1..].iter_mut().zip(signers.iter()) { - account_meta.write(AccountMeta::readonly(signer.address())); + account_meta.write(AccountRole::readonly(signer.address())); } // Instruction data layout: @@ -69,7 +66,7 @@ impl InitializeMultisig2<'_, '_, '_> { // - [1]: m (1 byte, u8) let data = &[19, m]; - let instruction = Instruction { + let instruction = InstructionView { program_id: token_program, accounts: unsafe { slice::from_raw_parts(acc_metas.as_ptr() as _, num_accounts) }, data, diff --git a/programs/token-2022/src/instructions/mint_to.rs b/programs/token-2022/src/instructions/mint_to.rs index cf239c15..911b989e 100644 --- a/programs/token-2022/src/instructions/mint_to.rs +++ b/programs/token-2022/src/instructions/mint_to.rs @@ -1,11 +1,12 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -37,10 +38,10 @@ impl MintTo<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.mint.address()), - AccountMeta::writable(self.account.address()), - AccountMeta::readonly_signer(self.mint_authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.mint.address()), + AccountRole::writable(self.account.address()), + AccountRole::readonly_signer(self.mint_authority.address()), ]; // Instruction data layout: @@ -53,7 +54,7 @@ impl MintTo<'_, '_> { // Set amount as u64 at offset [1..9] write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 9) }, diff --git a/programs/token-2022/src/instructions/mint_to_checked.rs b/programs/token-2022/src/instructions/mint_to_checked.rs index ee06fb90..031aaa27 100644 --- a/programs/token-2022/src/instructions/mint_to_checked.rs +++ b/programs/token-2022/src/instructions/mint_to_checked.rs @@ -1,11 +1,12 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -39,10 +40,10 @@ impl MintToChecked<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.mint.address()), - AccountMeta::writable(self.account.address()), - AccountMeta::readonly_signer(self.mint_authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.mint.address()), + AccountRole::writable(self.account.address()), + AccountRole::readonly_signer(self.mint_authority.address()), ]; // Instruction data layout: @@ -58,7 +59,7 @@ impl MintToChecked<'_, '_> { // Set decimals as u8 at offset [9] write_bytes(&mut instruction_data[9..], &[self.decimals]); - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) }, diff --git a/programs/token-2022/src/instructions/revoke.rs b/programs/token-2022/src/instructions/revoke.rs index e8c10c8c..f96add61 100644 --- a/programs/token-2022/src/instructions/revoke.rs +++ b/programs/token-2022/src/instructions/revoke.rs @@ -1,9 +1,10 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Revokes the delegate's authority. /// @@ -28,12 +29,12 @@ impl Revoke<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.source.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.source.address()), + AccountRole::readonly_signer(self.authority.address()), ]; - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: &[5], diff --git a/programs/token-2022/src/instructions/set_authority.rs b/programs/token-2022/src/instructions/set_authority.rs index 5eb110c3..34c8a225 100644 --- a/programs/token-2022/src/instructions/set_authority.rs +++ b/programs/token-2022/src/instructions/set_authority.rs @@ -1,11 +1,12 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -45,9 +46,9 @@ impl SetAuthority<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // instruction data @@ -73,7 +74,7 @@ impl SetAuthority<'_, '_> { length = 3; } - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, length) }, diff --git a/programs/token-2022/src/instructions/sync_native.rs b/programs/token-2022/src/instructions/sync_native.rs index 93e056b8..28ce0e76 100644 --- a/programs/token-2022/src/instructions/sync_native.rs +++ b/programs/token-2022/src/instructions/sync_native.rs @@ -1,9 +1,7 @@ -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; /// Given a native token account updates its amount field based /// on the account's underlying `lamports`. @@ -22,9 +20,9 @@ impl SyncNative<'_, '_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 1] = [AccountMeta::writable(self.native_token.address())]; + let account_metas: [AccountRole; 1] = [AccountRole::writable(self.native_token.address())]; - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: &[17], diff --git a/programs/token-2022/src/instructions/thaw_account.rs b/programs/token-2022/src/instructions/thaw_account.rs index 8e0fb261..89b2cf76 100644 --- a/programs/token-2022/src/instructions/thaw_account.rs +++ b/programs/token-2022/src/instructions/thaw_account.rs @@ -1,9 +1,10 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Thaw a Frozen account using the Mint's freeze authority /// @@ -31,13 +32,13 @@ impl ThawAccount<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly_signer(self.freeze_authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly_signer(self.freeze_authority.address()), ]; - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: &[11], diff --git a/programs/token-2022/src/instructions/transfer.rs b/programs/token-2022/src/instructions/transfer.rs index bb99e492..d5fb65ca 100644 --- a/programs/token-2022/src/instructions/transfer.rs +++ b/programs/token-2022/src/instructions/transfer.rs @@ -1,11 +1,12 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -37,10 +38,10 @@ impl Transfer<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.from.address()), - AccountMeta::writable(self.to.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.from.address()), + AccountRole::writable(self.to.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data layout: @@ -53,7 +54,7 @@ impl Transfer<'_, '_> { // Set amount as u64 at offset [1..9] write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 9) }, diff --git a/programs/token-2022/src/instructions/transfer_checked.rs b/programs/token-2022/src/instructions/transfer_checked.rs index 75a8a17e..00988330 100644 --- a/programs/token-2022/src/instructions/transfer_checked.rs +++ b/programs/token-2022/src/instructions/transfer_checked.rs @@ -1,11 +1,12 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -42,11 +43,11 @@ impl TransferChecked<'_, '_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 4] = [ - AccountMeta::writable(self.from.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::writable(self.to.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 4] = [ + AccountRole::writable(self.from.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::writable(self.to.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data layout: @@ -62,7 +63,7 @@ impl TransferChecked<'_, '_> { // Set decimals as u8 at offset [9] write_bytes(&mut instruction_data[9..], &[self.decimals]); - let instruction = Instruction { + let instruction = InstructionView { program_id: self.token_program, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) }, diff --git a/programs/token-2022/src/state/mint.rs b/programs/token-2022/src/state/mint.rs index 0391c92d..8e97064e 100644 --- a/programs/token-2022/src/state/mint.rs +++ b/programs/token-2022/src/state/mint.rs @@ -1,8 +1,6 @@ -use pinocchio::{ - account::{AccountView, Ref}, - error::ProgramError, - Address, -}; +use solana_account_view::{AccountView, Ref}; +use solana_address::Address; +use solana_program_error::ProgramError; use crate::ID; diff --git a/programs/token-2022/src/state/multisig.rs b/programs/token-2022/src/state/multisig.rs index ddc49bfe..8944b3af 100644 --- a/programs/token-2022/src/state/multisig.rs +++ b/programs/token-2022/src/state/multisig.rs @@ -1,9 +1,8 @@ use core::mem::size_of; -use pinocchio::{ - account::{AccountView, Ref}, - error::ProgramError, - Address, -}; + +use solana_account_view::{AccountView, Ref}; +use solana_address::Address; +use solana_program_error::ProgramError; use crate::{instructions::MAX_MULTISIG_SIGNERS, ID}; diff --git a/programs/token-2022/src/state/token.rs b/programs/token-2022/src/state/token.rs index adcd6661..bb401b4c 100644 --- a/programs/token-2022/src/state/token.rs +++ b/programs/token-2022/src/state/token.rs @@ -1,9 +1,8 @@ +use solana_account_view::{AccountView, Ref}; +use solana_address::Address; +use solana_program_error::ProgramError; + use super::AccountState; -use pinocchio::{ - account::{AccountView, Ref}, - error::ProgramError, - Address, -}; use crate::ID; diff --git a/programs/token/Cargo.toml b/programs/token/Cargo.toml index 08a880ce..bae60255 100644 --- a/programs/token/Cargo.toml +++ b/programs/token/Cargo.toml @@ -12,5 +12,7 @@ rust-version = { workspace = true } crate-type = ["rlib"] [dependencies] -pinocchio = { workspace = true } +solana-account-view = { workspace = true } solana-address = { workspace = true, features = ["decode"] } +solana-instruction-view = { workspace = true, features = ["cpi"] } +solana-program-error = { workspace = true } diff --git a/programs/token/src/instructions/approve.rs b/programs/token/src/instructions/approve.rs index e22442cb..7c6139be 100644 --- a/programs/token/src/instructions/approve.rs +++ b/programs/token/src/instructions/approve.rs @@ -1,11 +1,11 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -35,10 +35,10 @@ impl Approve<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.source.address()), - AccountMeta::readonly(self.delegate.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.source.address()), + AccountRole::readonly(self.delegate.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data @@ -51,7 +51,7 @@ impl Approve<'_> { // Set amount as u64 at offset [1..9] write_bytes(&mut instruction_data[1..], &self.amount.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 9) }, diff --git a/programs/token/src/instructions/approve_checked.rs b/programs/token/src/instructions/approve_checked.rs index 149c89d5..b26ba9f4 100644 --- a/programs/token/src/instructions/approve_checked.rs +++ b/programs/token/src/instructions/approve_checked.rs @@ -1,11 +1,11 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -40,11 +40,11 @@ impl ApproveChecked<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 4] = [ - AccountMeta::writable(self.source.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly(self.delegate.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 4] = [ + AccountRole::writable(self.source.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly(self.delegate.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data @@ -60,7 +60,7 @@ impl ApproveChecked<'_> { // Set decimals as u8 at offset [9] write_bytes(&mut instruction_data[9..], &[self.decimals]); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) }, diff --git a/programs/token/src/instructions/burn.rs b/programs/token/src/instructions/burn.rs index 4aa07706..4663001b 100644 --- a/programs/token/src/instructions/burn.rs +++ b/programs/token/src/instructions/burn.rs @@ -1,11 +1,11 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -35,10 +35,10 @@ impl Burn<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::writable(self.mint.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::writable(self.mint.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data @@ -51,7 +51,7 @@ impl Burn<'_> { // Set amount as u64 at offset [1..9] write_bytes(&mut instruction_data[1..], &self.amount.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 9) }, diff --git a/programs/token/src/instructions/burn_checked.rs b/programs/token/src/instructions/burn_checked.rs index 12198e15..c1980d0e 100644 --- a/programs/token/src/instructions/burn_checked.rs +++ b/programs/token/src/instructions/burn_checked.rs @@ -1,12 +1,13 @@ use core::slice::from_raw_parts; -use crate::{write_bytes, UNINIT_BYTE}; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; + +use crate::{write_bytes, UNINIT_BYTE}; /// Burns tokens by removing them from an account. /// @@ -36,10 +37,10 @@ impl BurnChecked<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::writable(self.mint.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::writable(self.mint.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data @@ -55,7 +56,7 @@ impl BurnChecked<'_> { // Set decimals as u8 at offset [9] write_bytes(&mut instruction_data[9..], &[self.decimals]); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) }, diff --git a/programs/token/src/instructions/close_account.rs b/programs/token/src/instructions/close_account.rs index 620d546a..c8108096 100644 --- a/programs/token/src/instructions/close_account.rs +++ b/programs/token/src/instructions/close_account.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Close an account by transferring all its SOL to the destination account. /// @@ -29,13 +29,13 @@ impl CloseAccount<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::writable(self.destination.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::writable(self.destination.address()), + AccountRole::readonly_signer(self.authority.address()), ]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &[9], diff --git a/programs/token/src/instructions/freeze_account.rs b/programs/token/src/instructions/freeze_account.rs index cf508cc2..0c15f6a8 100644 --- a/programs/token/src/instructions/freeze_account.rs +++ b/programs/token/src/instructions/freeze_account.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Freeze an initialized account using the Mint's freeze authority. /// @@ -29,13 +29,13 @@ impl FreezeAccount<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly_signer(self.freeze_authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly_signer(self.freeze_authority.address()), ]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &[10], diff --git a/programs/token/src/instructions/initialize_account.rs b/programs/token/src/instructions/initialize_account.rs index 79142dc8..62cb6a4e 100644 --- a/programs/token/src/instructions/initialize_account.rs +++ b/programs/token/src/instructions/initialize_account.rs @@ -1,9 +1,6 @@ -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - ProgramResult, -}; +use solana_account_view::AccountView; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; /// Initialize a new Token Account. /// @@ -27,14 +24,14 @@ impl InitializeAccount<'_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 4] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly(self.owner.address()), - AccountMeta::readonly(self.rent_sysvar.address()), + let account_metas: [AccountRole; 4] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly(self.owner.address()), + AccountRole::readonly(self.rent_sysvar.address()), ]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &[1], diff --git a/programs/token/src/instructions/initialize_account_2.rs b/programs/token/src/instructions/initialize_account_2.rs index 63e20679..ff46d532 100644 --- a/programs/token/src/instructions/initialize_account_2.rs +++ b/programs/token/src/instructions/initialize_account_2.rs @@ -1,11 +1,9 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -30,10 +28,10 @@ impl InitializeAccount2<'_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly(self.rent_sysvar.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly(self.rent_sysvar.address()), ]; // instruction data @@ -46,7 +44,7 @@ impl InitializeAccount2<'_> { // Set owner as [u8; 32] at offset [1..33] write_bytes(&mut instruction_data[1..], self.owner.as_array()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 33) }, diff --git a/programs/token/src/instructions/initialize_account_3.rs b/programs/token/src/instructions/initialize_account_3.rs index cdf877a9..69cc00cd 100644 --- a/programs/token/src/instructions/initialize_account_3.rs +++ b/programs/token/src/instructions/initialize_account_3.rs @@ -1,11 +1,9 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -27,9 +25,9 @@ impl InitializeAccount3<'_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), ]; // instruction data @@ -42,7 +40,7 @@ impl InitializeAccount3<'_> { // Set owner as [u8; 32] at offset [1..33] write_bytes(&mut instruction_data[1..], self.owner.as_array()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 33) }, diff --git a/programs/token/src/instructions/initialize_mint.rs b/programs/token/src/instructions/initialize_mint.rs index 2be1eb76..76fa1669 100644 --- a/programs/token/src/instructions/initialize_mint.rs +++ b/programs/token/src/instructions/initialize_mint.rs @@ -1,11 +1,9 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -31,9 +29,9 @@ impl InitializeMint<'_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.mint.address()), - AccountMeta::readonly(self.rent_sysvar.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.mint.address()), + AccountRole::readonly(self.rent_sysvar.address()), ]; // Instruction data layout: @@ -63,7 +61,7 @@ impl InitializeMint<'_> { length = 35; } - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, length) }, diff --git a/programs/token/src/instructions/initialize_mint_2.rs b/programs/token/src/instructions/initialize_mint_2.rs index 713723b4..851a2f3d 100644 --- a/programs/token/src/instructions/initialize_mint_2.rs +++ b/programs/token/src/instructions/initialize_mint_2.rs @@ -1,11 +1,9 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - Address, ProgramResult, -}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -28,7 +26,7 @@ impl InitializeMint2<'_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // Account metadata - let account_metas: [AccountMeta; 1] = [AccountMeta::writable(self.mint.address())]; + let account_metas: [AccountRole; 1] = [AccountRole::writable(self.mint.address())]; // Instruction data layout: // - [0]: instruction discriminator (1 byte, u8) @@ -57,7 +55,7 @@ impl InitializeMint2<'_> { length = 35; } - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, length) }, diff --git a/programs/token/src/instructions/initialize_multisig.rs b/programs/token/src/instructions/initialize_multisig.rs index 0f67c11a..ed47e557 100644 --- a/programs/token/src/instructions/initialize_multisig.rs +++ b/programs/token/src/instructions/initialize_multisig.rs @@ -1,12 +1,8 @@ use core::{mem::MaybeUninit, slice}; -use pinocchio::{ - account::AccountView, - cpi::invoke_with_bounds, - error::ProgramError, - instruction::{AccountMeta, Instruction}, - ProgramResult, -}; +use solana_account_view::AccountView; +use solana_instruction_view::{cpi::invoke_with_bounds, AccountRole, InstructionView}; +use solana_program_error::{ProgramError, ProgramResult}; /// Maximum number of multisignature signers. pub const MAX_MULTISIG_SIGNERS: usize = 11; @@ -49,7 +45,7 @@ impl InitializeMultisig<'_, '_> { let num_accounts = 2 + signers.len(); // Account metadata - const UNINIT_META: MaybeUninit = MaybeUninit::::uninit(); + const UNINIT_META: MaybeUninit = MaybeUninit::::uninit(); let mut acc_metas = [UNINIT_META; 2 + MAX_MULTISIG_SIGNERS]; unsafe { @@ -58,14 +54,14 @@ impl InitializeMultisig<'_, '_> { // - Index 0 and 1 are always present acc_metas .get_unchecked_mut(0) - .write(AccountMeta::writable(multisig.address())); + .write(AccountRole::writable(multisig.address())); acc_metas .get_unchecked_mut(1) - .write(AccountMeta::readonly(rent_sysvar.address())); + .write(AccountRole::readonly(rent_sysvar.address())); } for (account_meta, signer) in acc_metas[2..].iter_mut().zip(signers.iter()) { - account_meta.write(AccountMeta::readonly(signer.address())); + account_meta.write(AccountRole::readonly(signer.address())); } // Instruction data layout: @@ -73,7 +69,7 @@ impl InitializeMultisig<'_, '_> { // - [1]: m (1 byte, u8) let data = &[2, m]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: unsafe { slice::from_raw_parts(acc_metas.as_ptr() as _, num_accounts) }, data, diff --git a/programs/token/src/instructions/initialize_multisig_2.rs b/programs/token/src/instructions/initialize_multisig_2.rs index b3104ad2..a37e91a8 100644 --- a/programs/token/src/instructions/initialize_multisig_2.rs +++ b/programs/token/src/instructions/initialize_multisig_2.rs @@ -1,12 +1,8 @@ use core::{mem::MaybeUninit, slice}; -use pinocchio::{ - account::AccountView, - cpi::invoke_with_bounds, - error::ProgramError, - instruction::{AccountMeta, Instruction}, - ProgramResult, -}; +use solana_account_view::AccountView; +use solana_instruction_view::{cpi::invoke_with_bounds, AccountRole, InstructionView}; +use solana_program_error::{ProgramError, ProgramResult}; use crate::instructions::MAX_MULTISIG_SIGNERS; @@ -44,7 +40,7 @@ impl InitializeMultisig2<'_, '_> { let num_accounts = 1 + signers.len(); // Account metadata - const UNINIT_META: MaybeUninit = MaybeUninit::::uninit(); + const UNINIT_META: MaybeUninit = MaybeUninit::::uninit(); let mut acc_metas = [UNINIT_META; 1 + MAX_MULTISIG_SIGNERS]; unsafe { @@ -53,11 +49,11 @@ impl InitializeMultisig2<'_, '_> { // - Index 0 is always present acc_metas .get_unchecked_mut(0) - .write(AccountMeta::writable(multisig.address())); + .write(AccountRole::writable(multisig.address())); } for (account_meta, signer) in acc_metas[1..].iter_mut().zip(signers.iter()) { - account_meta.write(AccountMeta::readonly(signer.address())); + account_meta.write(AccountRole::readonly(signer.address())); } // Instruction data layout: @@ -65,7 +61,7 @@ impl InitializeMultisig2<'_, '_> { // - [1]: m (1 byte, u8) let data = &[19, m]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: unsafe { slice::from_raw_parts(acc_metas.as_ptr() as _, num_accounts) }, data, diff --git a/programs/token/src/instructions/mint_to.rs b/programs/token/src/instructions/mint_to.rs index 7ae31250..860eab7d 100644 --- a/programs/token/src/instructions/mint_to.rs +++ b/programs/token/src/instructions/mint_to.rs @@ -1,11 +1,11 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -35,10 +35,10 @@ impl MintTo<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.mint.address()), - AccountMeta::writable(self.account.address()), - AccountMeta::readonly_signer(self.mint_authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.mint.address()), + AccountRole::writable(self.account.address()), + AccountRole::readonly_signer(self.mint_authority.address()), ]; // Instruction data layout: @@ -51,7 +51,7 @@ impl MintTo<'_> { // Set amount as u64 at offset [1..9] write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 9) }, diff --git a/programs/token/src/instructions/mint_to_checked.rs b/programs/token/src/instructions/mint_to_checked.rs index 227ad379..76165b1e 100644 --- a/programs/token/src/instructions/mint_to_checked.rs +++ b/programs/token/src/instructions/mint_to_checked.rs @@ -1,11 +1,11 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -37,10 +37,10 @@ impl MintToChecked<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.mint.address()), - AccountMeta::writable(self.account.address()), - AccountMeta::readonly_signer(self.mint_authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.mint.address()), + AccountRole::writable(self.account.address()), + AccountRole::readonly_signer(self.mint_authority.address()), ]; // Instruction data layout: @@ -56,7 +56,7 @@ impl MintToChecked<'_> { // Set decimals as u8 at offset [9] write_bytes(&mut instruction_data[9..], &[self.decimals]); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) }, diff --git a/programs/token/src/instructions/revoke.rs b/programs/token/src/instructions/revoke.rs index d6a198e9..beb7b43c 100644 --- a/programs/token/src/instructions/revoke.rs +++ b/programs/token/src/instructions/revoke.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Revokes the delegate's authority. /// @@ -26,12 +26,12 @@ impl Revoke<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.source.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.source.address()), + AccountRole::readonly_signer(self.authority.address()), ]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &[5], diff --git a/programs/token/src/instructions/set_authority.rs b/programs/token/src/instructions/set_authority.rs index 8dbd7fb3..e5d6a52b 100644 --- a/programs/token/src/instructions/set_authority.rs +++ b/programs/token/src/instructions/set_authority.rs @@ -1,11 +1,12 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - Address, ProgramResult, +use solana_account_view::AccountView; +use solana_address::Address; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -43,9 +44,9 @@ impl SetAuthority<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 2] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 2] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // instruction data @@ -71,7 +72,7 @@ impl SetAuthority<'_> { length = 3; } - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, length) }, diff --git a/programs/token/src/instructions/sync_native.rs b/programs/token/src/instructions/sync_native.rs index 3cd6f043..30e6e25e 100644 --- a/programs/token/src/instructions/sync_native.rs +++ b/programs/token/src/instructions/sync_native.rs @@ -1,9 +1,6 @@ -use pinocchio::{ - account::AccountView, - cpi::invoke, - instruction::{AccountMeta, Instruction}, - ProgramResult, -}; +use solana_account_view::AccountView; +use solana_instruction_view::{cpi::invoke, AccountRole, InstructionView}; +use solana_program_error::ProgramResult; /// Given a native token account updates its amount field based /// on the account's underlying `lamports`. @@ -20,9 +17,9 @@ impl SyncNative<'_> { #[inline(always)] pub fn invoke(&self) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 1] = [AccountMeta::writable(self.native_token.address())]; + let account_metas: [AccountRole; 1] = [AccountRole::writable(self.native_token.address())]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &[17], diff --git a/programs/token/src/instructions/thaw_account.rs b/programs/token/src/instructions/thaw_account.rs index 75f6aeb5..83485a04 100644 --- a/programs/token/src/instructions/thaw_account.rs +++ b/programs/token/src/instructions/thaw_account.rs @@ -1,9 +1,9 @@ -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; /// Thaw a frozen account using the Mint's freeze authority. /// @@ -29,13 +29,13 @@ impl ThawAccount<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.account.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::readonly_signer(self.freeze_authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.account.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::readonly_signer(self.freeze_authority.address()), ]; - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: &[11], diff --git a/programs/token/src/instructions/transfer.rs b/programs/token/src/instructions/transfer.rs index 4188fd08..5fce6ba6 100644 --- a/programs/token/src/instructions/transfer.rs +++ b/programs/token/src/instructions/transfer.rs @@ -1,11 +1,11 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -35,10 +35,10 @@ impl Transfer<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 3] = [ - AccountMeta::writable(self.from.address()), - AccountMeta::writable(self.to.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 3] = [ + AccountRole::writable(self.from.address()), + AccountRole::writable(self.to.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data layout: @@ -51,7 +51,7 @@ impl Transfer<'_> { // Set amount as u64 at offset [1..9] write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes()); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 9) }, diff --git a/programs/token/src/instructions/transfer_checked.rs b/programs/token/src/instructions/transfer_checked.rs index 59bf92b1..3c56af5c 100644 --- a/programs/token/src/instructions/transfer_checked.rs +++ b/programs/token/src/instructions/transfer_checked.rs @@ -1,11 +1,11 @@ use core::slice::from_raw_parts; -use pinocchio::{ - account::AccountView, - instruction::{AccountMeta, Instruction, Signer}, - program::invoke_signed, - ProgramResult, +use solana_account_view::AccountView; +use solana_instruction_view::{ + cpi::{invoke_signed, Signer}, + AccountRole, InstructionView, }; +use solana_program_error::ProgramResult; use crate::{write_bytes, UNINIT_BYTE}; @@ -40,11 +40,11 @@ impl TransferChecked<'_> { #[inline(always)] pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { // account metadata - let account_metas: [AccountMeta; 4] = [ - AccountMeta::writable(self.from.address()), - AccountMeta::readonly(self.mint.address()), - AccountMeta::writable(self.to.address()), - AccountMeta::readonly_signer(self.authority.address()), + let account_metas: [AccountRole; 4] = [ + AccountRole::writable(self.from.address()), + AccountRole::readonly(self.mint.address()), + AccountRole::writable(self.to.address()), + AccountRole::readonly_signer(self.authority.address()), ]; // Instruction data layout: @@ -60,7 +60,7 @@ impl TransferChecked<'_> { // Set decimals as u8 at offset [9] write_bytes(&mut instruction_data[9..], &[self.decimals]); - let instruction = Instruction { + let instruction = InstructionView { program_id: &crate::ID, accounts: &account_metas, data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) }, diff --git a/programs/token/src/state/mint.rs b/programs/token/src/state/mint.rs index 520fd21e..0df03aa0 100644 --- a/programs/token/src/state/mint.rs +++ b/programs/token/src/state/mint.rs @@ -1,8 +1,6 @@ -use pinocchio::{ - account::{AccountView, Ref}, - error::ProgramError, - Address, -}; +use solana_account_view::{AccountView, Ref}; +use solana_address::Address; +use solana_program_error::ProgramError; use crate::ID; diff --git a/programs/token/src/state/multisig.rs b/programs/token/src/state/multisig.rs index a7f7bc50..32d6aa9a 100644 --- a/programs/token/src/state/multisig.rs +++ b/programs/token/src/state/multisig.rs @@ -1,9 +1,8 @@ use core::mem::size_of; -use pinocchio::{ - account::{AccountView, Ref}, - error::ProgramError, - Address, -}; + +use solana_account_view::{AccountView, Ref}; +use solana_address::Address; +use solana_program_error::ProgramError; use crate::{instructions::MAX_MULTISIG_SIGNERS, ID}; diff --git a/programs/token/src/state/token.rs b/programs/token/src/state/token.rs index fe3a83b7..e0092bd8 100644 --- a/programs/token/src/state/token.rs +++ b/programs/token/src/state/token.rs @@ -1,11 +1,8 @@ -use super::AccountState; -use pinocchio::{ - account::{AccountView, Ref}, - error::ProgramError, - Address, -}; +use solana_account_view::{AccountView, Ref}; +use solana_address::Address; +use solana_program_error::ProgramError; -use crate::ID; +use crate::{state::AccountState, ID}; /// Token account data. #[repr(C)] @@ -51,12 +48,12 @@ pub struct TokenAccount { impl TokenAccount { pub const LEN: usize = core::mem::size_of::(); - /// Return a `TokenAccount` from the given account info. + /// Return a `TokenAccount` from the given account view. /// /// This method performs owner and length validation on `AccountView`, safe borrowing /// the account data. #[inline] - pub fn from_account_info( + pub fn from_account_view( account_info: &AccountView, ) -> Result, ProgramError> { if account_info.data_len() != Self::LEN { diff --git a/sdk/pinocchio/Cargo.toml b/sdk/pinocchio/Cargo.toml index e1ff29e4..85ec757e 100644 --- a/sdk/pinocchio/Cargo.toml +++ b/sdk/pinocchio/Cargo.toml @@ -19,12 +19,14 @@ unexpected_cfgs = { level = "warn", check-cfg = [ [features] copy = ["solana-account-view/copy", "solana-address/copy"] +cpi = ["dep:solana-instruction-view"] std = ["solana-address/std"] [dependencies] solana-account-view = { workspace = true } solana-address = { workspace = true, features = ["syscalls"] } -solana-program-error = { version = "3.0.0", git = "https://github.com/febo/solana-sdk.git", branch = "solana-account-view" } +solana-instruction-view = { workspace = true, features = ["cpi"], optional = true } +solana-program-error = { workspace = true } [dev-dependencies] five8_const = { workspace = true } diff --git a/sdk/pinocchio/src/cpi.rs b/sdk/pinocchio/src/cpi.rs deleted file mode 100644 index 41b9952d..00000000 --- a/sdk/pinocchio/src/cpi.rs +++ /dev/null @@ -1,548 +0,0 @@ -//! Cross-program invocation helpers. - -use core::{mem::MaybeUninit, ops::Deref, slice::from_raw_parts}; - -use crate::{ - account::AccountView, - error::ProgramError, - hint::unlikely, - instruction::{Account, Instruction, Signer}, - Address, ProgramResult, -}; - -/// Maximum number of accounts that can be passed to a cross-program invocation. -pub const MAX_CPI_ACCOUNTS: usize = 64; - -/// Invoke a cross-program instruction from an array of `AccountView`s. -/// -/// This function is a convenience wrapper around the [`invoke_signed`] function -/// with the signers' seeds set to an empty slice. -/// -/// Note that this function is inlined to avoid the overhead of a function call, -/// but uses stack memory allocation. When a large number of accounts is needed, -/// it is recommended to use the [`slice_invoke`] function instead to reduce -/// stack memory utilization. -/// -/// # Important -/// -/// The accounts on the `account_views` slice must be in the same order as the -/// `accounts` field of the `instruction`. When the instruction has duplicated -/// accounts, it is necessary to pass a duplicated reference to the same account -/// to maintain the 1:1 relationship between `account_views` and `accounts`. -#[inline(always)] -pub fn invoke( - instruction: &Instruction, - account_views: &[&AccountView; ACCOUNTS], -) -> ProgramResult { - invoke_signed::(instruction, account_views, &[]) -} - -/// Invoke a cross-program instruction from a slice of `AccountView`s. -/// -/// This function is a convenience wrapper around the [`invoke_signed_with_bounds`] -/// function with the signers' seeds set to an empty slice. -/// -/// The `MAX_ACCOUNTS` constant defines the maximum number of accounts expected -/// to be passed to the cross-program invocation. This provides an upper bound to -/// the number of accounts that need to be statically allocated for cases where the -/// number of instruction accounts is not known at compile time. The final number of -/// accounts passed to the cross-program invocation will be the number of accounts -/// required by the `instruction`, even if `MAX_ACCOUNTS` is greater than that. When -/// `MAX_ACCOUNTS` is lower than the number of accounts expected by the instruction, -/// this function will return a [`ProgramError::InvalidArgument`] error. -/// -/// Note that this function is inlined to avoid the overhead of a function call, -/// but uses stack memory allocation. When a large number of accounts is needed, -/// it is recommended to use the [`slice_invoke`] function instead to reduce -/// stack memory utilization. -/// -/// # Important -/// -/// The accounts on the `account_views` slice must be in the same order as the -/// `accounts` field of the `instruction`. When the instruction has duplicated -/// accounts, it is necessary to pass a duplicated reference to the same account -/// to maintain the 1:1 relationship between `account_views` and `accounts`. -#[inline(always)] -pub fn invoke_with_bounds( - instruction: &Instruction, - account_views: &[&AccountView], -) -> ProgramResult { - invoke_signed_with_bounds::(instruction, account_views, &[]) -} - -/// Invoke a cross-program instruction from a slice of `AccountView`s. -/// -/// This function is a convenience wrapper around the [`slice_invoke_signed`] -/// function with the signers' seeds set to an empty slice. -/// -/// Note that the maximum number of accounts that can be passed to a cross-program -/// invocation is defined by the [`MAX_CPI_ACCOUNTS`] constant. Even if the slice -/// of `AccountView`s has more accounts, only the number of accounts required by -/// the `instruction` will be used. If the number of accounts required by the -/// instruction is greater than [`MAX_CPI_ACCOUNTS`], this function will return a -/// [`ProgramError::InvalidArgument`] error. -/// -/// # Important -/// -/// The accounts on the `account_views` slice must be in the same order as the -/// `accounts` field of the `instruction`. When the instruction has duplicated -/// accounts, it is necessary to pass a duplicated reference to the same account -/// to maintain the 1:1 relationship between `account_views` and `accounts`. -#[inline(always)] -pub fn slice_invoke(instruction: &Instruction, account_views: &[&AccountView]) -> ProgramResult { - slice_invoke_signed(instruction, account_views, &[]) -} - -/// Invoke a cross-program instruction with signatures from an array of -/// `AccountView`s. -/// -/// This function performs validation of the `account_views` slice to ensure that: -/// 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`. -/// 3. The borrow state of the accounts is compatible with the mutability of the -/// accounts in the instruction. -/// -/// This validation is done to ensure that the borrow checker rules are followed, -/// consuming CUs in the process. The `invoke_signed_unchecked` is an alternative -/// to this function that have lower CU consumption since it does not perform -/// any validation. This should only be used when the caller is sure that the borrow -/// checker rules are followed. -/// -/// Note that this function is inlined to avoid the overhead of a function call, -/// but uses stack memory allocation. When a large number of accounts is needed, -/// it is recommended to use the [`slice_invoke_signed`] function instead to reduce -/// stack memory utilization. -/// -/// # Important -/// -/// The accounts on the `account_views` slice must be in the same order as the -/// `accounts` field of the `instruction`. When the instruction has duplicated -/// accounts, it is necessary to pass a duplicated reference to the same account -/// to maintain the 1:1 relationship between `account_views` and `accounts`. -#[inline(always)] -pub fn invoke_signed( - instruction: &Instruction, - account_views: &[&AccountView; ACCOUNTS], - signers_seeds: &[Signer], -) -> ProgramResult { - // SAFETY: The array of `AccountView`s will be checked to ensure that it has - // the same number of accounts as the instruction – this indirectly validates - // that the stack allocated account storage `ACCOUNTS` is sufficient for the - // number of accounts expected by the instruction. - unsafe { - inner_invoke_signed_with_bounds::(instruction, account_views, signers_seeds) - } -} - -/// Invoke a cross-program instruction with signatures from a slice of -/// `AccountView`s. -/// -/// This function performs validation of the `account_views` slice to ensure that: -/// 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`. -/// 3. The borrow state of the accounts is compatible with the mutability of the -/// accounts in the instruction. -/// -/// This validation is done to ensure that the borrow checker rules are followed, -/// consuming CUs in the process. The [`invoke_signed_unchecked`] is an alternative -/// to this function that has lower CU consumption since it does not perform -/// any validation. This should only be used when the caller is sure that the borrow -/// checker rules are followed. -/// -/// The `MAX_ACCOUNTS` constant defines the maximum number of accounts expected -/// to be passed to the cross-program invocation. This provides an upper bound to -/// the number of accounts that need to be statically allocated for cases where the -/// number of instruction accounts is not known at compile time. The final number of -/// accounts passed to the cross-program invocation will be the number of accounts -/// required by the `instruction`, even if `MAX_ACCOUNTS` is greater than that. When -/// `MAX_ACCOUNTS` is lower than the number of accounts expected by the instruction, -/// this function will return a [`ProgramError::InvalidArgument`] error. -/// -/// Note that this function is inlined to avoid the overhead of a function call, -/// but uses stack memory allocation. When a large number of accounts is needed, -/// it is recommended to use the [`slice_invoke_signed`] function instead to reduce -/// stack memory utilization. -/// -/// # Important -/// -/// The accounts on the `account_views` slice must be in the same order as the -/// `accounts` field of the `instruction`. When the instruction has duplicated -/// accounts, it is necessary to pass a duplicated reference to the same account -/// to maintain the 1:1 relationship between `account_views` and `accounts`. -#[inline(always)] -pub fn invoke_signed_with_bounds( - instruction: &Instruction, - account_views: &[&AccountView], - signers_seeds: &[Signer], -) -> ProgramResult { - // Check that the stack allocated account storage `MAX_ACCOUNTS` is sufficient - // for the number of accounts expected by the instruction. - // - // The check for the slice of `AccountView`s not being less than the - // number of accounts expected by the instruction is done in - // `invoke_signed_with_bounds`. - if MAX_ACCOUNTS < instruction.accounts.len() { - return Err(ProgramError::InvalidArgument); - } - - // SAFETY: The stack allocated account storage `MAX_ACCOUNTS` was validated. - unsafe { - inner_invoke_signed_with_bounds::(instruction, account_views, signers_seeds) - } -} - -/// Invoke a cross-program instruction with signatures from a slice of -/// `AccountView`s. -/// -/// This function performs validation of the `account_views` slice to ensure that: -/// 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`. -/// 3. The borrow state of the accounts is compatible with the mutability of the -/// accounts in the instruction. -/// -/// This validation is done to ensure that the borrow checker rules are followed, -/// consuming CUs in the process. The [`invoke_signed_unchecked`] is an alternative -/// to this function that have lower CU consumption since it does not perform -/// any validation. This should only be used when the caller is sure that the borrow -/// checker rules are followed. -/// -/// Note that the maximum number of accounts that can be passed to a cross-program -/// invocation is defined by the `MAX_CPI_ACCOUNTS` constant. Even if the slice -/// of `AccountView`s has more accounts, only the number of accounts required by -/// the `instruction` will be used. If the number of accounts required by the -/// instruction is greater than [`MAX_CPI_ACCOUNTS`], this function will return a -/// [`ProgramError::InvalidArgument`] error. -/// -/// # Important -/// -/// The accounts on the `account_views` slice must be in the same order as the -/// `accounts` field of the `instruction`. When the instruction has duplicated -/// accounts, it is necessary to pass a duplicated reference to the same account -/// to maintain the 1:1 relationship between `account_views` and `accounts`. -pub fn slice_invoke_signed( - instruction: &Instruction, - account_views: &[&AccountView], - signers_seeds: &[Signer], -) -> ProgramResult { - // Check that the stack allocated account storage `MAX_CPI_ACCOUNTS` is - // sufficient for the number of accounts expected by the instruction. - // - // The check for the slice of `AccountView`s not being less than the - // number of accounts expected by the instruction is done in - // `invoke_signed_with_bounds`. - if MAX_CPI_ACCOUNTS < instruction.accounts.len() { - return Err(ProgramError::InvalidArgument); - } - - // SAFETY: The stack allocated account storage `MAX_CPI_ACCOUNTS` was validated. - unsafe { - inner_invoke_signed_with_bounds::( - instruction, - account_views, - signers_seeds, - ) - } -} - -/// Internal function to invoke a cross-program instruction with signatures -/// from a slice of `AccountView`s performing borrow checking. -/// -/// This function performs validation of the `account_views` slice to ensure that: -/// 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`. -/// 3. The borrow state of the accounts is compatible with the mutability of the -/// accounts in the instruction. -/// -/// # Safety -/// -/// This function is unsafe because it does not check that the stack allocated account -/// storage `MAX_ACCOUNTS` is sufficient for the number of accounts expected by the -/// instruction. Using a value of `MAX_ACCOUNTS` that is less than the number of accounts -/// expected by the instruction will result in undefined behavior. -#[inline(always)] -unsafe fn inner_invoke_signed_with_bounds( - instruction: &Instruction, - account_views: &[&AccountView], - signers_seeds: &[Signer], -) -> ProgramResult { - // Check that the number of `MAX_ACCOUNTS` provided is not greater than - // the maximum number of accounts allowed. - const { - assert!( - MAX_ACCOUNTS <= MAX_CPI_ACCOUNTS, - "MAX_ACCOUNTS is greater than allowed MAX_CPI_ACCOUNTS" - ); - } - - // Check that the number of accounts provided is not less than - // the number of accounts expected by the instruction. - if account_views.len() < instruction.accounts.len() { - return Err(ProgramError::NotEnoughAccountKeys); - } - - const UNINIT: MaybeUninit = MaybeUninit::::uninit(); - let mut accounts = [UNINIT; MAX_ACCOUNTS]; - - account_views - .iter() - .zip(instruction.accounts.iter()) - .zip(accounts.iter_mut()) - .try_for_each(|((account_view, account_meta), account)| { - // 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(account_view.address() != account_meta.address) { - return Err(ProgramError::InvalidArgument); - } - - // Determines the borrow state that would be invalid according - // to their mutability on the instruction. - let borrowed = if account_meta.is_writable { - // If the account is required to be writable, it cannot - // be currently borrowed. - account_view.is_borrowed() - } else { - // If the account is required to be read-only, it cannot - // be currently mutably borrowed. - account_view.is_borrowed_mut() - }; - - if borrowed { - return Err(ProgramError::AccountBorrowFailed); - } - - account.write(Account::from(*account_view)); - - Ok(()) - })?; - - // SAFETY: At this point it is guaranteed that account infos are borrowable - // according to their mutability on the instruction. - unsafe { - invoke_signed_unchecked( - instruction, - from_raw_parts(accounts.as_ptr() as _, instruction.accounts.len()), - signers_seeds, - ); - } - - Ok(()) -} - -/// Invoke a cross-program instruction but don't enforce Rust's aliasing rules. -/// -/// This function does not check that [`Account`]s are properly borrowable. -/// Those checks consume CUs that this function avoids. -/// -/// Note that the maximum number of accounts that can be passed to a cross-program -/// invocation is defined by the `MAX_CPI_ACCOUNTS` constant. Even if the slice -/// of `AccountView`s has more accounts, only the number of accounts required by -/// the `instruction` will be used. -/// -/// # Safety -/// -/// If any of the writable accounts passed to the callee contain data that is -/// borrowed within the calling program, and that data is written to by the -/// callee, then Rust's aliasing rules will be violated and cause undefined -/// behavior. -#[inline(always)] -pub unsafe fn invoke_unchecked(instruction: &Instruction, accounts: &[Account]) { - invoke_signed_unchecked(instruction, accounts, &[]) -} - -/// Invoke a cross-program instruction with signatures but don't enforce Rust's -/// aliasing rules. -/// -/// This function does not check that [`Account`]s are properly borrowable. -/// Those checks consume CUs that this function avoids. -/// -/// Note that the maximum number of accounts that can be passed to a cross-program -/// invocation is defined by the `MAX_CPI_ACCOUNTS` constant. Even if the slice -/// of `AccountView`s has more accounts, only the number of accounts required by -/// the `instruction` will be used. -/// -/// # Safety -/// -/// If any of the writable accounts passed to the callee contain data that is -/// borrowed within the calling program, and that data is written to by the -/// callee, then Rust's aliasing rules will be violated and cause undefined -/// behavior. -#[inline(always)] -pub unsafe fn invoke_signed_unchecked( - instruction: &Instruction, - accounts: &[Account], - signers_seeds: &[Signer], -) { - #[cfg(target_os = "solana")] - { - use crate::instruction::AccountMeta; - - /// An `Instruction` as expected by `sol_invoke_signed_c`. - /// - /// DO NOT EXPOSE THIS STRUCT: - /// - /// To ensure pointers are valid upon use, the scope of this struct should - /// only be limited to the stack where `sol_invoke_signed_c` happens and then - /// discarded immediately after. - #[repr(C)] - struct CInstruction<'a> { - /// Public key of the program. - program_id: *const Address, - - /// Accounts expected by the program instruction. - accounts: *const AccountMeta<'a>, - - /// Number of accounts expected by the program instruction. - accounts_len: u64, - - /// Data expected by the program instruction. - data: *const u8, - - /// Length of the data expected by the program instruction. - data_len: u64, - } - - let cpi_instruction = CInstruction { - program_id: instruction.program_id, - accounts: instruction.accounts.as_ptr(), - accounts_len: instruction.accounts.len() as u64, - data: instruction.data.as_ptr(), - data_len: instruction.data.len() as u64, - }; - - unsafe { - crate::syscalls::sol_invoke_signed_c( - &cpi_instruction as *const _ as *const u8, - accounts as *const _ as *const u8, - accounts.len() as u64, - signers_seeds as *const _ as *const u8, - signers_seeds.len() as u64, - ) - }; - } - - #[cfg(not(target_os = "solana"))] - core::hint::black_box((instruction, accounts, signers_seeds)); -} - -/// Maximum size that can be set using [`set_return_data`]. -pub const MAX_RETURN_DATA: usize = 1024; - -/// Set the running program's return data. -/// -/// Return data is a dedicated per-transaction buffer for data passed -/// from cross-program invoked programs back to their caller. -/// -/// The maximum size of return data is [`MAX_RETURN_DATA`]. Return data is -/// retrieved by the caller with [`get_return_data`]. -#[inline(always)] -pub fn set_return_data(data: &[u8]) { - #[cfg(target_os = "solana")] - unsafe { - crate::syscalls::sol_set_return_data(data.as_ptr(), data.len() as u64) - }; - - #[cfg(not(target_os = "solana"))] - core::hint::black_box(data); -} - -/// Get the return data from an invoked program. -/// -/// For every transaction there is a single buffer with maximum length -/// [`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 -/// the return data may represent values set by programs multiple calls down the -/// call stack, depending on the circumstances of transaction execution. -/// -/// Return data is set by the callee with [`set_return_data`]. -/// -/// Return data is cleared before every CPI invocation - a program that -/// has invoked no other programs can expect the return data to be `None`; if no -/// return data was set by the previous CPI invocation, then this function -/// returns `None`. -/// -/// Return data is not cleared after returning from CPI invocations. A -/// program that has called another program may retrieve return data that was -/// not set by the called program, but instead set by a program further down the -/// call stack; or, if a program calls itself recursively, it is possible that -/// the return data was not set by the immediate call to that program, but by a -/// subsequent recursive call to that program. Likewise, an external RPC caller -/// may see return data that was not set by the program it is directly calling, -/// but by a program that program called. -/// -/// For more about return data see the [documentation for the return data proposal][rdp]. -/// -/// [rdp]: https://docs.solanalabs.com/proposals/return-data -#[inline] -pub fn get_return_data() -> Option { - #[cfg(target_os = "solana")] - { - 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 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 _ as *mut u8, - ) - }; - - if size == 0 { - None - } else { - Some(ReturnData { - program_id: unsafe { program_id.assume_init() }, - data, - size: core::cmp::min(size as usize, MAX_RETURN_DATA), - }) - } - } - - #[cfg(not(target_os = "solana"))] - core::hint::black_box(None) -} - -/// Struct to hold the return data from an invoked program. -#[derive(Debug)] -pub struct ReturnData { - /// Program that most recently set the return data. - program_id: Address, - - /// Return data set by the program. - data: [MaybeUninit; MAX_RETURN_DATA], - - /// Length of the return data. - size: usize, -} - -impl ReturnData { - /// Returns the program that most recently set the return data. - pub fn program_id(&self) -> &Address { - &self.program_id - } - - /// Return the data set by the program. - pub fn as_slice(&self) -> &[u8] { - unsafe { from_raw_parts(self.data.as_ptr() as _, self.size) } - } -} - -impl Deref for ReturnData { - type Target = [u8]; - - fn deref(&self) -> &Self::Target { - self.as_slice() - } -} diff --git a/sdk/pinocchio/src/instruction.rs b/sdk/pinocchio/src/instruction.rs deleted file mode 100644 index 5be15b72..00000000 --- a/sdk/pinocchio/src/instruction.rs +++ /dev/null @@ -1,300 +0,0 @@ -//! Instruction types. - -use core::{marker::PhantomData, ops::Deref}; - -use crate::{account::AccountView, Address}; - -/// Information about a CPI instruction. -#[derive(Debug, Clone)] -pub struct Instruction<'a, 'b, 'c, 'd> -where - 'a: 'b, -{ - /// Address of the program. - pub program_id: &'c Address, - - /// Data expected by the program instruction. - pub data: &'d [u8], - - /// Metadata describing accounts that should be passed to the program. - pub accounts: &'b [AccountMeta<'a>], -} - -/// Use to query and convey information about the sibling instruction components -/// when calling the `sol_get_processed_sibling_instruction` syscall. -#[repr(C)] -#[cfg_attr(feature = "copy", derive(Copy))] -#[derive(Clone, Debug, Default, Eq, PartialEq)] -pub struct ProcessedSiblingInstruction { - /// Length of the instruction data - pub data_len: u64, - - /// Number of `AccountMeta` structures - pub accounts_len: u64, -} - -/// An `Account` for CPI invocations. -/// -/// This struct contains the same information as an [`AccountView`], but has -/// the memory layout as expected by `sol_invoke_signed_c` syscall. -#[repr(C)] -#[cfg_attr(feature = "copy", derive(Copy))] -#[derive(Clone, Debug)] -pub struct Account<'a> { - // Address of the account. - key: *const Address, - - // Number of lamports owned by this account. - lamports: *const u64, - - // Length of data in bytes. - data_len: u64, - - // On-chain data within this account. - data: *const u8, - - // Program that owns this account. - owner: *const Address, - - // The epoch at which this account will next owe rent. - rent_epoch: u64, - - // Transaction was signed by this account's key? - is_signer: bool, - - // Is the account writable? - is_writable: bool, - - // This account's data contains a loaded program (and is now read-only). - executable: bool, - - /// The pointers to the `AccountView` data are only valid for as long as the - /// `&'a AccountView` lives. Instead of holding a reference to the actual `AccountView`, - /// which would increase the size of the type, we claim to hold a reference without - /// actually holding one using a `PhantomData<&'a AccountInfo>`. - _account_info: PhantomData<&'a AccountView>, -} - -impl<'a> From<&'a AccountView> for Account<'a> { - fn from(account: &'a AccountView) -> Self { - Account { - key: account.address(), - lamports: &account.lamports(), - data_len: account.data_len() as u64, - data: account.data_ptr(), - owner: unsafe { account.owner() }, - // The `rent_epoch` field is not present in the `AccountView` struct, - // since the value occurs after the variable data of the account in - // the runtime input data. - rent_epoch: 0, - is_signer: account.is_signer(), - is_writable: account.is_writable(), - executable: account.executable(), - _account_info: PhantomData::<&'a AccountView>, - } - } -} - -/// Describes a single account read or written by a program during instruction -/// execution. -/// -/// When constructing an [`Instruction`], a list of all accounts that may be -/// read or written during the execution of that instruction must be supplied. -/// Any account that may be mutated by the program during execution, either its -/// data or metadata such as held lamports, must be writable. -/// -/// Note that because the Solana runtime schedules parallel transaction -/// execution around which accounts are writable, care should be taken that only -/// accounts which actually may be mutated are specified as writable. -#[repr(C)] -#[derive(Debug, Clone)] -pub struct AccountMeta<'a> { - /// Address of the account. - pub address: &'a Address, - - /// Indicates whether the account is writable or not. - pub is_writable: bool, - - /// Indicates whether the account signed the instruction or not. - pub is_signer: bool, -} - -impl<'a> AccountMeta<'a> { - /// Creates a new `AccountMeta`. - #[inline(always)] - pub const fn new(address: &'a Address, is_writable: bool, is_signer: bool) -> Self { - Self { - address, - is_writable, - is_signer, - } - } - - /// Creates a new read-only `AccountMeta`. - #[inline(always)] - pub const fn readonly(address: &'a Address) -> Self { - Self::new(address, false, false) - } - - /// Creates a new writable `AccountMeta`. - #[inline(always)] - 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(address: &'a Address) -> Self { - Self::new(address, false, true) - } - - /// Creates a new writable and signer `AccountMeta`. - #[inline(always)] - pub const fn writable_signer(address: &'a Address) -> Self { - Self::new(address, true, true) - } -} - -impl<'a> From<&'a AccountView> for AccountMeta<'a> { - fn from(account: &'a AccountView) -> Self { - AccountMeta::new( - account.address(), - account.is_writable(), - account.is_signer(), - ) - } -} - -/// Represents a signer seed. -/// -/// This struct contains the same information as a `[u8]`, but -/// has the memory layout as expected by `sol_invoke_signed_c` -/// syscall. -#[repr(C)] -#[derive(Debug, Clone)] -pub struct Seed<'a> { - /// Seed bytes. - pub(crate) seed: *const u8, - - /// Length of the seed bytes. - pub(crate) len: u64, - - /// The pointer to the seed bytes is only valid while the `&'a [u8]` lives. Instead - /// of holding a reference to the actual `[u8]`, which would increase the size of the - /// type, we claim to hold a reference without actually holding one using a - /// `PhantomData<&'a [u8]>`. - _bytes: PhantomData<&'a [u8]>, -} - -impl<'a> From<&'a [u8]> for Seed<'a> { - fn from(value: &'a [u8]) -> Self { - Self { - seed: value.as_ptr(), - len: value.len() as u64, - _bytes: PhantomData::<&[u8]>, - } - } -} - -impl<'a, const SIZE: usize> From<&'a [u8; SIZE]> for Seed<'a> { - fn from(value: &'a [u8; SIZE]) -> Self { - Self { - seed: value.as_ptr(), - len: value.len() as u64, - _bytes: PhantomData::<&[u8]>, - } - } -} - -impl Deref for Seed<'_> { - type Target = [u8]; - - fn deref(&self) -> &Self::Target { - unsafe { core::slice::from_raw_parts(self.seed, self.len as usize) } - } -} - -/// Represents a [program derived address][pda] (PDA) signer controlled by the -/// calling program. -/// -/// [pda]: https://solana.com/docs/core/cpi#program-derived-addresses -#[repr(C)] -#[derive(Debug, Clone)] -pub struct Signer<'a, 'b> { - /// Signer seeds. - pub(crate) seeds: *const Seed<'a>, - - /// Number of seeds. - pub(crate) len: u64, - - /// The pointer to the seeds is only valid while the `&'b [Seed<'a>]` lives. Instead - /// of holding a reference to the actual `[Seed<'a>]`, which would increase the size - /// of the type, we claim to hold a reference without actually holding one using a - /// `PhantomData<&'b [Seed<'a>]>`. - _seeds: PhantomData<&'b [Seed<'a>]>, -} - -impl<'a, 'b> From<&'b [Seed<'a>]> for Signer<'a, 'b> { - fn from(value: &'b [Seed<'a>]) -> Self { - Self { - seeds: value.as_ptr(), - len: value.len() as u64, - _seeds: PhantomData::<&'b [Seed<'a>]>, - } - } -} - -impl<'a, 'b, const SIZE: usize> From<&'b [Seed<'a>; SIZE]> for Signer<'a, 'b> { - fn from(value: &'b [Seed<'a>; SIZE]) -> Self { - Self { - seeds: value.as_ptr(), - len: value.len() as u64, - _seeds: PhantomData::<&'b [Seed<'a>]>, - } - } -} - -/// Convenience macro for constructing a `Signer` from a list of seeds -/// represented as byte slices. -/// -/// # Example -/// -/// Creating a signer for a PDA with a single seed and bump value: -/// ``` -/// use pinocchio::signer; -/// -/// let pda_bump = 255; -/// let signer = signer!(b"seed", &[pda_bump]); -/// ``` -#[macro_export] -#[deprecated(since = "0.8.0", note = "Use `seeds!` macro instead")] -macro_rules! signer { - ( $($seed:expr),* ) => { - $crate::instruction::Signer::from(&[$( - $seed.into(), - )*]) - }; -} - -/// Convenience macro for constructing a `[Seed; N]` array from a list of seeds. -/// -/// # Example -/// -/// Creating seeds array and signer for a PDA with a single seed and bump value: -/// ``` -/// use pinocchio::{seeds, instruction::Signer, Address}; -/// -/// let pda_bump = 0xffu8; -/// let pda_ref = &[pda_bump]; // prevent temporary value being freed -/// let example_key = Address::default(); -/// let seeds = seeds!(b"seed", example_key.as_ref(), pda_ref); -/// let signer = Signer::from(&seeds); -/// ``` -#[macro_export] -macro_rules! seeds { - ( $($seed:expr),* ) => { - [$( - $crate::instruction::Seed::from($seed), - )*] - }; -} diff --git a/sdk/pinocchio/src/lib.rs b/sdk/pinocchio/src/lib.rs index 24fb66f4..d0d161f8 100644 --- a/sdk/pinocchio/src/lib.rs +++ b/sdk/pinocchio/src/lib.rs @@ -1,13 +1,16 @@ //! # Pinocchio //! -//! Pinocchio is a zero-dependency library to create Solana programs in Rust. -//! It takes advantage of the way SVM loaders serialize the program input parameters -//! into a byte array that is then passed to the program's entrypoint to define -//! zero-copy types to read the input - these types are defined in an efficient way -//! taking into consideration that they will be used in on-chain programs. +//! Pinocchio is a "no-external" dependencies library to create Solana programs +//! in Rust, which means that the only dependencies are from the Solana SDK. This +//! reduces the chance of dependency conflicts when compiling the program. +//! +//! It takes advantage of the way SVM loaders serialize the program input +//! parameters into a byte array that is then passed to the program's entrypoint +//! to use zero-copy types to read the input - these types are defined in an efficient +//! way taking into consideration that they will be used in on-chain programs. //! //! It is intended to be used by on-chain programs only; for off-chain programs, -//! use instead the [`solana-sdk`] crate. +//! use instead [`solana-sdk`] crates. //! //! [`solana-sdk`]: https://docs.rs/solana-sdk/latest/solana_sdk/ //! @@ -31,10 +34,10 @@ //! ```ignore //! use pinocchio::{ //! AccountView, +//! Address, //! entrypoint, //! msg, -//! ProgramResult, -//! Address +//! ProgramResult //! }; //! //! entrypoint!(process_instruction); @@ -71,7 +74,7 @@ //! ### [`lazy_program_entrypoint!`] //! //! The [`entrypoint!`] macro looks similar to the "standard" one found in -//! [`solana-program`](https://docs.rs/solana-program-entrypoint/latest/solana_program_entrypoint/macro.entrypoint.html). +//! [`solana-program-entrypoint`](https://docs.rs/solana-program-entrypoint/latest/solana_program_entrypoint/macro.entrypoint.html). //! It parses the whole input and provides the `program_id`, `accounts` and //! `instruction_data` separately. This consumes compute units before the program //! begins its execution. In some cases, it is beneficial for a program to have @@ -137,12 +140,12 @@ //! ```ignore //! use pinocchio::{ //! AccountView, +//! Address, //! default_panic_handler, //! msg, //! no_allocator, //! program_entrypoint, -//! ProgramResult, -//! Address +//! ProgramResult //! }; //! //! program_entrypoint!(process_instruction); @@ -194,10 +197,10 @@ //! mod entrypoint { //! use pinocchio::{ //! AccountView, +//! Address, //! entrypoint, //! msg, -//! ProgramResult, -//! Address +//! ProgramResult //! }; //! //! entrypoint!(process_instruction); @@ -223,20 +226,15 @@ #[cfg(feature = "std")] extern crate std; -pub mod cpi; pub mod entrypoint; -pub mod instruction; pub mod log; pub mod memory; -#[deprecated(since = "0.8.0", note = "Use the `cpi` module instead")] -pub mod program { - pub use crate::cpi::*; -} 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_account_view` for downstream use. pub use solana_account_view as account; @@ -244,6 +242,10 @@ pub use solana_account_view as account; pub use solana_address as address; pub use solana_address::Address; +// Re-export the `solana_instruction_view` for downstream use. +#[cfg(feature = "cpi")] +pub use {solana_instruction_view as instruction, solana_instruction_view::cpi}; + // 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/syscalls.rs b/sdk/pinocchio/src/syscalls.rs index cb3f7d9b..b98157ed 100644 --- a/sdk/pinocchio/src/syscalls.rs +++ b/sdk/pinocchio/src/syscalls.rs @@ -1,9 +1,6 @@ //! Syscall functions. -use crate::{ - instruction::{AccountMeta, ProcessedSiblingInstruction}, - Address, -}; +use crate::Address; #[cfg(target_feature = "static-syscalls")] macro_rules! define_syscall { @@ -63,7 +60,7 @@ define_syscall!(fn sol_invoke_signed_rust(instruction_addr: *const u8, account_i 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 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 Address, data: *mut u8, accounts: *mut AccountMeta) -> u64); +define_syscall!(fn sol_get_processed_sibling_instruction(index: u64, meta: *mut u8, program_id: *mut Address, data: *mut u8, accounts: *mut u8) -> 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/instructions.rs b/sdk/pinocchio/src/sysvars/instructions.rs index fe6bf3d9..2a1e1f39 100644 --- a/sdk/pinocchio/src/sysvars/instructions.rs +++ b/sdk/pinocchio/src/sysvars/instructions.rs @@ -1,10 +1,13 @@ +use core::{marker::PhantomData, mem::size_of, ops::Deref}; + +#[cfg(feature = "cpi")] +use crate::instruction::AccountRole; use crate::{ account::{AccountView, Ref}, - address::{Address, ADDRESS_BYTES}, + address::ADDRESS_BYTES, error::ProgramError, - instruction::AccountMeta, + Address, }; -use core::{marker::PhantomData, mem::size_of, ops::Deref}; /// Instructions sysvar ID `Sysvar1nstructions1111111111111111111111111`. pub const INSTRUCTIONS_ID: Address = Address::new_from_array([ @@ -143,9 +146,9 @@ impl IntrospectedInstruction<'_> { /// performs the necessary index verification. However, to optimize performance for users /// who are sure that the index is in bounds, we have exposed it as an unsafe function. #[inline(always)] - pub unsafe fn get_account_meta_at_unchecked(&self, index: usize) -> &IntrospectedAccountMeta { - let offset = core::mem::size_of::() + (index * IntrospectedAccountMeta::LEN); - &*(self.raw.add(offset) as *const IntrospectedAccountMeta) + pub unsafe fn get_account_meta_at_unchecked(&self, index: usize) -> &IntrospectedAccountRole { + let offset = core::mem::size_of::() + (index * IntrospectedAccountRole::LEN); + &*(self.raw.add(offset) as *const IntrospectedAccountRole) } /// Get the account meta at the specified index. @@ -157,7 +160,7 @@ impl IntrospectedInstruction<'_> { pub fn get_account_meta_at( &self, index: usize, - ) -> Result<&IntrospectedAccountMeta, ProgramError> { + ) -> Result<&IntrospectedAccountRole, ProgramError> { // 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]) }); @@ -178,7 +181,7 @@ impl IntrospectedInstruction<'_> { // SAFETY: The program ID is located after the account metas. unsafe { &*(self.raw.add( - size_of::() + num_accounts as usize * size_of::(), + size_of::() + num_accounts as usize * size_of::(), ) as *const Address) } } @@ -188,7 +191,7 @@ impl IntrospectedInstruction<'_> { pub fn get_instruction_data(&self) -> &[u8] { // 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::() + * size_of::() + ADDRESS_BYTES; // SAFETY: The instruction data length is located after the program ID. @@ -206,16 +209,16 @@ impl IntrospectedInstruction<'_> { } } -/// The bit positions for the signer flags in the `AccountMeta`. +/// The bit positions for the signer flags in the `AccountRole`. const IS_SIGNER: u8 = 0b00000001; -/// The bit positions for the writable flags in the `AccountMeta`. +/// The bit positions for the writable flags in the `AccountRole`. const IS_WRITABLE: u8 = 0b00000010; #[repr(C)] #[cfg_attr(feature = "copy", derive(Copy))] #[derive(Clone, Debug, Eq, PartialEq)] -pub struct IntrospectedAccountMeta { +pub struct IntrospectedAccountRole { /// Account flags: /// * bit `0`: signer /// * bit `1`: writable @@ -225,7 +228,7 @@ pub struct IntrospectedAccountMeta { pub key: Address, } -impl IntrospectedAccountMeta { +impl IntrospectedAccountRole { const LEN: usize = core::mem::size_of::(); /// Indicate whether the account is writable or not. @@ -240,9 +243,10 @@ impl IntrospectedAccountMeta { (self.flags & IS_SIGNER) != 0 } - /// Convert the `IntrospectedAccountMeta` to an `AccountMeta`. + #[cfg(feature = "cpi")] + /// Convert the `IntrospectedAccountRole` to an `AccountRole`. #[inline(always)] - pub fn to_account_meta(&self) -> AccountMeta { - AccountMeta::new(&self.key, self.is_writable(), self.is_signer()) + pub fn to_account_role(&self) -> AccountRole { + AccountRole::new(&self.key, self.is_writable(), self.is_signer()) } } diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs b/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs index a26a760f..a81fa4bd 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs @@ -13,6 +13,8 @@ mod test_raw; #[cfg(test)] mod test_utils; +use core::{mem, ops::Deref, slice::from_raw_parts}; + use crate::{ account::{AccountView, Ref}, error::ProgramError, @@ -20,7 +22,7 @@ use crate::{ sysvars::clock::Slot, Address, }; -use core::{mem, ops::Deref, slice::from_raw_parts}; + #[cfg(feature = "std")] use std::boxed::Box;