Merge rust-bitcoin/rust-bitcoin#3288: priority: Move txid hash types to `primitives`
0403e52ce3
Move the transaction hash types over to primitives (Tobin C. Harding)7e454d756d
Define extension traits for txid types (Tobin C. Harding)832b726d03
Stop using all_zeros (Tobin C. Harding)d69c241b5c
Improve docs on associated consts (Tobin C. Harding)68c9e28165
Do not use private constructor for txid hash types (Tobin C. Harding)98328b5a7b
Use as_byte_array to encode hash type (Tobin C. Harding) Pull request description: Move the `Txid` and `Wtxid` hash wrapper types over to `primitives`. This introduces to `primitves` an unconditional dependency on `hashes`. ACKs for top commit: Kixunil: ACK0403e52ce3
apoelstra: ACK0403e52ce3
successfully ran local tests Tree-SHA512: d14fa95bc12c2399d30d4d640b5a3fce625d51adf587a8037158f7d7e7b6288170b2d4418ca2cb68f612086ea0bdd0fae3b577f84f0d60627072fdb2217a6531
This commit is contained in:
commit
0c2737f25a
|
@ -113,6 +113,7 @@ dependencies = [
|
|||
"bitcoin-internals",
|
||||
"bitcoin-io",
|
||||
"bitcoin-units",
|
||||
"bitcoin_hashes",
|
||||
"mutagen",
|
||||
"ordered",
|
||||
"serde",
|
||||
|
|
|
@ -112,6 +112,7 @@ dependencies = [
|
|||
"bitcoin-internals",
|
||||
"bitcoin-io",
|
||||
"bitcoin-units",
|
||||
"bitcoin_hashes",
|
||||
"mutagen",
|
||||
"ordered",
|
||||
"serde",
|
||||
|
|
|
@ -101,7 +101,7 @@ fn dummy_unspent_transaction_outputs() -> Vec<(OutPoint, TxOut)> {
|
|||
.script_pubkey();
|
||||
|
||||
let out_point_1 = OutPoint {
|
||||
txid: Txid::all_zeros(), // Obviously invalid.
|
||||
txid: Txid::from_byte_array([0xFF; 32]), // Arbitrary invalid dummy value.
|
||||
vout: 0,
|
||||
};
|
||||
|
||||
|
@ -115,7 +115,7 @@ fn dummy_unspent_transaction_outputs() -> Vec<(OutPoint, TxOut)> {
|
|||
.script_pubkey();
|
||||
|
||||
let out_point_2 = OutPoint {
|
||||
txid: Txid::all_zeros(), // Obviously invalid.
|
||||
txid: Txid::from_byte_array([0xFF; 32]), // Arbitrary invalid dummy value.
|
||||
vout: 1,
|
||||
};
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ fn dummy_unspent_transaction_output(wpkh: WPubkeyHash) -> (OutPoint, TxOut) {
|
|||
let script_pubkey = ScriptBuf::new_p2wpkh(wpkh);
|
||||
|
||||
let out_point = OutPoint {
|
||||
txid: Txid::all_zeros(), // Obviously invalid.
|
||||
txid: Txid::from_byte_array([0xFF; 32]), // Arbitrary invalid dummy value.
|
||||
vout: 0,
|
||||
};
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ fn dummy_unspent_transaction_output<C: Verification>(
|
|||
let script_pubkey = ScriptBuf::new_p2tr(secp, internal_key, None);
|
||||
|
||||
let out_point = OutPoint {
|
||||
txid: Txid::all_zeros(), // Obviously invalid.
|
||||
txid: Txid::from_byte_array([0xFF; 32]), // Arbitrary invalid dummy value.
|
||||
vout: 0,
|
||||
};
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ fn dummy_unspent_transaction_outputs() -> Vec<(OutPoint, TxOut)> {
|
|||
.script_pubkey();
|
||||
|
||||
let out_point_1 = OutPoint {
|
||||
txid: Txid::all_zeros(), // Obviously invalid.
|
||||
txid: Txid::from_byte_array([0xFF; 32]), // Arbitrary invalid dummy value.
|
||||
vout: 0,
|
||||
};
|
||||
|
||||
|
@ -125,7 +125,7 @@ fn dummy_unspent_transaction_outputs() -> Vec<(OutPoint, TxOut)> {
|
|||
.script_pubkey();
|
||||
|
||||
let out_point_2 = OutPoint {
|
||||
txid: Txid::all_zeros(), // Obviously invalid.
|
||||
txid: Txid::from_byte_array([0xFF; 32]), // Arbitrary invalid dummy value.
|
||||
vout: 1,
|
||||
};
|
||||
|
||||
|
|
|
@ -305,7 +305,7 @@ impl Block {
|
|||
let hashes = self.txdata.iter().enumerate().map(|(i, t)| {
|
||||
if i == 0 {
|
||||
// Replace the first hash with zeroes.
|
||||
Wtxid::all_zeros()
|
||||
Wtxid::COINBASE
|
||||
} else {
|
||||
t.compute_wtxid()
|
||||
}
|
||||
|
|
|
@ -226,7 +226,7 @@ mod test {
|
|||
|
||||
assert_eq!(gen.version, transaction::Version::ONE);
|
||||
assert_eq!(gen.input.len(), 1);
|
||||
assert_eq!(gen.input[0].previous_output.txid, Txid::all_zeros());
|
||||
assert_eq!(gen.input[0].previous_output.txid, Txid::COINBASE_PREVOUT);
|
||||
assert_eq!(gen.input[0].previous_output.vout, 0xFFFFFFFF);
|
||||
assert_eq!(serialize(&gen.input[0].script_sig),
|
||||
hex!("4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73"));
|
||||
|
|
|
@ -35,47 +35,25 @@ use crate::{Amount, FeeRate, SignedAmount, VarInt};
|
|||
#[doc(inline)]
|
||||
pub use primitives::transaction::*;
|
||||
|
||||
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);
|
||||
|
||||
impl Txid {
|
||||
/// The `Txid` used in a coinbase prevout.
|
||||
///
|
||||
/// This is used as the "txid" of the dummy input of a coinbase transaction. This is not a real
|
||||
/// TXID and should not be used in any other contexts. See [`OutPoint::COINBASE_PREVOUT`].
|
||||
pub const COINBASE_PREVOUT: Self = Self::from_byte_array([0; 32]);
|
||||
|
||||
/// The "all zeros" TXID.
|
||||
#[deprecated(since = "TBD", note = "use Txid::COINBASE_PREVOUT instead")]
|
||||
pub fn all_zeros() -> Self { Self::COINBASE_PREVOUT }
|
||||
crate::internal_macros::define_extension_trait! {
|
||||
/// Extension functionality for the [`Txid`] type.
|
||||
pub trait TxidExt impl for Txid {
|
||||
/// The "all zeros" TXID.
|
||||
#[deprecated(since = "TBD", note = "use Txid::COINBASE_PREVOUT instead")]
|
||||
fn all_zeros() -> Self { Self::COINBASE_PREVOUT }
|
||||
}
|
||||
}
|
||||
|
||||
impl Wtxid {
|
||||
/// The `Wtxid` of a coinbase transaction.
|
||||
///
|
||||
/// This is used as the wTXID for the coinbase transaction when constructing blocks,
|
||||
/// since the coinbase transaction contains a commitment to all transactions' wTXIDs
|
||||
/// but naturally cannot commit to its own. It is not a real wTXID and should not be
|
||||
/// used in other contexts.
|
||||
pub const COINBASE: Self = Self::from_byte_array([0; 32]);
|
||||
|
||||
/// The "all zeros" wTXID.
|
||||
#[deprecated(since = "TBD", note = "use Wtxid::COINBASE instead")]
|
||||
pub fn all_zeros() -> Self { Self::COINBASE }
|
||||
crate::internal_macros::define_extension_trait! {
|
||||
/// Extension functionality for the [`Wtxid`] type.
|
||||
pub trait WtxidExt impl for Wtxid {
|
||||
/// The "all zeros" wTXID.
|
||||
#[deprecated(since = "TBD", note = "use Wtxid::COINBASE instead")]
|
||||
fn all_zeros() -> Self { Self::COINBASE }
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait that abstracts over a transaction identifier i.e., `Txid` and `Wtxid`.
|
||||
|
@ -117,7 +95,7 @@ impl OutPoint {
|
|||
/// The `OutPoint` used in a coinbase prevout.
|
||||
///
|
||||
/// This is used as the dummy input for coinbase transactions because they don't have any
|
||||
/// previous outputs. This is not a real outpoint and should not be used in any other contexts.
|
||||
/// previous outputs. In other words, does not point to a real transaction.
|
||||
pub const COINBASE_PREVOUT: Self = Self { txid: Txid::COINBASE_PREVOUT, vout: u32::MAX };
|
||||
|
||||
/// Creates a new [`OutPoint`].
|
||||
|
@ -583,7 +561,7 @@ impl Transaction {
|
|||
self.input.consensus_encode(&mut enc).expect("engines don't error");
|
||||
self.output.consensus_encode(&mut enc).expect("engines don't error");
|
||||
self.lock_time.consensus_encode(&mut enc).expect("engines don't error");
|
||||
Txid(sha256d::Hash::from_engine(enc))
|
||||
Txid::from_byte_array(sha256d::Hash::from_engine(enc).to_byte_array())
|
||||
}
|
||||
|
||||
/// Computes the segwit version of the transaction id.
|
||||
|
@ -604,7 +582,7 @@ impl Transaction {
|
|||
pub fn compute_wtxid(&self) -> Wtxid {
|
||||
let mut enc = sha256d::Hash::engine();
|
||||
self.consensus_encode(&mut enc).expect("engines don't error");
|
||||
Wtxid(sha256d::Hash::from_engine(enc))
|
||||
Wtxid::from_byte_array(sha256d::Hash::from_engine(enc).to_byte_array())
|
||||
}
|
||||
|
||||
/// Returns the weight of this transaction, as defined by BIP-141.
|
||||
|
|
|
@ -181,7 +181,7 @@ macro_rules! impl_hashencode {
|
|||
($hashtype:ident) => {
|
||||
impl $crate::consensus::Encodable for $hashtype {
|
||||
fn consensus_encode<W: $crate::io::Write + ?Sized>(&self, w: &mut W) -> core::result::Result<usize, $crate::io::Error> {
|
||||
self.0.consensus_encode(w)
|
||||
self.as_byte_array().consensus_encode(w)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
//! # use bitcoin::Txid;
|
||||
//! # use bitcoin::merkle_tree::{MerkleNode as _, TxMerkleNode};
|
||||
//! # use bitcoin::hashes::Hash;
|
||||
//! # let tx1 = Txid::all_zeros(); // Dummy hash values.
|
||||
//! # let tx2 = Txid::all_zeros();
|
||||
//! # let tx1 = Txid::from_byte_array([0xAA; 32]); // Arbitrary dummy hash values.
|
||||
//! # let tx2 = Txid::from_byte_array([0xFF; 32]);
|
||||
//! let tx_hashes = vec![tx1, tx2]; // All the hashes we wish to merkelize.
|
||||
//! let root = TxMerkleNode::calculate_root(tx_hashes.into_iter());
|
||||
//! ```
|
||||
|
|
|
@ -16,11 +16,12 @@ exclude = ["tests", "contrib"]
|
|||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = ["alloc", "internals/std", "io/std", "units/std"]
|
||||
alloc = ["internals/alloc", "io/alloc", "units/alloc"]
|
||||
serde = ["dep:serde", "internals/serde", "units/serde", "alloc"]
|
||||
std = ["alloc", "hashes/std", "internals/std", "io/std", "units/std"]
|
||||
alloc = ["hashes/alloc", "internals/alloc", "io/alloc", "units/alloc"]
|
||||
serde = ["dep:serde", "hashes/serde", "internals/serde", "units/serde", "alloc"]
|
||||
|
||||
[dependencies]
|
||||
hashes = { package = "bitcoin_hashes", version = "0.14.0", default-features = false, features = ["bitcoin-io"] }
|
||||
internals = { package = "bitcoin-internals", version = "0.3.0" }
|
||||
io = { package = "bitcoin-io", version = "0.1.1", default-features = false }
|
||||
units = { package = "bitcoin-units", version = "0.1.0", default-features = false }
|
||||
|
|
|
@ -42,7 +42,11 @@ pub use units::*;
|
|||
#[cfg(feature = "alloc")]
|
||||
pub use self::locktime::{absolute, relative};
|
||||
#[doc(inline)]
|
||||
pub use self::{pow::CompactTarget, sequence::Sequence};
|
||||
pub use self::{
|
||||
pow::CompactTarget,
|
||||
sequence::Sequence,
|
||||
transaction::{Txid, Wtxid},
|
||||
};
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[allow(unused_imports)]
|
||||
|
|
|
@ -12,6 +12,40 @@
|
|||
|
||||
use core::fmt;
|
||||
|
||||
use hashes::sha256d;
|
||||
|
||||
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 Txid {
|
||||
/// The `Txid` used in a coinbase prevout.
|
||||
///
|
||||
/// This is used as the "txid" of the dummy input of a coinbase transaction. This is not a real
|
||||
/// TXID and should not be used in any other contexts. See `OutPoint::COINBASE_PREVOUT`.
|
||||
pub const COINBASE_PREVOUT: Self = Self::from_byte_array([0; 32]);
|
||||
}
|
||||
|
||||
impl Wtxid {
|
||||
/// The `Wtxid` of a coinbase transaction.
|
||||
///
|
||||
/// This is used as the wTXID for the coinbase transaction when constructing blocks (in the
|
||||
/// witness commitment tree) since the coinbase transaction contains a commitment to all
|
||||
/// transactions' wTXIDs but naturally cannot commit to its own.
|
||||
pub const COINBASE: Self = Self::from_byte_array([0; 32]);
|
||||
}
|
||||
|
||||
/// The transaction version.
|
||||
///
|
||||
/// Currently, as specified by [BIP-68], only version 1 and 2 are considered standard.
|
||||
|
|
Loading…
Reference in New Issue