solana_config_program_client/hooked/
short_vec.rs

1use {
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 the top bit is not set, this is the last byte.
45            if byte[0] & 0x80 == 0 {
46                break;
47            }
48        }
49
50        Ok(ShortU16(value))
51    }
52}
53
54/// ShortVec generic type.
55#[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    /// Each key tuple comprises a unique `Pubkey` identifier,
110    /// and `bool` whether that key is a signer of the data.
111    #[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/// Utility for extracting the `ConfigKeys` data from the account data.
130#[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    /// Return the serialized length.
151    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        // aliases
196        // 0x0000
197        assert_bad_deserialized_value(&[0x80, 0x00]);
198        assert_bad_deserialized_value(&[0x80, 0x80, 0x00]);
199        // 0x007f
200        assert_bad_deserialized_value(&[0xff, 0x00]);
201        assert_bad_deserialized_value(&[0xff, 0x80, 0x00]);
202        // 0x0080
203        assert_bad_deserialized_value(&[0x80, 0x81, 0x00]);
204        // 0x00ff
205        assert_bad_deserialized_value(&[0xff, 0x81, 0x00]);
206        // 0x0100
207        assert_bad_deserialized_value(&[0x80, 0x82, 0x00]);
208        // 0x07ff
209        assert_bad_deserialized_value(&[0xff, 0x8f, 0x00]);
210        // 0x3fff
211        assert_bad_deserialized_value(&[0xff, 0xff, 0x00]);
212
213        // too short
214        assert_bad_deserialized_value(&[]);
215        assert_bad_deserialized_value(&[0x80]);
216
217        // too long
218        assert_bad_deserialized_value(&[0x80, 0x80, 0x80, 0x00]);
219
220        // too large
221        // 0x0001_0000
222        assert_bad_deserialized_value(&[0x80, 0x80, 0x04]);
223        // 0x0001_8000
224        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, // 3-byte alias of 1
253            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}