Merge rust-bitcoin/rust-bitcoin#1675: Add utils to convert ChainHash to a Network

56569b32ef Add utils to convert ChainHash to a Network (benthecarman)

Pull request description:

ACKs for top commit:
  Kixunil:
    ACK 56569b32ef
  tcharding:
    ACK 56569b32ef

Tree-SHA512: a489fcb1c1208db4271076d88288658988a63209e56e7433bde82d7d5719450433348fcc3cb6aae59ffa6ed8aff510d6b031c6899d5cf64c503a53b2d4c692b8
This commit is contained in:
Andrew Poelstra 2023-02-27 23:46:09 +00:00
commit 13143d0f6f
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 57 additions and 0 deletions

View File

@ -30,12 +30,14 @@ use core::borrow::{Borrow, BorrowMut};
use core::convert::TryFrom;
use core::str::FromStr;
use core::{fmt, ops};
use core::fmt::Display;
use bitcoin_internals::{debug_from_display, write_err};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::consensus::encode::{self, Decodable, Encodable};
use crate::constants::ChainHash;
use crate::error::impl_std_error;
use crate::hashes::hex::{Error, FromHex};
use crate::io;
@ -141,6 +143,34 @@ impl Network {
};
Ok(network)
}
/// Return the network's chain hash (genesis block hash).
///
/// # Examples
///
/// ```rust
/// use bitcoin::network::constants::Network;
/// use bitcoin::blockdata::constants::ChainHash;
///
/// let network = Network::Bitcoin;
/// assert_eq!(network.chain_hash(), ChainHash::BITCOIN);
/// ```
pub fn chain_hash(self) -> ChainHash {
ChainHash::using_genesis_block(self)
}
/// Creates a `Network` from the chain hash (genesis block hash).
///
/// # Examples
///
/// ```rust
/// use bitcoin::network::constants::Network;
/// use bitcoin::blockdata::constants::ChainHash;
/// use std::convert::TryFrom;
///
/// assert_eq!(Ok(Network::Bitcoin), Network::try_from(ChainHash::BITCOIN));
/// ```
pub fn from_chain_hash(chain_hash: ChainHash) -> Option<Network> { Network::try_from(chain_hash).ok() }
}
/// An error in parsing network string.
@ -186,6 +216,33 @@ impl fmt::Display for Network {
}
}
/// Error in parsing network from chain hash.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UnknownChainHash(ChainHash);
impl Display for UnknownChainHash {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "unknown chain hash: {}", self.0)
}
}
impl_std_error!(UnknownChainHash);
impl TryFrom<ChainHash> for Network {
type Error = UnknownChainHash;
fn try_from(chain_hash: ChainHash) -> Result<Self, Self::Error> {
match chain_hash {
// Note: any new network entries must be matched against here.
ChainHash::BITCOIN => Ok(Network::Bitcoin),
ChainHash::TESTNET => Ok(Network::Testnet),
ChainHash::SIGNET => Ok(Network::Signet),
ChainHash::REGTEST => Ok(Network::Regtest),
_ => Err(UnknownChainHash(chain_hash)),
}
}
}
/// Network magic bytes to identify the cryptocurrency network the message was intended for.
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
pub struct Magic([u8; 4]);