add signet support

This commit is contained in:
Karl-Johan Alm 2019-07-10 13:53:53 +09:00
parent c1ae3b7955
commit a3d9899cb1
No known key found for this signature in database
GPG Key ID: 57AF762DB3353322
6 changed files with 69 additions and 7 deletions

View File

@ -128,6 +128,19 @@ pub fn genesis_block(network: Network) -> Block {
txdata: txdata txdata: txdata
} }
} }
Network::Signet => {
Block {
header: BlockHeader {
version: 1,
prev_blockhash: Default::default(),
merkle_root,
time: 1598918400,
bits: 0x1e0377ae,
nonce: 52613770
},
txdata: txdata
}
}
Network::Regtest => { Network::Regtest => {
Block { Block {
header: BlockHeader { header: BlockHeader {
@ -204,5 +217,19 @@ mod test {
assert_eq!(format!("{:x}", gen.header.block_hash()), assert_eq!(format!("{:x}", gen.header.block_hash()),
"000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943".to_string()); "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943".to_string());
} }
#[test]
fn signet_genesis_full_block() {
let gen = genesis_block(Network::Signet);
assert_eq!(gen.header.version, 1);
assert_eq!(gen.header.prev_blockhash, Default::default());
assert_eq!(format!("{:x}", gen.header.merkle_root),
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b".to_string());
assert_eq!(gen.header.time, 1598918400);
assert_eq!(gen.header.bits, 0x1e0377ae);
assert_eq!(gen.header.nonce, 52613770);
assert_eq!(format!("{:x}", gen.header.block_hash()),
"00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6".to_string());
}
} }

View File

@ -34,6 +34,13 @@ const MAX_BITS_TESTNET: Uint256 = Uint256([
0x0000000000000000u64, 0x0000000000000000u64,
0x00000000ffff0000u64, 0x00000000ffff0000u64,
]); ]);
/// Lowest possible difficulty for Signet. See comment on Params::pow_limit for more info.
const MAX_BITS_SIGNET: Uint256 = Uint256([
0x0000000000000000u64,
0x0000000000000000u64,
0x0000000000000000u64,
0x00000377ae000000u64,
]);
/// Lowest possible difficulty for Regtest. See comment on Params::pow_limit for more info. /// Lowest possible difficulty for Regtest. See comment on Params::pow_limit for more info.
const MAX_BITS_REGTEST: Uint256 = Uint256([ const MAX_BITS_REGTEST: Uint256 = Uint256([
0x0000000000000000u64, 0x0000000000000000u64,
@ -112,6 +119,20 @@ impl Params {
allow_min_difficulty_blocks: true, allow_min_difficulty_blocks: true,
no_pow_retargeting: false, no_pow_retargeting: false,
}, },
Network::Signet => Params {
network: Network::Signet,
bip16_time: 1333238400, // Apr 1 2012
bip34_height: 1,
bip65_height: 1,
bip66_height: 1,
rule_change_activation_threshold: 1916, // 95%
miner_confirmation_window: 2016,
pow_limit: MAX_BITS_SIGNET,
pow_target_spacing: 10 * 60, // 10 minutes.
pow_target_timespan: 14 * 24 * 60 * 60, // 2 weeks.
allow_min_difficulty_blocks: false,
no_pow_retargeting: false,
},
Network::Regtest => Params { Network::Regtest => Params {
network: Network::Regtest, network: Network::Regtest,
bip16_time: 1333238400, // Apr 1 2012 bip16_time: 1333238400, // Apr 1 2012

View File

@ -52,6 +52,8 @@ user_enum! {
Bitcoin <-> "bitcoin", Bitcoin <-> "bitcoin",
/// Bitcoin's testnet /// Bitcoin's testnet
Testnet <-> "testnet", Testnet <-> "testnet",
/// Bitcoin's signet
Signet <-> "signet",
/// Bitcoin's regtest /// Bitcoin's regtest
Regtest <-> "regtest" Regtest <-> "regtest"
} }
@ -73,6 +75,7 @@ impl Network {
match magic { match magic {
0xD9B4BEF9 => Some(Network::Bitcoin), 0xD9B4BEF9 => Some(Network::Bitcoin),
0x0709110B => Some(Network::Testnet), 0x0709110B => Some(Network::Testnet),
0x40CF030A => Some(Network::Signet),
0xDAB5BFFA => Some(Network::Regtest), 0xDAB5BFFA => Some(Network::Regtest),
_ => None _ => None
} }
@ -94,6 +97,7 @@ impl Network {
match self { match self {
Network::Bitcoin => 0xD9B4BEF9, Network::Bitcoin => 0xD9B4BEF9,
Network::Testnet => 0x0709110B, Network::Testnet => 0x0709110B,
Network::Signet => 0x40CF030A,
Network::Regtest => 0xDAB5BFFA, Network::Regtest => 0xDAB5BFFA,
} }
} }
@ -285,6 +289,10 @@ mod tests {
serialize(&Network::Testnet.magic()), serialize(&Network::Testnet.magic()),
&[0x0b, 0x11, 0x09, 0x07] &[0x0b, 0x11, 0x09, 0x07]
); );
assert_eq!(
serialize(&Network::Signet.magic()),
&[0x0a, 0x03, 0xcf, 0x40]
);
assert_eq!( assert_eq!(
serialize(&Network::Regtest.magic()), serialize(&Network::Regtest.magic()),
&[0xfa, 0xbf, 0xb5, 0xda] &[0xfa, 0xbf, 0xb5, 0xda]
@ -298,6 +306,10 @@ mod tests {
deserialize(&[0x0b, 0x11, 0x09, 0x07]).ok(), deserialize(&[0x0b, 0x11, 0x09, 0x07]).ok(),
Some(Network::Testnet.magic()) Some(Network::Testnet.magic())
); );
assert_eq!(
deserialize(&[0x0a, 0x03, 0xcf, 0x40]).ok(),
Some(Network::Signet.magic())
);
assert_eq!( assert_eq!(
deserialize(&[0xfa, 0xbf, 0xb5, 0xda]).ok(), deserialize(&[0xfa, 0xbf, 0xb5, 0xda]).ok(),
Some(Network::Regtest.magic()) Some(Network::Regtest.magic())
@ -309,10 +321,12 @@ mod tests {
assert_eq!(Network::Bitcoin.to_string(), "bitcoin"); assert_eq!(Network::Bitcoin.to_string(), "bitcoin");
assert_eq!(Network::Testnet.to_string(), "testnet"); assert_eq!(Network::Testnet.to_string(), "testnet");
assert_eq!(Network::Regtest.to_string(), "regtest"); assert_eq!(Network::Regtest.to_string(), "regtest");
assert_eq!(Network::Signet.to_string(), "signet");
assert_eq!("bitcoin".parse::<Network>().unwrap(), Network::Bitcoin); assert_eq!("bitcoin".parse::<Network>().unwrap(), Network::Bitcoin);
assert_eq!("testnet".parse::<Network>().unwrap(), Network::Testnet); assert_eq!("testnet".parse::<Network>().unwrap(), Network::Testnet);
assert_eq!("regtest".parse::<Network>().unwrap(), Network::Regtest); assert_eq!("regtest".parse::<Network>().unwrap(), Network::Regtest);
assert_eq!("signet".parse::<Network>().unwrap(), Network::Signet);
assert!("fakenet".parse::<Network>().is_err()); assert!("fakenet".parse::<Network>().is_err());
} }

View File

@ -365,7 +365,7 @@ impl Display for Address {
let mut prefixed = [0; 21]; let mut prefixed = [0; 21];
prefixed[0] = match self.network { prefixed[0] = match self.network {
Network::Bitcoin => 0, Network::Bitcoin => 0,
Network::Testnet | Network::Regtest => 111, Network::Testnet | Network::Signet | Network::Regtest => 111,
}; };
prefixed[1..].copy_from_slice(&hash[..]); prefixed[1..].copy_from_slice(&hash[..]);
base58::check_encode_slice_to_fmt(fmt, &prefixed[..]) base58::check_encode_slice_to_fmt(fmt, &prefixed[..])
@ -374,7 +374,7 @@ impl Display for Address {
let mut prefixed = [0; 21]; let mut prefixed = [0; 21];
prefixed[0] = match self.network { prefixed[0] = match self.network {
Network::Bitcoin => 5, Network::Bitcoin => 5,
Network::Testnet | Network::Regtest => 196, Network::Testnet | Network::Signet | Network::Regtest => 196,
}; };
prefixed[1..].copy_from_slice(&hash[..]); prefixed[1..].copy_from_slice(&hash[..]);
base58::check_encode_slice_to_fmt(fmt, &prefixed[..]) base58::check_encode_slice_to_fmt(fmt, &prefixed[..])
@ -385,7 +385,7 @@ impl Display for Address {
} => { } => {
let hrp = match self.network { let hrp = match self.network {
Network::Bitcoin => "bc", Network::Bitcoin => "bc",
Network::Testnet => "tb", Network::Testnet | Network::Signet => "tb",
Network::Regtest => "bcrt", Network::Regtest => "bcrt",
}; };
let mut bech32_writer = bech32::Bech32Writer::new(hrp, fmt)?; let mut bech32_writer = bech32::Bech32Writer::new(hrp, fmt)?;
@ -414,7 +414,7 @@ impl FromStr for Address {
let bech32_network = match find_bech32_prefix(s) { let bech32_network = match find_bech32_prefix(s) {
// note that upper or lowercase is allowed but NOT mixed case // note that upper or lowercase is allowed but NOT mixed case
"bc" | "BC" => Some(Network::Bitcoin), "bc" | "BC" => Some(Network::Bitcoin),
"tb" | "TB" => Some(Network::Testnet), "tb" | "TB" => Some(Network::Testnet), // this may also be signet
"bcrt" | "BCRT" => Some(Network::Regtest), "bcrt" | "BCRT" => Some(Network::Regtest),
_ => None, _ => None,
}; };

View File

@ -566,7 +566,7 @@ impl fmt::Display for ExtendedPrivKey {
let mut ret = [0; 78]; let mut ret = [0; 78];
ret[0..4].copy_from_slice(&match self.network { ret[0..4].copy_from_slice(&match self.network {
Network::Bitcoin => [0x04, 0x88, 0xAD, 0xE4], Network::Bitcoin => [0x04, 0x88, 0xAD, 0xE4],
Network::Testnet | Network::Regtest => [0x04, 0x35, 0x83, 0x94], Network::Testnet | Network::Signet | Network::Regtest => [0x04, 0x35, 0x83, 0x94],
}[..]); }[..]);
ret[4] = self.depth as u8; ret[4] = self.depth as u8;
ret[5..9].copy_from_slice(&self.parent_fingerprint[..]); ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
@ -623,7 +623,7 @@ impl fmt::Display for ExtendedPubKey {
let mut ret = [0; 78]; let mut ret = [0; 78];
ret[0..4].copy_from_slice(&match self.network { ret[0..4].copy_from_slice(&match self.network {
Network::Bitcoin => [0x04u8, 0x88, 0xB2, 0x1E], Network::Bitcoin => [0x04u8, 0x88, 0xB2, 0x1E],
Network::Testnet | Network::Regtest => [0x04u8, 0x35, 0x87, 0xCF], Network::Testnet | Network::Signet | Network::Regtest => [0x04u8, 0x35, 0x87, 0xCF],
}[..]); }[..]);
ret[4] = self.depth as u8; ret[4] = self.depth as u8;
ret[5..9].copy_from_slice(&self.parent_fingerprint[..]); ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);

View File

@ -173,7 +173,7 @@ impl PrivateKey {
let mut ret = [0; 34]; let mut ret = [0; 34];
ret[0] = match self.network { ret[0] = match self.network {
Network::Bitcoin => 128, Network::Bitcoin => 128,
Network::Testnet | Network::Regtest => 239, Network::Testnet | Network::Signet | Network::Regtest => 239,
}; };
ret[1..33].copy_from_slice(&self.key[..]); ret[1..33].copy_from_slice(&self.key[..]);
let privkey = if self.compressed { let privkey = if self.compressed {