From 7e146ede963d915d9ee1c69f73f52439f4300c93 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 27 Oct 2022 12:29:34 +1100 Subject: [PATCH] Make types in block module more terse Currently the types in the block module have longer names than necessary, "header" and "version" identifiers contain the word "block", this is unnecessary because we can write `block::Header` instead of `BlockHeader` when context is required. This allows us to use the naked type `Header` inside the `block` module with no loss of clarity. We are stuck with `BlockHash` because the type is defined along with all the other hash types in `hash_types`, leave it as is for now but re-export it from the `block` module to assist in putting types that are used together in scope in the same place, making import statements more ergonomic. --- bitcoin/src/bip152.rs | 12 +++--- bitcoin/src/blockdata/block.rs | 59 +++++++++++++++--------------- bitcoin/src/blockdata/constants.rs | 24 ++++++------ bitcoin/src/lib.rs | 2 +- bitcoin/src/network/message.rs | 10 ++--- bitcoin/src/pow.rs | 2 +- bitcoin/src/util/merkleblock.rs | 6 +-- 7 files changed, 57 insertions(+), 58 deletions(-) diff --git a/bitcoin/src/bip152.rs b/bitcoin/src/bip152.rs index aa8b90dd..857a150a 100644 --- a/bitcoin/src/bip152.rs +++ b/bitcoin/src/bip152.rs @@ -16,7 +16,7 @@ use crate::consensus::encode::{self, Decodable, Encodable, VarInt}; use crate::hashes::{sha256, siphash24, Hash}; use crate::internal_macros::{impl_bytes_newtype, impl_consensus_encoding}; use crate::prelude::*; -use crate::{io, Block, BlockHash, BlockHeader, Transaction}; +use crate::{io, block, Block, BlockHash, Transaction}; /// A BIP-152 error #[derive(Clone, PartialEq, Eq, Debug, Copy, PartialOrd, Ord, Hash)] @@ -100,7 +100,7 @@ impl_bytes_newtype!(ShortId, 6); impl ShortId { /// Calculate the SipHash24 keys used to calculate short IDs. - pub fn calculate_siphash_keys(header: &BlockHeader, nonce: u64) -> (u64, u64) { + pub fn calculate_siphash_keys(header: &block::Header, nonce: u64) -> (u64, u64) { // 1. single-SHA256 hashing the block header with the nonce appended (in little-endian) let h = { let mut engine = sha256::Hash::engine(); @@ -147,7 +147,7 @@ impl Decodable for ShortId { #[derive(PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)] pub struct HeaderAndShortIds { /// The header of the block being provided. - pub header: BlockHeader, + pub header: block::Header, /// A nonce for use in short transaction ID calculations. pub nonce: u64, /// The short transaction IDs calculated from the transactions @@ -374,7 +374,7 @@ mod test { use crate::consensus::encode::{deserialize, serialize}; use crate::hashes::hex::FromHex; use crate::{ - Block, BlockHash, BlockHeader, BlockVersion, CompactTarget, OutPoint, Script, Sequence, + CompactTarget, OutPoint, Script, Sequence, Transaction, TxIn, TxMerkleNode, TxOut, Txid, Witness, }; @@ -394,8 +394,8 @@ mod test { fn dummy_block() -> Block { Block { - header: BlockHeader { - version: BlockVersion(1), + header: block::Header { + version: block::Version(1), prev_blockhash: BlockHash::hash(&[0]), merkle_root: TxMerkleNode::hash(&[1]), time: 2, diff --git a/bitcoin/src/blockdata/block.rs b/bitcoin/src/blockdata/block.rs index 143bc208..9a80406c 100644 --- a/bitcoin/src/blockdata/block.rs +++ b/bitcoin/src/blockdata/block.rs @@ -16,7 +16,7 @@ use core::fmt; use crate::{merkle_tree, util}; use crate::util::Error::{BlockBadTarget, BlockBadProofOfWork}; use crate::hashes::{Hash, HashEngine}; -use crate::hash_types::{Wtxid, BlockHash, TxMerkleNode, WitnessMerkleNode, WitnessCommitment}; +use crate::hash_types::{Wtxid, TxMerkleNode, WitnessMerkleNode, WitnessCommitment}; use crate::consensus::{encode, Encodable, Decodable}; use crate::blockdata::transaction::Transaction; use crate::blockdata::constants::WITNESS_SCALE_FACTOR; @@ -26,6 +26,8 @@ use crate::VarInt; use crate::internal_macros::impl_consensus_encoding; use crate::io; +pub use crate::hash_types::BlockHash; + /// Bitcoin block header. /// /// Contains all the block's information except the actual transactions, but @@ -39,9 +41,9 @@ use crate::io; #[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 BlockHeader { +pub struct Header { /// Block version, now repurposed for soft fork signalling. - pub version: BlockVersion, + pub version: Version, /// Reference to the previous block in the chain. pub prev_blockhash: BlockHash, /// The root hash of the merkle tree of transactions in the block. @@ -54,9 +56,9 @@ pub struct BlockHeader { pub nonce: u32, } -impl_consensus_encoding!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce); +impl_consensus_encoding!(Header, version, prev_blockhash, merkle_root, time, bits, nonce); -impl BlockHeader { +impl Header { /// Returns the block hash. pub fn block_hash(&self) -> BlockHash { let mut engine = BlockHash::engine(); @@ -110,9 +112,9 @@ impl BlockHeader { #[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 BlockVersion(pub i32); +pub struct Version(pub i32); -impl BlockVersion { +impl Version { /// 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. @@ -142,21 +144,21 @@ impl BlockVersion { } } -impl Default for BlockVersion { - fn default() -> BlockVersion { +impl Default for Version { + fn default() -> Version { Self::NO_SOFT_FORK_SIGNALLING } } -impl Encodable for BlockVersion { +impl Encodable for Version { fn consensus_encode(&self, w: &mut W) -> Result { self.0.consensus_encode(w) } } -impl Decodable for BlockVersion { +impl Decodable for Version { fn consensus_decode(r: &mut R) -> Result { - Decodable::consensus_decode(r).map(BlockVersion) + Decodable::consensus_decode(r).map(Version) } } @@ -176,7 +178,7 @@ impl Decodable for BlockVersion { #[cfg_attr(feature = "serde", serde(crate = "actual_serde"))] pub struct Block { /// The block header - pub header: BlockHeader, + pub header: Header, /// List of transactions contained in the block pub txdata: Vec } @@ -300,7 +302,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 < BlockVersion(2) { + if self.header.version < Version(2) { return Err(Bip34Error::Unsupported); } @@ -364,14 +366,14 @@ impl std::error::Error for Bip34Error { } } -impl From for BlockHash { - fn from(header: BlockHeader) -> BlockHash { +impl From
for BlockHash { + fn from(header: Header) -> BlockHash { header.block_hash() } } -impl From<&BlockHeader> for BlockHash { - fn from(header: &BlockHeader) -> BlockHash { +impl From<&Header> for BlockHash { + fn from(header: &Header) -> BlockHash { header.block_hash() } } @@ -393,10 +395,7 @@ mod tests { use super::*; use crate::hashes::hex::FromHex; - - use crate::blockdata::block::{Block, BlockHeader, BlockVersion}; use crate::consensus::encode::{deserialize, serialize}; - use crate::util::Error::{BlockBadTarget, BlockBadProofOfWork}; #[test] fn test_coinbase_and_bip34() { @@ -434,7 +433,7 @@ mod tests { assert!(decode.is_ok()); assert!(bad_decode.is_err()); let real_decode = decode.unwrap(); - assert_eq!(real_decode.header.version, BlockVersion(1)); + assert_eq!(real_decode.header.version, Version(1)); assert_eq!(serialize(&real_decode.header.prev_blockhash), prevhash); assert_eq!(real_decode.header.merkle_root, real_decode.compute_merkle_root().unwrap()); assert_eq!(serialize(&real_decode.header.merkle_root), merkle); @@ -469,7 +468,7 @@ mod tests { assert!(decode.is_ok()); let real_decode = decode.unwrap(); - assert_eq!(real_decode.header.version, BlockVersion(BlockVersion::USE_VERSION_BITS as i32)); // VERSIONBITS but no bits set + assert_eq!(real_decode.header.version, Version(Version::USE_VERSION_BITS as i32)); // VERSIONBITS but no bits set assert_eq!(serialize(&real_decode.header.prev_blockhash), prevhash); assert_eq!(serialize(&real_decode.header.merkle_root), merkle); assert_eq!(real_decode.header.merkle_root, real_decode.compute_merkle_root().unwrap()); @@ -496,19 +495,19 @@ mod tests { let decode: Result = deserialize(&block); assert!(decode.is_ok()); let real_decode = decode.unwrap(); - assert_eq!(real_decode.header.version, BlockVersion(2147483647)); + assert_eq!(real_decode.header.version, Version(2147483647)); let block2 = Vec::from_hex("000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(); let decode2: Result = deserialize(&block2); assert!(decode2.is_ok()); let real_decode2 = decode2.unwrap(); - assert_eq!(real_decode2.header.version, BlockVersion(-2147483648)); + assert_eq!(real_decode2.header.version, Version(-2147483648)); } #[test] fn validate_pow_test() { let some_header = Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap(); - let some_header: BlockHeader = deserialize(&some_header).expect("Can't deserialize correct block header"); + let some_header: Header = deserialize(&some_header).expect("Can't deserialize correct block header"); assert_eq!(some_header.validate_pow(some_header.target()).unwrap(), some_header.block_hash()); // test with zero target @@ -518,7 +517,7 @@ mod tests { } // test with modified header - let mut invalid_header: BlockHeader = some_header; + let mut invalid_header: Header = some_header; invalid_header.version.0 += 1; match invalid_header.validate_pow(invalid_header.target()) { Err(BlockBadProofOfWork) => (), @@ -530,7 +529,7 @@ mod tests { fn compact_roundrtip_test() { let some_header = Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap(); - let header: BlockHeader = deserialize(&some_header).expect("Can't deserialize correct block header"); + let header: Header = deserialize(&some_header).expect("Can't deserialize correct block header"); assert_eq!(header.bits, header.target().to_compact_lossy()); } @@ -539,7 +538,7 @@ mod tests { fn soft_fork_signalling() { for i in 0..31 { let version_int = (0x20000000u32 ^ 1< Block { match network { Network::Bitcoin => { Block { - header: BlockHeader { - version: BlockVersion(1), + header: block::Header { + version: block::Version(1), prev_blockhash: Hash::all_zeros(), merkle_root, time: 1231006505, @@ -124,8 +124,8 @@ pub fn genesis_block(network: Network) -> Block { } Network::Testnet => { Block { - header: BlockHeader { - version: BlockVersion(1), + header: block::Header { + version: block::Version(1), prev_blockhash: Hash::all_zeros(), merkle_root, time: 1296688602, @@ -137,8 +137,8 @@ pub fn genesis_block(network: Network) -> Block { } Network::Signet => { Block { - header: BlockHeader { - version: BlockVersion(1), + header: block::Header { + version: block::Version(1), prev_blockhash: Hash::all_zeros(), merkle_root, time: 1598918400, @@ -150,8 +150,8 @@ pub fn genesis_block(network: Network) -> Block { } Network::Regtest => { Block { - header: BlockHeader { - version: BlockVersion(1), + header: block::Header { + version: block::Version(1), 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, BlockVersion(1)); + assert_eq!(gen.header.version, block::Version(1)); 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, BlockVersion(1)); + assert_eq!(gen.header.version, block::Version(1)); 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, BlockVersion(1)); + assert_eq!(gen.header.version, block::Version(1)); assert_eq!(gen.header.prev_blockhash, Hash::all_zeros()); assert_eq!(gen.header.merkle_root.to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"); assert_eq!(gen.header.time, 1598918400); diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index 7ac69e9e..faff0e9c 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -115,7 +115,7 @@ use std::io; use core2::io; pub use crate::address::{Address, AddressType}; -pub use crate::blockdata::block::{self, Block, BlockHeader, BlockVersion}; +pub use crate::blockdata::block::{self, Block}; pub use crate::blockdata::locktime::{self, absolute, relative}; pub use crate::blockdata::script::{self, Script}; pub use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut}; diff --git a/bitcoin/src/network/message.rs b/bitcoin/src/network/message.rs index 6de93622..5a6e3d43 100644 --- a/bitcoin/src/network/message.rs +++ b/bitcoin/src/network/message.rs @@ -182,7 +182,7 @@ pub enum NetworkMessage { /// `block` Block(block::Block), /// `headers` - Headers(Vec), + Headers(Vec), /// `sendheaders` SendHeaders, /// `getaddr` @@ -317,7 +317,7 @@ impl RawNetworkMessage { } } -struct HeaderSerializationWrapper<'a>(&'a Vec); +struct HeaderSerializationWrapper<'a>(&'a Vec); impl<'a> Encodable for HeaderSerializationWrapper<'a> { #[inline] @@ -380,7 +380,7 @@ impl Encodable for RawNetworkMessage { } } -struct HeaderDeserializationWrapper(Vec); +struct HeaderDeserializationWrapper(Vec); impl Decodable for HeaderDeserializationWrapper { #[inline] @@ -479,7 +479,7 @@ mod test { use crate::network::address::{Address, AddrV2, AddrV2Message}; use super::message_network::{Reject, RejectReason, VersionMessage}; use crate::network::message_blockdata::{Inventory, GetBlocksMessage, GetHeadersMessage}; - use crate::blockdata::block::{Block, BlockHeader}; + use crate::blockdata::block::{self, Block}; use crate::network::message_filter::{GetCFilters, CFilter, GetCFHeaders, CFHeaders, GetCFCheckpt, CFCheckpt}; use crate::blockdata::transaction::Transaction; use crate::blockdata::script::Script; @@ -498,7 +498,7 @@ mod test { let version_msg: VersionMessage = deserialize(&Vec::from_hex("721101000100000000000000e6e0845300000000010000000000000000000000000000000000ffff0000000000000100000000000000fd87d87eeb4364f22cf54dca59412db7208d47d920cffce83ee8102f5361746f7368693a302e392e39392f2c9f040001").unwrap()).unwrap(); let tx: Transaction = deserialize(&Vec::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap()).unwrap(); let block: Block = deserialize(&include_bytes!("../../tests/data/testnet_block_000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b.raw")[..]).unwrap(); - let header: BlockHeader = deserialize(&Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap()).unwrap(); + let header: block::Header = deserialize(&Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap()).unwrap(); let script: Script = deserialize(&Vec::from_hex("1976a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac").unwrap()).unwrap(); let merkle_block: MerkleBlock = deserialize(&Vec::from_hex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101").unwrap()).unwrap(); let cmptblock = deserialize(&Vec::from_hex("00000030d923ad36ff2d955abab07f8a0a6e813bc6e066b973e780c5e36674cad5d1cd1f6e265f2a17a0d35cbe701fe9d06e2c6324cfe135f6233e8b767bfa3fb4479b71115dc562ffff7f2006000000000000000000000000010002000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0302ee00ffffffff0100f9029500000000015100000000").unwrap()).unwrap(); diff --git a/bitcoin/src/pow.rs b/bitcoin/src/pow.rs index be0730e4..6b5121d5 100644 --- a/bitcoin/src/pow.rs +++ b/bitcoin/src/pow.rs @@ -237,7 +237,7 @@ impl Target { /// `0xffff_ffff_ffff_ffff_ffff_ffff` `difficulty()` will saturate at `u128::MAX`. /// /// [max]: Target::max - /// [target]: crate::blockdata::block::BlockHeader::target + /// [target]: crate::blockdata::block::Header::target pub fn difficulty(&self) -> u128 { let d = Target::MAX.0 / self.0; d.saturating_to_u128() diff --git a/bitcoin/src/util/merkleblock.rs b/bitcoin/src/util/merkleblock.rs index 057cb0ba..d6a7baff 100644 --- a/bitcoin/src/util/merkleblock.rs +++ b/bitcoin/src/util/merkleblock.rs @@ -49,11 +49,11 @@ use crate::io; use crate::hashes::Hash; use crate::hash_types::{Txid, TxMerkleNode}; +use crate::blockdata::block::{self, Block}; use crate::blockdata::transaction::Transaction; use crate::blockdata::constants::{MAX_BLOCK_WEIGHT, MIN_TRANSACTION_WEIGHT}; use crate::consensus::encode::{self, Decodable, Encodable}; use crate::util::merkleblock::MerkleBlockError::*; -use crate::{Block, BlockHeader}; /// An error when verifying the merkle block. #[derive(Clone, PartialEq, Eq, Debug)] @@ -408,7 +408,7 @@ impl Decodable for PartialMerkleTree { #[derive(PartialEq, Eq, Clone, Debug)] pub struct MerkleBlock { /// The block header - pub header: BlockHeader, + pub header: block::Header, /// Transactions making up a partial merkle tree pub txn: PartialMerkleTree, } @@ -464,7 +464,7 @@ impl MerkleBlock { /// The `header` is the block header, `block_txids` is the full list of txids included in the block and /// `match_txids` is a function that returns true for the ids that should be included in the partial merkle tree. pub fn from_header_txids_with_predicate( - header: &BlockHeader, + header: &block::Header, block_txids: &[Txid], match_txids: F, ) -> Self