Merge rust-bitcoin/rust-bitcoin#2178: Move hash types to where they live

801c72e056 Add deprecation comment to hash_types module (Tobin C. Harding)
61351c917f Move impl_asref_push_bytes to internal_macros (Tobin C. Harding)
2b4b66dee3 Move impl_hashencode to internal_macros (Tobin C. Harding)
2a0ac1258a Move the bip158 filter hash types (Tobin C. Harding)
3107f80aac Move transaction hash types (Tobin C. Harding)
61c02ff202 Move block hash types (Tobin C. Harding)

Pull request description:

  Move hash types out of `hash_types` and into the modules where they are primarily used. Adds deprecated re-export so this is not a breaking change.

  Is an alternate solution to #2072

  Resolves: #2072

ACKs for top commit:
  apoelstra:
    ACK 801c72e056
  Kixunil:
    ACK 801c72e056

Tree-SHA512: 4ccac63553de3f7d417213429c0f5c2b7ebc3c2d77a9feb6d4a7daa233565fc62617edf6426a421d251eadc0841235a719bd7fd3f980302c7a2bf3dacb8b4a61
This commit is contained in:
Andrew Poelstra 2023-12-10 00:11:15 +00:00
commit aeb220ddc2
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
14 changed files with 118 additions and 135 deletions

View File

@ -373,10 +373,10 @@ mod test {
use hex::FromHex; use hex::FromHex;
use super::*; use super::*;
use crate::blockdata::block::TxMerkleNode;
use crate::blockdata::locktime::absolute; use crate::blockdata::locktime::absolute;
use crate::blockdata::transaction; use crate::blockdata::transaction;
use crate::consensus::encode::{deserialize, serialize}; use crate::consensus::encode::{deserialize, serialize};
use crate::hash_types::TxMerkleNode;
use crate::{ use crate::{
Amount, CompactTarget, OutPoint, ScriptBuf, Sequence, Transaction, TxIn, TxOut, Txid, Amount, CompactTarget, OutPoint, ScriptBuf, Sequence, Transaction, TxIn, TxOut, Txid,
Witness, Witness,

View File

@ -41,21 +41,31 @@
use core::cmp::{self, Ordering}; use core::cmp::{self, Ordering};
use core::fmt::{self, Display, Formatter}; use core::fmt::{self, Display, Formatter};
use hashes::{siphash24, Hash}; use hashes::{sha256d, siphash24, Hash};
use internals::write_err; use internals::write_err;
use crate::blockdata::block::Block; use crate::blockdata::block::{Block, BlockHash};
use crate::blockdata::script::Script; use crate::blockdata::script::Script;
use crate::blockdata::transaction::OutPoint; use crate::blockdata::transaction::OutPoint;
use crate::consensus::encode::VarInt; use crate::consensus::encode::VarInt;
use crate::consensus::{Decodable, Encodable}; use crate::consensus::{Decodable, Encodable};
use crate::hash_types::{BlockHash, FilterHash, FilterHeader}; use crate::internal_macros::impl_hashencode;
use crate::prelude::*; use crate::prelude::*;
/// Golomb encoding parameter as in BIP-158, see also https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845 /// Golomb encoding parameter as in BIP-158, see also https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845
const P: u8 = 19; const P: u8 = 19;
const M: u64 = 784931; const M: u64 = 784931;
hashes::hash_newtype! {
/// Filter hash, as defined in BIP-157
pub struct FilterHash(sha256d::Hash);
/// Filter header, as defined in BIP-157
pub struct FilterHeader(sha256d::Hash);
}
impl_hashencode!(FilterHash);
impl_hashencode!(FilterHeader);
/// Errors for blockfilter. /// Errors for blockfilter.
#[derive(Debug)] #[derive(Debug)]
#[non_exhaustive] #[non_exhaustive]
@ -554,8 +564,8 @@ mod test {
use serde_json::Value; use serde_json::Value;
use super::*; use super::*;
use crate::blockdata::block::BlockHash;
use crate::consensus::encode::deserialize; use crate::consensus::encode::deserialize;
use crate::hash_types::BlockHash;
use crate::ScriptBuf; use crate::ScriptBuf;
#[test] #[test]

View File

@ -10,23 +10,38 @@
use core::fmt; use core::fmt;
use hashes::{Hash, HashEngine}; use hashes::{sha256d, Hash, HashEngine};
use super::Weight; use super::Weight;
use crate::blockdata::script; use crate::blockdata::script;
use crate::blockdata::transaction::Transaction; use crate::blockdata::transaction::{Transaction, Txid, Wtxid};
use crate::consensus::{encode, Decodable, Encodable}; use crate::consensus::{encode, Decodable, Encodable};
use crate::hash_types::{TxMerkleNode, WitnessCommitment, WitnessMerkleNode, Wtxid}; use crate::internal_macros::{impl_consensus_encoding, impl_hashencode};
use crate::internal_macros::impl_consensus_encoding;
use crate::pow::{CompactTarget, Target, Work}; use crate::pow::{CompactTarget, Target, Work};
use crate::prelude::*; use crate::prelude::*;
use crate::{merkle_tree, Network, VarInt}; use crate::{merkle_tree, Network, VarInt};
#[rustfmt::skip] // Keep public re-exports separate. hashes::hash_newtype! {
#[doc(inline)] /// A bitcoin block hash.
pub use crate::{ pub struct BlockHash(sha256d::Hash);
hash_types::BlockHash, /// A hash of the Merkle tree branch or root for transactions.
}; pub struct TxMerkleNode(sha256d::Hash);
/// A hash corresponding to the Merkle tree root for witness data.
pub struct WitnessMerkleNode(sha256d::Hash);
/// A hash corresponding to the witness structure commitment in the coinbase transaction.
pub struct WitnessCommitment(sha256d::Hash);
}
impl_hashencode!(BlockHash);
impl_hashencode!(TxMerkleNode);
impl_hashencode!(WitnessMerkleNode);
impl From<Txid> for TxMerkleNode {
fn from(txid: Txid) -> Self { Self::from_byte_array(txid.to_byte_array()) }
}
impl From<Wtxid> for WitnessMerkleNode {
fn from(wtxid: Wtxid) -> Self { Self::from_byte_array(wtxid.to_byte_array()) }
}
/// Bitcoin block header. /// Bitcoin block header.
/// ///

View File

@ -72,6 +72,7 @@ use serde;
use crate::blockdata::opcodes::all::*; use crate::blockdata::opcodes::all::*;
use crate::blockdata::opcodes::{self, Opcode}; use crate::blockdata::opcodes::{self, Opcode};
use crate::consensus::{encode, Decodable, Encodable}; use crate::consensus::{encode, Decodable, Encodable};
use crate::internal_macros::impl_asref_push_bytes;
use crate::prelude::*; use crate::prelude::*;
use crate::{io, OutPoint}; use crate::{io, OutPoint};
@ -91,7 +92,7 @@ hashes::hash_newtype! {
/// SegWit version of a Bitcoin Script bytecode hash. /// SegWit version of a Bitcoin Script bytecode hash.
pub struct WScriptHash(sha256::Hash); pub struct WScriptHash(sha256::Hash);
} }
crate::hash_types::impl_asref_push_bytes!(ScriptHash, WScriptHash); impl_asref_push_bytes!(ScriptHash, WScriptHash);
impl From<ScriptBuf> for ScriptHash { impl From<ScriptBuf> for ScriptHash {
fn from(script: ScriptBuf) -> ScriptHash { script.script_hash() } fn from(script: ScriptBuf) -> ScriptHash { script.script_hash() }

View File

@ -23,8 +23,7 @@ use crate::blockdata::locktime::relative;
use crate::blockdata::script::{Script, ScriptBuf}; use crate::blockdata::script::{Script, ScriptBuf};
use crate::blockdata::witness::Witness; use crate::blockdata::witness::Witness;
use crate::consensus::{encode, Decodable, Encodable}; use crate::consensus::{encode, Decodable, Encodable};
use crate::hash_types::{Txid, Wtxid}; use crate::internal_macros::{impl_consensus_encoding, impl_hashencode};
use crate::internal_macros::impl_consensus_encoding;
use crate::parse::impl_parse_str_from_int_infallible; use crate::parse::impl_parse_str_from_int_infallible;
use crate::prelude::*; use crate::prelude::*;
use crate::script::Push; use crate::script::Push;
@ -38,6 +37,21 @@ use crate::{Amount, VarInt};
#[doc(inline)] #[doc(inline)]
pub use crate::consensus::validation::TxVerifyError; pub use crate::consensus::validation::TxVerifyError;
hashes::hash_newtype! {
/// A bitcoin transaction hash/transaction ID.
///
/// For compatibility with the existing Bitcoin infrastructure and historical and current
/// versions of the Bitcoin Core software itself, this and other [`sha256d::Hash`] types, are
/// serialized in reverse byte order when converted to a hex string via [`std::fmt::Display`]
/// trait operations. See [`hashes::Hash::DISPLAY_BACKWARD`] for more details.
pub struct Txid(sha256d::Hash);
/// A bitcoin witness transaction ID.
pub struct Wtxid(sha256d::Hash);
}
impl_hashencode!(Txid);
impl_hashencode!(Wtxid);
/// The marker MUST be a 1-byte zero value: 0x00. (BIP-141) /// The marker MUST be a 1-byte zero value: 0x00. (BIP-141)
const SEGWIT_MARKER: u8 = 0x00; const SEGWIT_MARKER: u8 = 0x00;
/// The flag MUST be a 1-byte non-zero value. Currently, 0x01 MUST be used. (BIP-141) /// The flag MUST be a 1-byte non-zero value. Currently, 0x01 MUST be used. (BIP-141)

View File

@ -23,9 +23,9 @@ use internals::write_err;
use io::{Cursor, Read}; use io::{Cursor, Read};
use crate::bip152::{PrefilledTransaction, ShortId}; use crate::bip152::{PrefilledTransaction, ShortId};
use crate::blockdata::block; use crate::bip158::{FilterHash, FilterHeader};
use crate::blockdata::block::{self, BlockHash, TxMerkleNode};
use crate::blockdata::transaction::{Transaction, TxIn, TxOut}; use crate::blockdata::transaction::{Transaction, TxIn, TxOut};
use crate::hash_types::{BlockHash, FilterHash, FilterHeader, TxMerkleNode};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::p2p::{ use crate::p2p::{
address::{AddrV2Message, Address}, address::{AddrV2Message, Address},

View File

@ -14,6 +14,7 @@ use hex::FromHex;
use internals::write_err; use internals::write_err;
use crate::crypto::ecdsa; use crate::crypto::ecdsa;
use crate::internal_macros::impl_asref_push_bytes;
use crate::network::Network; use crate::network::Network;
use crate::prelude::*; use crate::prelude::*;
use crate::taproot::{TapNodeHash, TapTweakHash}; use crate::taproot::{TapNodeHash, TapTweakHash};
@ -252,7 +253,7 @@ hashes::hash_newtype! {
/// SegWit version of a public key hash. /// SegWit version of a public key hash.
pub struct WPubkeyHash(hash160::Hash); pub struct WPubkeyHash(hash160::Hash);
} }
crate::hash_types::impl_asref_push_bytes!(PubkeyHash, WPubkeyHash); impl_asref_push_bytes!(PubkeyHash, WPubkeyHash);
impl From<PublicKey> for PubkeyHash { impl From<PublicKey> for PubkeyHash {
fn from(key: PublicKey) -> PubkeyHash { key.pubkey_hash() } fn from(key: PublicKey) -> PubkeyHash { key.pubkey_hash() }

View File

@ -2,108 +2,10 @@
//! Bitcoin hash types. //! Bitcoin hash types.
//! //!
//! This module defines types for hashes used throughout the library. These //! This module is deprecated. You can find hash types in their respective, hopefully obvious, modules.
//! types are needed in order to avoid mixing data of the same hash format
//! (e.g. `SHA256d`) but of different meaning (such as transaction id, block
//! hash).
//!
#[rustfmt::skip] #[deprecated(since = "0.0.0-NEXT-RELEASE", note = "use crate::T instead")]
macro_rules! impl_hashencode { pub use crate::{
($hashtype:ident) => { BlockHash, FilterHash, FilterHeader, TxMerkleNode, Txid, WitnessCommitment, WitnessMerkleNode,
impl $crate::consensus::Encodable for $hashtype { Wtxid,
fn consensus_encode<W: $crate::io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, $crate::io::Error> { };
self.0.consensus_encode(w)
}
}
impl $crate::consensus::Decodable for $hashtype {
fn consensus_decode<R: $crate::io::Read + ?Sized>(r: &mut R) -> Result<Self, $crate::consensus::encode::Error> {
use $crate::hashes::Hash;
Ok(Self::from_byte_array(<<$hashtype as $crate::hashes::Hash>::Bytes>::consensus_decode(r)?))
}
}
};
}
#[rustfmt::skip]
macro_rules! impl_asref_push_bytes {
($($hashtype:ident),*) => {
$(
impl AsRef<$crate::blockdata::script::PushBytes> for $hashtype {
fn as_ref(&self) -> &$crate::blockdata::script::PushBytes {
use $crate::hashes::Hash;
self.as_byte_array().into()
}
}
impl From<$hashtype> for $crate::blockdata::script::PushBytesBuf {
fn from(hash: $hashtype) -> Self {
use $crate::hashes::Hash;
hash.as_byte_array().into()
}
}
)*
};
}
pub(crate) use impl_asref_push_bytes;
// newtypes module is solely here so we can rustfmt::skip.
#[rustfmt::skip]
#[doc(inline)]
pub use newtypes::*;
#[rustfmt::skip]
mod newtypes {
use hashes::{sha256d, hash_newtype};
hash_newtype! {
/// A bitcoin transaction hash/transaction ID.
///
/// For compatibility with the existing Bitcoin infrastructure and historical
/// and current versions of the Bitcoin Core software itself, this and
/// other [`sha256d::Hash`] types, are serialized in reverse
/// byte order when converted to a hex string via [`std::fmt::Display`] trait operations.
/// See [`hashes::Hash::DISPLAY_BACKWARD`] for more details.
pub struct Txid(sha256d::Hash);
/// A bitcoin witness transaction ID.
pub struct Wtxid(sha256d::Hash);
/// A bitcoin block hash.
pub struct BlockHash(sha256d::Hash);
/// A hash of the Merkle tree branch or root for transactions
pub struct TxMerkleNode(sha256d::Hash);
/// A hash corresponding to the Merkle tree root for witness data
pub struct WitnessMerkleNode(sha256d::Hash);
/// A hash corresponding to the witness structure commitment in the coinbase transaction
pub struct WitnessCommitment(sha256d::Hash);
/// Filter hash, as defined in BIP-157
pub struct FilterHash(sha256d::Hash);
/// Filter header, as defined in BIP-157
pub struct FilterHeader(sha256d::Hash);
}
impl_hashencode!(Txid);
impl_hashencode!(Wtxid);
impl_hashencode!(BlockHash);
impl_hashencode!(TxMerkleNode);
impl_hashencode!(WitnessMerkleNode);
impl_hashencode!(FilterHash);
impl_hashencode!(FilterHeader);
impl From<Txid> for TxMerkleNode {
fn from(txid: Txid) -> Self {
Self::from(txid.0)
}
}
impl From<Wtxid> for WitnessMerkleNode {
fn from(wtxid: Wtxid) -> Self {
Self::from(wtxid.0)
}
}
}

View File

@ -191,3 +191,44 @@ macro_rules! impl_bytes_newtype {
}; };
} }
pub(crate) use impl_bytes_newtype; pub(crate) use impl_bytes_newtype;
#[rustfmt::skip]
macro_rules! impl_hashencode {
($hashtype:ident) => {
impl $crate::consensus::Encodable for $hashtype {
fn consensus_encode<W: $crate::io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, $crate::io::Error> {
self.0.consensus_encode(w)
}
}
impl $crate::consensus::Decodable for $hashtype {
fn consensus_decode<R: $crate::io::Read + ?Sized>(r: &mut R) -> Result<Self, $crate::consensus::encode::Error> {
use $crate::hashes::Hash;
Ok(Self::from_byte_array(<<$hashtype as $crate::hashes::Hash>::Bytes>::consensus_decode(r)?))
}
}
};
}
pub(crate) use impl_hashencode;
#[rustfmt::skip]
macro_rules! impl_asref_push_bytes {
($($hashtype:ident),*) => {
$(
impl AsRef<$crate::blockdata::script::PushBytes> for $hashtype {
fn as_ref(&self) -> &$crate::blockdata::script::PushBytes {
use $crate::hashes::Hash;
self.as_byte_array().into()
}
}
impl From<$hashtype> for $crate::blockdata::script::PushBytesBuf {
fn from(hash: $hashtype) -> Self {
use $crate::hashes::Hash;
hash.as_byte_array().into()
}
}
)*
};
}
pub(crate) use impl_asref_push_bytes;

View File

@ -116,8 +116,9 @@ pub mod taproot;
pub use crate::{ pub use crate::{
address::{Address, AddressType}, address::{Address, AddressType},
amount::{Amount, Denomination, SignedAmount}, amount::{Amount, Denomination, SignedAmount},
bip158::{FilterHash, FilterHeader},
bip32::XKeyIdentifier, bip32::XKeyIdentifier,
blockdata::block::{self, Block}, blockdata::block::{self, Block, BlockHash, TxMerkleNode, WitnessMerkleNode, WitnessCommitment},
blockdata::constants, blockdata::constants,
blockdata::fee_rate::FeeRate, blockdata::fee_rate::FeeRate,
blockdata::locktime::{self, absolute, relative}, blockdata::locktime::{self, absolute, relative},
@ -125,14 +126,13 @@ pub use crate::{
blockdata::script::witness_program::{self, WitnessProgram}, blockdata::script::witness_program::{self, WitnessProgram},
blockdata::script::witness_version::{self, WitnessVersion}, blockdata::script::witness_version::{self, WitnessVersion},
blockdata::script::{self, Script, ScriptBuf, ScriptHash, WScriptHash}, blockdata::script::{self, Script, ScriptBuf, ScriptHash, WScriptHash},
blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut}, blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut, Txid, Wtxid},
blockdata::weight::Weight, blockdata::weight::Weight,
blockdata::witness::{self, Witness}, blockdata::witness::{self, Witness},
consensus::encode::VarInt, consensus::encode::VarInt,
crypto::ecdsa, crypto::ecdsa,
crypto::key::{self, PrivateKey, PubkeyHash, PublicKey, WPubkeyHash, XOnlyPublicKey}, crypto::key::{self, PrivateKey, PubkeyHash, PublicKey, WPubkeyHash, XOnlyPublicKey},
crypto::sighash::{self, LegacySighash, SegwitV0Sighash, TapSighash, TapSighashTag}, crypto::sighash::{self, LegacySighash, SegwitV0Sighash, TapSighash, TapSighashTag},
hash_types::{BlockHash, FilterHash, FilterHeader, TxMerkleNode, Txid, WitnessCommitment, Wtxid},
merkle_tree::MerkleBlock, merkle_tree::MerkleBlock,
network::Network, network::Network,
pow::{CompactTarget, Target, Work}, pow::{CompactTarget, Target, Work},

View File

@ -43,11 +43,10 @@ use core::fmt;
use hashes::Hash; use hashes::Hash;
use self::MerkleBlockError::*; use self::MerkleBlockError::*;
use crate::blockdata::block::{self, Block}; use crate::blockdata::block::{self, Block, TxMerkleNode};
use crate::blockdata::transaction::Transaction; use crate::blockdata::transaction::{Transaction, Txid};
use crate::blockdata::weight::Weight; use crate::blockdata::weight::Weight;
use crate::consensus::encode::{self, Decodable, Encodable}; use crate::consensus::encode::{self, Decodable, Encodable};
use crate::hash_types::{TxMerkleNode, Txid};
use crate::prelude::*; use crate::prelude::*;
/// Data structure that represents a block header paired to a partial merkle tree. /// Data structure that represents a block header paired to a partial merkle tree.
@ -540,8 +539,6 @@ mod tests {
use super::*; use super::*;
use crate::consensus::encode::{deserialize, serialize}; use crate::consensus::encode::{deserialize, serialize};
#[cfg(feature = "rand-std")]
use crate::hash_types::TxMerkleNode;
use crate::{Block, Txid}; use crate::{Block, Txid};
#[cfg(feature = "rand-std")] #[cfg(feature = "rand-std")]

View File

@ -8,8 +8,9 @@
use hashes::{sha256d, Hash as _}; use hashes::{sha256d, Hash as _};
use crate::blockdata::block::BlockHash;
use crate::blockdata::transaction::{Txid, Wtxid};
use crate::consensus::encode::{self, Decodable, Encodable}; use crate::consensus::encode::{self, Decodable, Encodable};
use crate::hash_types::{BlockHash, Txid, Wtxid};
use crate::internal_macros::impl_consensus_encoding; use crate::internal_macros::impl_consensus_encoding;
use crate::prelude::*; use crate::prelude::*;
use crate::{io, p2p}; use crate::{io, p2p};

View File

@ -5,7 +5,8 @@
//! This module describes BIP157 Client Side Block Filtering network messages. //! This module describes BIP157 Client Side Block Filtering network messages.
//! //!
use crate::hash_types::{BlockHash, FilterHash, FilterHeader}; use crate::bip158::{FilterHash, FilterHeader};
use crate::blockdata::block::BlockHash;
use crate::internal_macros::impl_consensus_encoding; use crate::internal_macros::impl_consensus_encoding;
/// getcfilters message /// getcfilters message

View File

@ -13,10 +13,10 @@ use io::{Read, Write};
#[cfg(all(test, mutate))] #[cfg(all(test, mutate))]
use mutagen::mutate; use mutagen::mutate;
use crate::blockdata::block::BlockHash;
use crate::consensus::encode::{self, Decodable, Encodable}; use crate::consensus::encode::{self, Decodable, Encodable};
#[cfg(doc)] #[cfg(doc)]
use crate::consensus::Params; use crate::consensus::Params;
use crate::hash_types::BlockHash;
use crate::prelude::String; use crate::prelude::String;
use crate::string::FromHexStr; use crate::string::FromHexStr;
use crate::Network; use crate::Network;