feat: rust-bitcoin supports testnet4
This commit is contained in:
parent
afa91a2030
commit
2424b654d5
|
@ -194,7 +194,7 @@ impl fmt::Display for AddressInner {
|
|||
pub enum KnownHrp {
|
||||
/// The main Bitcoin network.
|
||||
Mainnet,
|
||||
/// The test networks, testnet (testnet3), and signet.
|
||||
/// The test networks, testnet (testnet3), testnet4, and signet.
|
||||
Testnets,
|
||||
/// The regtest network.
|
||||
Regtest,
|
||||
|
@ -720,6 +720,7 @@ impl Address<NetworkUnchecked> {
|
|||
///
|
||||
/// let address: Address<NetworkUnchecked> = "32iVBEu4dxkUQk9dJbZUiBiQdmypcEyJRf".parse().unwrap();
|
||||
/// assert!(address.is_valid_for_network(Network::Bitcoin));
|
||||
/// assert_eq!(address.is_valid_for_network(Network::Testnet(TestnetVersion::V4)), false);
|
||||
/// ```
|
||||
pub fn is_valid_for_network(&self, n: Network) -> bool {
|
||||
use AddressInner::*;
|
||||
|
@ -887,8 +888,8 @@ mod tests {
|
|||
use hex_lit::hex;
|
||||
|
||||
use super::*;
|
||||
use crate::network::params;
|
||||
use crate::network::Network::{Bitcoin, Testnet};
|
||||
use crate::network::{params, TestnetVersion};
|
||||
use crate::script::ScriptBufExt as _;
|
||||
|
||||
fn roundtrips(addr: &Address, network: Network) {
|
||||
|
@ -941,7 +942,7 @@ mod tests {
|
|||
let addr = Address::p2pkh(key, NetworkKind::Test);
|
||||
assert_eq!(&addr.to_string(), "mqkhEMH6NCeYjFybv7pvFC22MFeaNT9AQC");
|
||||
assert_eq!(addr.address_type(), Some(AddressType::P2pkh));
|
||||
roundtrips(&addr, Testnet(crate::TestnetVersion::V3));
|
||||
roundtrips(&addr, Testnet(TestnetVersion::V3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -964,7 +965,7 @@ mod tests {
|
|||
let addr = Address::p2sh(&script, NetworkKind::Test).unwrap();
|
||||
assert_eq!(&addr.to_string(), "2N3zXjbwdTcPsJiy8sUK9FhWJhqQCxA8Jjr");
|
||||
assert_eq!(addr.address_type(), Some(AddressType::P2sh));
|
||||
roundtrips(&addr, Testnet(crate::TestnetVersion::V3));
|
||||
roundtrips(&addr, Testnet(TestnetVersion::V3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1281,7 +1282,7 @@ mod tests {
|
|||
let address = address_string
|
||||
.parse::<Address<_>>()
|
||||
.expect("address")
|
||||
.require_network(Network::Testnet(crate::TestnetVersion::V3))
|
||||
.require_network(Network::Testnet(TestnetVersion::V3))
|
||||
.expect("testnet");
|
||||
|
||||
let pubkey_string = "04e96e22004e3db93530de27ccddfdf1463975d2138ac018fc3e7ba1a2e5e0aad8e424d0b55e2436eb1d0dcd5cb2b8bcc6d53412c22f358de57803a6a655fbbd04";
|
||||
|
|
|
@ -477,7 +477,7 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
use crate::consensus::encode::{deserialize, serialize};
|
||||
use crate::Network;
|
||||
use crate::{Network, TestnetVersion};
|
||||
|
||||
#[test]
|
||||
fn test_coinbase_and_bip34() {
|
||||
|
@ -546,7 +546,7 @@ mod tests {
|
|||
// Check testnet block 000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b
|
||||
#[test]
|
||||
fn segwit_block_test() {
|
||||
let params = Params::new(Network::Testnet(crate::TestnetVersion::V3));
|
||||
let params = Params::new(Network::Testnet(TestnetVersion::V3));
|
||||
let segwit_block = include_bytes!("../../tests/data/testnet_block_000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b.raw").to_vec();
|
||||
|
||||
let decode: Result<Block, _> = deserialize(&segwit_block);
|
||||
|
|
|
@ -72,8 +72,11 @@ const GENESIS_OUTPUT_PK: [u8; 65] = [
|
|||
0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f
|
||||
];
|
||||
|
||||
#[rustfmt::skip]
|
||||
const TESTNET4_GENESIS_OUTPUT_PK: [u8; 33] = [0x00; 33];
|
||||
|
||||
/// Constructs and returns the coinbase (and only) transaction of the Bitcoin genesis block.
|
||||
fn bitcoin_genesis_tx() -> Transaction {
|
||||
fn bitcoin_genesis_tx(params: &Params) -> Transaction {
|
||||
// Base
|
||||
let mut ret = Transaction {
|
||||
version: transaction::Version::ONE,
|
||||
|
@ -82,21 +85,35 @@ fn bitcoin_genesis_tx() -> Transaction {
|
|||
output: vec![],
|
||||
};
|
||||
|
||||
// Inputs
|
||||
let in_script = script::Builder::new()
|
||||
.push_int_unchecked(486604799)
|
||||
.push_int_non_minimal(4)
|
||||
.push_slice(b"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks")
|
||||
.into_script();
|
||||
let (in_script, out_script) = {
|
||||
match params.network {
|
||||
Network::Testnet(TestnetVersion::V4) => (
|
||||
script::Builder::new()
|
||||
.push_int_unchecked(486604799)
|
||||
.push_int_non_minimal(4)
|
||||
.push_slice(b"03/May/2024 000000000000000000001ebd58c244970b3aa9d783bb001011fbe8ea8e98e00e")
|
||||
.into_script(),
|
||||
script::Builder::new().push_slice(TESTNET4_GENESIS_OUTPUT_PK).push_opcode(OP_CHECKSIG).into_script(),
|
||||
|
||||
),
|
||||
_ => (
|
||||
script::Builder::new()
|
||||
.push_int_unchecked(486604799)
|
||||
.push_int_non_minimal(4)
|
||||
.push_slice(b"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks")
|
||||
.into_script(),
|
||||
script::Builder::new().push_slice(GENESIS_OUTPUT_PK).push_opcode(OP_CHECKSIG).into_script(),
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
ret.input.push(TxIn {
|
||||
previous_output: OutPoint::COINBASE_PREVOUT,
|
||||
script_sig: in_script,
|
||||
sequence: Sequence::MAX,
|
||||
witness: Witness::default(),
|
||||
});
|
||||
// Outputs
|
||||
let out_script =
|
||||
script::Builder::new().push_slice(GENESIS_OUTPUT_PK).push_opcode(OP_CHECKSIG).into_script();
|
||||
|
||||
ret.output.push(TxOut { value: Amount::from_sat(50 * 100_000_000), script_pubkey: out_script });
|
||||
|
||||
// end
|
||||
|
@ -105,12 +122,12 @@ fn bitcoin_genesis_tx() -> Transaction {
|
|||
|
||||
/// Constructs and returns the genesis block.
|
||||
pub fn genesis_block(params: impl AsRef<Params>) -> Block {
|
||||
let params_ref = params.as_ref();
|
||||
let txdata = vec![bitcoin_genesis_tx()];
|
||||
let params = params.as_ref();
|
||||
let txdata = vec![bitcoin_genesis_tx(params)];
|
||||
let hash: sha256d::Hash = txdata[0].compute_txid().into();
|
||||
let merkle_root: crate::TxMerkleNode = hash.into();
|
||||
|
||||
match params_ref.network {
|
||||
match params.network {
|
||||
Network::Bitcoin => Block {
|
||||
header: block::Header {
|
||||
version: block::Version::ONE,
|
||||
|
@ -133,6 +150,17 @@ pub fn genesis_block(params: impl AsRef<Params>) -> Block {
|
|||
},
|
||||
txdata,
|
||||
},
|
||||
Network::Testnet(TestnetVersion::V4) => Block {
|
||||
header: block::Header {
|
||||
version: block::Version::ONE,
|
||||
prev_blockhash: BlockHash::GENESIS_PREVIOUS_BLOCK_HASH,
|
||||
merkle_root,
|
||||
time: 1714777860,
|
||||
bits: CompactTarget::from_consensus(0x1d00ffff),
|
||||
nonce: 393743547,
|
||||
},
|
||||
txdata,
|
||||
},
|
||||
Network::Signet => Block {
|
||||
header: block::Header {
|
||||
version: block::Version::ONE,
|
||||
|
@ -172,10 +200,21 @@ impl ChainHash {
|
|||
101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0,
|
||||
]);
|
||||
/// `ChainHash` for testnet3 bitcoin.
|
||||
#[deprecated(since = "0.33.0", note = "Use TESTNET3 instead")]
|
||||
pub const TESTNET: Self = Self([
|
||||
67, 73, 127, 215, 248, 38, 149, 113, 8, 244, 163, 15, 217, 206, 195, 174, 186, 121, 151,
|
||||
32, 132, 233, 14, 173, 1, 234, 51, 9, 0, 0, 0, 0,
|
||||
]);
|
||||
/// `ChainHash` for testnet3 bitcoin.
|
||||
pub const TESTNET3: Self = Self([
|
||||
67, 73, 127, 215, 248, 38, 149, 113, 8, 244, 163, 15, 217, 206, 195, 174, 186, 121, 151,
|
||||
32, 132, 233, 14, 173, 1, 234, 51, 9, 0, 0, 0, 0,
|
||||
]);
|
||||
/// `ChainHash` for testnet4 bitcoin.
|
||||
pub const TESTNET4: Self = Self([
|
||||
67, 240, 139, 218, 176, 80, 227, 91, 86, 124, 134, 75, 145, 244, 127, 80, 174, 114, 90,
|
||||
226, 222, 83, 188, 251, 186, 242, 132, 218, 0, 0, 0, 0,
|
||||
]);
|
||||
/// `ChainHash` for signet bitcoin.
|
||||
pub const SIGNET: Self = Self([
|
||||
246, 30, 238, 59, 99, 163, 128, 164, 119, 160, 99, 175, 50, 178, 187, 201, 124, 159, 249,
|
||||
|
@ -194,7 +233,8 @@ impl ChainHash {
|
|||
pub fn using_genesis_block(params: impl AsRef<Params>) -> Self {
|
||||
match params.as_ref().network {
|
||||
Network::Bitcoin => Self::BITCOIN,
|
||||
Network::Testnet(TestnetVersion::V3) => Self::TESTNET,
|
||||
Network::Testnet(TestnetVersion::V3) => Self::TESTNET3,
|
||||
Network::Testnet(TestnetVersion::V4) => Self::TESTNET4,
|
||||
Network::Signet => Self::SIGNET,
|
||||
Network::Regtest => Self::REGTEST,
|
||||
}
|
||||
|
@ -207,7 +247,8 @@ impl ChainHash {
|
|||
pub const fn using_genesis_block_const(network: Network) -> Self {
|
||||
match network {
|
||||
Network::Bitcoin => Self::BITCOIN,
|
||||
Network::Testnet(TestnetVersion::V3) => Self::TESTNET,
|
||||
Network::Testnet(TestnetVersion::V3) => Self::TESTNET3,
|
||||
Network::Testnet(TestnetVersion::V4) => Self::TESTNET4,
|
||||
Network::Signet => Self::SIGNET,
|
||||
Network::Regtest => Self::REGTEST,
|
||||
}
|
||||
|
@ -230,7 +271,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn bitcoin_genesis_first_transaction() {
|
||||
let gen = bitcoin_genesis_tx();
|
||||
let gen = bitcoin_genesis_tx(&Params::MAINNET);
|
||||
|
||||
assert_eq!(gen.version, transaction::Version::ONE);
|
||||
assert_eq!(gen.input.len(), 1);
|
||||
|
@ -286,7 +327,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn testnet_genesis_full_block() {
|
||||
let gen = genesis_block(¶ms::TESTNET);
|
||||
let gen = genesis_block(¶ms::TESTNET3);
|
||||
assert_eq!(gen.header.version, block::Version::ONE);
|
||||
assert_eq!(gen.header.prev_blockhash, BlockHash::GENESIS_PREVIOUS_BLOCK_HASH);
|
||||
assert_eq!(
|
||||
|
@ -341,6 +382,7 @@ mod test {
|
|||
match network {
|
||||
Network::Bitcoin => {},
|
||||
Network::Testnet(TestnetVersion::V3) => {},
|
||||
Network::Testnet(TestnetVersion::V4) => {},
|
||||
Network::Signet => {},
|
||||
Network::Regtest => {},
|
||||
_ => panic!("update ChainHash::using_genesis_block and chain_hash_genesis_block with new variants"),
|
||||
|
@ -361,6 +403,7 @@ mod test {
|
|||
chain_hash_genesis_block! {
|
||||
mainnet_chain_hash_genesis_block, Network::Bitcoin;
|
||||
testnet_chain_hash_genesis_block, Network::Testnet(TestnetVersion::V3);
|
||||
testnet4_chain_hash_genesis_block, Network::Testnet(TestnetVersion::V4);
|
||||
signet_chain_hash_genesis_block, Network::Signet;
|
||||
regtest_chain_hash_genesis_block, Network::Regtest;
|
||||
}
|
||||
|
|
|
@ -202,12 +202,12 @@ mod primitive {
|
|||
}
|
||||
}
|
||||
|
||||
// Sizes up to 73 to support all pubkey and signature sizes
|
||||
// Sizes up to 76 to support all pubkey and signature sizes
|
||||
from_array! {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
|
||||
71, 72, 73,
|
||||
71, 72, 73, 74, 75, 76
|
||||
}
|
||||
|
||||
/// Owned, growable counterpart to `PushBytes`.
|
||||
|
|
|
@ -68,6 +68,8 @@ impl From<Network> for NetworkKind {
|
|||
pub enum TestnetVersion {
|
||||
/// Testnet version 3.
|
||||
V3,
|
||||
/// Testnet version 4.
|
||||
V4,
|
||||
}
|
||||
|
||||
/// The cryptocurrency network to act on.
|
||||
|
@ -163,6 +165,7 @@ impl Network {
|
|||
Network::Bitcoin => "main",
|
||||
// For user-side compatibility, testnet3 is retained as test
|
||||
Network::Testnet(TestnetVersion::V3) => "test",
|
||||
Network::Testnet(TestnetVersion::V4) => "testnet4",
|
||||
Network::Signet => "signet",
|
||||
Network::Regtest => "regtest",
|
||||
}
|
||||
|
@ -183,6 +186,7 @@ impl Network {
|
|||
let network = match core_arg {
|
||||
"main" => Bitcoin,
|
||||
"test" => Testnet(TestnetVersion::V3),
|
||||
"testnet4" => Testnet(TestnetVersion::V4),
|
||||
"signet" => Signet,
|
||||
"regtest" => Regtest,
|
||||
_ => return Err(ParseNetworkError(core_arg.to_owned())),
|
||||
|
@ -221,7 +225,8 @@ impl Network {
|
|||
pub const fn params(self) -> &'static Params {
|
||||
match self {
|
||||
Network::Bitcoin => &Params::BITCOIN,
|
||||
Network::Testnet(TestnetVersion::V3) => &Params::TESTNET,
|
||||
Network::Testnet(TestnetVersion::V3) => &Params::TESTNET3,
|
||||
Network::Testnet(TestnetVersion::V4) => &Params::TESTNET4,
|
||||
Network::Signet => &Params::SIGNET,
|
||||
Network::Regtest => &Params::REGTEST,
|
||||
}
|
||||
|
@ -233,6 +238,7 @@ impl Network {
|
|||
match self {
|
||||
Network::Bitcoin => "bitcoin",
|
||||
Network::Testnet(TestnetVersion::V3) => "testnet",
|
||||
Network::Testnet(TestnetVersion::V4) => "testnet4",
|
||||
Network::Signet => "signet",
|
||||
Network::Regtest => "regtest",
|
||||
}
|
||||
|
@ -266,7 +272,7 @@ pub mod as_core_arg {
|
|||
Network::from_core_arg(s).map_err(|_| {
|
||||
E::invalid_value(
|
||||
serde::de::Unexpected::Str(s),
|
||||
&"bitcoin network encoded as a string (either main, test, signet or regtest)",
|
||||
&"bitcoin network encoded as a string (either main, test, testnet4, signet or regtest)",
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -274,7 +280,7 @@ pub mod as_core_arg {
|
|||
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(
|
||||
formatter,
|
||||
"bitcoin network encoded as a string (either main, test, signet or regtest)"
|
||||
"bitcoin network encoded as a string (either main, test, testnet4, signet or regtest)"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -303,16 +309,12 @@ impl FromStr for Network {
|
|||
type Err = ParseNetworkError;
|
||||
|
||||
#[inline]
|
||||
/// Parses a string slice into a `Network` enum variant.
|
||||
/// This function is used internally to convert a string representation
|
||||
/// of a network type into its corresponding `Network` enum variant.
|
||||
/// Returns `Ok(Network)` if the string matches a known network type,
|
||||
/// otherwise returns `Err(ParseNetworkError)`.
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"bitcoin" => Ok(Network::Bitcoin),
|
||||
// For user-side compatibility, testnet3 is retained as testnet
|
||||
"testnet" => Ok(Network::Testnet(TestnetVersion::V3)),
|
||||
"testnet4" => Ok(Network::Testnet(TestnetVersion::V4)),
|
||||
"signet" => Ok(Network::Signet),
|
||||
"regtest" => Ok(Network::Regtest),
|
||||
_ => Err(ParseNetworkError(s.to_owned())),
|
||||
|
@ -349,7 +351,8 @@ impl TryFrom<ChainHash> for Network {
|
|||
match chain_hash {
|
||||
// Note: any new network entries must be matched against here.
|
||||
ChainHash::BITCOIN => Ok(Network::Bitcoin),
|
||||
ChainHash::TESTNET => Ok(Network::Testnet(TestnetVersion::V3)),
|
||||
ChainHash::TESTNET3 => Ok(Network::Testnet(TestnetVersion::V3)),
|
||||
ChainHash::TESTNET4 => Ok(Network::Testnet(TestnetVersion::V4)),
|
||||
ChainHash::SIGNET => Ok(Network::Signet),
|
||||
ChainHash::REGTEST => Ok(Network::Regtest),
|
||||
_ => Err(UnknownChainHashError(chain_hash)),
|
||||
|
@ -359,7 +362,7 @@ impl TryFrom<ChainHash> for Network {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Network;
|
||||
use super::{Network, TestnetVersion};
|
||||
use crate::consensus::encode::{deserialize, serialize};
|
||||
use crate::p2p::ServiceFlags;
|
||||
|
||||
|
@ -367,16 +370,24 @@ mod tests {
|
|||
fn serialize_test() {
|
||||
assert_eq!(serialize(&Network::Bitcoin.magic()), &[0xf9, 0xbe, 0xb4, 0xd9]);
|
||||
assert_eq!(
|
||||
serialize(&Network::Testnet(crate::TestnetVersion::V3).magic()),
|
||||
serialize(&Network::Testnet(TestnetVersion::V3).magic()),
|
||||
&[0x0b, 0x11, 0x09, 0x07]
|
||||
);
|
||||
assert_eq!(
|
||||
serialize(&Network::Testnet(TestnetVersion::V4).magic()),
|
||||
&[0x1c, 0x16, 0x3f, 0x28]
|
||||
);
|
||||
assert_eq!(serialize(&Network::Signet.magic()), &[0x0a, 0x03, 0xcf, 0x40]);
|
||||
assert_eq!(serialize(&Network::Regtest.magic()), &[0xfa, 0xbf, 0xb5, 0xda]);
|
||||
|
||||
assert_eq!(deserialize(&[0xf9, 0xbe, 0xb4, 0xd9]).ok(), Some(Network::Bitcoin.magic()));
|
||||
assert_eq!(
|
||||
deserialize(&[0x0b, 0x11, 0x09, 0x07]).ok(),
|
||||
Some(Network::Testnet(crate::TestnetVersion::V3).magic())
|
||||
Some(Network::Testnet(TestnetVersion::V3).magic())
|
||||
);
|
||||
assert_eq!(
|
||||
deserialize(&[0x1c, 0x16, 0x3f, 0x28]).ok(),
|
||||
Some(Network::Testnet(TestnetVersion::V4).magic())
|
||||
);
|
||||
assert_eq!(deserialize(&[0x0a, 0x03, 0xcf, 0x40]).ok(), Some(Network::Signet.magic()));
|
||||
assert_eq!(deserialize(&[0xfa, 0xbf, 0xb5, 0xda]).ok(), Some(Network::Regtest.magic()));
|
||||
|
@ -385,15 +396,14 @@ mod tests {
|
|||
#[test]
|
||||
fn string_test() {
|
||||
assert_eq!(Network::Bitcoin.to_string(), "bitcoin");
|
||||
assert_eq!(Network::Testnet(crate::TestnetVersion::V3).to_string(), "testnet");
|
||||
assert_eq!(Network::Testnet(TestnetVersion::V3).to_string(), "testnet");
|
||||
assert_eq!(Network::Testnet(TestnetVersion::V4).to_string(), "testnet4");
|
||||
assert_eq!(Network::Regtest.to_string(), "regtest");
|
||||
assert_eq!(Network::Signet.to_string(), "signet");
|
||||
|
||||
assert_eq!("bitcoin".parse::<Network>().unwrap(), Network::Bitcoin);
|
||||
assert_eq!(
|
||||
"testnet".parse::<Network>().unwrap(),
|
||||
Network::Testnet(crate::TestnetVersion::V3)
|
||||
);
|
||||
assert_eq!("testnet".parse::<Network>().unwrap(), Network::Testnet(TestnetVersion::V3));
|
||||
assert_eq!("testnet4".parse::<Network>().unwrap(), Network::Testnet(TestnetVersion::V4));
|
||||
assert_eq!("regtest".parse::<Network>().unwrap(), Network::Regtest);
|
||||
assert_eq!("signet".parse::<Network>().unwrap(), Network::Signet);
|
||||
assert!("fakenet".parse::<Network>().is_err());
|
||||
|
@ -446,7 +456,8 @@ mod tests {
|
|||
use Network::*;
|
||||
let tests = vec![
|
||||
(Bitcoin, "bitcoin"),
|
||||
(Testnet(crate::TestnetVersion::V3), "testnet"),
|
||||
(Testnet(TestnetVersion::V3), "testnet"),
|
||||
(Testnet(TestnetVersion::V4), "testnet4"),
|
||||
(Signet, "signet"),
|
||||
(Regtest, "regtest"),
|
||||
];
|
||||
|
@ -467,7 +478,8 @@ mod tests {
|
|||
fn from_to_core_arg() {
|
||||
let expected_pairs = [
|
||||
(Network::Bitcoin, "main"),
|
||||
(Network::Testnet(crate::TestnetVersion::V3), "test"),
|
||||
(Network::Testnet(TestnetVersion::V3), "test"),
|
||||
(Network::Testnet(TestnetVersion::V4), "testnet4"),
|
||||
(Network::Regtest, "regtest"),
|
||||
(Network::Signet, "signet"),
|
||||
];
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//! Bitcoin consensus parameters.
|
||||
//!
|
||||
//! This module provides a predefined set of parameters for different Bitcoin
|
||||
//! chains (such as mainnet, testnet).
|
||||
//! chains (such as mainnet, testnet, testnet4).
|
||||
//!
|
||||
//! # Custom Signets Example
|
||||
//!
|
||||
|
@ -128,8 +128,13 @@ pub struct Params {
|
|||
///
|
||||
/// [using-statics-or-consts]: <https://doc.rust-lang.org/reference/items/static-items.html#using-statics-or-consts>
|
||||
pub static MAINNET: Params = Params::MAINNET;
|
||||
/// The testnet parameters.
|
||||
pub static TESTNET: Params = Params::TESTNET;
|
||||
/// The testnet3 parameters.
|
||||
#[deprecated(since = "0.33.0", note = "Use TESTNET3 instead")]
|
||||
pub static TESTNET: Params = Params::TESTNET3;
|
||||
/// The testnet3 parameters.
|
||||
pub static TESTNET3: Params = Params::TESTNET3;
|
||||
/// The testnet4 parameters.
|
||||
pub static TESTNET4: Params = Params::TESTNET4;
|
||||
/// The signet parameters.
|
||||
pub static SIGNET: Params = Params::SIGNET;
|
||||
/// The regtest parameters.
|
||||
|
@ -157,7 +162,8 @@ impl Params {
|
|||
no_pow_retargeting: false,
|
||||
};
|
||||
|
||||
/// The testnet parameters.
|
||||
/// The testnet3 parameters.
|
||||
#[deprecated(since = "0.33.0", note = "Use TESTNET3 instead")]
|
||||
pub const TESTNET: Params = Params {
|
||||
network: Network::Testnet(TestnetVersion::V3),
|
||||
bip16_time: 1333238400, // Apr 1 2012
|
||||
|
@ -174,6 +180,40 @@ impl Params {
|
|||
no_pow_retargeting: false,
|
||||
};
|
||||
|
||||
/// The testnet3 parameters.
|
||||
pub const TESTNET3: Params = Params {
|
||||
network: Network::Testnet(TestnetVersion::V3),
|
||||
bip16_time: 1333238400, // Apr 1 2012
|
||||
bip34_height: BlockHeight::from_u32(21111), // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8
|
||||
bip65_height: BlockHeight::from_u32(581885), // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
|
||||
bip66_height: BlockHeight::from_u32(330776), // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182
|
||||
rule_change_activation_threshold: BlockInterval::from_u32(1512), // 75%
|
||||
miner_confirmation_window: BlockInterval::from_u32(2016),
|
||||
pow_limit: Target::MAX_ATTAINABLE_TESTNET,
|
||||
max_attainable_target: Target::MAX_ATTAINABLE_TESTNET,
|
||||
pow_target_spacing: 10 * 60, // 10 minutes.
|
||||
pow_target_timespan: 14 * 24 * 60 * 60, // 2 weeks.
|
||||
allow_min_difficulty_blocks: true,
|
||||
no_pow_retargeting: false,
|
||||
};
|
||||
|
||||
/// The testnet4 parameters.
|
||||
pub const TESTNET4: Params = Params {
|
||||
network: Network::Testnet(TestnetVersion::V4),
|
||||
bip16_time: 1333238400, // Apr 1 2012
|
||||
bip34_height: BlockHeight::from_u32(1),
|
||||
bip65_height: BlockHeight::from_u32(1),
|
||||
bip66_height: BlockHeight::from_u32(1),
|
||||
rule_change_activation_threshold: BlockInterval::from_u32(1512), // 75%
|
||||
miner_confirmation_window: BlockInterval::from_u32(2016),
|
||||
pow_limit: Target::MAX_ATTAINABLE_TESTNET,
|
||||
max_attainable_target: Target::MAX_ATTAINABLE_TESTNET,
|
||||
pow_target_spacing: 10 * 60, // 10 minutes.
|
||||
pow_target_timespan: 14 * 24 * 60 * 60, // 2 weeks.
|
||||
allow_min_difficulty_blocks: true,
|
||||
no_pow_retargeting: false,
|
||||
};
|
||||
|
||||
/// The signet parameters.
|
||||
pub const SIGNET: Params = Params {
|
||||
network: Network::Signet,
|
||||
|
@ -208,11 +248,12 @@ impl Params {
|
|||
no_pow_retargeting: true,
|
||||
};
|
||||
|
||||
/// Creates parameters set for the given network. /// Creates parameters set for the given network.
|
||||
/// Creates parameters set for the given network.
|
||||
pub const fn new(network: Network) -> Self {
|
||||
match network {
|
||||
Network::Bitcoin => Params::MAINNET,
|
||||
Network::Testnet(TestnetVersion::V3) => Params::TESTNET,
|
||||
Network::Testnet(TestnetVersion::V3) => Params::TESTNET3,
|
||||
Network::Testnet(TestnetVersion::V4) => Params::TESTNET4,
|
||||
Network::Signet => Params::SIGNET,
|
||||
Network::Regtest => Params::REGTEST,
|
||||
}
|
||||
|
@ -245,12 +286,5 @@ impl AsRef<Params> for Params {
|
|||
}
|
||||
|
||||
impl AsRef<Params> for Network {
|
||||
fn as_ref(&self) -> &Params {
|
||||
match *self {
|
||||
Network::Bitcoin => &MAINNET,
|
||||
Network::Testnet(TestnetVersion::V3) => &TESTNET,
|
||||
Network::Signet => &SIGNET,
|
||||
Network::Regtest => ®TEST,
|
||||
}
|
||||
}
|
||||
fn as_ref(&self) -> &Params { Self::params(*self) }
|
||||
}
|
||||
|
|
|
@ -217,7 +217,12 @@ impl Magic {
|
|||
/// Bitcoin mainnet network magic bytes.
|
||||
pub const BITCOIN: Self = Self([0xF9, 0xBE, 0xB4, 0xD9]);
|
||||
/// Bitcoin testnet3 network magic bytes.
|
||||
#[deprecated(since = "0.33.0", note = "Use TESTNET3 instead")]
|
||||
pub const TESTNET: Self = Self([0x0B, 0x11, 0x09, 0x07]);
|
||||
/// Bitcoin testnet3 network magic bytes.
|
||||
pub const TESTNET3: Self = Self([0x0B, 0x11, 0x09, 0x07]);
|
||||
/// Bitcoin testnet4 network magic bytes.
|
||||
pub const TESTNET4: Self = Self([0x1c, 0x16, 0x3f, 0x28]);
|
||||
/// Bitcoin signet network magic bytes.
|
||||
pub const SIGNET: Self = Self([0x0A, 0x03, 0xCF, 0x40]);
|
||||
/// Bitcoin regtest network magic bytes.
|
||||
|
@ -274,7 +279,8 @@ macro_rules! generate_network_magic_conversion {
|
|||
// `Network -> Magic` and `Magic -> Network`
|
||||
generate_network_magic_conversion! {
|
||||
Network::Bitcoin => Magic::BITCOIN,
|
||||
Network::Testnet(TestnetVersion::V3) => Magic::TESTNET,
|
||||
Network::Testnet(TestnetVersion::V3) => Magic::TESTNET3,
|
||||
Network::Testnet(TestnetVersion::V4) => Magic::TESTNET4,
|
||||
Network::Signet => Magic::SIGNET,
|
||||
Network::Regtest => Magic::REGTEST,
|
||||
}
|
||||
|
@ -432,6 +438,7 @@ mod tests {
|
|||
let known_network_magic_strs = [
|
||||
("f9beb4d9", Network::Bitcoin),
|
||||
("0b110907", Network::Testnet(TestnetVersion::V3)),
|
||||
("1c163f28", Network::Testnet(TestnetVersion::V4)),
|
||||
("fabfb5da", Network::Regtest),
|
||||
("0a03cf40", Network::Signet),
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue