stake: Add BorshDeserialize trait to structs (#19958)
This commit is contained in:
@ -11,6 +11,7 @@ use {
|
|||||||
},
|
},
|
||||||
stake_history::StakeHistory,
|
stake_history::StakeHistory,
|
||||||
},
|
},
|
||||||
|
borsh::{maybestd::io, BorshDeserialize, BorshSchema},
|
||||||
std::collections::HashSet,
|
std::collections::HashSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -23,6 +24,29 @@ pub enum StakeState {
|
|||||||
RewardsPool,
|
RewardsPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BorshDeserialize for StakeState {
|
||||||
|
fn deserialize(buf: &mut &[u8]) -> io::Result<Self> {
|
||||||
|
let enum_value: u32 = BorshDeserialize::deserialize(buf)?;
|
||||||
|
match enum_value {
|
||||||
|
0 => Ok(StakeState::Uninitialized),
|
||||||
|
1 => {
|
||||||
|
let meta: Meta = BorshDeserialize::deserialize(buf)?;
|
||||||
|
Ok(StakeState::Initialized(meta))
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
let meta: Meta = BorshDeserialize::deserialize(buf)?;
|
||||||
|
let stake: Stake = BorshDeserialize::deserialize(buf)?;
|
||||||
|
Ok(StakeState::Stake(meta, stake))
|
||||||
|
}
|
||||||
|
3 => Ok(StakeState::RewardsPool),
|
||||||
|
_ => Err(io::Error::new(
|
||||||
|
io::ErrorKind::InvalidData,
|
||||||
|
"Invalid enum value",
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for StakeState {
|
impl Default for StakeState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
StakeState::Uninitialized
|
StakeState::Uninitialized
|
||||||
@ -75,7 +99,18 @@ pub enum StakeAuthorize {
|
|||||||
Withdrawer,
|
Withdrawer,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone, Copy, AbiExample)]
|
#[derive(
|
||||||
|
Default,
|
||||||
|
Debug,
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
|
PartialEq,
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
AbiExample,
|
||||||
|
BorshDeserialize,
|
||||||
|
BorshSchema,
|
||||||
|
)]
|
||||||
pub struct Lockup {
|
pub struct Lockup {
|
||||||
/// UnixTimestamp at which this stake will allow withdrawal, unless the
|
/// UnixTimestamp at which this stake will allow withdrawal, unless the
|
||||||
/// transaction is signed by the custodian
|
/// transaction is signed by the custodian
|
||||||
@ -97,7 +132,18 @@ impl Lockup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone, Copy, AbiExample)]
|
#[derive(
|
||||||
|
Default,
|
||||||
|
Debug,
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
|
PartialEq,
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
AbiExample,
|
||||||
|
BorshDeserialize,
|
||||||
|
BorshSchema,
|
||||||
|
)]
|
||||||
pub struct Authorized {
|
pub struct Authorized {
|
||||||
pub staker: Pubkey,
|
pub staker: Pubkey,
|
||||||
pub withdrawer: Pubkey,
|
pub withdrawer: Pubkey,
|
||||||
@ -164,7 +210,18 @@ impl Authorized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone, Copy, AbiExample)]
|
#[derive(
|
||||||
|
Default,
|
||||||
|
Debug,
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
|
PartialEq,
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
AbiExample,
|
||||||
|
BorshDeserialize,
|
||||||
|
BorshSchema,
|
||||||
|
)]
|
||||||
pub struct Meta {
|
pub struct Meta {
|
||||||
pub rent_exempt_reserve: u64,
|
pub rent_exempt_reserve: u64,
|
||||||
pub authorized: Authorized,
|
pub authorized: Authorized,
|
||||||
@ -237,7 +294,9 @@ impl Meta {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy, AbiExample)]
|
#[derive(
|
||||||
|
Debug, Serialize, Deserialize, PartialEq, Clone, Copy, AbiExample, BorshDeserialize, BorshSchema,
|
||||||
|
)]
|
||||||
pub struct Delegation {
|
pub struct Delegation {
|
||||||
/// to whom the stake is delegated
|
/// to whom the stake is delegated
|
||||||
pub voter_pubkey: Pubkey,
|
pub voter_pubkey: Pubkey,
|
||||||
@ -456,7 +515,18 @@ impl Delegation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone, Copy, AbiExample)]
|
#[derive(
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
|
PartialEq,
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
AbiExample,
|
||||||
|
BorshDeserialize,
|
||||||
|
BorshSchema,
|
||||||
|
)]
|
||||||
pub struct Stake {
|
pub struct Stake {
|
||||||
pub delegation: Delegation,
|
pub delegation: Delegation,
|
||||||
/// credits observed is credits from vote account state when delegated or redeemed
|
/// credits observed is credits from vote account state when delegated or redeemed
|
||||||
@ -496,3 +566,76 @@ impl Stake {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use {
|
||||||
|
super::*, crate::borsh::try_from_slice_unchecked, assert_matches::assert_matches,
|
||||||
|
bincode::serialize,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn check_borsh_deserialization(stake: StakeState) {
|
||||||
|
let serialized = serialize(&stake).unwrap();
|
||||||
|
let deserialized = StakeState::try_from_slice(&serialized).unwrap();
|
||||||
|
assert_eq!(stake, deserialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bincode_vs_borsh() {
|
||||||
|
check_borsh_deserialization(StakeState::Uninitialized);
|
||||||
|
check_borsh_deserialization(StakeState::RewardsPool);
|
||||||
|
check_borsh_deserialization(StakeState::Initialized(Meta {
|
||||||
|
rent_exempt_reserve: u64::MAX,
|
||||||
|
authorized: Authorized {
|
||||||
|
staker: Pubkey::new_unique(),
|
||||||
|
withdrawer: Pubkey::new_unique(),
|
||||||
|
},
|
||||||
|
lockup: Lockup::default(),
|
||||||
|
}));
|
||||||
|
check_borsh_deserialization(StakeState::Stake(
|
||||||
|
Meta {
|
||||||
|
rent_exempt_reserve: 1,
|
||||||
|
authorized: Authorized {
|
||||||
|
staker: Pubkey::new_unique(),
|
||||||
|
withdrawer: Pubkey::new_unique(),
|
||||||
|
},
|
||||||
|
lockup: Lockup::default(),
|
||||||
|
},
|
||||||
|
Stake {
|
||||||
|
delegation: Delegation {
|
||||||
|
voter_pubkey: Pubkey::new_unique(),
|
||||||
|
stake: u64::MAX,
|
||||||
|
activation_epoch: Epoch::MAX,
|
||||||
|
deactivation_epoch: Epoch::MAX,
|
||||||
|
warmup_cooldown_rate: f64::MAX,
|
||||||
|
},
|
||||||
|
credits_observed: 1,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn borsh_deserialization_live_data() {
|
||||||
|
let data = [
|
||||||
|
1, 0, 0, 0, 128, 213, 34, 0, 0, 0, 0, 0, 133, 0, 79, 231, 141, 29, 73, 61, 232, 35,
|
||||||
|
119, 124, 168, 12, 120, 216, 195, 29, 12, 166, 139, 28, 36, 182, 186, 154, 246, 149,
|
||||||
|
224, 109, 52, 100, 133, 0, 79, 231, 141, 29, 73, 61, 232, 35, 119, 124, 168, 12, 120,
|
||||||
|
216, 195, 29, 12, 166, 139, 28, 36, 182, 186, 154, 246, 149, 224, 109, 52, 100, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
];
|
||||||
|
// As long as we get the 4-byte enum and the first field right, then
|
||||||
|
// we're sure the rest works out
|
||||||
|
let deserialized = try_from_slice_unchecked::<StakeState>(&data).unwrap();
|
||||||
|
assert_matches!(
|
||||||
|
deserialized,
|
||||||
|
StakeState::Initialized(Meta {
|
||||||
|
rent_exempt_reserve: 2282880,
|
||||||
|
..
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user