use consensus::encode::{Decodable, Encodable};
use consensus::encode::{self, Encoder, Decoder};
pub const PROTOCOL_VERSION: u32 = 70001;
pub const SERVICES: u64 = 0;
pub const USER_AGENT: &'static str = "bitcoin-rust v0.1";
user_enum! {
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
pub enum Network {
Bitcoin <-> "bitcoin",
Testnet <-> "testnet",
Regtest <-> "regtest"
}
}
impl Network {
pub fn from_magic(magic: u32) -> Option<Network> {
match magic {
0xD9B4BEF9 => Some(Network::Bitcoin),
0x0709110B => Some(Network::Testnet),
0xDAB5BFFA => Some(Network::Regtest),
_ => None
}
}
pub fn magic(&self) -> u32 {
match *self {
Network::Bitcoin => 0xD9B4BEF9,
Network::Testnet => 0x0709110B,
Network::Regtest => 0xDAB5BFFA,
}
}
}
impl<S: Encoder> Encodable<S> for Network {
#[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
self.magic().consensus_encode(s)
}
}
impl<D: Decoder> Decodable<D> for Network {
#[inline]
fn consensus_decode(d: &mut D) -> Result<Network, encode::Error> {
u32::consensus_decode(d)
.and_then(|m| {
Network::from_magic(m)
.ok_or(encode::Error::UnknownNetworkMagic(m))
})
}
}
#[cfg(test)]
mod tests {
use super::Network;
use consensus::encode::{deserialize, serialize};
#[test]
fn serialize_test() {
assert_eq!(serialize(&Network::Bitcoin), vec![0xf9, 0xbe, 0xb4, 0xd9]);
assert_eq!(serialize(&Network::Testnet), vec![0x0b, 0x11, 0x09, 0x07]);
assert_eq!(serialize(&Network::Regtest), vec![0xfa, 0xbf, 0xb5, 0xda]);
assert_eq!(deserialize(&[0xf9, 0xbe, 0xb4, 0xd9]).ok(), Some(Network::Bitcoin));
assert_eq!(deserialize(&[0x0b, 0x11, 0x09, 0x07]).ok(), Some(Network::Testnet));
assert_eq!(deserialize(&[0xfa, 0xbf, 0xb5, 0xda]).ok(), Some(Network::Regtest));
let bad: Result<Network, _> = deserialize("fakenet".as_bytes());
assert!(bad.is_err());
}
#[test]
fn string_test() {
assert_eq!(Network::Bitcoin.to_string(), "bitcoin");
assert_eq!(Network::Testnet.to_string(), "testnet");
assert_eq!(Network::Regtest.to_string(), "regtest");
assert_eq!("bitcoin".parse::<Network>().unwrap(), Network::Bitcoin);
assert_eq!("testnet".parse::<Network>().unwrap(), Network::Testnet);
assert_eq!("regtest".parse::<Network>().unwrap(), Network::Regtest);
assert!("fakenet".parse::<Network>().is_err());
}
}