diff --git a/src/bin/electrs.rs b/src/bin/electrs.rs index 91a51eef..a4c0408b 100644 --- a/src/bin/electrs.rs +++ b/src/bin/electrs.rs @@ -50,6 +50,7 @@ fn run_server(config: Arc) -> Result<()> { config.daemon_rpc_addr, config.cookie_getter(), config.network_type, + config.magic, signal.clone(), &metrics, )?); diff --git a/src/bin/tx-fingerprint-stats.rs b/src/bin/tx-fingerprint-stats.rs index 55cb6797..5b38561f 100644 --- a/src/bin/tx-fingerprint-stats.rs +++ b/src/bin/tx-fingerprint-stats.rs @@ -35,6 +35,7 @@ fn main() { config.daemon_rpc_addr, config.cookie_getter(), config.network_type, + config.magic, signal, &metrics, ) diff --git a/src/chain.rs b/src/chain.rs index de726186..8abf9a4a 100644 --- a/src/chain.rs +++ b/src/chain.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + #[cfg(not(feature = "liquid"))] // use regular Bitcoin data structures pub use bitcoin::{ blockdata::{opcodes, script, witness::Witness}, @@ -32,6 +34,8 @@ pub enum Network { #[cfg(not(feature = "liquid"))] Testnet, #[cfg(not(feature = "liquid"))] + Testnet4, + #[cfg(not(feature = "liquid"))] Regtest, #[cfg(not(feature = "liquid"))] Signet, @@ -129,22 +133,25 @@ pub fn genesis_hash(network: Network) -> BlockHash { return liquid_genesis_hash(network); } -pub fn bitcoin_genesis_hash(network: BNetwork) -> bitcoin::BlockHash { +pub fn bitcoin_genesis_hash(network: Network) -> bitcoin::BlockHash { lazy_static! { static ref BITCOIN_GENESIS: bitcoin::BlockHash = genesis_block(BNetwork::Bitcoin).block_hash(); static ref TESTNET_GENESIS: bitcoin::BlockHash = genesis_block(BNetwork::Testnet).block_hash(); + static ref TESTNET4_GENESIS: bitcoin::BlockHash = + BlockHash::from_str("00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043").unwrap(); static ref REGTEST_GENESIS: bitcoin::BlockHash = genesis_block(BNetwork::Regtest).block_hash(); static ref SIGNET_GENESIS: bitcoin::BlockHash = genesis_block(BNetwork::Signet).block_hash(); } match network { - BNetwork::Bitcoin => *BITCOIN_GENESIS, - BNetwork::Testnet => *TESTNET_GENESIS, - BNetwork::Regtest => *REGTEST_GENESIS, - BNetwork::Signet => *SIGNET_GENESIS, + Network::Bitcoin => *BITCOIN_GENESIS, + Network::Testnet => *TESTNET_GENESIS, + Network::Testnet4 => *TESTNET4_GENESIS, + Network::Regtest => *REGTEST_GENESIS, + Network::Signet => *SIGNET_GENESIS, } } @@ -174,6 +181,8 @@ impl From<&str> for Network { #[cfg(not(feature = "liquid"))] "testnet" => Network::Testnet, #[cfg(not(feature = "liquid"))] + "testnet4" => Network::Testnet4, + #[cfg(not(feature = "liquid"))] "regtest" => Network::Regtest, #[cfg(not(feature = "liquid"))] "signet" => Network::Signet, @@ -196,6 +205,7 @@ impl From for BNetwork { match network { Network::Bitcoin => BNetwork::Bitcoin, Network::Testnet => BNetwork::Testnet, + Network::Testnet4 => BNetwork::Testnet, Network::Regtest => BNetwork::Regtest, Network::Signet => BNetwork::Signet, } diff --git a/src/config.rs b/src/config.rs index 8278d985..a5e903ce 100644 --- a/src/config.rs +++ b/src/config.rs @@ -33,6 +33,7 @@ pub struct Config { // See below for the documentation of each field: pub log: stderrlog::StdErrLog, pub network_type: Network, + pub magic: Option, pub db_path: PathBuf, pub daemon_dir: PathBuf, pub blocks_dir: PathBuf, @@ -137,6 +138,12 @@ impl Config { .help(&network_help) .takes_value(true), ) + .arg( + Arg::with_name("magic") + .long("magic") + .default_value("") + .takes_value(true), + ) .arg( Arg::with_name("electrum_rpc_addr") .long("electrum-rpc-addr") @@ -328,6 +335,10 @@ impl Config { let network_name = m.value_of("network").unwrap_or("mainnet"); let network_type = Network::from(network_name); + let magic: Option = m + .value_of("magic") + .filter(|s| !s.is_empty()) + .map(|s| u32::from_str_radix(s, 16).expect("invalid network magic")); let db_dir = Path::new(m.value_of("db_dir").unwrap_or("./db")); let db_path = db_dir.join(network_name); @@ -353,6 +364,8 @@ impl Config { Network::Regtest => 18443, #[cfg(not(feature = "liquid"))] Network::Signet => 38332, + #[cfg(not(feature = "liquid"))] + Network::Testnet4 => 48332, #[cfg(feature = "liquid")] Network::Liquid => 7041, @@ -365,6 +378,8 @@ impl Config { #[cfg(not(feature = "liquid"))] Network::Testnet => 60001, #[cfg(not(feature = "liquid"))] + Network::Testnet4 => 40001, + #[cfg(not(feature = "liquid"))] Network::Regtest => 60401, #[cfg(not(feature = "liquid"))] Network::Signet => 60601, @@ -385,6 +400,8 @@ impl Config { Network::Regtest => 3002, #[cfg(not(feature = "liquid"))] Network::Signet => 3003, + #[cfg(not(feature = "liquid"))] + Network::Testnet4 => 3004, #[cfg(feature = "liquid")] Network::Liquid => 3000, @@ -401,6 +418,8 @@ impl Config { #[cfg(not(feature = "liquid"))] Network::Regtest => 24224, #[cfg(not(feature = "liquid"))] + Network::Testnet4 => 44224, + #[cfg(not(feature = "liquid"))] Network::Signet => 54224, #[cfg(feature = "liquid")] @@ -449,6 +468,8 @@ impl Config { #[cfg(not(feature = "liquid"))] Network::Testnet => daemon_dir.push("testnet3"), #[cfg(not(feature = "liquid"))] + Network::Testnet4 => daemon_dir.push("testnet4"), + #[cfg(not(feature = "liquid"))] Network::Regtest => daemon_dir.push("regtest"), #[cfg(not(feature = "liquid"))] Network::Signet => daemon_dir.push("signet"), @@ -486,6 +507,7 @@ impl Config { let config = Config { log, network_type, + magic, db_path, daemon_dir, blocks_dir, diff --git a/src/daemon.rs b/src/daemon.rs index 3f370bf8..b8bde690 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -284,6 +284,7 @@ pub struct Daemon { daemon_dir: PathBuf, blocks_dir: PathBuf, network: Network, + magic: Option, conn: Mutex, message_id: Counter, // for monotonic JSONRPC 'id' signal: Waiter, @@ -300,6 +301,7 @@ impl Daemon { daemon_rpc_addr: SocketAddr, cookie_getter: Arc, network: Network, + magic: Option, signal: Waiter, metrics: &Metrics, ) -> Result { @@ -307,6 +309,7 @@ impl Daemon { daemon_dir, blocks_dir, network, + magic, conn: Mutex::new(Connection::new( daemon_rpc_addr, cookie_getter, @@ -367,6 +370,7 @@ impl Daemon { daemon_dir: self.daemon_dir.clone(), blocks_dir: self.blocks_dir.clone(), network: self.network, + magic: self.magic, conn: Mutex::new(self.conn.lock().unwrap().reconnect()?), message_id: Counter::new(), signal: self.signal.clone(), @@ -387,7 +391,7 @@ impl Daemon { } pub fn magic(&self) -> u32 { - self.network.magic() + self.magic.unwrap_or_else(|| self.network.magic()) } fn call_jsonrpc(&self, method: &str, request: &Value) -> Result { diff --git a/src/rest.rs b/src/rest.rs index eab06de5..2e061b11 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -1668,7 +1668,7 @@ fn address_to_scripthash(addr: &str, network: Network) -> Result