2014-07-18 13:56:17 +00:00
|
|
|
// Rust Bitcoin Library
|
|
|
|
// Written in 2014 by
|
|
|
|
// Andrew Poelstra <apoelstra@wpsoftware.net>
|
|
|
|
//
|
|
|
|
// To the extent possible under law, the author(s) have dedicated all
|
|
|
|
// copyright and related and neighboring rights to this software to
|
|
|
|
// the public domain worldwide. This software is distributed without
|
|
|
|
// any warranty.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the CC0 Public Domain Dedication
|
|
|
|
// along with this software.
|
|
|
|
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
|
|
|
//
|
|
|
|
|
2018-08-10 17:09:22 +00:00
|
|
|
//! Network constants
|
2014-07-18 13:56:17 +00:00
|
|
|
//!
|
|
|
|
//! This module provides various constants relating to the Bitcoin network
|
|
|
|
//! protocol, such as protocol versioning and magic header bytes.
|
|
|
|
//!
|
Move relevant names into consensus::encode
- Move network::encodable::* to consensus::encode::*
- Rename Consensus{En,De}codable to {En,De}codable (now under
consensus::encode)
- Move network::serialize::Error to consensus::encode::Error
- Remove Raw{En,De}coder, implement {En,De}coder for T: {Write,Read}
instead
- Move network::serialize::Simple{En,De}coder to
consensus::encode::{En,De}coder
- Rename util::Error::Serialize to util::Error::Encode
- Modify comments to refer to new names
- Modify files to refer to new names
- Expose {En,De}cod{able,er}, {de,}serialize, Params
- Do not return Result for serialize{,_hex} as serializing to a Vec
should never fail
2018-09-20 10:15:45 +00:00
|
|
|
//! The [`Network`][1] type implements the [`Decodable`][2] and
|
|
|
|
//! [`Encodable`][3] traits and encodes the magic bytes of the given
|
2018-08-10 17:09:22 +00:00
|
|
|
//! network
|
|
|
|
//!
|
|
|
|
//! [1]: enum.Network.html
|
Move relevant names into consensus::encode
- Move network::encodable::* to consensus::encode::*
- Rename Consensus{En,De}codable to {En,De}codable (now under
consensus::encode)
- Move network::serialize::Error to consensus::encode::Error
- Remove Raw{En,De}coder, implement {En,De}coder for T: {Write,Read}
instead
- Move network::serialize::Simple{En,De}coder to
consensus::encode::{En,De}coder
- Rename util::Error::Serialize to util::Error::Encode
- Modify comments to refer to new names
- Modify files to refer to new names
- Expose {En,De}cod{able,er}, {de,}serialize, Params
- Do not return Result for serialize{,_hex} as serializing to a Vec
should never fail
2018-09-20 10:15:45 +00:00
|
|
|
//! [2]: ../../consensus/encode/trait.Decodable.html
|
|
|
|
//! [3]: ../../consensus/encode/trait.Encodable.html
|
2018-08-10 17:09:22 +00:00
|
|
|
//!
|
|
|
|
//! # Example: encoding a network's magic bytes
|
|
|
|
//!
|
|
|
|
//! ```rust
|
|
|
|
//! use bitcoin::network::constants::Network;
|
Move relevant names into consensus::encode
- Move network::encodable::* to consensus::encode::*
- Rename Consensus{En,De}codable to {En,De}codable (now under
consensus::encode)
- Move network::serialize::Error to consensus::encode::Error
- Remove Raw{En,De}coder, implement {En,De}coder for T: {Write,Read}
instead
- Move network::serialize::Simple{En,De}coder to
consensus::encode::{En,De}coder
- Rename util::Error::Serialize to util::Error::Encode
- Modify comments to refer to new names
- Modify files to refer to new names
- Expose {En,De}cod{able,er}, {de,}serialize, Params
- Do not return Result for serialize{,_hex} as serializing to a Vec
should never fail
2018-09-20 10:15:45 +00:00
|
|
|
//! use bitcoin::consensus::encode::serialize;
|
2018-08-10 17:09:22 +00:00
|
|
|
//!
|
|
|
|
//! let network = Network::Bitcoin;
|
Move relevant names into consensus::encode
- Move network::encodable::* to consensus::encode::*
- Rename Consensus{En,De}codable to {En,De}codable (now under
consensus::encode)
- Move network::serialize::Error to consensus::encode::Error
- Remove Raw{En,De}coder, implement {En,De}coder for T: {Write,Read}
instead
- Move network::serialize::Simple{En,De}coder to
consensus::encode::{En,De}coder
- Rename util::Error::Serialize to util::Error::Encode
- Modify comments to refer to new names
- Modify files to refer to new names
- Expose {En,De}cod{able,er}, {de,}serialize, Params
- Do not return Result for serialize{,_hex} as serializing to a Vec
should never fail
2018-09-20 10:15:45 +00:00
|
|
|
//! let bytes = serialize(&network);
|
2018-08-10 17:09:22 +00:00
|
|
|
//!
|
|
|
|
//! assert_eq!(&bytes[..], &[0xF9, 0xBE, 0xB4, 0xD9]);
|
|
|
|
//! ```
|
2014-07-18 13:56:17 +00:00
|
|
|
|
2019-05-23 18:43:47 +00:00
|
|
|
use consensus::{encode, Decodable, Encodable, ReadExt, WriteExt};
|
2014-07-18 21:38:35 +00:00
|
|
|
|
2018-08-10 17:09:22 +00:00
|
|
|
/// Version of the protocol as appearing in network message headers
|
|
|
|
pub const PROTOCOL_VERSION: u32 = 70001;
|
|
|
|
/// Bitfield of services provided by this node
|
|
|
|
pub const SERVICES: u64 = 0;
|
|
|
|
/// User agent as it appears in the version message
|
|
|
|
pub const USER_AGENT: &'static str = "bitcoin-rust v0.1";
|
|
|
|
|
2015-01-18 18:16:01 +00:00
|
|
|
user_enum! {
|
2018-08-10 17:09:22 +00:00
|
|
|
/// The cryptocurrency to act on
|
2018-08-20 09:10:21 +00:00
|
|
|
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
|
2015-04-07 01:51:11 +00:00
|
|
|
pub enum Network {
|
2018-08-10 17:09:22 +00:00
|
|
|
/// Classic Bitcoin
|
2015-04-07 01:51:11 +00:00
|
|
|
Bitcoin <-> "bitcoin",
|
2018-08-10 17:09:22 +00:00
|
|
|
/// Bitcoin's testnet
|
2018-05-17 13:08:02 +00:00
|
|
|
Testnet <-> "testnet",
|
2018-08-10 17:09:22 +00:00
|
|
|
/// Bitcoin's regtest
|
2018-05-17 13:08:02 +00:00
|
|
|
Regtest <-> "regtest"
|
2015-04-07 01:51:11 +00:00
|
|
|
}
|
2015-01-18 18:16:01 +00:00
|
|
|
}
|
2014-08-03 13:03:00 +00:00
|
|
|
|
2018-08-10 17:09:22 +00:00
|
|
|
impl Network {
|
|
|
|
/// Creates a `Network` from the magic bytes.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use bitcoin::network::constants::Network;
|
|
|
|
///
|
|
|
|
/// assert_eq!(Some(Network::Bitcoin), Network::from_magic(0xD9B4BEF9));
|
|
|
|
/// assert_eq!(None, Network::from_magic(0xFFFFFFFF));
|
|
|
|
/// ```
|
|
|
|
pub fn from_magic(magic: u32) -> Option<Network> {
|
|
|
|
// Note: any new entries here must be added to `magic` below
|
|
|
|
match magic {
|
|
|
|
0xD9B4BEF9 => Some(Network::Bitcoin),
|
|
|
|
0x0709110B => Some(Network::Testnet),
|
|
|
|
0xDAB5BFFA => Some(Network::Regtest),
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
2014-07-18 13:56:17 +00:00
|
|
|
|
2018-08-10 17:09:22 +00:00
|
|
|
/// Return the network magic bytes, which should be encoded little-endian
|
|
|
|
/// at the start of every message
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use bitcoin::network::constants::Network;
|
|
|
|
///
|
|
|
|
/// let network = Network::Bitcoin;
|
|
|
|
/// assert_eq!(network.magic(), 0xD9B4BEF9);
|
|
|
|
/// ```
|
|
|
|
pub fn magic(&self) -> u32 {
|
|
|
|
// Note: any new entries here must be added to `from_magic` above
|
|
|
|
match *self {
|
|
|
|
Network::Bitcoin => 0xD9B4BEF9,
|
|
|
|
Network::Testnet => 0x0709110B,
|
|
|
|
Network::Regtest => 0xDAB5BFFA,
|
|
|
|
}
|
2015-04-07 01:51:11 +00:00
|
|
|
}
|
2014-07-18 21:38:35 +00:00
|
|
|
}
|
|
|
|
|
2019-05-23 18:43:47 +00:00
|
|
|
impl<S: WriteExt> Encodable<S> for Network {
|
2018-08-10 17:09:22 +00:00
|
|
|
/// Encodes the magic bytes of `Network`.
|
2015-04-07 01:51:11 +00:00
|
|
|
#[inline]
|
Move relevant names into consensus::encode
- Move network::encodable::* to consensus::encode::*
- Rename Consensus{En,De}codable to {En,De}codable (now under
consensus::encode)
- Move network::serialize::Error to consensus::encode::Error
- Remove Raw{En,De}coder, implement {En,De}coder for T: {Write,Read}
instead
- Move network::serialize::Simple{En,De}coder to
consensus::encode::{En,De}coder
- Rename util::Error::Serialize to util::Error::Encode
- Modify comments to refer to new names
- Modify files to refer to new names
- Expose {En,De}cod{able,er}, {de,}serialize, Params
- Do not return Result for serialize{,_hex} as serializing to a Vec
should never fail
2018-09-20 10:15:45 +00:00
|
|
|
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
2018-08-10 17:09:22 +00:00
|
|
|
self.magic().consensus_encode(s)
|
2015-04-07 01:51:11 +00:00
|
|
|
}
|
2014-08-01 16:01:39 +00:00
|
|
|
}
|
2014-07-18 21:38:35 +00:00
|
|
|
|
2019-05-23 18:43:47 +00:00
|
|
|
impl<D: ReadExt> Decodable<D> for Network {
|
2018-08-10 17:09:22 +00:00
|
|
|
/// Decodes the magic bytes of `Network`.
|
2015-04-07 01:51:11 +00:00
|
|
|
#[inline]
|
Move relevant names into consensus::encode
- Move network::encodable::* to consensus::encode::*
- Rename Consensus{En,De}codable to {En,De}codable (now under
consensus::encode)
- Move network::serialize::Error to consensus::encode::Error
- Remove Raw{En,De}coder, implement {En,De}coder for T: {Write,Read}
instead
- Move network::serialize::Simple{En,De}coder to
consensus::encode::{En,De}coder
- Rename util::Error::Serialize to util::Error::Encode
- Modify comments to refer to new names
- Modify files to refer to new names
- Expose {En,De}cod{able,er}, {de,}serialize, Params
- Do not return Result for serialize{,_hex} as serializing to a Vec
should never fail
2018-09-20 10:15:45 +00:00
|
|
|
fn consensus_decode(d: &mut D) -> Result<Network, encode::Error> {
|
2018-08-10 17:09:22 +00:00
|
|
|
u32::consensus_decode(d)
|
|
|
|
.and_then(|m| {
|
|
|
|
Network::from_magic(m)
|
Move relevant names into consensus::encode
- Move network::encodable::* to consensus::encode::*
- Rename Consensus{En,De}codable to {En,De}codable (now under
consensus::encode)
- Move network::serialize::Error to consensus::encode::Error
- Remove Raw{En,De}coder, implement {En,De}coder for T: {Write,Read}
instead
- Move network::serialize::Simple{En,De}coder to
consensus::encode::{En,De}coder
- Rename util::Error::Serialize to util::Error::Encode
- Modify comments to refer to new names
- Modify files to refer to new names
- Expose {En,De}cod{able,er}, {de,}serialize, Params
- Do not return Result for serialize{,_hex} as serializing to a Vec
should never fail
2018-09-20 10:15:45 +00:00
|
|
|
.ok_or(encode::Error::UnknownNetworkMagic(m))
|
2018-08-10 17:09:22 +00:00
|
|
|
})
|
2014-07-18 21:38:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-03 13:03:00 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2015-04-05 17:58:49 +00:00
|
|
|
use super::Network;
|
Move relevant names into consensus::encode
- Move network::encodable::* to consensus::encode::*
- Rename Consensus{En,De}codable to {En,De}codable (now under
consensus::encode)
- Move network::serialize::Error to consensus::encode::Error
- Remove Raw{En,De}coder, implement {En,De}coder for T: {Write,Read}
instead
- Move network::serialize::Simple{En,De}coder to
consensus::encode::{En,De}coder
- Rename util::Error::Serialize to util::Error::Encode
- Modify comments to refer to new names
- Modify files to refer to new names
- Expose {En,De}cod{able,er}, {de,}serialize, Params
- Do not return Result for serialize{,_hex} as serializing to a Vec
should never fail
2018-09-20 10:15:45 +00:00
|
|
|
use consensus::encode::{deserialize, serialize};
|
2014-08-03 13:03:00 +00:00
|
|
|
|
2014-08-06 02:08:06 +00:00
|
|
|
#[test]
|
2014-08-03 13:03:00 +00:00
|
|
|
fn serialize_test() {
|
Move relevant names into consensus::encode
- Move network::encodable::* to consensus::encode::*
- Rename Consensus{En,De}codable to {En,De}codable (now under
consensus::encode)
- Move network::serialize::Error to consensus::encode::Error
- Remove Raw{En,De}coder, implement {En,De}coder for T: {Write,Read}
instead
- Move network::serialize::Simple{En,De}coder to
consensus::encode::{En,De}coder
- Rename util::Error::Serialize to util::Error::Encode
- Modify comments to refer to new names
- Modify files to refer to new names
- Expose {En,De}cod{able,er}, {de,}serialize, Params
- Do not return Result for serialize{,_hex} as serializing to a Vec
should never fail
2018-09-20 10:15:45 +00:00
|
|
|
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]);
|
2014-08-03 13:03:00 +00:00
|
|
|
|
2015-04-08 22:23:45 +00:00
|
|
|
assert_eq!(deserialize(&[0xf9, 0xbe, 0xb4, 0xd9]).ok(), Some(Network::Bitcoin));
|
|
|
|
assert_eq!(deserialize(&[0x0b, 0x11, 0x09, 0x07]).ok(), Some(Network::Testnet));
|
2018-05-17 13:08:02 +00:00
|
|
|
assert_eq!(deserialize(&[0xfa, 0xbf, 0xb5, 0xda]).ok(), Some(Network::Regtest));
|
2014-08-03 13:03:00 +00:00
|
|
|
|
2015-04-08 22:23:45 +00:00
|
|
|
let bad: Result<Network, _> = deserialize("fakenet".as_bytes());
|
2014-08-03 13:03:00 +00:00
|
|
|
assert!(bad.is_err());
|
|
|
|
}
|
2018-05-16 09:22:07 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn string_test() {
|
|
|
|
assert_eq!(Network::Bitcoin.to_string(), "bitcoin");
|
|
|
|
assert_eq!(Network::Testnet.to_string(), "testnet");
|
2018-07-26 00:51:15 +00:00
|
|
|
assert_eq!(Network::Regtest.to_string(), "regtest");
|
2018-05-16 09:22:07 +00:00
|
|
|
|
2018-05-18 09:08:11 +00:00
|
|
|
assert_eq!("bitcoin".parse::<Network>().unwrap(), Network::Bitcoin);
|
|
|
|
assert_eq!("testnet".parse::<Network>().unwrap(), Network::Testnet);
|
2018-07-26 00:51:15 +00:00
|
|
|
assert_eq!("regtest".parse::<Network>().unwrap(), Network::Regtest);
|
2018-05-16 09:22:07 +00:00
|
|
|
assert!("fakenet".parse::<Network>().is_err());
|
|
|
|
}
|
2014-08-03 13:03:00 +00:00
|
|
|
}
|
|
|
|
|