1mod errors;
5mod network;
6mod payload;
7mod protocol;
8pub use self::errors::Error;
9pub use self::network::Network;
10pub use self::payload::{BLSPublicKey, Payload};
11pub use self::protocol::Protocol;
12
13use data_encoding::Encoding;
14#[allow(unused_imports)]
15use data_encoding_macro::{internal_new_encoding, new_encoding};
16use encoding::{blake2b_variable, serde_bytes, Cbor};
17use once_cell::sync::OnceCell;
18use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
19use std::hash::Hash;
20use std::str::FromStr;
21use std::{borrow::Cow, fmt};
22
23const ADDRESS_ENCODER: Encoding = new_encoding! {
25 symbols: "abcdefghijklmnopqrstuvwxyz234567",
26 padding: None,
27};
28
29pub const PAYLOAD_HASH_LEN: usize = 20;
31
32pub const SECP_PUB_LEN: usize = 65;
34
35pub const BLS_PUB_LEN: usize = 48;
37
38pub const CHECKSUM_HASH_LEN: usize = 4;
40
41const MAX_ADDRESS_LEN: usize = 84 + 2;
42const MAINNET_PREFIX: &str = "f";
43const TESTNET_PREFIX: &str = "t";
44
45#[cfg(feature = "json")]
46const UNDEF_ADDR_STRING: &str = "<empty>";
47
48pub static NETWORK_DEFAULT: OnceCell<Network> = OnceCell::new();
50
51#[derive(PartialEq, Eq, Clone, Debug, Hash, Copy)]
54pub struct Address {
55 network: Network,
56 payload: Payload,
57}
58
59impl Address {
60 fn new(network: Network, protocol: Protocol, bz: &[u8]) -> Result<Self, Error> {
62 Ok(Self {
63 network,
64 payload: Payload::new(protocol, bz)?,
65 })
66 }
67
68 pub fn from_bytes(bz: &[u8]) -> Result<Self, Error> {
70 if bz.len() < 2 {
71 Err(Error::InvalidLength)
72 } else {
73 let protocol = Protocol::from_byte(bz[0]).ok_or(Error::UnknownProtocol)?;
74 Self::new(
75 *NETWORK_DEFAULT.get_or_init(|| Network::Mainnet),
76 protocol,
77 &bz[1..],
78 )
79 }
80 }
81
82 pub fn new_id(id: u64) -> Self {
84 Self {
85 network: *NETWORK_DEFAULT.get_or_init(|| Network::Mainnet),
86 payload: Payload::ID(id),
87 }
88 }
89
90 pub fn new_secp256k1(pubkey: &[u8]) -> Result<Self, Error> {
92 if pubkey.len() != 65 {
93 return Err(Error::InvalidSECPLength(pubkey.len()));
94 }
95 Ok(Self {
96 network: *NETWORK_DEFAULT.get_or_init(|| Network::Mainnet),
97 payload: Payload::Secp256k1(address_hash(pubkey)),
98 })
99 }
100
101 pub fn new_actor(data: &[u8]) -> Self {
103 Self {
104 network: *NETWORK_DEFAULT.get_or_init(|| Network::Mainnet),
105 payload: Payload::Actor(address_hash(data)),
106 }
107 }
108
109 pub fn new_bls(pubkey: &[u8]) -> Result<Self, Error> {
111 if pubkey.len() != BLS_PUB_LEN {
112 return Err(Error::InvalidBLSLength(pubkey.len()));
113 }
114 let mut key = [0u8; BLS_PUB_LEN];
115 key.copy_from_slice(pubkey);
116 Ok(Self {
117 network: *NETWORK_DEFAULT.get_or_init(|| Network::Mainnet),
118 payload: Payload::BLS(key.into()),
119 })
120 }
121
122 pub fn protocol(&self) -> Protocol {
124 Protocol::from(self.payload)
125 }
126
127 pub fn payload(&self) -> &Payload {
130 &self.payload
131 }
132
133 pub fn into_payload(self) -> Payload {
136 self.payload
137 }
138
139 pub fn payload_bytes(&self) -> Vec<u8> {
141 self.payload.to_raw_bytes()
142 }
143
144 pub fn network(&self) -> Network {
146 self.network
147 }
148
149 pub fn set_network(&mut self, network: Network) -> &mut Self {
151 self.network = network;
152 self
153 }
154
155 pub fn to_bytes(self) -> Vec<u8> {
157 self.payload.to_bytes()
158 }
159
160 pub fn id(&self) -> Result<u64, Error> {
162 match self.payload {
163 Payload::ID(id) => Ok(id),
164 _ => Err(Error::NonIDAddress),
165 }
166 }
167}
168
169impl fmt::Display for Address {
170 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171 write!(f, "{}", encode(self))
172 }
173}
174
175impl FromStr for Address {
176 type Err = Error;
177 fn from_str(addr: &str) -> Result<Self, Error> {
178 if addr.len() > MAX_ADDRESS_LEN || addr.len() < 3 {
179 return Err(Error::InvalidLength);
180 }
181 let network: Network = match addr.get(0..1).ok_or(Error::UnknownNetwork)? {
183 TESTNET_PREFIX => Network::Testnet,
184 MAINNET_PREFIX => Network::Mainnet,
185 _ => {
186 return Err(Error::UnknownNetwork);
187 }
188 };
189
190 let protocol: Protocol = match addr.get(1..2).ok_or(Error::UnknownProtocol)? {
192 "0" => Protocol::ID,
193 "1" => Protocol::Secp256k1,
194 "2" => Protocol::Actor,
195 "3" => Protocol::BLS,
196 _ => {
197 return Err(Error::UnknownProtocol);
198 }
199 };
200
201 let raw = addr.get(2..).ok_or(Error::InvalidPayload)?;
203 if protocol == Protocol::ID {
204 if raw.len() > 20 {
205 return Err(Error::InvalidLength);
207 }
208 let id = raw.parse::<u64>()?;
209 return Ok(Address {
210 network,
211 payload: Payload::ID(id),
212 });
213 }
214
215 let mut payload = ADDRESS_ENCODER.decode(raw.as_bytes())?;
217 let cksm = payload.split_off(payload.len() - CHECKSUM_HASH_LEN);
219
220 if (protocol == Protocol::Secp256k1 || protocol == Protocol::Actor)
222 && payload.len() != PAYLOAD_HASH_LEN
223 {
224 return Err(Error::InvalidPayload);
225 }
226
227 if protocol == Protocol::BLS && payload.len() != BLS_PUB_LEN {
229 return Err(Error::InvalidPayload);
230 }
231
232 let mut ingest = payload.clone();
234 ingest.insert(0, protocol as u8);
235 if !validate_checksum(&ingest, cksm) {
236 return Err(Error::InvalidChecksum);
237 }
238
239 Address::new(network, protocol, &payload)
240 }
241}
242
243impl Serialize for Address {
244 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
245 where
246 S: Serializer,
247 {
248 let address_bytes = self.to_bytes();
249 serde_bytes::Serialize::serialize(&address_bytes, s)
250 }
251}
252
253impl<'de> Deserialize<'de> for Address {
254 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
255 where
256 D: Deserializer<'de>,
257 {
258 let bz: Cow<'de, [u8]> = serde_bytes::Deserialize::deserialize(deserializer)?;
259
260 Address::from_bytes(&bz).map_err(de::Error::custom)
262 }
263}
264
265impl Cbor for Address {}
266
267fn encode(addr: &Address) -> String {
269 match addr.protocol() {
270 Protocol::Secp256k1 | Protocol::Actor | Protocol::BLS => {
271 let ingest = addr.to_bytes();
272 let mut bz = addr.payload_bytes();
273
274 bz.extend(checksum(&ingest));
276 format!(
277 "{}{}{}",
278 addr.network.to_prefix(),
279 addr.protocol().to_string(),
280 ADDRESS_ENCODER.encode(bz.as_mut()),
281 )
282 }
283 Protocol::ID => format!(
284 "{}{}{}",
285 addr.network.to_prefix(),
286 addr.protocol().to_string(),
287 from_leb_bytes(&addr.payload_bytes()).expect("should read encoded bytes"),
288 ),
289 }
290}
291
292pub(crate) fn to_leb_bytes(id: u64) -> Result<Vec<u8>, Error> {
293 let mut buf = Vec::new();
294
295 leb128::write::unsigned(&mut buf, id)?;
297
298 Ok(buf)
300}
301
302pub(crate) fn from_leb_bytes(bz: &[u8]) -> Result<u64, Error> {
303 let mut readable = bz;
304
305 let id = leb128::read::unsigned(&mut readable)?;
307
308 if to_leb_bytes(id)? == bz {
309 Ok(id)
310 } else {
311 Err(Error::InvalidAddressIDPayload(bz.to_owned()))
312 }
313}
314
315#[cfg(test)]
316mod tests {
317 use crate::{errors::Error, from_leb_bytes, to_leb_bytes};
319
320 #[test]
321 fn test_from_leb_bytes_passing() {
322 let passing = vec![67];
323 assert_eq!(
324 to_leb_bytes(from_leb_bytes(&passing).unwrap()),
325 Ok(vec![67])
326 );
327 }
328
329 #[test]
330 fn test_from_leb_bytes_extra_bytes() {
331 let extra_bytes = vec![67, 0, 1, 2];
332
333 match from_leb_bytes(&extra_bytes) {
334 Ok(id) => {
335 println!(
336 "Successfully decoded bytes when it was not supposed to. Result was: {:?}",
337 &to_leb_bytes(id).unwrap()
338 );
339 panic!();
340 }
341 Err(e) => {
342 assert_eq!(e, Error::InvalidAddressIDPayload(extra_bytes));
343 }
344 }
345 }
346
347 #[test]
348 fn test_from_leb_bytes_minimal_encoding() {
349 let minimal_encoding = vec![67, 0, 130, 0];
350
351 match from_leb_bytes(&minimal_encoding) {
352 Ok(id) => {
353 println!(
354 "Successfully decoded bytes when it was not supposed to. Result was: {:?}",
355 &to_leb_bytes(id).unwrap()
356 );
357 panic!();
358 }
359 Err(e) => {
360 assert_eq!(e, Error::InvalidAddressIDPayload(minimal_encoding));
361 }
362 }
363 }
364}
365
366pub fn checksum(ingest: &[u8]) -> Vec<u8> {
368 blake2b_variable(ingest, CHECKSUM_HASH_LEN)
369}
370
371pub fn validate_checksum(ingest: &[u8], expect: Vec<u8>) -> bool {
373 let digest = checksum(ingest);
374 digest == expect
375}
376
377fn address_hash(ingest: &[u8]) -> [u8; 20] {
379 let digest = blake2b_variable(ingest, PAYLOAD_HASH_LEN);
380 let mut hash = [0u8; 20];
381 hash.clone_from_slice(&digest);
382 hash
383}
384
385#[cfg(feature = "json")]
386pub mod json {
387 use super::*;
388 use serde::{Deserialize, Deserializer, Serializer};
389 use std::borrow::Cow;
390
391 #[derive(Deserialize, Serialize)]
393 #[serde(transparent)]
394 pub struct AddressJson(#[serde(with = "self")] pub Address);
395
396 #[derive(Serialize)]
398 #[serde(transparent)]
399 pub struct AddressJsonRef<'a>(#[serde(with = "self")] pub &'a Address);
400
401 impl From<Address> for AddressJson {
402 fn from(address: Address) -> Self {
403 Self(address)
404 }
405 }
406
407 impl From<AddressJson> for Address {
408 fn from(address: AddressJson) -> Self {
409 address.0
410 }
411 }
412
413 pub fn serialize<S>(m: &Address, serializer: S) -> Result<S::Ok, S::Error>
414 where
415 S: Serializer,
416 {
417 serializer.serialize_str(&encode(m))
418 }
419
420 pub fn deserialize<'de, D>(deserializer: D) -> Result<Address, D::Error>
421 where
422 D: Deserializer<'de>,
423 {
424 let address_as_string: Cow<'de, str> = Deserialize::deserialize(deserializer)?;
425 Address::from_str(&address_as_string).map_err(de::Error::custom)
426 }
427
428 #[cfg(feature = "json")]
429 pub mod vec {
430 use super::*;
431 use crate::json::{AddressJson, AddressJsonRef};
432 use forest_json_utils::GoVecVisitor;
433 use serde::ser::SerializeSeq;
434
435 #[derive(Deserialize, Serialize)]
437 #[serde(transparent)]
438 pub struct AddressJsonVec(#[serde(with = "self")] pub Vec<Address>);
439
440 #[derive(Serialize)]
442 #[serde(transparent)]
443 pub struct AddressJsonSlice<'a>(#[serde(with = "self")] pub &'a [Address]);
444
445 pub fn serialize<S>(m: &[Address], serializer: S) -> Result<S::Ok, S::Error>
446 where
447 S: Serializer,
448 {
449 let mut seq = serializer.serialize_seq(Some(m.len()))?;
450 for e in m {
451 seq.serialize_element(&AddressJsonRef(e))?;
452 }
453 seq.end()
454 }
455
456 pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Address>, D::Error>
457 where
458 D: Deserializer<'de>,
459 {
460 deserializer.deserialize_any(GoVecVisitor::<Address, AddressJson>::new())
461 }
462 }
463
464 pub mod opt {
465 use super::*;
466 use serde::{self, Deserialize, Deserializer, Serializer};
467 use std::borrow::Cow;
468
469 pub fn serialize<S>(v: &Option<Address>, serializer: S) -> Result<S::Ok, S::Error>
470 where
471 S: Serializer,
472 {
473 if let Some(unwrapped_address) = v.as_ref() {
474 serializer.serialize_str(&encode(unwrapped_address))
475 } else {
476 serializer.serialize_str(UNDEF_ADDR_STRING)
477 }
478 }
479
480 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Address>, D::Error>
481 where
482 D: Deserializer<'de>,
483 {
484 let address_as_string: Cow<'de, str> = Deserialize::deserialize(deserializer)?;
485 if address_as_string == UNDEF_ADDR_STRING {
486 return Ok(None);
487 }
488 Ok(Some(
489 Address::from_str(&address_as_string).map_err(de::Error::custom)?,
490 ))
491 }
492 }
493}