Merge rust-bitcoin/rust-bitcoin#3401: Move the `block` hash types over to `primitives`
2d8c613340
Move the block hash types to primitives (Tobin C. Harding)6b9429ac7b
Remove BlockHash::all_zeros (Tobin C. Harding)20d8dbd586
Add missing line of whitespace (Tobin C. Harding) Pull request description: As an initial step in moving the `block` module, just move over the hash types `BlockHash` and `WitnessCommitment`. Patch 2 introduces an associated const `BlockHash::GENESIS_PREV_BLOCKHASH` and removes `all_zeros`. ACKs for top commit: apoelstra: ACK2d8c613340
successfully ran local tests Tree-SHA512: 64aa0ae81e1c8ab1b5d4cd8cd28e6ef04ed01bf79175dc5b1fd607a6f0967e06b0aaf4c10ad368e2b327edcad3705187b6643d5ca8647716319424f19a838ba1
This commit is contained in:
commit
0b5e0bac31
|
@ -497,7 +497,7 @@ mod test {
|
||||||
{
|
{
|
||||||
// test serialization
|
// test serialization
|
||||||
let raw: Vec<u8> = serialize(&BlockTransactionsRequest {
|
let raw: Vec<u8> = serialize(&BlockTransactionsRequest {
|
||||||
block_hash: BlockHash::all_zeros(),
|
block_hash: BlockHash::from_byte_array([0; 32]),
|
||||||
indexes: testcase.1,
|
indexes: testcase.1,
|
||||||
});
|
});
|
||||||
let mut expected_raw: Vec<u8> = [0u8; 32].to_vec();
|
let mut expected_raw: Vec<u8> = [0u8; 32].to_vec();
|
||||||
|
@ -520,7 +520,7 @@ mod test {
|
||||||
#[should_panic] // 'attempt to add with overflow' in consensus_encode()
|
#[should_panic] // 'attempt to add with overflow' in consensus_encode()
|
||||||
fn test_getblocktx_panic_when_encoding_u64_max() {
|
fn test_getblocktx_panic_when_encoding_u64_max() {
|
||||||
serialize(&BlockTransactionsRequest {
|
serialize(&BlockTransactionsRequest {
|
||||||
block_hash: BlockHash::all_zeros(),
|
block_hash: BlockHash::from_byte_array([0; 32]),
|
||||||
indexes: vec![u64::MAX],
|
indexes: vec![u64::MAX],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,20 +23,11 @@ use crate::prelude::Vec;
|
||||||
use crate::script::{self, ScriptExt as _};
|
use crate::script::{self, ScriptExt as _};
|
||||||
use crate::transaction::{Transaction, Wtxid};
|
use crate::transaction::{Transaction, Wtxid};
|
||||||
|
|
||||||
hashes::hash_newtype! {
|
#[rustfmt::skip] // Keep public re-exports separate.
|
||||||
/// A bitcoin block hash.
|
#[doc(inline)]
|
||||||
pub struct BlockHash(sha256d::Hash);
|
pub use primitives::block::*;
|
||||||
/// A hash corresponding to the witness structure commitment in the coinbase transaction.
|
|
||||||
pub struct WitnessCommitment(sha256d::Hash);
|
|
||||||
}
|
|
||||||
impl_hashencode!(BlockHash);
|
impl_hashencode!(BlockHash);
|
||||||
impl BlockHash {
|
|
||||||
/// The "all zeros" blockhash.
|
|
||||||
///
|
|
||||||
/// This is not the hash of a real block. It is used as the previous blockhash
|
|
||||||
/// of the genesis block and in other placeholder contexts.
|
|
||||||
pub fn all_zeros() -> Self { Self::from_byte_array([0; 32]) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Bitcoin block header.
|
/// Bitcoin block header.
|
||||||
///
|
///
|
||||||
|
@ -76,7 +67,7 @@ impl Header {
|
||||||
pub fn block_hash(&self) -> BlockHash {
|
pub fn block_hash(&self) -> BlockHash {
|
||||||
let mut engine = sha256d::Hash::engine();
|
let mut engine = sha256d::Hash::engine();
|
||||||
self.consensus_encode(&mut engine).expect("engines don't error");
|
self.consensus_encode(&mut engine).expect("engines don't error");
|
||||||
BlockHash(sha256d::Hash::from_engine(engine))
|
BlockHash::from_byte_array(sha256d::Hash::from_engine(engine).to_byte_array())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the target (range [0, T] inclusive) that a blockhash must land in to be valid.
|
/// Computes the target (range [0, T] inclusive) that a blockhash must land in to be valid.
|
||||||
|
@ -298,7 +289,7 @@ impl Block {
|
||||||
let mut encoder = sha256d::Hash::engine();
|
let mut encoder = sha256d::Hash::engine();
|
||||||
witness_root.consensus_encode(&mut encoder).expect("engines don't error");
|
witness_root.consensus_encode(&mut encoder).expect("engines don't error");
|
||||||
encoder.input(witness_reserved_value);
|
encoder.input(witness_reserved_value);
|
||||||
WitnessCommitment(sha256d::Hash::from_engine(encoder))
|
WitnessCommitment::from_byte_array(sha256d::Hash::from_engine(encoder).to_byte_array())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the Merkle root of transactions hashed for witness.
|
/// Computes the Merkle root of transactions hashed for witness.
|
||||||
|
|
|
@ -113,7 +113,7 @@ pub fn genesis_block(params: impl AsRef<Params>) -> Block {
|
||||||
Network::Bitcoin => Block {
|
Network::Bitcoin => Block {
|
||||||
header: block::Header {
|
header: block::Header {
|
||||||
version: block::Version::ONE,
|
version: block::Version::ONE,
|
||||||
prev_blockhash: BlockHash::all_zeros(),
|
prev_blockhash: BlockHash::GENESIS_PREVIOUS_BLOCK_HASH,
|
||||||
merkle_root,
|
merkle_root,
|
||||||
time: 1231006505,
|
time: 1231006505,
|
||||||
bits: CompactTarget::from_consensus(0x1d00ffff),
|
bits: CompactTarget::from_consensus(0x1d00ffff),
|
||||||
|
@ -124,7 +124,7 @@ pub fn genesis_block(params: impl AsRef<Params>) -> Block {
|
||||||
Network::Testnet => Block {
|
Network::Testnet => Block {
|
||||||
header: block::Header {
|
header: block::Header {
|
||||||
version: block::Version::ONE,
|
version: block::Version::ONE,
|
||||||
prev_blockhash: BlockHash::all_zeros(),
|
prev_blockhash: BlockHash::GENESIS_PREVIOUS_BLOCK_HASH,
|
||||||
merkle_root,
|
merkle_root,
|
||||||
time: 1296688602,
|
time: 1296688602,
|
||||||
bits: CompactTarget::from_consensus(0x1d00ffff),
|
bits: CompactTarget::from_consensus(0x1d00ffff),
|
||||||
|
@ -135,7 +135,7 @@ pub fn genesis_block(params: impl AsRef<Params>) -> Block {
|
||||||
Network::Signet => Block {
|
Network::Signet => Block {
|
||||||
header: block::Header {
|
header: block::Header {
|
||||||
version: block::Version::ONE,
|
version: block::Version::ONE,
|
||||||
prev_blockhash: BlockHash::all_zeros(),
|
prev_blockhash: BlockHash::GENESIS_PREVIOUS_BLOCK_HASH,
|
||||||
merkle_root,
|
merkle_root,
|
||||||
time: 1598918400,
|
time: 1598918400,
|
||||||
bits: CompactTarget::from_consensus(0x1e0377ae),
|
bits: CompactTarget::from_consensus(0x1e0377ae),
|
||||||
|
@ -146,7 +146,7 @@ pub fn genesis_block(params: impl AsRef<Params>) -> Block {
|
||||||
Network::Regtest => Block {
|
Network::Regtest => Block {
|
||||||
header: block::Header {
|
header: block::Header {
|
||||||
version: block::Version::ONE,
|
version: block::Version::ONE,
|
||||||
prev_blockhash: BlockHash::all_zeros(),
|
prev_blockhash: BlockHash::GENESIS_PREVIOUS_BLOCK_HASH,
|
||||||
merkle_root,
|
merkle_root,
|
||||||
time: 1296688602,
|
time: 1296688602,
|
||||||
bits: CompactTarget::from_consensus(0x207fffff),
|
bits: CompactTarget::from_consensus(0x207fffff),
|
||||||
|
@ -261,7 +261,7 @@ mod test {
|
||||||
let gen = genesis_block(¶ms::MAINNET);
|
let gen = genesis_block(¶ms::MAINNET);
|
||||||
|
|
||||||
assert_eq!(gen.header.version, block::Version::ONE);
|
assert_eq!(gen.header.version, block::Version::ONE);
|
||||||
assert_eq!(gen.header.prev_blockhash, BlockHash::all_zeros());
|
assert_eq!(gen.header.prev_blockhash, BlockHash::GENESIS_PREVIOUS_BLOCK_HASH);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
gen.header.merkle_root.to_string(),
|
gen.header.merkle_root.to_string(),
|
||||||
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
||||||
|
@ -280,7 +280,7 @@ mod test {
|
||||||
fn testnet_genesis_full_block() {
|
fn testnet_genesis_full_block() {
|
||||||
let gen = genesis_block(¶ms::TESTNET);
|
let gen = genesis_block(¶ms::TESTNET);
|
||||||
assert_eq!(gen.header.version, block::Version::ONE);
|
assert_eq!(gen.header.version, block::Version::ONE);
|
||||||
assert_eq!(gen.header.prev_blockhash, BlockHash::all_zeros());
|
assert_eq!(gen.header.prev_blockhash, BlockHash::GENESIS_PREVIOUS_BLOCK_HASH);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
gen.header.merkle_root.to_string(),
|
gen.header.merkle_root.to_string(),
|
||||||
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
||||||
|
@ -298,7 +298,7 @@ mod test {
|
||||||
fn signet_genesis_full_block() {
|
fn signet_genesis_full_block() {
|
||||||
let gen = genesis_block(¶ms::SIGNET);
|
let gen = genesis_block(¶ms::SIGNET);
|
||||||
assert_eq!(gen.header.version, block::Version::ONE);
|
assert_eq!(gen.header.version, block::Version::ONE);
|
||||||
assert_eq!(gen.header.prev_blockhash, BlockHash::all_zeros());
|
assert_eq!(gen.header.prev_blockhash, BlockHash::GENESIS_PREVIOUS_BLOCK_HASH);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
gen.header.merkle_root.to_string(),
|
gen.header.merkle_root.to_string(),
|
||||||
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
||||||
|
|
|
@ -159,7 +159,7 @@ mod tests {
|
||||||
assert_eq!(real_decode.version, 70002);
|
assert_eq!(real_decode.version, 70002);
|
||||||
assert_eq!(real_decode.locator_hashes.len(), 1);
|
assert_eq!(real_decode.locator_hashes.len(), 1);
|
||||||
assert_eq!(serialize(&real_decode.locator_hashes[0]), genhash);
|
assert_eq!(serialize(&real_decode.locator_hashes[0]), genhash);
|
||||||
assert_eq!(real_decode.stop_hash, BlockHash::all_zeros());
|
assert_eq!(real_decode.stop_hash, BlockHash::GENESIS_PREVIOUS_BLOCK_HASH);
|
||||||
|
|
||||||
assert_eq!(serialize(&real_decode), from_sat);
|
assert_eq!(serialize(&real_decode), from_sat);
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ mod tests {
|
||||||
assert_eq!(real_decode.version, 70002);
|
assert_eq!(real_decode.version, 70002);
|
||||||
assert_eq!(real_decode.locator_hashes.len(), 1);
|
assert_eq!(real_decode.locator_hashes.len(), 1);
|
||||||
assert_eq!(serialize(&real_decode.locator_hashes[0]), genhash);
|
assert_eq!(serialize(&real_decode.locator_hashes[0]), genhash);
|
||||||
assert_eq!(real_decode.stop_hash, BlockHash::all_zeros());
|
assert_eq!(real_decode.stop_hash, BlockHash::GENESIS_PREVIOUS_BLOCK_HASH);
|
||||||
|
|
||||||
assert_eq!(serialize(&real_decode), from_sat);
|
assert_eq!(serialize(&real_decode), from_sat);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1771,7 +1771,7 @@ mod tests {
|
||||||
// Block 2015, the only information used are `bits` and `time`
|
// Block 2015, the only information used are `bits` and `time`
|
||||||
let current = Header {
|
let current = Header {
|
||||||
version: Version::ONE,
|
version: Version::ONE,
|
||||||
prev_blockhash: BlockHash::all_zeros(),
|
prev_blockhash: BlockHash::from_byte_array([0; 32]),
|
||||||
merkle_root: TxMerkleNode::from_byte_array([0; 32]),
|
merkle_root: TxMerkleNode::from_byte_array([0; 32]),
|
||||||
time: 1599332177,
|
time: 1599332177,
|
||||||
bits: epoch_start.bits,
|
bits: epoch_start.bits,
|
||||||
|
@ -1793,7 +1793,7 @@ mod tests {
|
||||||
// Block 2016, the only information used is `time`
|
// Block 2016, the only information used is `time`
|
||||||
let epoch_start = Header {
|
let epoch_start = Header {
|
||||||
version: Version::ONE,
|
version: Version::ONE,
|
||||||
prev_blockhash: BlockHash::all_zeros(),
|
prev_blockhash: BlockHash::from_byte_array([0; 32]),
|
||||||
merkle_root: TxMerkleNode::from_byte_array([0; 32]),
|
merkle_root: TxMerkleNode::from_byte_array([0; 32]),
|
||||||
time: 1599332844,
|
time: 1599332844,
|
||||||
bits: starting_bits,
|
bits: starting_bits,
|
||||||
|
@ -1803,7 +1803,7 @@ mod tests {
|
||||||
// Block 4031, the only information used are `bits` and `time`
|
// Block 4031, the only information used are `bits` and `time`
|
||||||
let current = Header {
|
let current = Header {
|
||||||
version: Version::ONE,
|
version: Version::ONE,
|
||||||
prev_blockhash: BlockHash::all_zeros(),
|
prev_blockhash: BlockHash::from_byte_array([0; 32]),
|
||||||
merkle_root: TxMerkleNode::from_byte_array([0; 32]),
|
merkle_root: TxMerkleNode::from_byte_array([0; 32]),
|
||||||
time: 1600591200,
|
time: 1600591200,
|
||||||
bits: starting_bits,
|
bits: starting_bits,
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
//! Bitcoin blocks.
|
||||||
|
//!
|
||||||
|
//! A block is a bundle of transactions with a proof-of-work attached,
|
||||||
|
//! which commits to an earlier block to form the blockchain. This
|
||||||
|
//! module describes structures and functions needed to describe
|
||||||
|
//! these blocks and the blockchain.
|
||||||
|
|
||||||
|
use hashes::sha256d;
|
||||||
|
|
||||||
|
hashes::hash_newtype! {
|
||||||
|
/// A bitcoin block hash.
|
||||||
|
pub struct BlockHash(sha256d::Hash);
|
||||||
|
/// A hash corresponding to the witness structure commitment in the coinbase transaction.
|
||||||
|
pub struct WitnessCommitment(sha256d::Hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockHash {
|
||||||
|
/// Dummy hash used as the previous blockhash of the genesis block.
|
||||||
|
pub const GENESIS_PREVIOUS_BLOCK_HASH: Self = Self::from_byte_array([0; 32]);
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ extern crate std;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
|
||||||
|
pub mod block;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub mod locktime;
|
pub mod locktime;
|
||||||
pub mod opcodes;
|
pub mod opcodes;
|
||||||
|
@ -45,6 +46,7 @@ pub use units::*;
|
||||||
pub use self::locktime::{absolute, relative};
|
pub use self::locktime::{absolute, relative};
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use self::{
|
pub use self::{
|
||||||
|
block::{BlockHash, WitnessCommitment},
|
||||||
pow::CompactTarget,
|
pow::CompactTarget,
|
||||||
sequence::Sequence,
|
sequence::Sequence,
|
||||||
transaction::{Txid, Wtxid},
|
transaction::{Txid, Wtxid},
|
||||||
|
|
Loading…
Reference in New Issue