pub const MAX_SCID_BLOCK: u64 = 0x00ffffff;
pub const MAX_SCID_TX_INDEX: u64 = 0x00ffffff;
pub const MAX_SCID_VOUT_INDEX: u64 = 0xffff;
#[derive(Debug, PartialEq)]
pub enum ShortChannelIdError {
BlockOverflow,
TxIndexOverflow,
VoutIndexOverflow,
}
pub fn block_from_scid(short_channel_id: &u64) -> u32 {
return (short_channel_id >> 40) as u32;
}
pub fn scid_from_parts(block: u64, tx_index: u64, vout_index: u64) -> Result<u64, ShortChannelIdError> {
if block > MAX_SCID_BLOCK {
return Err(ShortChannelIdError::BlockOverflow);
}
if tx_index > MAX_SCID_TX_INDEX {
return Err(ShortChannelIdError::TxIndexOverflow);
}
if vout_index > MAX_SCID_VOUT_INDEX {
return Err(ShortChannelIdError::VoutIndexOverflow);
}
Ok((block << 40) | (tx_index << 16) | vout_index)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_block_from_scid() {
assert_eq!(block_from_scid(&0x000000_000000_0000), 0);
assert_eq!(block_from_scid(&0x000001_000000_0000), 1);
assert_eq!(block_from_scid(&0x000001_ffffff_ffff), 1);
assert_eq!(block_from_scid(&0x800000_ffffff_ffff), 0x800000);
assert_eq!(block_from_scid(&0xffffff_ffffff_ffff), 0xffffff);
}
#[test]
fn test_scid_from_parts() {
assert_eq!(scid_from_parts(0x00000000, 0x00000000, 0x0000).unwrap(), 0x000000_000000_0000);
assert_eq!(scid_from_parts(0x00000001, 0x00000002, 0x0003).unwrap(), 0x000001_000002_0003);
assert_eq!(scid_from_parts(0x00111111, 0x00222222, 0x3333).unwrap(), 0x111111_222222_3333);
assert_eq!(scid_from_parts(0x00ffffff, 0x00ffffff, 0xffff).unwrap(), 0xffffff_ffffff_ffff);
assert_eq!(scid_from_parts(0x01ffffff, 0x00000000, 0x0000).err().unwrap(), ShortChannelIdError::BlockOverflow);
assert_eq!(scid_from_parts(0x00000000, 0x01ffffff, 0x0000).err().unwrap(), ShortChannelIdError::TxIndexOverflow);
assert_eq!(scid_from_parts(0x00000000, 0x00000000, 0x010000).err().unwrap(), ShortChannelIdError::VoutIndexOverflow);
}
}