ant_registers/
address.rs

1// Copyright 2024 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
4// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
5// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
6// KIND, either express or implied. Please review the Licences for the specific language governing
7// permissions and limitations relating to use of the SAFE Network Software.
8
9use crate::error::{Error, Result};
10
11use bls::{PublicKey, PK_SIZE};
12use serde::{Deserialize, Serialize};
13use std::{
14    fmt::{Debug, Display},
15    hash::Hash,
16};
17use xor_name::{XorName, XOR_NAME_LEN};
18
19/// Address of a Register on the SAFE Network
20#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
21pub struct RegisterAddress {
22    /// User chosen meta, can be anything, the register's name on the network will be the hash of this meta and the owner
23    pub(crate) meta: XorName,
24    /// Owner of the register
25    pub(crate) owner: PublicKey,
26}
27
28impl Display for RegisterAddress {
29    /// Display the register address in hex format that can be parsed by `RegisterAddress::from_hex`.
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        write!(f, "{}", &self.to_hex())
32    }
33}
34
35impl Debug for RegisterAddress {
36    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37        write!(
38            f,
39            "RegisterAddress({}) {{ meta: {:?}, owner: {:?} }}",
40            &self.to_hex()[0..6],
41            self.meta,
42            self.owner
43        )
44    }
45}
46
47impl RegisterAddress {
48    /// Construct a new `RegisterAddress` given `meta` and `owner`.
49    pub fn new(meta: XorName, owner: PublicKey) -> Self {
50        Self { meta, owner }
51    }
52
53    /// Return the network name of the register.
54    /// This is used to locate the register on the network.
55    pub fn xorname(&self) -> XorName {
56        let mut bytes = vec![];
57        bytes.extend_from_slice(&self.meta.0);
58        bytes.extend_from_slice(&self.owner.to_bytes());
59        XorName::from_content(&bytes)
60    }
61
62    /// Serialize this `RegisterAddress` instance to a hex-encoded `String`.
63    pub fn to_hex(&self) -> String {
64        let mut bytes = vec![];
65        bytes.extend_from_slice(&self.meta.0);
66        bytes.extend_from_slice(&self.owner.to_bytes());
67        hex::encode(bytes)
68    }
69
70    /// Deserialize a hex-encoded representation of a `RegisterAddress` to a `RegisterAddress` instance.
71    pub fn from_hex(hex: &str) -> Result<Self> {
72        let bytes = hex::decode(hex).map_err(|_| Error::HexDeserializeFailed)?;
73        let meta_bytes: [u8; XOR_NAME_LEN] = bytes[..XOR_NAME_LEN]
74            .try_into()
75            .map_err(|_| Error::HexDeserializeFailed)?;
76        let meta = XorName(meta_bytes);
77        let owner_bytes: [u8; PK_SIZE] = bytes[XOR_NAME_LEN..]
78            .try_into()
79            .map_err(|_| Error::HexDeserializeFailed)?;
80        let owner = PublicKey::from_bytes(owner_bytes).map_err(|_| Error::HexDeserializeFailed)?;
81        Ok(Self { meta, owner })
82    }
83
84    /// Return the user chosen meta.
85    pub fn meta(&self) -> XorName {
86        self.meta
87    }
88
89    /// Return the owner.
90    pub fn owner(&self) -> PublicKey {
91        self.owner
92    }
93}
94
95#[cfg(test)]
96mod tests {
97    use bls::SecretKey;
98
99    use super::*;
100
101    #[test]
102    fn test_register_hex_conversion() {
103        let mut rng = rand::thread_rng();
104        let owner = SecretKey::random().public_key();
105        let meta = XorName::random(&mut rng);
106        let addr = RegisterAddress::new(meta, owner);
107        let hex = &addr.to_hex();
108        let addr2 = RegisterAddress::from_hex(hex).unwrap();
109
110        assert_eq!(addr, addr2);
111
112        let bad_hex = format!("{hex}0");
113        let err = RegisterAddress::from_hex(&bad_hex);
114        assert_eq!(err, Err(Error::HexDeserializeFailed));
115    }
116}