use crate::config;
use bitcoin::{BlockHash, Txid};
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PowFunction {
Sha256d,
Scrypt,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ChainParams {
pub magic: [u8; 4],
pub port: u16,
pub dns_seeds: &'static [&'static str],
pub fixed_seeds: &'static [&'static str],
pub pow: PowFunction,
pub pow_limit_bits: u32,
pub retarget_interval: u64,
pub retarget_lookback: u64,
pub target_timespan: u32,
pub target_spacing: u32,
pub allow_min_difficulty: bool,
pub retargets: bool,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Chain {
BitcoinMainnet,
BitcoinRegtest,
BitcoinTestnet4,
LitecoinMainnet,
LitecoinTestnet,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ChainId(pub BlockHash);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BlockRef {
pub height: u64,
pub hash: BlockHash,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Placement {
Unknown,
Mempool,
Included(BlockRef),
Orphaned(BlockRef),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum InclusionTrust {
ProviderClaim,
ValidatingNode,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Observation {
pub chain: ChainId,
pub txid: Txid,
pub tip: BlockRef,
pub placement: Placement,
pub trust: InclusionTrust,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ChainUpdate {
Advanced {
previous: BlockRef,
tip: BlockRef,
},
Reorganized {
previous: BlockRef,
ancestor: BlockRef,
tip: BlockRef,
},
}
impl Chain {
pub const LITECOIN_TESTNET_GENESIS: &str =
"4966625a4b2851d9fdee139e56211a0d88575f59ed816ff5e6a63deb4e3e29a0";
pub fn label(self) -> &'static str {
match self {
Self::LitecoinMainnet => "Litecoin mainnet",
Self::LitecoinTestnet => "Litecoin testnet",
Self::BitcoinMainnet => "Bitcoin mainnet",
Self::BitcoinRegtest => "Bitcoin regtest",
Self::BitcoinTestnet4 => "Bitcoin testnet4",
}
}
pub fn address_hrp(self) -> &'static str {
match self {
Self::BitcoinMainnet => "bc",
Self::BitcoinRegtest => "bcrt",
Self::BitcoinTestnet4 => "tb",
Self::LitecoinMainnet => "ltc",
Self::LitecoinTestnet => "tltc",
}
}
pub fn params(self) -> &'static ChainParams {
match self {
Self::BitcoinMainnet => &config::BITCOIN_MAINNET,
Self::LitecoinMainnet => &config::LITECOIN_MAINNET,
Self::LitecoinTestnet => &config::LITECOIN_TESTNET,
Self::BitcoinRegtest => &config::BITCOIN_REGTEST,
Self::BitcoinTestnet4 => &config::BITCOIN_TESTNET4,
}
}
pub fn genesis(self) -> Result<ChainId, bitcoin::hex::HexToArrayError> {
let genesis = match self {
Self::BitcoinMainnet => {
bitcoin::blockdata::constants::genesis_block(bitcoin::Network::Bitcoin).block_hash()
}
Self::BitcoinRegtest => {
bitcoin::blockdata::constants::genesis_block(bitcoin::Network::Regtest).block_hash()
}
Self::BitcoinTestnet4 => {
bitcoin::blockdata::constants::genesis_block(bitcoin::Network::Testnet4)
.block_hash()
}
Self::LitecoinMainnet => {
"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2".parse()?
}
Self::LitecoinTestnet => Self::LITECOIN_TESTNET_GENESIS.parse()?,
};
Ok(ChainId(genesis))
}
}