1use crate::error::ModelsError;
4use crate::prehash::PreHashed;
5use massa_hash::{Hash, HashDeserializer, HASH_SIZE_BYTES};
6use massa_serialization::{
7 DeserializeError, Deserializer, SerializeError, Serializer, U64VarIntDeserializer,
8 U64VarIntSerializer,
9};
10use massa_signature::{PublicKey, PublicKeyV0};
11use nom::error::{context, ContextError, ErrorKind, ParseError};
12use nom::{IResult, Parser};
13use serde::{Deserialize, Serialize};
14use std::ops::Bound::{Excluded, Included};
15use std::str::FromStr;
16use transition::Versioned;
17
18#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
20pub enum Address {
21 #[allow(missing_docs)]
22 User(UserAddress),
23 #[allow(missing_docs)]
24 SC(SCAddress),
25}
26
27#[allow(missing_docs)]
28#[transition::versioned(versions("0"))]
30#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
31pub struct SCAddress(pub Hash);
32
33#[allow(missing_docs)]
34#[transition::versioned(versions("0"))]
36#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
37pub struct UserAddress(pub Hash);
38
39const ADDRESS_PREFIX: char = 'A';
40const USER_PREFIX: u64 = 0;
42const SC_PREFIX: u64 = 1;
43
44impl std::fmt::Display for Address {
45 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
46 match self {
47 Address::User(address) => address.fmt(f),
48 Address::SC(address) => address.fmt(f),
49 }
50 }
51}
52
53impl std::fmt::Display for UserAddress {
54 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
55 match self {
56 UserAddress::UserAddressV0(address) => address.fmt(f),
57 }
58 }
59}
60
61impl std::fmt::Display for SCAddress {
62 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
63 match self {
64 SCAddress::SCAddressV0(address) => address.fmt(f),
65 }
66 }
67}
68
69#[transition::impl_version(versions("0"))]
70impl std::fmt::Display for UserAddress {
71 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
72 let u64_serializer = U64VarIntSerializer::new();
73 let mut bytes: Vec<u8> = Vec::new();
74 u64_serializer
75 .serialize(&Self::VERSION, &mut bytes)
76 .map_err(|_| std::fmt::Error)?;
77 bytes.extend(self.0.to_bytes());
78 write!(
79 f,
80 "{}U{}",
81 ADDRESS_PREFIX,
82 bs58::encode(bytes).with_check().into_string()
83 )
84 }
85}
86
87#[transition::impl_version(versions("0"))]
88impl std::fmt::Display for SCAddress {
89 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
90 let u64_serializer = U64VarIntSerializer::new();
91 let mut bytes: Vec<u8> = Vec::new();
92 u64_serializer
93 .serialize(&Self::VERSION, &mut bytes)
94 .map_err(|_| std::fmt::Error)?;
95 bytes.extend(self.0.to_bytes());
96 write!(
97 f,
98 "{}S{}",
99 ADDRESS_PREFIX,
100 bs58::encode(bytes).with_check().into_string()
101 )
102 }
103}
104
105impl std::fmt::Debug for Address {
108 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
109 write!(f, "{}", self)
110 }
111}
112
113impl ::serde::Serialize for Address {
114 fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
115 match self {
116 Address::User(address) => address.serialize(s),
117 Address::SC(address) => address.serialize(s),
118 }
119 }
120}
121
122impl ::serde::Serialize for UserAddress {
123 fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
124 match self {
125 UserAddress::UserAddressV0(address) => address.serialize(s),
126 }
127 }
128}
129
130impl ::serde::Serialize for SCAddress {
131 fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
132 match self {
133 SCAddress::SCAddressV0(address) => address.serialize(s),
134 }
135 }
136}
137
138#[transition::impl_version(versions("0"))]
139impl ::serde::Serialize for UserAddress {
140 fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
141 if s.is_human_readable() {
142 s.collect_str(&self.to_string())
143 } else {
144 s.serialize_bytes(&self.to_prefixed_bytes())
145 }
146 }
147}
148
149#[transition::impl_version(versions("0"))]
150impl ::serde::Serialize for SCAddress {
151 fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
152 if s.is_human_readable() {
153 s.collect_str(&self.to_string())
154 } else {
155 s.serialize_bytes(&self.to_prefixed_bytes())
156 }
157 }
158}
159
160impl<'de> ::serde::Deserialize<'de> for Address {
161 fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Address, D::Error> {
162 if d.is_human_readable() {
163 struct AddressVisitor;
164
165 impl<'de> ::serde::de::Visitor<'de> for AddressVisitor {
166 type Value = Address;
167
168 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
169 formatter.write_str("A + {U | S} + base58::encode(version + hash)")
170 }
171
172 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
173 where
174 E: ::serde::de::Error,
175 {
176 if let Ok(v_str) = std::str::from_utf8(v) {
177 Address::from_str(v_str).map_err(E::custom)
178 } else {
179 Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self))
180 }
181 }
182
183 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
184 where
185 E: ::serde::de::Error,
186 {
187 Address::from_str(v).map_err(E::custom)
188 }
189 }
190 d.deserialize_str(AddressVisitor)
191 } else {
192 struct BytesVisitor;
193
194 impl<'de> ::serde::de::Visitor<'de> for BytesVisitor {
195 type Value = Address;
196
197 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
198 formatter.write_str("[u64varint-of-addr-variant][u64varint-of-version][bytes]")
199 }
200
201 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
202 where
203 E: ::serde::de::Error,
204 {
205 AddressDeserializer::new()
206 .deserialize::<DeserializeError>(v)
207 .map_err(E::custom)
208 .map(|r| r.1)
209 }
210 }
211
212 d.deserialize_bytes(BytesVisitor)
213 }
214 }
215}
216
217impl FromStr for Address {
218 type Err = ModelsError;
219 fn from_str(s: &str) -> Result<Self, Self::Err> {
220 let prefix_err = Err(ModelsError::AddressParseError(
221 "Invalid address: Address prefix 'AU' or 'AS' not found".to_string(),
222 ));
223
224 let mut chars = s.chars();
226 let Some(ADDRESS_PREFIX) = chars.next() else {
227 return prefix_err;
228 };
229 let Some(pref) = chars.next() else {
230 return prefix_err;
231 };
232
233 let res = match pref {
234 'U' => Address::User(UserAddress::from_str_without_prefixed_type(chars.as_str())?),
235 'S' => Address::SC(SCAddress::from_str_without_prefixed_type(chars.as_str())?),
236 _ => return prefix_err,
237 };
238 Ok(res)
239 }
240}
241
242impl Address {
243 pub fn get_thread(&self, thread_count: u8) -> u8 {
246 match self {
247 Address::User(addr) => addr.get_thread(thread_count),
248 Address::SC(_addr) => 0,
250 }
251 }
252
253 pub fn from_public_key(public_key: &PublicKey) -> Self {
256 Address::User(UserAddress::from_public_key(public_key))
257 }
258
259 pub fn to_prefixed_bytes(self) -> Vec<u8> {
261 match self {
262 Address::User(addr) => addr.to_prefixed_bytes(),
263 Address::SC(addr) => addr.to_prefixed_bytes(),
264 }
265 }
266}
267
268impl UserAddress {
269 fn get_thread(&self, thread_count: u8) -> u8 {
271 match self {
272 UserAddress::UserAddressV0(addr) => addr.get_thread(thread_count),
273 }
274 }
275
276 fn from_public_key(public_key: &PublicKey) -> Self {
278 match public_key {
279 PublicKey::PublicKeyV0(pk) => {
280 UserAddressVariant)
281 }
282 }
283 }
284
285 fn from_str_without_prefixed_type(s: &str) -> Result<Self, ModelsError> {
286 let decoded_bs58_check = bs58::decode(s).with_check(None).into_vec().map_err(|err| {
287 ModelsError::AddressParseError(format!(
288 "in UserAddress from_str_without_prefixed_type: {}",
289 err
290 ))
291 })?;
292 let u64_deserializer = U64VarIntDeserializer::new(Included(0), Included(u64::MAX));
293 let (rest, version) = u64_deserializer
294 .deserialize::<DeserializeError>(&decoded_bs58_check[..])
295 .map_err(|err| {
296 ModelsError::AddressParseError(format!(
297 "in UserAddress from_str_without_prefixed_type: {}",
298 err
299 ))
300 })?;
301
302 match version {
303 <UserAddress!["0"]>::VERSION => Ok(UserAddressVariant?,
305 )),
306 unhandled_version => Err(ModelsError::AddressParseError(format!(
307 "version {} is not handled for UserAddress",
308 unhandled_version
309 ))),
310 }
311 }
312
313 pub fn to_prefixed_bytes(self) -> Vec<u8> {
315 match self {
316 UserAddress::UserAddressV0(addr) => addr.to_prefixed_bytes(),
317 }
318 }
319}
320
321#[transition::impl_version(versions("0"))]
322impl UserAddress {
323 pub fn get_version(&self) -> u64 {
325 Self::VERSION
326 }
327
328 fn to_prefixed_bytes(self) -> Vec<u8> {
330 let mut buff = vec![];
331 let addr_type_ser = U64VarIntSerializer::new();
332 let addr_vers_ser = U64VarIntSerializer::new();
333 addr_type_ser
334 .serialize(&USER_PREFIX, &mut buff)
335 .expect("impl always returns Ok(())");
336 addr_vers_ser
337 .serialize(&Self::VERSION, &mut buff)
338 .expect("impl always returns Ok(())");
339 buff.extend_from_slice(&self.0.to_bytes()[..]);
340 buff
341 }
342
343 fn get_thread(&self, thread_count: u8) -> u8 {
345 (self.0.to_bytes()[0])
346 .checked_shr(8 - thread_count.trailing_zeros())
347 .unwrap_or(0)
348 }
349
350 fn from_bytes(data: &[u8]) -> Result<UserAddress, ModelsError> {
352 Ok(UserAddress(Hash::from_bytes(&data.try_into().map_err(
353 |_| {
354 ModelsError::BufferError(format!(
355 "expected a buffer of size {}, but found a size of {}",
356 HASH_SIZE_BYTES,
357 &data.len()
358 ))
359 },
360 )?)))
361 }
362}
363
364#[transition::impl_version(versions("0"), structures("UserAddress", "PublicKey"))]
365impl UserAddress {
366 pub fn from_public_key(public_key: &PublicKey) -> Self {
368 UserAddress(Hash::compute_from(&public_key.to_bytes()))
369 }
370}
371
372#[transition::impl_version(versions("0"))]
373impl UserAddress {}
374
375impl SCAddress {
376 fn from_str_without_prefixed_type(s: &str) -> Result<Self, ModelsError> {
377 let decoded_bs58_check = bs58::decode(s).with_check(None).into_vec().map_err(|err| {
378 ModelsError::AddressParseError(format!(
379 "in SCAddress from_str_without_prefixed_type: {}",
380 err
381 ))
382 })?;
383 let u64_deserializer = U64VarIntDeserializer::new(Included(0), Included(u64::MAX));
384 let (rest, version) = u64_deserializer
385 .deserialize::<DeserializeError>(&decoded_bs58_check[..])
386 .map_err(|err| {
387 ModelsError::AddressParseError(format!(
388 "in SCAddress from_str_without_prefixed_type: {}",
389 err
390 ))
391 })?;
392
393 match version {
394 <SCAddress!["0"]>::VERSION => {
395 Ok(SCAddressVariant?))
396 }
397 unhandled_version => Err(ModelsError::AddressParseError(format!(
398 "version {} is not handled for SCAddress",
399 unhandled_version
400 ))),
401 }
402 }
403
404 pub fn to_prefixed_bytes(self) -> Vec<u8> {
406 match self {
407 SCAddress::SCAddressV0(addr) => addr.to_prefixed_bytes(),
408 }
409 }
410}
411
412#[transition::impl_version(versions("0"))]
413impl SCAddress {
414 pub fn get_version(&self) -> u64 {
416 Self::VERSION
417 }
418}
419
420#[transition::impl_version(versions("0"))]
421impl SCAddress {
422 pub fn to_prefixed_bytes(self) -> Vec<u8> {
424 let mut buff = vec![];
425 let addr_type_ser = U64VarIntSerializer::new();
426 let addr_vers_ser = U64VarIntSerializer::new();
427 addr_type_ser
428 .serialize(&SC_PREFIX, &mut buff)
429 .expect("impl always returns Ok(())");
430 addr_vers_ser
431 .serialize(&Self::VERSION, &mut buff)
432 .expect("impl always returns Ok(())");
433 buff.extend_from_slice(&self.0.to_bytes()[..]);
434 buff
435 }
436
437 fn from_bytes(data: &[u8]) -> Result<SCAddress, ModelsError> {
439 Ok(SCAddress(Hash::from_bytes(&data.try_into().map_err(
440 |_| {
441 ModelsError::BufferError(format!(
442 "expected a buffer of size {}, but found a size of {}",
443 HASH_SIZE_BYTES,
444 &data.len()
445 ))
446 },
447 )?)))
448 }
449}
450
451impl PreHashed for Address {}
453
454#[derive(Default, Clone)]
456pub struct AddressSerializer {
457 type_serializer: U64VarIntSerializer,
458 version_serializer: U64VarIntSerializer,
459}
460
461impl AddressSerializer {
462 pub fn new() -> Self {
464 Self {
465 type_serializer: U64VarIntSerializer::new(),
466 version_serializer: U64VarIntSerializer::new(),
467 }
468 }
469}
470
471impl Serializer<Address> for AddressSerializer {
472 fn serialize(&self, value: &Address, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
473 match value {
474 Address::User(addr) => self.serialize(addr, buffer),
475 Address::SC(addr) => self.serialize(addr, buffer),
476 }
477 }
478}
479
480impl Serializer<UserAddress> for AddressSerializer {
481 fn serialize(&self, value: &UserAddress, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
482 self.type_serializer.serialize(&USER_PREFIX, buffer)?;
483 match value {
484 UserAddress::UserAddressV0(addr) => self.serialize(addr, buffer),
485 }
486 }
487}
488
489#[transition::impl_version(versions("0"), structures("UserAddress"))]
490impl Serializer<UserAddress> for AddressSerializer {
491 fn serialize(&self, value: &UserAddress, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
492 self.version_serializer
493 .serialize(&value.get_version(), buffer)?;
494 buffer.extend_from_slice(&value.0.into_bytes());
495 Ok(())
496 }
497}
498
499impl Serializer<SCAddress> for AddressSerializer {
500 fn serialize(&self, value: &SCAddress, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
501 self.type_serializer.serialize(&SC_PREFIX, buffer)?;
502 match value {
503 SCAddress::SCAddressV0(addr) => self.serialize(addr, buffer),
504 }
505 }
506}
507
508#[transition::impl_version(versions("0"), structures("SCAddress"))]
509impl Serializer<SCAddress> for AddressSerializer {
510 fn serialize(&self, value: &SCAddress, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
511 self.version_serializer
512 .serialize(&value.get_version(), buffer)?;
513 buffer.extend_from_slice(&value.0.into_bytes());
514 Ok(())
515 }
516}
517
518#[derive(Clone)]
520pub struct AddressDeserializer {
521 type_deserializer: U64VarIntDeserializer,
522 version_deserializer: U64VarIntDeserializer,
523 hash_deserializer: HashDeserializer,
524}
525
526impl Default for AddressDeserializer {
527 fn default() -> Self {
528 AddressDeserializer::new()
529 }
530}
531
532impl AddressDeserializer {
533 pub const fn new() -> Self {
535 Self {
536 type_deserializer: U64VarIntDeserializer::new(Included(0), Included(1)),
537 version_deserializer: U64VarIntDeserializer::new(Included(0), Excluded(u64::MAX)),
538 hash_deserializer: HashDeserializer::new(),
539 }
540 }
541}
542
543impl Deserializer<Address> for AddressDeserializer {
544 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
545 &self,
546 buffer: &'a [u8],
547 ) -> IResult<&'a [u8], Address, E> {
548 if buffer.len() < 2 {
550 return Err(nom::Err::Error(E::from_error_kind(buffer, ErrorKind::Eof)));
551 }
552 let (rest, addr_type) =
553 self.type_deserializer
554 .deserialize(buffer)
555 .map_err(|_: nom::Err<E>| {
556 nom::Err::Error(E::from_error_kind(buffer, ErrorKind::Eof))
557 })?;
558 match addr_type {
559 USER_PREFIX => {
560 let (rest, addr) = self.deserialize(rest)?;
561 Ok((rest, Address::User(addr)))
562 }
563 SC_PREFIX => {
564 let (rest, addr) = self.deserialize(rest)?;
565 Ok((rest, Address::SC(addr)))
566 }
567 _ => Err(nom::Err::Error(E::from_error_kind(buffer, ErrorKind::Eof))),
568 }
569 }
570}
571
572impl Deserializer<UserAddress> for AddressDeserializer {
573 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
574 &self,
575 buffer: &'a [u8],
576 ) -> IResult<&'a [u8], UserAddress, E> {
577 if buffer.len() < 2 {
579 return Err(nom::Err::Error(E::from_error_kind(buffer, ErrorKind::Eof)));
580 }
581 let (rest, addr_vers) =
582 self.version_deserializer
583 .deserialize(buffer)
584 .map_err(|_: nom::Err<E>| {
585 nom::Err::Error(E::from_error_kind(buffer, ErrorKind::Eof))
586 })?;
587 match addr_vers {
588 <UserAddress!["0"]>::VERSION => {
589 let (rest, addr) = self.deserialize(rest)?;
590 Ok((rest, UserAddressVariant))
591 }
592 _ => Err(nom::Err::Error(E::from_error_kind(buffer, ErrorKind::Eof))),
593 }
594 }
595}
596
597#[transition::impl_version(versions("0"), structures("UserAddress"))]
598impl Deserializer<UserAddress> for AddressDeserializer {
599 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
600 &self,
601 buffer: &'a [u8],
602 ) -> IResult<&'a [u8], UserAddress, E> {
603 context("Failed UserAddress deserialization", |input| {
604 self.hash_deserializer.deserialize(input)
605 })
606 .map(UserAddress)
607 .parse(buffer)
608 }
609}
610
611impl Deserializer<SCAddress> for AddressDeserializer {
612 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
613 &self,
614 buffer: &'a [u8],
615 ) -> IResult<&'a [u8], SCAddress, E> {
616 if buffer.len() < 2 {
618 return Err(nom::Err::Error(E::from_error_kind(buffer, ErrorKind::Eof)));
619 }
620 let (rest, addr_vers) =
621 self.version_deserializer
622 .deserialize(buffer)
623 .map_err(|_: nom::Err<E>| {
624 nom::Err::Error(E::from_error_kind(buffer, ErrorKind::Eof))
625 })?;
626 match addr_vers {
627 <SCAddress!["0"]>::VERSION => {
628 let (rest, addr) = self.deserialize(rest)?;
629 Ok((rest, SCAddressVariant))
630 }
631 _ => Err(nom::Err::Error(E::from_error_kind(buffer, ErrorKind::Eof))),
632 }
633 }
634}
635
636#[transition::impl_version(versions("0"), structures("SCAddress"))]
637impl Deserializer<SCAddress> for AddressDeserializer {
638 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
639 &self,
640 buffer: &'a [u8],
641 ) -> IResult<&'a [u8], SCAddress, E> {
642 context("Failed SCAddress deserialization", |input| {
643 self.hash_deserializer.deserialize(input)
644 })
645 .map(SCAddress)
646 .parse(buffer)
647 }
648}
649
650#[derive(Clone, Debug, Serialize, Deserialize)]
652pub struct ExecutionAddressCycleInfo {
653 pub cycle: u64,
655 pub is_final: bool,
657 pub ok_count: u64,
659 pub nok_count: u64,
661 pub active_rolls: Option<u64>,
663}
664
665#[cfg(test)]
666mod test {
667 use crate::config::THREAD_COUNT;
668
669 use super::*;
670
671 #[test]
672 fn test_address() {
673 let expected_user_addr =
674 Address::from_str("AU12fZLkHnLED3okr8Lduyty7dz9ZKkd24xMCc2JJWPcdmfn2eUEx").unwrap();
675 let expected_sc_addr =
676 Address::from_str("AS12fZLkHnLED3okr8Lduyty7dz9ZKkd24xMCc2JJWPcdmfn2eUEx").unwrap();
677
678 let hash = massa_hash::Hash::compute_from("ADDR".as_bytes());
679 let actual_user_addr = Address::User(UserAddress::UserAddressV0(UserAddressV0(hash)));
680 let actual_sc_addr = Address::SC(SCAddress::SCAddressV0(SCAddressV0(hash)));
681
682 assert_eq!(actual_user_addr, expected_user_addr);
683 assert_eq!(actual_sc_addr, expected_sc_addr);
684 }
685
686 #[test]
687 fn test_address_errors() {
688 let expected_error_0 =
689 "address parsing error: Invalid address: Address prefix 'AU' or 'AS' not found"
690 .to_string();
691 let actual_error_0 = Address::from_str("UnexpectedAddress")
692 .unwrap_err()
693 .to_string();
694
695 let expected_error_1 = "address parsing error: in SCAddress from_str_without_prefixed_type: invalid checksum, calculated checksum: '[255, 246, 254, 58]', expected checksum: [188, 126, 221, 98]".to_string();
696 let actual_error_1 = Address::from_str("ASSomeUnexpectedAddress")
697 .unwrap_err()
698 .to_string();
699
700 let expected_error_2 = "address parsing error: in SCAddress from_str_without_prefixed_type: provided string contained invalid character '_' at byte 0".to_string();
701 let actual_error_2 = Address::from_str("AS_SomeUnexpectedAddress")
702 .unwrap_err()
703 .to_string();
704
705 let expected_error_3 = "address parsing error: in UserAddress from_str_without_prefixed_type: invalid checksum, calculated checksum: '[255, 246, 254, 58]', expected checksum: [188, 126, 221, 98]".to_string();
706 let actual_error_3 = Address::from_str("AUSomeUnexpectedAddress")
707 .unwrap_err()
708 .to_string();
709
710 let expected_error_4 = "address parsing error: in UserAddress from_str_without_prefixed_type: provided string contained invalid character '_' at byte 0".to_string();
711 let actual_error_4 = Address::from_str("AU_SomeUnexpectedAddress")
712 .unwrap_err()
713 .to_string();
714
715 assert_eq!(actual_error_0, expected_error_0);
716 assert_eq!(actual_error_1, expected_error_1);
717 assert_eq!(actual_error_2, expected_error_2);
718 assert_eq!(actual_error_3, expected_error_3);
719 assert_eq!(actual_error_4, expected_error_4);
720 }
721
722 #[test]
723 fn test_address_get_thread() {
724 let hash = massa_hash::Hash::compute_from("ADDR".as_bytes());
725
726 let user_addr_0 = Address::User(UserAddress::UserAddressV0(UserAddressV0(hash)));
727 let thread_addr_0 = user_addr_0.get_thread(THREAD_COUNT);
728 let hash = massa_hash::Hash::compute_from("ADDR2".as_bytes());
729
730 let user_addr_1 = Address::User(UserAddress::UserAddressV0(UserAddressV0(hash)));
731 let thread_addr_1 = user_addr_1.get_thread(THREAD_COUNT);
732
733 assert_ne!(thread_addr_0, thread_addr_1);
734 }
735
736 #[test]
737 fn test_address_serde() {
738 let expected_addr =
739 Address::from_str("AU12fZLkHnLED3okr8Lduyty7dz9ZKkd24xMCc2JJWPcdmfn2eUEx").unwrap();
740
741 let serialized = serde_json::to_string(&expected_addr).unwrap();
742 let actual_addr: Address = serde_json::from_str(&serialized).unwrap();
743
744 assert_eq!(actual_addr, expected_addr);
745 }
746}