1use massa_db_exports::LEDGER_PREFIX;
2use massa_models::{
3 address::{Address, AddressDeserializer, AddressSerializer},
4 serialization::{VecU8Deserializer, VecU8Serializer},
5};
6use massa_serialization::{
7 Deserializer, SerializeError, Serializer, U64VarIntDeserializer, U64VarIntSerializer,
8};
9use nom::error::{ContextError, ParseError};
10use num_enum::{IntoPrimitive, TryFromPrimitive};
11use std::ops::Bound::Included;
12
13pub const VERSION_IDENT: u8 = 0u8;
14pub const BALANCE_IDENT: u8 = 1u8;
15pub const BYTECODE_IDENT: u8 = 2u8;
16pub const DATASTORE_IDENT: u8 = 3u8;
17pub const KEY_VERSION: u64 = 0;
18
19#[derive(PartialEq, Eq, Clone, IntoPrimitive, TryFromPrimitive, Debug)]
20#[repr(u8)]
21enum KeyTypeId {
22 Version = 0,
23 Balance = 1,
24 Bytecode = 2,
25 Datastore = 3,
26}
27
28#[derive(PartialEq, Eq, Clone, Debug)]
29pub enum KeyType {
30 VERSION,
31 BALANCE,
32 BYTECODE,
33 DATASTORE(Vec<u8>),
34}
35
36#[derive(Default, Clone)]
37pub struct KeyTypeSerializer {
38 vec_u8_serializer: VecU8Serializer,
39 with_datastore_key_length: bool,
46}
47
48impl KeyTypeSerializer {
49 pub fn new(with_datastore_key_length: bool) -> Self {
52 Self {
53 vec_u8_serializer: VecU8Serializer::new(),
54 with_datastore_key_length,
55 }
56 }
57}
58
59impl Serializer<KeyType> for KeyTypeSerializer {
60 fn serialize(&self, value: &KeyType, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
61 match value {
62 KeyType::VERSION => buffer.extend(&[u8::from(KeyTypeId::Version)]),
63 KeyType::BALANCE => buffer.extend(&[u8::from(KeyTypeId::Balance)]),
64 KeyType::BYTECODE => buffer.extend(&[u8::from(KeyTypeId::Bytecode)]),
65 KeyType::DATASTORE(data) => {
66 buffer.extend(&[u8::from(KeyTypeId::Datastore)]);
67 if self.with_datastore_key_length {
68 self.vec_u8_serializer.serialize(data, buffer)?;
69 } else {
70 buffer.extend(data);
71 }
72 }
73 }
74 Ok(())
75 }
76}
77
78#[derive(Clone)]
79pub struct KeyTypeDeserializer {
80 vec_u8_deserializer: VecU8Deserializer,
81 with_datastore_key_length: bool,
83}
84
85impl KeyTypeDeserializer {
86 pub fn new(max_datastore_key_length: u8, with_datastore_key_length: bool) -> Self {
90 Self {
91 vec_u8_deserializer: VecU8Deserializer::new(
92 Included(u64::MIN),
93 Included(max_datastore_key_length as u64),
94 ),
95 with_datastore_key_length,
96 }
97 }
98}
99
100impl Deserializer<KeyType> for KeyTypeDeserializer {
101 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
102 &self,
103 input: &'a [u8],
104 ) -> nom::IResult<&'a [u8], KeyType, E> {
105 let (rest, key_type) = nom::number::complete::le_u8(input)?;
106 match KeyTypeId::try_from(key_type) {
107 Ok(KeyTypeId::Balance) => Ok((rest, KeyType::BALANCE)),
108 Ok(KeyTypeId::Bytecode) => Ok((rest, KeyType::BYTECODE)),
109 Ok(KeyTypeId::Datastore) => {
110 if self.with_datastore_key_length {
111 let (rest, data) = self.vec_u8_deserializer.deserialize(rest)?;
112 Ok((rest, KeyType::DATASTORE(data)))
113 } else {
114 Ok((&[], KeyType::DATASTORE(rest.to_vec())))
115 }
116 }
117 Ok(KeyTypeId::Version) => Ok((rest, KeyType::VERSION)),
118 Err(_) => Err(nom::Err::Error(E::from_error_kind(
119 rest,
120 nom::error::ErrorKind::Tag,
121 ))),
122 }
123 }
124}
125
126#[derive(PartialEq, Eq, Clone, Debug)]
128pub struct Key {
129 pub key_type: KeyType,
130 pub address: Address,
131}
132
133impl Key {
134 pub fn new(address: &Address, key_type: KeyType) -> Self {
135 Self {
136 key_type,
137 address: *address,
138 }
139 }
140}
141
142pub fn datastore_prefix_from_address(address: &Address, prefix: &[u8]) -> Vec<u8> {
144 let mut res_prefix = LEDGER_PREFIX.as_bytes().to_vec();
145 U64VarIntSerializer::new()
146 .serialize(&KEY_VERSION, &mut res_prefix)
147 .unwrap();
148 AddressSerializer::new()
149 .serialize(address, &mut res_prefix)
150 .unwrap();
151 res_prefix.push(DATASTORE_IDENT);
152 res_prefix.extend(prefix);
153 res_prefix
154}
155
156#[derive(Default, Clone)]
158pub struct KeySerializer {
159 address_serializer: AddressSerializer,
160 key_type_serializer: KeyTypeSerializer,
161 version_byte_serializer: U64VarIntSerializer,
162}
163
164impl KeySerializer {
165 pub fn new(with_datastore_key_length: bool) -> Self {
168 Self {
169 address_serializer: AddressSerializer::new(),
170 key_type_serializer: KeyTypeSerializer::new(with_datastore_key_length),
171 version_byte_serializer: U64VarIntSerializer::new(),
172 }
173 }
174}
175
176impl Serializer<Key> for KeySerializer {
177 fn serialize(&self, value: &Key, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
191 buffer.extend(LEDGER_PREFIX.as_bytes());
192
193 self.version_byte_serializer
194 .serialize(&KEY_VERSION, buffer)?;
195 self.address_serializer.serialize(&value.address, buffer)?;
196 self.key_type_serializer
197 .serialize(&value.key_type, buffer)?;
198
199 Ok(())
200 }
201}
202
203#[derive(Clone)]
205pub struct KeyDeserializer {
206 address_deserializer: AddressDeserializer,
207 key_type_deserializer: KeyTypeDeserializer,
208 version_byte_deserializer: U64VarIntDeserializer,
209}
210
211impl KeyDeserializer {
212 pub fn new(max_datastore_key_length: u8, with_datastore_key_length: bool) -> Self {
216 Self {
217 address_deserializer: AddressDeserializer::new(),
218 key_type_deserializer: KeyTypeDeserializer::new(
219 max_datastore_key_length,
220 with_datastore_key_length,
221 ),
222 version_byte_deserializer: U64VarIntDeserializer::new(Included(0), Included(u64::MAX)),
223 }
224 }
225}
226
227impl Deserializer<Key> for KeyDeserializer {
228 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
254 &self,
255 buffer: &'a [u8],
256 ) -> nom::IResult<&'a [u8], Key, E> {
257 let prefix_len = LEDGER_PREFIX.len();
261 let after_prefix = buffer.get(prefix_len..).ok_or_else(|| {
262 nom::Err::Error(E::from_error_kind(buffer, nom::error::ErrorKind::Eof))
263 })?;
264
265 let (rest, version) = self.version_byte_deserializer.deserialize(after_prefix)?;
266 if version != KEY_VERSION {
271 return Err(nom::Err::Error(E::from_error_kind(
272 after_prefix,
273 nom::error::ErrorKind::Verify,
274 )));
275 }
276 let (rest, address) = self.address_deserializer.deserialize(rest)?;
277 let (rest, key_type) = self.key_type_deserializer.deserialize(rest)?;
278
279 Ok((rest, Key { address, key_type }))
280 }
281}
282
283#[cfg(test)]
284mod tests {
285 use super::{Key, KeyDeserializer, KeySerializer, KeyType};
286 use massa_db_exports::LEDGER_PREFIX;
287 use massa_models::address::Address;
288 use massa_serialization::{DeserializeError, Deserializer, Serializer};
289 use std::str::FromStr;
290
291 fn sample_address() -> Address {
292 Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap()
293 }
294
295 #[test]
296 fn canonical_key_still_round_trips() {
297 let key = Key::new(&sample_address(), KeyType::BALANCE);
298 let mut serialized = Vec::new();
299 KeySerializer::new(true)
300 .serialize(&key, &mut serialized)
301 .unwrap();
302 let (rest, deser) = KeyDeserializer::new(255, true)
303 .deserialize::<DeserializeError>(&serialized)
304 .unwrap();
305 assert!(rest.is_empty());
306 assert_eq!(deser, key);
307 }
308
309 #[test]
310 fn undersized_buffer_errors_instead_of_panicking() {
311 let short = vec![0u8; LEDGER_PREFIX.len().saturating_sub(1)];
314 let res = KeyDeserializer::new(255, true).deserialize::<DeserializeError>(&short);
315 assert!(res.is_err(), "undersized buffer must produce a parse error");
316 }
317
318 #[test]
319 fn non_canonical_version_is_rejected() {
320 let key = Key::new(&sample_address(), KeyType::BALANCE);
321 let mut serialized = Vec::new();
322 KeySerializer::new(true)
323 .serialize(&key, &mut serialized)
324 .unwrap();
325
326 let version_idx = LEDGER_PREFIX.len();
330 assert_eq!(serialized[version_idx], 0u8);
331 serialized[version_idx] = 1u8;
332
333 let res = KeyDeserializer::new(255, true).deserialize::<DeserializeError>(&serialized);
334 assert!(res.is_err(), "a non-canonical key version must be rejected");
335 }
336}