solana_loader_v3_interface/
state.rs1use solana_pubkey::Pubkey;
2#[cfg(feature = "wincode")]
3use wincode::{SchemaRead, SchemaWrite};
4
5#[cfg_attr(feature = "frozen-abi", derive(solana_frozen_abi_macro::AbiExample))]
7#[cfg_attr(
8 feature = "serde",
9 derive(serde_derive::Deserialize, serde_derive::Serialize)
10)]
11#[cfg_attr(feature = "wincode", derive(SchemaRead, SchemaWrite))]
12#[derive(Debug, PartialEq, Eq, Clone, Copy)]
13pub enum UpgradeableLoaderState {
14 Uninitialized,
16 Buffer {
18 authority_address: Option<Pubkey>,
20 },
23 Program {
25 programdata_address: Pubkey,
27 },
28 ProgramData {
30 slot: u64,
32 upgrade_authority_address: Option<Pubkey>,
34 },
37}
38impl UpgradeableLoaderState {
39 pub const fn size_of_uninitialized() -> usize {
41 4 }
43
44 pub const fn size_of_buffer_metadata() -> usize {
46 37 }
48
49 pub const fn size_of_programdata_metadata() -> usize {
51 45 }
53
54 pub const fn size_of_program() -> usize {
56 36 }
58
59 pub const fn size_of_buffer(program_len: usize) -> usize {
61 Self::size_of_buffer_metadata().saturating_add(program_len)
62 }
63
64 pub const fn size_of_programdata(program_len: usize) -> usize {
66 Self::size_of_programdata_metadata().saturating_add(program_len)
67 }
68}
69
70#[cfg(all(test, feature = "wincode"))]
71mod tests {
72 use {super::*, test_case::test_case};
73
74 #[test]
75 fn test_state_size_of_uninitialized() {
76 let state = UpgradeableLoaderState::Uninitialized;
77 let size = wincode::serialized_size(&state).unwrap();
78 assert_eq!(UpgradeableLoaderState::size_of_uninitialized() as u64, size);
79 }
80
81 #[test]
82 fn test_state_size_of_buffer_metadata() {
83 let state = UpgradeableLoaderState::Buffer {
84 authority_address: Some(Pubkey::default()),
85 };
86 let size = wincode::serialized_size(&state).unwrap();
87 assert_eq!(
88 UpgradeableLoaderState::size_of_buffer_metadata() as u64,
89 size
90 );
91 }
92
93 #[test]
94 fn test_state_size_of_programdata_metadata() {
95 let state = UpgradeableLoaderState::ProgramData {
96 upgrade_authority_address: Some(Pubkey::default()),
97 slot: 0,
98 };
99 let size = wincode::serialized_size(&state).unwrap();
100 assert_eq!(
101 UpgradeableLoaderState::size_of_programdata_metadata() as u64,
102 size
103 );
104 }
105
106 #[test]
107 fn test_state_size_of_program() {
108 let state = UpgradeableLoaderState::Program {
109 programdata_address: Pubkey::default(),
110 };
111 let size = wincode::serialized_size(&state).unwrap();
112 assert_eq!(UpgradeableLoaderState::size_of_program() as u64, size);
113 }
114
115 #[test_case(UpgradeableLoaderState::Uninitialized)]
118 #[test_case(UpgradeableLoaderState::Buffer { authority_address: Some(Pubkey::default()) })]
119 #[test_case(UpgradeableLoaderState::Buffer { authority_address: None })]
120 #[test_case(UpgradeableLoaderState::Program { programdata_address: Pubkey::default() })]
121 #[test_case(UpgradeableLoaderState::ProgramData { slot: 123_456_789, upgrade_authority_address: Some(Pubkey::default()) })]
122 #[test_case(UpgradeableLoaderState::ProgramData { slot: 0, upgrade_authority_address: None })]
123 fn wire_compat_bincode_vs_wincode(state: UpgradeableLoaderState) {
124 let bincode_bytes = bincode::serialize(&state).unwrap();
125 let wincode_bytes = wincode::serialize(&state).unwrap();
126 assert_eq!(bincode_bytes, wincode_bytes);
127
128 let from_bincode: UpgradeableLoaderState = bincode::deserialize(&bincode_bytes).unwrap();
129 let from_wincode: UpgradeableLoaderState = wincode::deserialize(&wincode_bytes).unwrap();
130 assert_eq!(from_bincode, state);
131 assert_eq!(from_wincode, state);
132 }
133}