Skip to content
This repository has been archived by the owner on Jan 10, 2025. It is now read-only.

Commit

Permalink
record: Remove dependency on solana-program (#7445)
Browse files Browse the repository at this point in the history
#### Problem

It's possible to write programs without solana-program, but spl-record
still has a dependency on it.

#### Summary of changes

Mostly straightforward, replacing the crates with their components. I
also removed a dependency on spl-pod, because that brings in
solana-zk-sdk, which does require solana-program currently.
  • Loading branch information
joncinque authored Nov 4, 2024
1 parent 412f94d commit 04f4942
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 67 deletions.
11 changes: 9 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions record/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,16 @@ test-sbf = []
bytemuck = { version = "1.19.0", features = ["derive"] }
num-derive = "0.4"
num-traits = "0.2"
solana-program = "2.1.0"
solana-account-info = "2.1.0"
solana-decode-error = "2.1.0"
solana-instruction = { version = "2.1.0", features = ["std"] }
solana-msg = "2.1.0"
solana-program-entrypoint = "2.1.0"
solana-program-error = "2.1.0"
solana-program-pack = "2.1.0"
solana-pubkey = { version = "2.1.0", features = ["bytemuck"] }
solana-rent = "2.1.0"
thiserror = "1.0"
spl-pod = { version = "0.5.0", path = "../../libraries/pod" }

[dev-dependencies]
solana-program-test = "2.1.0"
Expand Down
2 changes: 0 additions & 2 deletions record/program/Xargo.toml

This file was deleted.

6 changes: 4 additions & 2 deletions record/program/src/entrypoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#![cfg(all(target_os = "solana", not(feature = "no-entrypoint")))]

use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};
use {
solana_account_info::AccountInfo, solana_program_error::ProgramResult, solana_pubkey::Pubkey,
};

solana_program::entrypoint!(process_instruction);
solana_program_entrypoint::entrypoint!(process_instruction);
fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
Expand Down
5 changes: 2 additions & 3 deletions record/program/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//! Error types
use {
num_derive::FromPrimitive,
solana_program::{decode_error::DecodeError, program_error::ProgramError},
thiserror::Error,
num_derive::FromPrimitive, solana_decode_error::DecodeError,
solana_program_error::ProgramError, thiserror::Error,
};

/// Errors that may be returned by the program.
Expand Down
10 changes: 4 additions & 6 deletions record/program/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
use {
crate::id,
solana_program::{
instruction::{AccountMeta, Instruction},
program_error::ProgramError,
pubkey::Pubkey,
},
solana_instruction::{AccountMeta, Instruction},
solana_program_error::ProgramError,
solana_pubkey::Pubkey,
std::mem::size_of,
};

Expand Down Expand Up @@ -203,7 +201,7 @@ pub fn reallocate(record_account: &Pubkey, signer: &Pubkey, data_length: u64) ->

#[cfg(test)]
mod tests {
use {super::*, crate::state::tests::TEST_BYTES, solana_program::program_error::ProgramError};
use {super::*, crate::state::tests::TEST_BYTES, solana_program_error::ProgramError};

#[test]
fn serialize_initialize() {
Expand Down
7 changes: 5 additions & 2 deletions record/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ pub mod state;

// Export current SDK types for downstream users building with a different SDK
// version
pub use solana_program;
pub use {
solana_account_info, solana_decode_error, solana_instruction, solana_msg,
solana_program_entrypoint, solana_program_error, solana_program_pack, solana_pubkey,
};

solana_program::declare_id!("recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5");
solana_pubkey::declare_id!("recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5");
42 changes: 22 additions & 20 deletions record/program/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@
use {
crate::{error::RecordError, instruction::RecordInstruction, state::RecordData},
solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
msg,
program_error::ProgramError,
program_pack::IsInitialized,
pubkey::Pubkey,
},
spl_pod::bytemuck::{pod_from_bytes, pod_from_bytes_mut, pod_get_packed_len},
solana_account_info::{next_account_info, AccountInfo},
solana_msg::msg,
solana_program_error::{ProgramError, ProgramResult},
solana_program_pack::IsInitialized,
solana_pubkey::Pubkey,
};

fn check_authority(authority_info: &AccountInfo, expected_authority: &Pubkey) -> ProgramResult {
Expand Down Expand Up @@ -46,9 +42,10 @@ pub fn process_instruction(
return Err(ProgramError::InvalidAccountData);
}

let account_data = pod_from_bytes_mut::<RecordData>(
let account_data = bytemuck::try_from_bytes_mut::<RecordData>(
&mut raw_data[..RecordData::WRITABLE_START_INDEX],
)?;
)
.map_err(|_| ProgramError::InvalidArgument)?;
if account_data.is_initialized() {
msg!("Record account already initialized");
return Err(ProgramError::AccountAlreadyInitialized);
Expand All @@ -68,8 +65,10 @@ pub fn process_instruction(
if raw_data.len() < RecordData::WRITABLE_START_INDEX {
return Err(ProgramError::InvalidAccountData);
}
let account_data =
pod_from_bytes::<RecordData>(&raw_data[..RecordData::WRITABLE_START_INDEX])?;
let account_data = bytemuck::try_from_bytes::<RecordData>(
&raw_data[..RecordData::WRITABLE_START_INDEX],
)
.map_err(|_| ProgramError::InvalidArgument)?;
if !account_data.is_initialized() {
msg!("Record account not initialized");
return Err(ProgramError::UninitializedAccount);
Expand All @@ -95,9 +94,10 @@ pub fn process_instruction(
if raw_data.len() < RecordData::WRITABLE_START_INDEX {
return Err(ProgramError::InvalidAccountData);
}
let account_data = pod_from_bytes_mut::<RecordData>(
let account_data = bytemuck::try_from_bytes_mut::<RecordData>(
&mut raw_data[..RecordData::WRITABLE_START_INDEX],
)?;
)
.map_err(|_| ProgramError::InvalidArgument)?;
if !account_data.is_initialized() {
msg!("Record account not initialized");
return Err(ProgramError::UninitializedAccount);
Expand All @@ -116,9 +116,10 @@ pub fn process_instruction(
if raw_data.len() < RecordData::WRITABLE_START_INDEX {
return Err(ProgramError::InvalidAccountData);
}
let account_data = pod_from_bytes_mut::<RecordData>(
let account_data = bytemuck::try_from_bytes_mut::<RecordData>(
&mut raw_data[..RecordData::WRITABLE_START_INDEX],
)?;
)
.map_err(|_| ProgramError::InvalidArgument)?;
if !account_data.is_initialized() {
msg!("Record not initialized");
return Err(ProgramError::UninitializedAccount);
Expand All @@ -143,9 +144,10 @@ pub fn process_instruction(
if raw_data.len() < RecordData::WRITABLE_START_INDEX {
return Err(ProgramError::InvalidAccountData);
}
let account_data = pod_from_bytes_mut::<RecordData>(
let account_data = bytemuck::try_from_bytes_mut::<RecordData>(
&mut raw_data[..RecordData::WRITABLE_START_INDEX],
)?;
)
.map_err(|_| ProgramError::InvalidArgument)?;
if !account_data.is_initialized() {
msg!("Record not initialized");
return Err(ProgramError::UninitializedAccount);
Expand All @@ -155,7 +157,7 @@ pub fn process_instruction(

// needed account length is the sum of the meta data length and the specified
// data length
let needed_account_length = pod_get_packed_len::<RecordData>()
let needed_account_length = std::mem::size_of::<RecordData>()
.checked_add(
usize::try_from(data_length).map_err(|_| ProgramError::InvalidArgument)?,
)
Expand Down
17 changes: 8 additions & 9 deletions record/program/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Program state
use {
bytemuck::{Pod, Zeroable},
solana_program::{program_pack::IsInitialized, pubkey::Pubkey},
solana_program_pack::IsInitialized,
solana_pubkey::Pubkey,
};

/// Header type for recorded account data
Expand Down Expand Up @@ -32,11 +33,7 @@ impl IsInitialized for RecordData {

#[cfg(test)]
pub mod tests {
use {
super::*,
solana_program::program_error::ProgramError,
spl_pod::bytemuck::{pod_bytes_of, pod_from_bytes},
};
use {super::*, solana_program_error::ProgramError};

/// Version for tests
pub const TEST_VERSION: u8 = 1;
Expand All @@ -54,9 +51,9 @@ pub mod tests {
fn serialize_data() {
let mut expected = vec![TEST_VERSION];
expected.extend_from_slice(&TEST_PUBKEY.to_bytes());
assert_eq!(pod_bytes_of(&TEST_RECORD_DATA), expected);
assert_eq!(bytemuck::bytes_of(&TEST_RECORD_DATA), expected);
assert_eq!(
*pod_from_bytes::<RecordData>(&expected).unwrap(),
*bytemuck::try_from_bytes::<RecordData>(&expected).unwrap(),
TEST_RECORD_DATA,
);
}
Expand All @@ -66,7 +63,9 @@ pub mod tests {
let mut expected = vec![TEST_VERSION];
expected.extend_from_slice(&TEST_PUBKEY.to_bytes());
expected.extend_from_slice(&TEST_BYTES);
let err: ProgramError = pod_from_bytes::<RecordData>(&expected).unwrap_err();
let err = bytemuck::try_from_bytes::<RecordData>(&expected)
.map_err(|_| ProgramError::InvalidArgument)
.unwrap_err();
assert_eq!(err, ProgramError::InvalidArgument);
}
}
40 changes: 21 additions & 19 deletions record/program/tests/functional.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
#![cfg(feature = "test-sbf")]

use {
solana_program::{
instruction::{AccountMeta, Instruction, InstructionError},
pubkey::Pubkey,
rent::Rent,
system_instruction,
},
solana_instruction::{error::InstructionError, AccountMeta, Instruction},
solana_program_test::*,
solana_pubkey::Pubkey,
solana_rent::Rent,
solana_sdk::{
signature::{Keypair, Signer},
system_instruction,
transaction::{Transaction, TransactionError},
},
spl_pod::bytemuck::{pod_from_bytes, pod_get_packed_len},
spl_record::{
error::RecordError, id, instruction, processor::process_instruction, state::RecordData,
},
Expand All @@ -28,7 +25,7 @@ async fn initialize_storage_account(
account: &Keypair,
data: &[u8],
) {
let account_length = pod_get_packed_len::<RecordData>()
let account_length = std::mem::size_of::<RecordData>()
.checked_add(data.len())
.unwrap();
let transaction = Transaction::new_signed_with_payer(
Expand Down Expand Up @@ -70,7 +67,8 @@ async fn initialize_success() {
.unwrap()
.unwrap();
let account_data =
pod_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX]).unwrap();
bytemuck::try_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX])
.unwrap();
assert_eq!(account_data.authority, authority.pubkey());
assert_eq!(account_data.version, RecordData::CURRENT_VERSION);
assert_eq!(&account.data[RecordData::WRITABLE_START_INDEX..], data);
Expand All @@ -84,7 +82,7 @@ async fn initialize_with_seed_success() {
let seed = "storage";
let account = Pubkey::create_with_seed(&authority.pubkey(), seed, &id()).unwrap();
let data = &[111u8; 8];
let account_length = pod_get_packed_len::<RecordData>()
let account_length = std::mem::size_of::<RecordData>()
.checked_add(data.len())
.unwrap();
let transaction = Transaction::new_signed_with_payer(
Expand Down Expand Up @@ -117,7 +115,8 @@ async fn initialize_with_seed_success() {
.unwrap()
.unwrap();
let account_data =
pod_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX]).unwrap();
bytemuck::try_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX])
.unwrap();
assert_eq!(account_data.authority, authority.pubkey());
assert_eq!(account_data.version, RecordData::CURRENT_VERSION);
assert_eq!(&account.data[RecordData::WRITABLE_START_INDEX..], data);
Expand Down Expand Up @@ -185,7 +184,8 @@ async fn write_success() {
.unwrap()
.unwrap();
let account_data =
pod_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX]).unwrap();
bytemuck::try_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX])
.unwrap();
assert_eq!(account_data.authority, authority.pubkey());
assert_eq!(account_data.version, RecordData::CURRENT_VERSION);
assert_eq!(&account.data[RecordData::WRITABLE_START_INDEX..], new_data);
Expand Down Expand Up @@ -269,7 +269,7 @@ async fn close_account_success() {
let authority = Keypair::new();
let account = Keypair::new();
let data = &[222u8; 8];
let account_length = pod_get_packed_len::<RecordData>()
let account_length = std::mem::size_of::<RecordData>()
.checked_add(data.len())
.unwrap();
initialize_storage_account(&mut context, &authority, &account, data).await;
Expand Down Expand Up @@ -407,9 +407,10 @@ async fn set_authority_success() {
.await
.unwrap()
.unwrap();
let account_data =
pod_from_bytes::<RecordData>(&account_handle.data[..RecordData::WRITABLE_START_INDEX])
.unwrap();
let account_data = bytemuck::try_from_bytes::<RecordData>(
&account_handle.data[..RecordData::WRITABLE_START_INDEX],
)
.unwrap();
assert_eq!(account_data.authority, new_authority.pubkey());

let new_data = &[200u8; 8];
Expand All @@ -436,9 +437,10 @@ async fn set_authority_success() {
.await
.unwrap()
.unwrap();
let account_data =
pod_from_bytes::<RecordData>(&account_handle.data[..RecordData::WRITABLE_START_INDEX])
.unwrap();
let account_data = bytemuck::try_from_bytes::<RecordData>(
&account_handle.data[..RecordData::WRITABLE_START_INDEX],
)
.unwrap();
assert_eq!(account_data.authority, new_authority.pubkey());
assert_eq!(account_data.version, RecordData::CURRENT_VERSION);
assert_eq!(
Expand Down

0 comments on commit 04f4942

Please sign in to comment.