Make block::Version inner value private

The Bitcoin block version is a signed integer for historical reasons,
but we bit twiddle it like an unsigned integer and during consensus
encode/decode we cast the signed value to an unsigned value.

In order to hide this confusion, make the inner value private and add a
couple of constants for v1 and v2 block versions.
This commit is contained in:
Tobin C. Harding 2022-10-27 12:55:06 +11:00
parent 7e146ede96
commit 24984f095f
3 changed files with 18 additions and 10 deletions

View File

@ -395,7 +395,7 @@ mod test {
fn dummy_block() -> Block {
Block {
header: block::Header {
version: block::Version(1),
version: block::Version::ONE,
prev_blockhash: BlockHash::hash(&[0]),
merkle_root: TxMerkleNode::hash(&[1]),
time: 2,

View File

@ -112,13 +112,21 @@ impl Header {
#[derive(Copy, PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
pub struct Version(pub i32);
pub struct Version(i32);
impl Version {
/// The original Bitcoin Block v1.
pub const ONE: Self = Self(1);
/// BIP-34 Block v2.
pub const TWO: Self = Self(2);
/// BIP-9 compatible version number that does not signal for any softforks.
pub const NO_SOFT_FORK_SIGNALLING: Self = Self(Self::USE_VERSION_BITS as i32);
/// BIP-9 soft fork signal bits mask.
const VERSION_BITS_MASK: u32 = 0x1FFF_FFFF;
/// 32bit value starting with `001` to use version bits.
///
/// The value has the top three bits `001` which enables the use of version bits to signal for soft forks.
@ -302,7 +310,7 @@ impl Block {
// number (including a sign bit). Height is the height of the mined
// block in the block chain, where the genesis block is height zero (0).
if self.header.version < Version(2) {
if self.header.version < Version::TWO {
return Err(Bip34Error::Unsupported);
}

View File

@ -112,7 +112,7 @@ pub fn genesis_block(network: Network) -> Block {
Network::Bitcoin => {
Block {
header: block::Header {
version: block::Version(1),
version: block::Version::ONE,
prev_blockhash: Hash::all_zeros(),
merkle_root,
time: 1231006505,
@ -125,7 +125,7 @@ pub fn genesis_block(network: Network) -> Block {
Network::Testnet => {
Block {
header: block::Header {
version: block::Version(1),
version: block::Version::ONE,
prev_blockhash: Hash::all_zeros(),
merkle_root,
time: 1296688602,
@ -138,7 +138,7 @@ pub fn genesis_block(network: Network) -> Block {
Network::Signet => {
Block {
header: block::Header {
version: block::Version(1),
version: block::Version::ONE,
prev_blockhash: Hash::all_zeros(),
merkle_root,
time: 1598918400,
@ -151,7 +151,7 @@ pub fn genesis_block(network: Network) -> Block {
Network::Regtest => {
Block {
header: block::Header {
version: block::Version(1),
version: block::Version::ONE,
prev_blockhash: Hash::all_zeros(),
merkle_root,
time: 1296688602,
@ -224,7 +224,7 @@ mod test {
fn bitcoin_genesis_full_block() {
let gen = genesis_block(Network::Bitcoin);
assert_eq!(gen.header.version, block::Version(1));
assert_eq!(gen.header.version, block::Version::ONE);
assert_eq!(gen.header.prev_blockhash, Hash::all_zeros());
assert_eq!(gen.header.merkle_root.to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
@ -237,7 +237,7 @@ mod test {
#[test]
fn testnet_genesis_full_block() {
let gen = genesis_block(Network::Testnet);
assert_eq!(gen.header.version, block::Version(1));
assert_eq!(gen.header.version, block::Version::ONE);
assert_eq!(gen.header.prev_blockhash, Hash::all_zeros());
assert_eq!(gen.header.merkle_root.to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
assert_eq!(gen.header.time, 1296688602);
@ -249,7 +249,7 @@ mod test {
#[test]
fn signet_genesis_full_block() {
let gen = genesis_block(Network::Signet);
assert_eq!(gen.header.version, block::Version(1));
assert_eq!(gen.header.version, block::Version::ONE);
assert_eq!(gen.header.prev_blockhash, Hash::all_zeros());
assert_eq!(gen.header.merkle_root.to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
assert_eq!(gen.header.time, 1598918400);