9d59aa91cece52a6a50c9d514fead7e6f1858685
[rapid-gossip-sync-server] / src / hex_utils.rs
1 use bitcoin::secp256k1::PublicKey;
2
3 pub fn to_vec(hex: &str) -> Option<Vec<u8>> {
4     let mut out = Vec::with_capacity(hex.len() / 2);
5
6     let mut b = 0;
7     for (idx, c) in hex.as_bytes().iter().enumerate() {
8         b <<= 4;
9         match *c {
10             b'A'..=b'F' => b |= c - b'A' + 10,
11             b'a'..=b'f' => b |= c - b'a' + 10,
12             b'0'..=b'9' => b |= c - b'0',
13             _ => return None,
14         }
15         if (idx & 1) == 1 {
16             out.push(b);
17             b = 0;
18         }
19     }
20
21     Some(out)
22 }
23
24 pub fn to_composite_index(scid: i64, timestamp: i64, direction: bool) -> String {
25         let scid_be = scid.to_be_bytes();
26         let res = format!("{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}:{}:{}",
27                 scid_be[0], scid_be[1], scid_be[2], scid_be[3],
28                 scid_be[4], scid_be[5], scid_be[6], scid_be[7],
29                 timestamp, direction as u8);
30         assert_eq!(res.len(), 29); // Our SQL Type requires len of 29
31         res
32 }
33
34 pub fn to_compressed_pubkey(hex: &str) -> Option<PublicKey> {
35     let data = match to_vec(&hex[0..33 * 2]) {
36         Some(bytes) => bytes,
37         None => return None,
38     };
39     match PublicKey::from_slice(&data) {
40         Ok(pk) => Some(pk),
41         Err(_) => None,
42     }
43 }