solana_config_program_client/hooked/
short_vec.rs1use {
2 borsh::{BorshDeserialize, BorshSerialize},
3 solana_program::pubkey::Pubkey,
4};
5#[cfg(feature = "serde")]
6use {
7 serde::{Deserialize, Deserializer, Serialize, Serializer},
8 solana_program::short_vec,
9};
10
11struct ShortU16(u16);
12
13impl BorshSerialize for ShortU16 {
14 fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
15 let mut value = self.0;
16 while value > 0x7F {
17 writer.write_all(&[(value as u8) | 0x80])?;
18 value >>= 7;
19 }
20 writer.write_all(&[value as u8])
21 }
22}
23
24impl BorshDeserialize for ShortU16 {
25 fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
26 let mut value: u16 = 0;
27 let mut shift = 0;
28
29 loop {
30 let mut byte = [0u8; 1];
31 reader.read_exact(&mut byte)?;
32 let part = (byte[0] & 0x7F) as u16;
33
34 if shift >= 16 {
35 return Err(std::io::Error::new(
36 std::io::ErrorKind::InvalidData,
37 "Overflow while decoding",
38 ));
39 }
40
41 value |= part << shift;
42 shift += 7;
43
44 if byte[0] & 0x80 == 0 {
46 break;
47 }
48 }
49
50 Ok(ShortU16(value))
51 }
52}
53
54#[derive(Clone, Debug, Eq, PartialEq)]
56pub struct ShortVec<T>(pub Vec<T>);
57
58fn borsh_serialize_as_short_vec<T: BorshSerialize, W: std::io::Write>(
59 vec: &Vec<T>,
60 writer: &mut W,
61) -> std::io::Result<()> {
62 ShortU16(vec.len() as u16).serialize(writer)?;
63 for item in vec {
64 item.serialize(writer)?;
65 }
66 Ok(())
67}
68
69impl<T: BorshSerialize> BorshSerialize for ShortVec<T> {
70 fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
71 borsh_serialize_as_short_vec(&self.0, writer)
72 }
73}
74
75impl<T: BorshDeserialize> BorshDeserialize for ShortVec<T> {
76 fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
77 let ShortU16(len) = ShortU16::deserialize_reader(reader)?;
78 let mut vec = Vec::with_capacity(len as usize);
79 for _ in 0..len {
80 vec.push(T::deserialize_reader(reader)?);
81 }
82 Ok(ShortVec(vec))
83 }
84}
85
86#[cfg(feature = "serde")]
87impl<T: Serialize> Serialize for ShortVec<T> {
88 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
89 where
90 S: Serializer,
91 {
92 short_vec::serialize(&self.0, serializer)
93 }
94}
95
96#[cfg(feature = "serde")]
97impl<'de, T: Deserialize<'de>> Deserialize<'de> for ShortVec<T> {
98 fn deserialize<D>(deserializer: D) -> Result<ShortVec<T>, D::Error>
99 where
100 D: Deserializer<'de>,
101 {
102 short_vec::deserialize(deserializer).map(ShortVec)
103 }
104}
105
106#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
107#[derive(Clone, Debug, Eq, PartialEq)]
108pub struct ConfigKeys {
109 #[cfg_attr(feature = "serde", serde(with = "short_vec"))]
112 pub keys: Vec<(Pubkey, bool)>,
113}
114
115impl BorshSerialize for ConfigKeys {
116 fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
117 borsh_serialize_as_short_vec(&self.keys, writer)
118 }
119}
120
121impl BorshDeserialize for ConfigKeys {
122 fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
123 Ok(ConfigKeys {
124 keys: ShortVec::deserialize_reader(reader)?.0,
125 })
126 }
127}
128
129#[cfg(feature = "serde")]
131pub fn get_config_data(bytes: &[u8]) -> Result<&[u8], bincode::Error> {
132 bincode::deserialize::<ConfigKeys>(bytes)
133 .and_then(|keys| bincode::serialized_size(&keys))
134 .map(|offset| &bytes[offset as usize..])
135}
136
137#[cfg(test)]
138mod tests {
139 use {
140 super::*,
141 bincode::deserialize,
142 solana_program::{
143 pubkey::Pubkey,
144 short_vec::{decode_shortu16_len, ShortU16},
145 },
146 };
147 #[cfg(feature = "serde")]
148 use {assert_matches::assert_matches, bincode::serialize};
149
150 fn encode_len(len: u16) -> Vec<u8> {
152 bincode::serialize(&ShortU16(len)).unwrap()
153 }
154
155 fn assert_len_encoding(len: u16, bytes: &[u8]) {
156 assert_eq!(encode_len(len), bytes, "unexpected usize encoding");
157 assert_eq!(
158 decode_shortu16_len(bytes).unwrap(),
159 (usize::from(len), bytes.len()),
160 "unexpected usize decoding"
161 );
162 }
163
164 #[test]
165 fn test_short_vec_encode_len() {
166 assert_len_encoding(0x0, &[0x0]);
167 assert_len_encoding(0x7f, &[0x7f]);
168 assert_len_encoding(0x80, &[0x80, 0x01]);
169 assert_len_encoding(0xff, &[0xff, 0x01]);
170 assert_len_encoding(0x100, &[0x80, 0x02]);
171 assert_len_encoding(0x7fff, &[0xff, 0xff, 0x01]);
172 assert_len_encoding(0xffff, &[0xff, 0xff, 0x03]);
173 }
174
175 fn assert_good_deserialized_value(value: u16, bytes: &[u8]) {
176 assert_eq!(value, deserialize::<ShortU16>(bytes).unwrap().0);
177 }
178
179 fn assert_bad_deserialized_value(bytes: &[u8]) {
180 assert!(deserialize::<ShortU16>(bytes).is_err());
181 }
182
183 #[test]
184 fn test_deserialize() {
185 assert_good_deserialized_value(0x0000, &[0x00]);
186 assert_good_deserialized_value(0x007f, &[0x7f]);
187 assert_good_deserialized_value(0x0080, &[0x80, 0x01]);
188 assert_good_deserialized_value(0x00ff, &[0xff, 0x01]);
189 assert_good_deserialized_value(0x0100, &[0x80, 0x02]);
190 assert_good_deserialized_value(0x07ff, &[0xff, 0x0f]);
191 assert_good_deserialized_value(0x3fff, &[0xff, 0x7f]);
192 assert_good_deserialized_value(0x4000, &[0x80, 0x80, 0x01]);
193 assert_good_deserialized_value(0xffff, &[0xff, 0xff, 0x03]);
194
195 assert_bad_deserialized_value(&[0x80, 0x00]);
198 assert_bad_deserialized_value(&[0x80, 0x80, 0x00]);
199 assert_bad_deserialized_value(&[0xff, 0x00]);
201 assert_bad_deserialized_value(&[0xff, 0x80, 0x00]);
202 assert_bad_deserialized_value(&[0x80, 0x81, 0x00]);
204 assert_bad_deserialized_value(&[0xff, 0x81, 0x00]);
206 assert_bad_deserialized_value(&[0x80, 0x82, 0x00]);
208 assert_bad_deserialized_value(&[0xff, 0x8f, 0x00]);
210 assert_bad_deserialized_value(&[0xff, 0xff, 0x00]);
212
213 assert_bad_deserialized_value(&[]);
215 assert_bad_deserialized_value(&[0x80]);
216
217 assert_bad_deserialized_value(&[0x80, 0x80, 0x80, 0x00]);
219
220 assert_bad_deserialized_value(&[0x80, 0x80, 0x04]);
223 assert_bad_deserialized_value(&[0x80, 0x80, 0x06]);
225 }
226
227 #[cfg(feature = "serde")]
228 #[test]
229 fn test_short_vec_u8() {
230 let vec = ShortVec(vec![4u8; 32]);
231 let bytes = serialize(&vec).unwrap();
232 assert_eq!(bytes.len(), vec.0.len() + 1);
233
234 let vec1: ShortVec<u8> = deserialize(&bytes).unwrap();
235 assert_eq!(vec.0, vec1.0);
236 }
237
238 #[cfg(feature = "serde")]
239 #[test]
240 fn test_short_vec_u8_too_long() {
241 let vec = ShortVec(vec![4u8; u16::MAX as usize]);
242 assert_matches!(serialize(&vec), Ok(_));
243
244 let vec = ShortVec(vec![4u8; u16::MAX as usize + 1]);
245 assert_matches!(serialize(&vec), Err(_));
246 }
247
248 #[cfg(feature = "serde")]
249 #[test]
250 fn test_short_vec_aliased_length() {
251 let bytes = [
252 0x81, 0x80, 0x00, 0x00,
254 ];
255 assert!(deserialize::<ShortVec<u8>>(&bytes).is_err());
256 }
257
258 #[test]
259 fn test_serialization_borsh() {
260 fn test_serialization(data: ConfigKeys) {
261 let bytes = data.try_to_vec().unwrap();
262 let data1 = ConfigKeys::try_from_slice(&bytes).unwrap();
263 assert_eq!(data, data1);
264 }
265
266 test_serialization(ConfigKeys { keys: vec![] });
267
268 test_serialization(ConfigKeys {
269 keys: vec![(Pubkey::new_unique(), false)],
270 });
271
272 test_serialization(ConfigKeys {
273 keys: vec![(Pubkey::new_unique(), true), (Pubkey::new_unique(), false)],
274 });
275
276 test_serialization(ConfigKeys {
277 keys: vec![
278 (Pubkey::new_unique(), true),
279 (Pubkey::new_unique(), false),
280 (Pubkey::new_unique(), true),
281 (Pubkey::new_unique(), true),
282 (Pubkey::new_unique(), false),
283 (Pubkey::new_unique(), true),
284 ],
285 });
286 }
287}