+ fn decode(v: &[u8]) -> Result<Self, DecodeError> {
+ let features = GlobalFeatures::decode(&v[..])?;
+ if v.len() < features.encoded_len() + 4 + 33 + 3 + 32 + 2 {
+ return Err(DecodeError::WrongLength);
+ }
+ let start = features.encoded_len();
+
+ let mut rgb = [0; 3];
+ rgb.copy_from_slice(&v[start + 37..start + 40]);
+
+ let mut alias = [0; 32];
+ alias.copy_from_slice(&v[start + 40..start + 72]);
+
+ let addrlen = byte_utils::slice_to_be16(&v[start + 72..start + 74]) as usize;
+ if v.len() < start + 74 + addrlen {
+ return Err(DecodeError::WrongLength);
+ }
+
+ let mut addresses = Vec::with_capacity(4);
+ let mut read_pos = start + 74;
+ loop {
+ if v.len() <= read_pos { break; }
+ match v[read_pos] {
+ 0 => { read_pos += 1; },
+ 1 => {
+ if v.len() < read_pos + 1 + 6 {
+ return Err(DecodeError::WrongLength);
+ }
+ if addresses.len() > 0 {
+ return Err(DecodeError::ExtraAddressesPerType);
+ }
+ let mut addr = [0; 4];
+ addr.copy_from_slice(&v[read_pos + 1..read_pos + 5]);
+ addresses.push(NetAddress::IPv4 {
+ addr,
+ port: byte_utils::slice_to_be16(&v[read_pos + 5..read_pos + 7]),
+ });
+ read_pos += 1 + 6;
+ },
+ 2 => {
+ if v.len() < read_pos + 1 + 18 {
+ return Err(DecodeError::WrongLength);
+ }
+ if addresses.len() > 1 || (addresses.len() == 1 && addresses[0].get_id() != 1) {
+ return Err(DecodeError::ExtraAddressesPerType);
+ }
+ let mut addr = [0; 16];
+ addr.copy_from_slice(&v[read_pos + 1..read_pos + 17]);
+ addresses.push(NetAddress::IPv6 {
+ addr,
+ port: byte_utils::slice_to_be16(&v[read_pos + 17..read_pos + 19]),
+ });
+ read_pos += 1 + 18;
+ },
+ 3 => {
+ if v.len() < read_pos + 1 + 12 {
+ return Err(DecodeError::WrongLength);
+ }
+ if addresses.len() > 2 || (addresses.len() > 0 && addresses.last().unwrap().get_id() > 2) {
+ return Err(DecodeError::ExtraAddressesPerType);
+ }
+ let mut addr = [0; 10];
+ addr.copy_from_slice(&v[read_pos + 1..read_pos + 11]);
+ addresses.push(NetAddress::OnionV2 {
+ addr,
+ port: byte_utils::slice_to_be16(&v[read_pos + 11..read_pos + 13]),
+ });
+ read_pos += 1 + 12;
+ },
+ 4 => {
+ if v.len() < read_pos + 1 + 37 {
+ return Err(DecodeError::WrongLength);
+ }
+ if addresses.len() > 3 || (addresses.len() > 0 && addresses.last().unwrap().get_id() > 3) {
+ return Err(DecodeError::ExtraAddressesPerType);
+ }
+ let mut ed25519_pubkey = [0; 32];
+ ed25519_pubkey.copy_from_slice(&v[read_pos + 1..read_pos + 33]);
+ addresses.push(NetAddress::OnionV3 {
+ ed25519_pubkey,
+ checksum: byte_utils::slice_to_be16(&v[read_pos + 33..read_pos + 35]),
+ version: v[read_pos + 35],
+ port: byte_utils::slice_to_be16(&v[read_pos + 36..read_pos + 38]),
+ });
+ read_pos += 1 + 37;
+ },
+ _ => { break; } // We've read all we can, we dont understand anything higher (and they're sorted)
+ }
+ }
+
+ let secp_ctx = Secp256k1::without_caps();
+ Ok(Self {
+ features,
+ timestamp: byte_utils::slice_to_be32(&v[start..start + 4]),
+ node_id: secp_pubkey!(&secp_ctx, &v[start + 4..start + 37]),
+ rgb,
+ alias,
+ addresses,
+ })