Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 04f4942

Browse files
authored
record: Remove dependency on solana-program (#7445)
#### 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.
1 parent 412f94d commit 04f4942

File tree

10 files changed

+84
-67
lines changed

10 files changed

+84
-67
lines changed

Cargo.lock

Lines changed: 9 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

record/program/Cargo.toml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,16 @@ test-sbf = []
1515
bytemuck = { version = "1.19.0", features = ["derive"] }
1616
num-derive = "0.4"
1717
num-traits = "0.2"
18-
solana-program = "2.1.0"
18+
solana-account-info = "2.1.0"
19+
solana-decode-error = "2.1.0"
20+
solana-instruction = { version = "2.1.0", features = ["std"] }
21+
solana-msg = "2.1.0"
22+
solana-program-entrypoint = "2.1.0"
23+
solana-program-error = "2.1.0"
24+
solana-program-pack = "2.1.0"
25+
solana-pubkey = { version = "2.1.0", features = ["bytemuck"] }
26+
solana-rent = "2.1.0"
1927
thiserror = "1.0"
20-
spl-pod = { version = "0.5.0", path = "../../libraries/pod" }
2128

2229
[dev-dependencies]
2330
solana-program-test = "2.1.0"

record/program/Xargo.toml

Lines changed: 0 additions & 2 deletions
This file was deleted.

record/program/src/entrypoint.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
33
#![cfg(all(target_os = "solana", not(feature = "no-entrypoint")))]
44

5-
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};
5+
use {
6+
solana_account_info::AccountInfo, solana_program_error::ProgramResult, solana_pubkey::Pubkey,
7+
};
68

7-
solana_program::entrypoint!(process_instruction);
9+
solana_program_entrypoint::entrypoint!(process_instruction);
810
fn process_instruction(
911
program_id: &Pubkey,
1012
accounts: &[AccountInfo],

record/program/src/error.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
//! Error types
22
33
use {
4-
num_derive::FromPrimitive,
5-
solana_program::{decode_error::DecodeError, program_error::ProgramError},
6-
thiserror::Error,
4+
num_derive::FromPrimitive, solana_decode_error::DecodeError,
5+
solana_program_error::ProgramError, thiserror::Error,
76
};
87

98
/// Errors that may be returned by the program.

record/program/src/instruction.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22
33
use {
44
crate::id,
5-
solana_program::{
6-
instruction::{AccountMeta, Instruction},
7-
program_error::ProgramError,
8-
pubkey::Pubkey,
9-
},
5+
solana_instruction::{AccountMeta, Instruction},
6+
solana_program_error::ProgramError,
7+
solana_pubkey::Pubkey,
108
std::mem::size_of,
119
};
1210

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

204202
#[cfg(test)]
205203
mod tests {
206-
use {super::*, crate::state::tests::TEST_BYTES, solana_program::program_error::ProgramError};
204+
use {super::*, crate::state::tests::TEST_BYTES, solana_program_error::ProgramError};
207205

208206
#[test]
209207
fn serialize_initialize() {

record/program/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ pub mod state;
99

1010
// Export current SDK types for downstream users building with a different SDK
1111
// version
12-
pub use solana_program;
12+
pub use {
13+
solana_account_info, solana_decode_error, solana_instruction, solana_msg,
14+
solana_program_entrypoint, solana_program_error, solana_program_pack, solana_pubkey,
15+
};
1316

14-
solana_program::declare_id!("recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5");
17+
solana_pubkey::declare_id!("recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5");

record/program/src/processor.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,11 @@
22
33
use {
44
crate::{error::RecordError, instruction::RecordInstruction, state::RecordData},
5-
solana_program::{
6-
account_info::{next_account_info, AccountInfo},
7-
entrypoint::ProgramResult,
8-
msg,
9-
program_error::ProgramError,
10-
program_pack::IsInitialized,
11-
pubkey::Pubkey,
12-
},
13-
spl_pod::bytemuck::{pod_from_bytes, pod_from_bytes_mut, pod_get_packed_len},
5+
solana_account_info::{next_account_info, AccountInfo},
6+
solana_msg::msg,
7+
solana_program_error::{ProgramError, ProgramResult},
8+
solana_program_pack::IsInitialized,
9+
solana_pubkey::Pubkey,
1410
};
1511

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

49-
let account_data = pod_from_bytes_mut::<RecordData>(
45+
let account_data = bytemuck::try_from_bytes_mut::<RecordData>(
5046
&mut raw_data[..RecordData::WRITABLE_START_INDEX],
51-
)?;
47+
)
48+
.map_err(|_| ProgramError::InvalidArgument)?;
5249
if account_data.is_initialized() {
5350
msg!("Record account already initialized");
5451
return Err(ProgramError::AccountAlreadyInitialized);
@@ -68,8 +65,10 @@ pub fn process_instruction(
6865
if raw_data.len() < RecordData::WRITABLE_START_INDEX {
6966
return Err(ProgramError::InvalidAccountData);
7067
}
71-
let account_data =
72-
pod_from_bytes::<RecordData>(&raw_data[..RecordData::WRITABLE_START_INDEX])?;
68+
let account_data = bytemuck::try_from_bytes::<RecordData>(
69+
&raw_data[..RecordData::WRITABLE_START_INDEX],
70+
)
71+
.map_err(|_| ProgramError::InvalidArgument)?;
7372
if !account_data.is_initialized() {
7473
msg!("Record account not initialized");
7574
return Err(ProgramError::UninitializedAccount);
@@ -95,9 +94,10 @@ pub fn process_instruction(
9594
if raw_data.len() < RecordData::WRITABLE_START_INDEX {
9695
return Err(ProgramError::InvalidAccountData);
9796
}
98-
let account_data = pod_from_bytes_mut::<RecordData>(
97+
let account_data = bytemuck::try_from_bytes_mut::<RecordData>(
9998
&mut raw_data[..RecordData::WRITABLE_START_INDEX],
100-
)?;
99+
)
100+
.map_err(|_| ProgramError::InvalidArgument)?;
101101
if !account_data.is_initialized() {
102102
msg!("Record account not initialized");
103103
return Err(ProgramError::UninitializedAccount);
@@ -116,9 +116,10 @@ pub fn process_instruction(
116116
if raw_data.len() < RecordData::WRITABLE_START_INDEX {
117117
return Err(ProgramError::InvalidAccountData);
118118
}
119-
let account_data = pod_from_bytes_mut::<RecordData>(
119+
let account_data = bytemuck::try_from_bytes_mut::<RecordData>(
120120
&mut raw_data[..RecordData::WRITABLE_START_INDEX],
121-
)?;
121+
)
122+
.map_err(|_| ProgramError::InvalidArgument)?;
122123
if !account_data.is_initialized() {
123124
msg!("Record not initialized");
124125
return Err(ProgramError::UninitializedAccount);
@@ -143,9 +144,10 @@ pub fn process_instruction(
143144
if raw_data.len() < RecordData::WRITABLE_START_INDEX {
144145
return Err(ProgramError::InvalidAccountData);
145146
}
146-
let account_data = pod_from_bytes_mut::<RecordData>(
147+
let account_data = bytemuck::try_from_bytes_mut::<RecordData>(
147148
&mut raw_data[..RecordData::WRITABLE_START_INDEX],
148-
)?;
149+
)
150+
.map_err(|_| ProgramError::InvalidArgument)?;
149151
if !account_data.is_initialized() {
150152
msg!("Record not initialized");
151153
return Err(ProgramError::UninitializedAccount);
@@ -155,7 +157,7 @@ pub fn process_instruction(
155157

156158
// needed account length is the sum of the meta data length and the specified
157159
// data length
158-
let needed_account_length = pod_get_packed_len::<RecordData>()
160+
let needed_account_length = std::mem::size_of::<RecordData>()
159161
.checked_add(
160162
usize::try_from(data_length).map_err(|_| ProgramError::InvalidArgument)?,
161163
)

record/program/src/state.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
//! Program state
22
use {
33
bytemuck::{Pod, Zeroable},
4-
solana_program::{program_pack::IsInitialized, pubkey::Pubkey},
4+
solana_program_pack::IsInitialized,
5+
solana_pubkey::Pubkey,
56
};
67

78
/// Header type for recorded account data
@@ -32,11 +33,7 @@ impl IsInitialized for RecordData {
3233

3334
#[cfg(test)]
3435
pub mod tests {
35-
use {
36-
super::*,
37-
solana_program::program_error::ProgramError,
38-
spl_pod::bytemuck::{pod_bytes_of, pod_from_bytes},
39-
};
36+
use {super::*, solana_program_error::ProgramError};
4037

4138
/// Version for tests
4239
pub const TEST_VERSION: u8 = 1;
@@ -54,9 +51,9 @@ pub mod tests {
5451
fn serialize_data() {
5552
let mut expected = vec![TEST_VERSION];
5653
expected.extend_from_slice(&TEST_PUBKEY.to_bytes());
57-
assert_eq!(pod_bytes_of(&TEST_RECORD_DATA), expected);
54+
assert_eq!(bytemuck::bytes_of(&TEST_RECORD_DATA), expected);
5855
assert_eq!(
59-
*pod_from_bytes::<RecordData>(&expected).unwrap(),
56+
*bytemuck::try_from_bytes::<RecordData>(&expected).unwrap(),
6057
TEST_RECORD_DATA,
6158
);
6259
}
@@ -66,7 +63,9 @@ pub mod tests {
6663
let mut expected = vec![TEST_VERSION];
6764
expected.extend_from_slice(&TEST_PUBKEY.to_bytes());
6865
expected.extend_from_slice(&TEST_BYTES);
69-
let err: ProgramError = pod_from_bytes::<RecordData>(&expected).unwrap_err();
66+
let err = bytemuck::try_from_bytes::<RecordData>(&expected)
67+
.map_err(|_| ProgramError::InvalidArgument)
68+
.unwrap_err();
7069
assert_eq!(err, ProgramError::InvalidArgument);
7170
}
7271
}

record/program/tests/functional.rs

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
#![cfg(feature = "test-sbf")]
22

33
use {
4-
solana_program::{
5-
instruction::{AccountMeta, Instruction, InstructionError},
6-
pubkey::Pubkey,
7-
rent::Rent,
8-
system_instruction,
9-
},
4+
solana_instruction::{error::InstructionError, AccountMeta, Instruction},
105
solana_program_test::*,
6+
solana_pubkey::Pubkey,
7+
solana_rent::Rent,
118
solana_sdk::{
129
signature::{Keypair, Signer},
10+
system_instruction,
1311
transaction::{Transaction, TransactionError},
1412
},
15-
spl_pod::bytemuck::{pod_from_bytes, pod_get_packed_len},
1613
spl_record::{
1714
error::RecordError, id, instruction, processor::process_instruction, state::RecordData,
1815
},
@@ -28,7 +25,7 @@ async fn initialize_storage_account(
2825
account: &Keypair,
2926
data: &[u8],
3027
) {
31-
let account_length = pod_get_packed_len::<RecordData>()
28+
let account_length = std::mem::size_of::<RecordData>()
3229
.checked_add(data.len())
3330
.unwrap();
3431
let transaction = Transaction::new_signed_with_payer(
@@ -70,7 +67,8 @@ async fn initialize_success() {
7067
.unwrap()
7168
.unwrap();
7269
let account_data =
73-
pod_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX]).unwrap();
70+
bytemuck::try_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX])
71+
.unwrap();
7472
assert_eq!(account_data.authority, authority.pubkey());
7573
assert_eq!(account_data.version, RecordData::CURRENT_VERSION);
7674
assert_eq!(&account.data[RecordData::WRITABLE_START_INDEX..], data);
@@ -84,7 +82,7 @@ async fn initialize_with_seed_success() {
8482
let seed = "storage";
8583
let account = Pubkey::create_with_seed(&authority.pubkey(), seed, &id()).unwrap();
8684
let data = &[111u8; 8];
87-
let account_length = pod_get_packed_len::<RecordData>()
85+
let account_length = std::mem::size_of::<RecordData>()
8886
.checked_add(data.len())
8987
.unwrap();
9088
let transaction = Transaction::new_signed_with_payer(
@@ -117,7 +115,8 @@ async fn initialize_with_seed_success() {
117115
.unwrap()
118116
.unwrap();
119117
let account_data =
120-
pod_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX]).unwrap();
118+
bytemuck::try_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX])
119+
.unwrap();
121120
assert_eq!(account_data.authority, authority.pubkey());
122121
assert_eq!(account_data.version, RecordData::CURRENT_VERSION);
123122
assert_eq!(&account.data[RecordData::WRITABLE_START_INDEX..], data);
@@ -185,7 +184,8 @@ async fn write_success() {
185184
.unwrap()
186185
.unwrap();
187186
let account_data =
188-
pod_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX]).unwrap();
187+
bytemuck::try_from_bytes::<RecordData>(&account.data[..RecordData::WRITABLE_START_INDEX])
188+
.unwrap();
189189
assert_eq!(account_data.authority, authority.pubkey());
190190
assert_eq!(account_data.version, RecordData::CURRENT_VERSION);
191191
assert_eq!(&account.data[RecordData::WRITABLE_START_INDEX..], new_data);
@@ -269,7 +269,7 @@ async fn close_account_success() {
269269
let authority = Keypair::new();
270270
let account = Keypair::new();
271271
let data = &[222u8; 8];
272-
let account_length = pod_get_packed_len::<RecordData>()
272+
let account_length = std::mem::size_of::<RecordData>()
273273
.checked_add(data.len())
274274
.unwrap();
275275
initialize_storage_account(&mut context, &authority, &account, data).await;
@@ -407,9 +407,10 @@ async fn set_authority_success() {
407407
.await
408408
.unwrap()
409409
.unwrap();
410-
let account_data =
411-
pod_from_bytes::<RecordData>(&account_handle.data[..RecordData::WRITABLE_START_INDEX])
412-
.unwrap();
410+
let account_data = bytemuck::try_from_bytes::<RecordData>(
411+
&account_handle.data[..RecordData::WRITABLE_START_INDEX],
412+
)
413+
.unwrap();
413414
assert_eq!(account_data.authority, new_authority.pubkey());
414415

415416
let new_data = &[200u8; 8];
@@ -436,9 +437,10 @@ async fn set_authority_success() {
436437
.await
437438
.unwrap()
438439
.unwrap();
439-
let account_data =
440-
pod_from_bytes::<RecordData>(&account_handle.data[..RecordData::WRITABLE_START_INDEX])
441-
.unwrap();
440+
let account_data = bytemuck::try_from_bytes::<RecordData>(
441+
&account_handle.data[..RecordData::WRITABLE_START_INDEX],
442+
)
443+
.unwrap();
442444
assert_eq!(account_data.authority, new_authority.pubkey());
443445
assert_eq!(account_data.version, RecordData::CURRENT_VERSION);
444446
assert_eq!(

0 commit comments

Comments
 (0)