New HashTypes defined according to #284 (WIP), Txid is completed
This commit is contained in:
parent
e2caebc42e
commit
ec92a05682
|
@ -112,7 +112,7 @@ impl Block {
|
||||||
|
|
||||||
impl MerkleRoot for Block {
|
impl MerkleRoot for Block {
|
||||||
fn merkle_root(&self) -> sha256d::Hash {
|
fn merkle_root(&self) -> sha256d::Hash {
|
||||||
bitcoin_merkle_root(self.txdata.iter().map(|obj| obj.txid()).collect())
|
bitcoin_merkle_root(self.txdata.iter().map(|obj| obj.txid().into()).collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,14 +96,15 @@ fn bitcoin_genesis_tx() -> Transaction {
|
||||||
|
|
||||||
/// Constructs and returns the genesis block
|
/// Constructs and returns the genesis block
|
||||||
pub fn genesis_block(network: Network) -> Block {
|
pub fn genesis_block(network: Network) -> Block {
|
||||||
|
let txdata = vec![bitcoin_genesis_tx()];
|
||||||
|
let merkle_root = txdata[0].txid().into();
|
||||||
match network {
|
match network {
|
||||||
Network::Bitcoin => {
|
Network::Bitcoin => {
|
||||||
let txdata = vec![bitcoin_genesis_tx()];
|
|
||||||
Block {
|
Block {
|
||||||
header: BlockHeader {
|
header: BlockHeader {
|
||||||
version: 1,
|
version: 1,
|
||||||
prev_blockhash: Default::default(),
|
prev_blockhash: Default::default(),
|
||||||
merkle_root: txdata[0].txid(),
|
merkle_root,
|
||||||
time: 1231006505,
|
time: 1231006505,
|
||||||
bits: 0x1d00ffff,
|
bits: 0x1d00ffff,
|
||||||
nonce: 2083236893
|
nonce: 2083236893
|
||||||
|
@ -112,12 +113,11 @@ pub fn genesis_block(network: Network) -> Block {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Network::Testnet => {
|
Network::Testnet => {
|
||||||
let txdata = vec![bitcoin_genesis_tx()];
|
|
||||||
Block {
|
Block {
|
||||||
header: BlockHeader {
|
header: BlockHeader {
|
||||||
version: 1,
|
version: 1,
|
||||||
prev_blockhash: Default::default(),
|
prev_blockhash: Default::default(),
|
||||||
merkle_root: txdata[0].txid(),
|
merkle_root,
|
||||||
time: 1296688602,
|
time: 1296688602,
|
||||||
bits: 0x1d00ffff,
|
bits: 0x1d00ffff,
|
||||||
nonce: 414098458
|
nonce: 414098458
|
||||||
|
@ -126,12 +126,11 @@ pub fn genesis_block(network: Network) -> Block {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Network::Regtest => {
|
Network::Regtest => {
|
||||||
let txdata = vec![bitcoin_genesis_tx()];
|
|
||||||
Block {
|
Block {
|
||||||
header: BlockHeader {
|
header: BlockHeader {
|
||||||
version: 1,
|
version: 1,
|
||||||
prev_blockhash: Default::default(),
|
prev_blockhash: Default::default(),
|
||||||
merkle_root: txdata[0].txid(),
|
merkle_root,
|
||||||
time: 1296688602,
|
time: 1296688602,
|
||||||
bits: 0x207fffff,
|
bits: 0x207fffff,
|
||||||
nonce: 2
|
nonce: 2
|
||||||
|
|
|
@ -34,13 +34,14 @@ use util::hash::BitcoinHash;
|
||||||
#[cfg(feature="bitcoinconsensus")] use blockdata::script;
|
#[cfg(feature="bitcoinconsensus")] use blockdata::script;
|
||||||
use blockdata::script::Script;
|
use blockdata::script::Script;
|
||||||
use consensus::{encode, serialize, Decodable, Encodable};
|
use consensus::{encode, serialize, Decodable, Encodable};
|
||||||
|
use hash_types::*;
|
||||||
use VarInt;
|
use VarInt;
|
||||||
|
|
||||||
/// A reference to a transaction output
|
/// A reference to a transaction output
|
||||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct OutPoint {
|
pub struct OutPoint {
|
||||||
/// The referenced transaction's txid
|
/// The referenced transaction's txid
|
||||||
pub txid: sha256d::Hash,
|
pub txid: Txid,
|
||||||
/// The index of the referenced output in its transaction's vout
|
/// The index of the referenced output in its transaction's vout
|
||||||
pub vout: u32,
|
pub vout: u32,
|
||||||
}
|
}
|
||||||
|
@ -49,7 +50,7 @@ serde_struct_human_string_impl!(OutPoint, "an OutPoint", txid, vout);
|
||||||
impl OutPoint {
|
impl OutPoint {
|
||||||
/// Create a new [OutPoint].
|
/// Create a new [OutPoint].
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(txid: sha256d::Hash, vout: u32) -> OutPoint {
|
pub fn new(txid: Txid, vout: u32) -> OutPoint {
|
||||||
OutPoint {
|
OutPoint {
|
||||||
txid: txid,
|
txid: txid,
|
||||||
vout: vout,
|
vout: vout,
|
||||||
|
@ -175,7 +176,7 @@ impl ::std::str::FromStr for OutPoint {
|
||||||
return Err(ParseOutPointError::Format);
|
return Err(ParseOutPointError::Format);
|
||||||
}
|
}
|
||||||
Ok(OutPoint {
|
Ok(OutPoint {
|
||||||
txid: sha256d::Hash::from_hex(&s[..colon]).map_err(ParseOutPointError::Txid)?,
|
txid: Txid::from_hex(&s[..colon]).map_err(ParseOutPointError::Txid)?,
|
||||||
vout: parse_vout(&s[colon+1..])?,
|
vout: parse_vout(&s[colon+1..])?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -293,13 +294,13 @@ impl Transaction {
|
||||||
/// to the output of `BitcoinHash::bitcoin_hash()`, but for segwit transactions,
|
/// to the output of `BitcoinHash::bitcoin_hash()`, but for segwit transactions,
|
||||||
/// this will give the correct txid (not including witnesses) while `bitcoin_hash`
|
/// this will give the correct txid (not including witnesses) while `bitcoin_hash`
|
||||||
/// will also hash witnesses.
|
/// will also hash witnesses.
|
||||||
pub fn txid(&self) -> sha256d::Hash {
|
pub fn txid(&self) -> Txid {
|
||||||
let mut enc = sha256d::Hash::engine();
|
let mut enc = sha256d::Hash::engine();
|
||||||
self.version.consensus_encode(&mut enc).unwrap();
|
self.version.consensus_encode(&mut enc).unwrap();
|
||||||
self.input.consensus_encode(&mut enc).unwrap();
|
self.input.consensus_encode(&mut enc).unwrap();
|
||||||
self.output.consensus_encode(&mut enc).unwrap();
|
self.output.consensus_encode(&mut enc).unwrap();
|
||||||
self.lock_time.consensus_encode(&mut enc).unwrap();
|
self.lock_time.consensus_encode(&mut enc).unwrap();
|
||||||
sha256d::Hash::from_engine(enc)
|
Txid::from_engine(enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a signature hash for a given input index with a given sighash flag.
|
/// Computes a signature hash for a given input index with a given sighash flag.
|
||||||
|
@ -630,6 +631,8 @@ mod tests {
|
||||||
use hashes::{sha256d, Hash};
|
use hashes::{sha256d, Hash};
|
||||||
use hashes::hex::FromHex;
|
use hashes::hex::FromHex;
|
||||||
|
|
||||||
|
use hash_types::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_outpoint() {
|
fn test_outpoint() {
|
||||||
assert_eq!(OutPoint::from_str("i don't care"),
|
assert_eq!(OutPoint::from_str("i don't care"),
|
||||||
|
@ -645,20 +648,20 @@ mod tests {
|
||||||
assert_eq!(OutPoint::from_str("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:+42"),
|
assert_eq!(OutPoint::from_str("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:+42"),
|
||||||
Err(ParseOutPointError::VoutNotCanonical));
|
Err(ParseOutPointError::VoutNotCanonical));
|
||||||
assert_eq!(OutPoint::from_str("i don't care:1"),
|
assert_eq!(OutPoint::from_str("i don't care:1"),
|
||||||
Err(ParseOutPointError::Txid(sha256d::Hash::from_hex("i don't care").unwrap_err())));
|
Err(ParseOutPointError::Txid(Txid::from_hex("i don't care").unwrap_err())));
|
||||||
assert_eq!(OutPoint::from_str("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c945X:1"),
|
assert_eq!(OutPoint::from_str("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c945X:1"),
|
||||||
Err(ParseOutPointError::Txid(sha256d::Hash::from_hex("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c945X").unwrap_err())));
|
Err(ParseOutPointError::Txid(Txid::from_hex("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c945X").unwrap_err())));
|
||||||
assert_eq!(OutPoint::from_str("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:lol"),
|
assert_eq!(OutPoint::from_str("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:lol"),
|
||||||
Err(ParseOutPointError::Vout(u32::from_str("lol").unwrap_err())));
|
Err(ParseOutPointError::Vout(u32::from_str("lol").unwrap_err())));
|
||||||
|
|
||||||
assert_eq!(OutPoint::from_str("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:42"),
|
assert_eq!(OutPoint::from_str("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:42"),
|
||||||
Ok(OutPoint{
|
Ok(OutPoint{
|
||||||
txid: sha256d::Hash::from_hex("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456").unwrap(),
|
txid: Txid::from_hex("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456").unwrap(),
|
||||||
vout: 42,
|
vout: 42,
|
||||||
}));
|
}));
|
||||||
assert_eq!(OutPoint::from_str("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:0"),
|
assert_eq!(OutPoint::from_str("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:0"),
|
||||||
Ok(OutPoint{
|
Ok(OutPoint{
|
||||||
txid: sha256d::Hash::from_hex("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456").unwrap(),
|
txid: Txid::from_hex("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456").unwrap(),
|
||||||
vout: 0,
|
vout: 0,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Rust Bitcoin Library
|
||||||
|
// Written in 2014 by
|
||||||
|
// Andrew Poelstra <apoelstra@wpsoftware.net>
|
||||||
|
//
|
||||||
|
// To the extent possible under law, the author(s) have dedicated all
|
||||||
|
// copyright and related and neighboring rights to this software to
|
||||||
|
// the public domain worldwide. This software is distributed without
|
||||||
|
// any warranty.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the CC0 Public Domain Dedication
|
||||||
|
// along with this software.
|
||||||
|
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
//! File defines types for hashes used throughout the library. These types are needed in order
|
||||||
|
//! to avoid mixing data of the same hash format (like SHA256d) but of different meaning
|
||||||
|
//! (transaction id, block hash etc).
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
use consensus::encode::{Encodable, Decodable, Error};
|
||||||
|
use hashes::{sha256, sha256d, hash160, Hash};
|
||||||
|
use hashes::hex::{ToHex, FromHex};
|
||||||
|
|
||||||
|
macro_rules! impl_hashencode {
|
||||||
|
($hashtype:ident) => {
|
||||||
|
impl Encodable for $hashtype {
|
||||||
|
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, Error> {
|
||||||
|
self.0.consensus_encode(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for $hashtype {
|
||||||
|
fn consensus_decode<D: io::Read>(d: D) -> Result<Self, Error> {
|
||||||
|
let inner = <<$hashtype as Hash>::Inner>::consensus_decode(d)?;
|
||||||
|
Ok(Self::from_slice(&inner).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_newtype!(Txid, sha256d::Hash, 32, doc="A bitcoin transaction hash/transaction ID.");
|
||||||
|
hash_newtype!(Wtxid, sha256d::Hash, 32, doc="A bitcoin witness transaction ID.");
|
||||||
|
hash_newtype!(BlockHash, sha256d::Hash, 32, doc="A bitcoin block hash.");
|
||||||
|
hash_newtype!(PubkeyHash, hash160::Hash, 20, doc="A hash of a public key.");
|
||||||
|
hash_newtype!(ScriptHash, hash160::Hash, 20, doc="A hash of Bitcoin Script bytecode.");
|
||||||
|
hash_newtype!(WPubkeyHash, hash160::Hash, 20, doc="SegWit version of a public key hash.");
|
||||||
|
hash_newtype!(WScriptHash, sha256::Hash, 32, doc="SegWit version of a Bitcoin Script bytecode hash.");
|
||||||
|
hash_newtype!(XpubIdentifier, hash160::Hash, 20, doc="XpubIdentifier as defined in BIP-32.");
|
||||||
|
|
||||||
|
impl_hashencode!(Txid);
|
|
@ -52,7 +52,7 @@
|
||||||
#![allow(ellipsis_inclusive_range_patterns)]
|
#![allow(ellipsis_inclusive_range_patterns)]
|
||||||
|
|
||||||
// Re-exported dependencies.
|
// Re-exported dependencies.
|
||||||
pub extern crate bitcoin_hashes as hashes;
|
#[macro_use] pub extern crate bitcoin_hashes as hashes;
|
||||||
pub extern crate secp256k1;
|
pub extern crate secp256k1;
|
||||||
pub extern crate bech32;
|
pub extern crate bech32;
|
||||||
|
|
||||||
|
@ -77,7 +77,10 @@ pub mod network;
|
||||||
pub mod blockdata;
|
pub mod blockdata;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod consensus;
|
pub mod consensus;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
pub mod hash_types;
|
||||||
|
|
||||||
|
pub use hash_types::*;
|
||||||
pub use blockdata::block::Block;
|
pub use blockdata::block::Block;
|
||||||
pub use blockdata::block::BlockHeader;
|
pub use blockdata::block::BlockHeader;
|
||||||
pub use blockdata::script::Script;
|
pub use blockdata::script::Script;
|
||||||
|
|
|
@ -163,7 +163,7 @@ impl Decodable for PartiallySignedTransaction {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use hashes::hex::FromHex;
|
use hashes::hex::FromHex;
|
||||||
use hashes::sha256d;
|
use hash_types::Txid;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ mod tests {
|
||||||
lock_time: 1257139,
|
lock_time: 1257139,
|
||||||
input: vec![TxIn {
|
input: vec![TxIn {
|
||||||
previous_output: OutPoint {
|
previous_output: OutPoint {
|
||||||
txid: sha256d::Hash::from_hex(
|
txid: Txid::from_hex(
|
||||||
"f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126",
|
"f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126",
|
||||||
).unwrap(),
|
).unwrap(),
|
||||||
vout: 0,
|
vout: 0,
|
||||||
|
@ -315,7 +315,7 @@ mod tests {
|
||||||
use hex::decode as hex_decode;
|
use hex::decode as hex_decode;
|
||||||
|
|
||||||
use hashes::hex::FromHex;
|
use hashes::hex::FromHex;
|
||||||
use hashes::sha256d;
|
use hash_types::Txid;
|
||||||
|
|
||||||
use blockdata::script::Script;
|
use blockdata::script::Script;
|
||||||
use blockdata::transaction::{SigHashType, Transaction, TxIn, TxOut, OutPoint};
|
use blockdata::transaction::{SigHashType, Transaction, TxIn, TxOut, OutPoint};
|
||||||
|
@ -363,7 +363,7 @@ mod tests {
|
||||||
lock_time: 1257139,
|
lock_time: 1257139,
|
||||||
input: vec![TxIn {
|
input: vec![TxIn {
|
||||||
previous_output: OutPoint {
|
previous_output: OutPoint {
|
||||||
txid: sha256d::Hash::from_hex(
|
txid: Txid::from_hex(
|
||||||
"f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126",
|
"f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126",
|
||||||
).unwrap(),
|
).unwrap(),
|
||||||
vout: 0,
|
vout: 0,
|
||||||
|
@ -391,7 +391,7 @@ mod tests {
|
||||||
lock_time: 0,
|
lock_time: 0,
|
||||||
input: vec![TxIn {
|
input: vec![TxIn {
|
||||||
previous_output: OutPoint {
|
previous_output: OutPoint {
|
||||||
txid: sha256d::Hash::from_hex(
|
txid: Txid::from_hex(
|
||||||
"e567952fb6cc33857f392efa3a46c995a28f69cca4bb1b37e0204dab1ec7a389",
|
"e567952fb6cc33857f392efa3a46c995a28f69cca4bb1b37e0204dab1ec7a389",
|
||||||
).unwrap(),
|
).unwrap(),
|
||||||
vout: 1,
|
vout: 1,
|
||||||
|
@ -405,7 +405,7 @@ mod tests {
|
||||||
},
|
},
|
||||||
TxIn {
|
TxIn {
|
||||||
previous_output: OutPoint {
|
previous_output: OutPoint {
|
||||||
txid: sha256d::Hash::from_hex(
|
txid: Txid::from_hex(
|
||||||
"b490486aec3ae671012dddb2bb08466bef37720a533a894814ff1da743aaf886",
|
"b490486aec3ae671012dddb2bb08466bef37720a533a894814ff1da743aaf886",
|
||||||
).unwrap(),
|
).unwrap(),
|
||||||
vout: 1,
|
vout: 1,
|
||||||
|
@ -548,7 +548,7 @@ mod tests {
|
||||||
let tx = &psbt.global.unsigned_tx;
|
let tx = &psbt.global.unsigned_tx;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tx.txid(),
|
tx.txid(),
|
||||||
sha256d::Hash::from_hex(
|
Txid::from_hex(
|
||||||
"75c5c9665a570569ad77dd1279e6fd4628a093c4dcbf8d41532614044c14c115"
|
"75c5c9665a570569ad77dd1279e6fd4628a093c4dcbf8d41532614044c14c115"
|
||||||
).unwrap()
|
).unwrap()
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue