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

Commit 517be45

Browse files
authored
stake-pool: Use unaligned types for safe pointer cast (#5179)
* stake-pool: Use unaligned types for safe pointer cast * Update CLI for modified types
1 parent 3ce05a3 commit 517be45

20 files changed

+238
-204
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libraries/pod/src/primitives.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ use bytemuck::{Pod, Zeroable};
44
#[cfg(feature = "serde-traits")]
55
use serde::{Deserialize, Serialize};
66

7+
#[cfg(feature = "borsh")]
8+
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
9+
710
/// The standard `bool` is not a `Pod`, define a replacement that is
811
#[cfg_attr(feature = "serde-traits", derive(Serialize, Deserialize))]
912
#[cfg_attr(feature = "serde-traits", serde(from = "bool", into = "bool"))]
@@ -72,6 +75,10 @@ pub struct PodI16([u8; 2]);
7275
impl_int_conversion!(PodI16, i16);
7376

7477
/// `u32` type that can be used in `Pod`s
78+
#[cfg_attr(
79+
feature = "borsh",
80+
derive(BorshDeserialize, BorshSerialize, BorshSchema)
81+
)]
7582
#[cfg_attr(feature = "serde-traits", derive(Serialize, Deserialize))]
7683
#[cfg_attr(feature = "serde-traits", serde(from = "u32", into = "u32"))]
7784
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
@@ -80,6 +87,10 @@ pub struct PodU32([u8; 4]);
8087
impl_int_conversion!(PodU32, u32);
8188

8289
/// `u64` type that can be used in Pods
90+
#[cfg_attr(
91+
feature = "borsh",
92+
derive(BorshDeserialize, BorshSerialize, BorshSchema)
93+
)]
8394
#[cfg_attr(feature = "serde-traits", derive(Serialize, Deserialize))]
8495
#[cfg_attr(feature = "serde-traits", serde(from = "u64", into = "u64"))]
8596
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]

stake-pool/cli/src/main.rs

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ fn command_vsa_remove(
499499
.find(vote_account)
500500
.ok_or("Vote account not found in validator list")?;
501501

502-
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix);
502+
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into());
503503
let (stake_account_address, _) = find_stake_program_address(
504504
&spl_stake_pool::id(),
505505
vote_account,
@@ -520,7 +520,7 @@ fn command_vsa_remove(
520520
stake_pool_address,
521521
vote_account,
522522
validator_seed,
523-
validator_stake_info.transient_seed_suffix,
523+
validator_stake_info.transient_seed_suffix.into(),
524524
),
525525
];
526526
unique_signers!(signers);
@@ -545,7 +545,7 @@ fn command_increase_validator_stake(
545545
let validator_stake_info = validator_list
546546
.find(vote_account)
547547
.ok_or("Vote account not found in validator list")?;
548-
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix);
548+
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into());
549549

550550
let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()];
551551
unique_signers!(signers);
@@ -559,7 +559,7 @@ fn command_increase_validator_stake(
559559
vote_account,
560560
lamports,
561561
validator_seed,
562-
validator_stake_info.transient_seed_suffix,
562+
validator_stake_info.transient_seed_suffix.into(),
563563
),
564564
],
565565
&signers,
@@ -584,7 +584,7 @@ fn command_decrease_validator_stake(
584584
let validator_stake_info = validator_list
585585
.find(vote_account)
586586
.ok_or("Vote account not found in validator list")?;
587-
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix);
587+
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into());
588588

589589
let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()];
590590
unique_signers!(signers);
@@ -598,7 +598,7 @@ fn command_decrease_validator_stake(
598598
vote_account,
599599
lamports,
600600
validator_seed,
601-
validator_stake_info.transient_seed_suffix,
601+
validator_stake_info.transient_seed_suffix.into(),
602602
),
603603
],
604604
&signers,
@@ -692,7 +692,7 @@ fn command_deposit_stake(
692692
let validator_stake_info = validator_list
693693
.find(&vote_account)
694694
.ok_or("Vote account not found in the stake pool")?;
695-
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix);
695+
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into());
696696

697697
// Calculate validator stake account address linked to the pool
698698
let (validator_stake_account, _) = find_stake_program_address(
@@ -872,7 +872,7 @@ fn command_deposit_all_stake(
872872
let validator_stake_info = validator_list
873873
.find(&vote_account)
874874
.ok_or("Vote account not found in the stake pool")?;
875-
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix);
875+
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into());
876876

877877
// Calculate validator stake account address linked to the pool
878878
let (validator_stake_account, _) = find_stake_program_address(
@@ -1084,7 +1084,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult {
10841084
.validators
10851085
.iter()
10861086
.map(|validator| {
1087-
let validator_seed = NonZeroU32::new(validator.validator_seed_suffix);
1087+
let validator_seed = NonZeroU32::new(validator.validator_seed_suffix.into());
10881088
let (stake_account_address, _) = find_stake_program_address(
10891089
&spl_stake_pool::id(),
10901090
&validator.vote_account_address,
@@ -1095,18 +1095,18 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult {
10951095
&spl_stake_pool::id(),
10961096
&validator.vote_account_address,
10971097
stake_pool_address,
1098-
validator.transient_seed_suffix,
1098+
validator.transient_seed_suffix.into(),
10991099
);
1100-
let update_required = validator.last_update_epoch != epoch_info.epoch;
1100+
let update_required = u64::from(validator.last_update_epoch) != epoch_info.epoch;
11011101
CliStakePoolStakeAccountInfo {
11021102
vote_account_address: validator.vote_account_address.to_string(),
11031103
stake_account_address: stake_account_address.to_string(),
1104-
validator_active_stake_lamports: validator.active_stake_lamports,
1105-
validator_last_update_epoch: validator.last_update_epoch,
1104+
validator_active_stake_lamports: validator.active_stake_lamports.into(),
1105+
validator_last_update_epoch: validator.last_update_epoch.into(),
11061106
validator_lamports: validator.stake_lamports().unwrap(),
11071107
validator_transient_stake_account_address: transient_stake_account_address
11081108
.to_string(),
1109-
validator_transient_stake_lamports: validator.transient_stake_lamports,
1109+
validator_transient_stake_lamports: validator.transient_stake_lamports.into(),
11101110
update_required,
11111111
}
11121112
})
@@ -1255,7 +1255,7 @@ fn prepare_withdraw_accounts(
12551255
&validator_list,
12561256
stake_pool,
12571257
|validator| {
1258-
let validator_seed = NonZeroU32::new(validator.validator_seed_suffix);
1258+
let validator_seed = NonZeroU32::new(validator.validator_seed_suffix.into());
12591259
let (stake_account_address, _) = find_stake_program_address(
12601260
&spl_stake_pool::id(),
12611261
&validator.vote_account_address,
@@ -1265,7 +1265,7 @@ fn prepare_withdraw_accounts(
12651265

12661266
(
12671267
stake_account_address,
1268-
validator.active_stake_lamports,
1268+
validator.active_stake_lamports.into(),
12691269
Some(validator.vote_account_address),
12701270
)
12711271
},
@@ -1279,14 +1279,12 @@ fn prepare_withdraw_accounts(
12791279
&spl_stake_pool::id(),
12801280
&validator.vote_account_address,
12811281
stake_pool_address,
1282-
validator.transient_seed_suffix,
1282+
validator.transient_seed_suffix.into(),
12831283
);
12841284

12851285
(
12861286
transient_stake_account_address,
1287-
validator
1288-
.transient_stake_lamports
1289-
.saturating_sub(min_balance),
1287+
u64::from(validator.transient_stake_lamports).saturating_sub(min_balance),
12901288
Some(validator.vote_account_address),
12911289
)
12921290
},
@@ -1438,7 +1436,7 @@ fn command_withdraw_stake(
14381436
let validator_stake_info = validator_list
14391437
.find(&vote_account)
14401438
.ok_or(format!("Provided stake account is delegated to a vote account {} which does not exist in the stake pool", vote_account))?;
1441-
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix);
1439+
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into());
14421440
let (stake_account_address, _) = find_stake_program_address(
14431441
&spl_stake_pool::id(),
14441442
&vote_account,
@@ -1474,7 +1472,7 @@ fn command_withdraw_stake(
14741472
"Provided vote account address {} does not exist in the stake pool",
14751473
vote_account_address
14761474
))?;
1477-
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix);
1475+
let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into());
14781476
let (stake_account_address, _) = find_stake_program_address(
14791477
&spl_stake_pool::id(),
14801478
vote_account_address,

stake-pool/cli/src/output.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,12 @@ pub(crate) struct CliStakePoolValidator {
372372
impl From<ValidatorStakeInfo> for CliStakePoolValidator {
373373
fn from(v: ValidatorStakeInfo) -> Self {
374374
Self {
375-
active_stake_lamports: v.active_stake_lamports,
376-
transient_stake_lamports: v.transient_stake_lamports,
377-
last_update_epoch: v.last_update_epoch,
378-
transient_seed_suffix: v.transient_seed_suffix,
379-
unused: v.unused,
380-
validator_seed_suffix: v.validator_seed_suffix,
375+
active_stake_lamports: v.active_stake_lamports.into(),
376+
transient_stake_lamports: v.transient_stake_lamports.into(),
377+
last_update_epoch: v.last_update_epoch.into(),
378+
transient_seed_suffix: v.transient_seed_suffix.into(),
379+
unused: v.unused.into(),
380+
validator_seed_suffix: v.validator_seed_suffix.into(),
381381
status: CliStakePoolValidatorStakeStatus::from(v.status),
382382
vote_account_address: v.vote_account_address.to_string(),
383383
}

stake-pool/program/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ serde = "1.0.188"
2121
serde_derive = "1.0.103"
2222
solana-program = "1.16.3"
2323
spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] }
24+
spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] }
2425
spl-token-2022 = { version = "0.7", path = "../../token/program-2022", features = [ "no-entrypoint" ] }
2526
thiserror = "1.0"
2627
bincode = "1.3.1"

stake-pool/program/src/big_vec.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ mod tests {
246246

247247
#[derive(Debug, PartialEq)]
248248
struct TestStruct {
249-
value: u64,
249+
value: [u8; 8],
250250
}
251251

252252
impl Sealed for TestStruct {}
@@ -259,29 +259,30 @@ mod tests {
259259
}
260260
fn unpack_from_slice(src: &[u8]) -> Result<Self, ProgramError> {
261261
Ok(TestStruct {
262-
value: u64::try_from_slice(src).unwrap(),
262+
value: src.try_into().unwrap(),
263263
})
264264
}
265265
}
266266

267267
impl TestStruct {
268-
fn new(value: u64) -> Self {
268+
fn new(value: u8) -> Self {
269+
let value = [value, 0, 0, 0, 0, 0, 0, 0];
269270
Self { value }
270271
}
271272
}
272273

273-
fn from_slice<'data>(data: &'data mut [u8], vec: &[u64]) -> BigVec<'data> {
274+
fn from_slice<'data>(data: &'data mut [u8], vec: &[u8]) -> BigVec<'data> {
274275
let mut big_vec = BigVec { data };
275276
for element in vec {
276277
big_vec.push(TestStruct::new(*element)).unwrap();
277278
}
278279
big_vec
279280
}
280281

281-
fn check_big_vec_eq(big_vec: &BigVec, slice: &[u64]) {
282+
fn check_big_vec_eq(big_vec: &BigVec, slice: &[u8]) {
282283
assert!(big_vec
283284
.iter::<TestStruct>()
284-
.map(|x| &x.value)
285+
.map(|x| &x.value[0])
285286
.zip(slice.iter())
286287
.all(|(a, b)| a == b));
287288
}
@@ -314,11 +315,11 @@ mod tests {
314315
check_big_vec_eq(&v, &[2, 4]);
315316
}
316317

317-
fn find_predicate(a: &[u8], b: u64) -> bool {
318+
fn find_predicate(a: &[u8], b: u8) -> bool {
318319
if a.len() != 8 {
319320
false
320321
} else {
321-
u64::try_from_slice(&a[0..8]).unwrap() == b
322+
a[0] == b
322323
}
323324
}
324325

@@ -344,7 +345,7 @@ mod tests {
344345
let mut test_struct = v
345346
.find_mut::<TestStruct, _>(|x| find_predicate(x, 1))
346347
.unwrap();
347-
test_struct.value = 0;
348+
test_struct.value = [0; 8];
348349
check_big_vec_eq(&v, &[0, 2, 3, 4]);
349350
assert_eq!(v.find_mut::<TestStruct, _>(|x| find_predicate(x, 5)), None);
350351
}
@@ -354,8 +355,8 @@ mod tests {
354355
let mut data = [0u8; 4 + 8 * 4];
355356
let mut v = from_slice(&mut data, &[1, 2, 3, 4]);
356357
let mut slice = v.deserialize_mut_slice::<TestStruct>(1, 2).unwrap();
357-
slice[0].value = 10;
358-
slice[1].value = 11;
358+
slice[0].value[0] = 10;
359+
slice[1].value[0] = 11;
359360
check_big_vec_eq(&v, &[1, 10, 11, 4]);
360361
assert_eq!(
361362
v.deserialize_mut_slice::<TestStruct>(1, 4).unwrap_err(),

stake-pool/program/src/instruction.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,13 +1247,13 @@ pub fn update_validator_list_balance(
12471247
program_id,
12481248
vote_account_address,
12491249
stake_pool,
1250-
NonZeroU32::new(validator_stake_info.validator_seed_suffix),
1250+
NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()),
12511251
);
12521252
let (transient_stake_account, _) = find_transient_stake_program_address(
12531253
program_id,
12541254
vote_account_address,
12551255
stake_pool,
1256-
validator_stake_info.transient_seed_suffix,
1256+
validator_stake_info.transient_seed_suffix.into(),
12571257
);
12581258
vec![
12591259
AccountMeta::new(validator_stake_account, false),

0 commit comments

Comments
 (0)