Merge rust-bitcoin/rust-bitcoin#1351: Improve block version
248f9a3b4b
Use capital letters for Bitcoin Core (Tobin C. Harding)832169eb8d
Add to/from_consensus methods to Version type (Tobin C. Harding)24984f095f
Make block::Version inner value private (Tobin C. Harding)7e146ede96
Make types in block module more terse (Tobin C. Harding) Pull request description: After initial attempt and review this PR has been re-written. - Patch 1: Make types in `block` more terse, this is preparatory clean up based on suggestion below. - Patch 2: Make inner value of `Version` private to hide the i32/u32 discrepancy This is a follow up to #1240 ACKs for top commit: Kixunil: ACK248f9a3b4b
apoelstra: ACK248f9a3b4b
Tree-SHA512: ee031035288a2bcc246a9837a6028c254c51daf78a5cc2441b467ab7f183f1700a63911a2e78b84a20674ce0a83851a7c3bb7e46644a56fdd255685b9a0bf7f2
This commit is contained in:
commit
4bce69db27
|
@ -16,7 +16,7 @@ use crate::consensus::encode::{self, Decodable, Encodable, VarInt};
|
||||||
use crate::hashes::{sha256, siphash24, Hash};
|
use crate::hashes::{sha256, siphash24, Hash};
|
||||||
use crate::internal_macros::{impl_bytes_newtype, impl_consensus_encoding};
|
use crate::internal_macros::{impl_bytes_newtype, impl_consensus_encoding};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::{io, Block, BlockHash, BlockHeader, Transaction};
|
use crate::{io, block, Block, BlockHash, Transaction};
|
||||||
|
|
||||||
/// A BIP-152 error
|
/// A BIP-152 error
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Copy, PartialOrd, Ord, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Copy, PartialOrd, Ord, Hash)]
|
||||||
|
@ -100,7 +100,7 @@ impl_bytes_newtype!(ShortId, 6);
|
||||||
|
|
||||||
impl ShortId {
|
impl ShortId {
|
||||||
/// Calculate the SipHash24 keys used to calculate short IDs.
|
/// 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)
|
// 1. single-SHA256 hashing the block header with the nonce appended (in little-endian)
|
||||||
let h = {
|
let h = {
|
||||||
let mut engine = sha256::Hash::engine();
|
let mut engine = sha256::Hash::engine();
|
||||||
|
@ -147,7 +147,7 @@ impl Decodable for ShortId {
|
||||||
#[derive(PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)]
|
#[derive(PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)]
|
||||||
pub struct HeaderAndShortIds {
|
pub struct HeaderAndShortIds {
|
||||||
/// The header of the block being provided.
|
/// The header of the block being provided.
|
||||||
pub header: BlockHeader,
|
pub header: block::Header,
|
||||||
/// A nonce for use in short transaction ID calculations.
|
/// A nonce for use in short transaction ID calculations.
|
||||||
pub nonce: u64,
|
pub nonce: u64,
|
||||||
/// The short transaction IDs calculated from the transactions
|
/// The short transaction IDs calculated from the transactions
|
||||||
|
@ -374,7 +374,7 @@ mod test {
|
||||||
use crate::consensus::encode::{deserialize, serialize};
|
use crate::consensus::encode::{deserialize, serialize};
|
||||||
use crate::hashes::hex::FromHex;
|
use crate::hashes::hex::FromHex;
|
||||||
use crate::{
|
use crate::{
|
||||||
Block, BlockHash, BlockHeader, BlockVersion, CompactTarget, OutPoint, Script, Sequence,
|
CompactTarget, OutPoint, Script, Sequence,
|
||||||
Transaction, TxIn, TxMerkleNode, TxOut, Txid, Witness,
|
Transaction, TxIn, TxMerkleNode, TxOut, Txid, Witness,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -394,8 +394,8 @@ mod test {
|
||||||
|
|
||||||
fn dummy_block() -> Block {
|
fn dummy_block() -> Block {
|
||||||
Block {
|
Block {
|
||||||
header: BlockHeader {
|
header: block::Header {
|
||||||
version: BlockVersion(1),
|
version: block::Version::ONE,
|
||||||
prev_blockhash: BlockHash::hash(&[0]),
|
prev_blockhash: BlockHash::hash(&[0]),
|
||||||
merkle_root: TxMerkleNode::hash(&[1]),
|
merkle_root: TxMerkleNode::hash(&[1]),
|
||||||
time: 2,
|
time: 2,
|
||||||
|
|
|
@ -16,7 +16,7 @@ use core::fmt;
|
||||||
use crate::{merkle_tree, util};
|
use crate::{merkle_tree, util};
|
||||||
use crate::util::Error::{BlockBadTarget, BlockBadProofOfWork};
|
use crate::util::Error::{BlockBadTarget, BlockBadProofOfWork};
|
||||||
use crate::hashes::{Hash, HashEngine};
|
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::consensus::{encode, Encodable, Decodable};
|
||||||
use crate::blockdata::transaction::Transaction;
|
use crate::blockdata::transaction::Transaction;
|
||||||
use crate::blockdata::constants::WITNESS_SCALE_FACTOR;
|
use crate::blockdata::constants::WITNESS_SCALE_FACTOR;
|
||||||
|
@ -26,6 +26,8 @@ use crate::VarInt;
|
||||||
use crate::internal_macros::impl_consensus_encoding;
|
use crate::internal_macros::impl_consensus_encoding;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
|
|
||||||
|
pub use crate::hash_types::BlockHash;
|
||||||
|
|
||||||
/// Bitcoin block header.
|
/// Bitcoin block header.
|
||||||
///
|
///
|
||||||
/// Contains all the block's information except the actual transactions, but
|
/// 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)]
|
#[derive(Copy, PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
||||||
pub struct BlockHeader {
|
pub struct Header {
|
||||||
/// Block version, now repurposed for soft fork signalling.
|
/// Block version, now repurposed for soft fork signalling.
|
||||||
pub version: BlockVersion,
|
pub version: Version,
|
||||||
/// Reference to the previous block in the chain.
|
/// Reference to the previous block in the chain.
|
||||||
pub prev_blockhash: BlockHash,
|
pub prev_blockhash: BlockHash,
|
||||||
/// The root hash of the merkle tree of transactions in the block.
|
/// The root hash of the merkle tree of transactions in the block.
|
||||||
|
@ -54,9 +56,9 @@ pub struct BlockHeader {
|
||||||
pub nonce: u32,
|
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.
|
/// Returns the block hash.
|
||||||
pub fn block_hash(&self) -> BlockHash {
|
pub fn block_hash(&self) -> BlockHash {
|
||||||
let mut engine = BlockHash::engine();
|
let mut engine = BlockHash::engine();
|
||||||
|
@ -110,18 +112,40 @@ impl BlockHeader {
|
||||||
#[derive(Copy, PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)]
|
#[derive(Copy, PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
||||||
pub struct BlockVersion(pub i32);
|
pub struct Version(i32);
|
||||||
|
|
||||||
|
impl Version {
|
||||||
|
/// The original Bitcoin Block v1.
|
||||||
|
pub const ONE: Self = Self(1);
|
||||||
|
|
||||||
|
/// BIP-34 Block v2.
|
||||||
|
pub const TWO: Self = Self(2);
|
||||||
|
|
||||||
impl BlockVersion {
|
|
||||||
/// BIP-9 compatible version number that does not signal for any softforks.
|
/// 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);
|
pub const NO_SOFT_FORK_SIGNALLING: Self = Self(Self::USE_VERSION_BITS as i32);
|
||||||
|
|
||||||
/// BIP-9 soft fork signal bits mask.
|
/// BIP-9 soft fork signal bits mask.
|
||||||
const VERSION_BITS_MASK: u32 = 0x1FFF_FFFF;
|
const VERSION_BITS_MASK: u32 = 0x1FFF_FFFF;
|
||||||
|
|
||||||
/// 32bit value starting with `001` to use version bits.
|
/// 32bit value starting with `001` to use version bits.
|
||||||
///
|
///
|
||||||
/// The value has the top three bits `001` which enables the use of version bits to signal for soft forks.
|
/// The value has the top three bits `001` which enables the use of version bits to signal for soft forks.
|
||||||
const USE_VERSION_BITS: u32 = 0x2000_0000;
|
const USE_VERSION_BITS: u32 = 0x2000_0000;
|
||||||
|
|
||||||
|
/// Creates a [`Version`] from a signed 32 bit integer value.
|
||||||
|
///
|
||||||
|
/// This is the data type used in consensus code in Bitcoin Core.
|
||||||
|
pub fn from_consensus(v: i32) -> Self {
|
||||||
|
Version(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the inner `i32` value.
|
||||||
|
///
|
||||||
|
/// This is the data type used in consensus code in Bitcoin Core.
|
||||||
|
pub fn to_consensus(self) -> i32 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
/// Check whether the version number is signalling a soft fork at the given bit.
|
/// Check whether the version number is signalling a soft fork at the given bit.
|
||||||
///
|
///
|
||||||
/// A block is signalling for a soft fork under BIP-9 if the first 3 bits are `001` and
|
/// A block is signalling for a soft fork under BIP-9 if the first 3 bits are `001` and
|
||||||
|
@ -142,21 +166,21 @@ impl BlockVersion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BlockVersion {
|
impl Default for Version {
|
||||||
fn default() -> BlockVersion {
|
fn default() -> Version {
|
||||||
Self::NO_SOFT_FORK_SIGNALLING
|
Self::NO_SOFT_FORK_SIGNALLING
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for BlockVersion {
|
impl Encodable for Version {
|
||||||
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
||||||
self.0.consensus_encode(w)
|
self.0.consensus_encode(w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for BlockVersion {
|
impl Decodable for Version {
|
||||||
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Decodable::consensus_decode(r).map(BlockVersion)
|
Decodable::consensus_decode(r).map(Version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +200,7 @@ impl Decodable for BlockVersion {
|
||||||
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
/// The block header
|
/// The block header
|
||||||
pub header: BlockHeader,
|
pub header: Header,
|
||||||
/// List of transactions contained in the block
|
/// List of transactions contained in the block
|
||||||
pub txdata: Vec<Transaction>
|
pub txdata: Vec<Transaction>
|
||||||
}
|
}
|
||||||
|
@ -300,7 +324,7 @@ impl Block {
|
||||||
// number (including a sign bit). Height is the height of the mined
|
// 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).
|
// block in the block chain, where the genesis block is height zero (0).
|
||||||
|
|
||||||
if self.header.version < BlockVersion(2) {
|
if self.header.version < Version::TWO {
|
||||||
return Err(Bip34Error::Unsupported);
|
return Err(Bip34Error::Unsupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,14 +388,14 @@ impl std::error::Error for Bip34Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BlockHeader> for BlockHash {
|
impl From<Header> for BlockHash {
|
||||||
fn from(header: BlockHeader) -> BlockHash {
|
fn from(header: Header) -> BlockHash {
|
||||||
header.block_hash()
|
header.block_hash()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&BlockHeader> for BlockHash {
|
impl From<&Header> for BlockHash {
|
||||||
fn from(header: &BlockHeader) -> BlockHash {
|
fn from(header: &Header) -> BlockHash {
|
||||||
header.block_hash()
|
header.block_hash()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -393,10 +417,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::hashes::hex::FromHex;
|
use crate::hashes::hex::FromHex;
|
||||||
|
|
||||||
use crate::blockdata::block::{Block, BlockHeader, BlockVersion};
|
|
||||||
use crate::consensus::encode::{deserialize, serialize};
|
use crate::consensus::encode::{deserialize, serialize};
|
||||||
use crate::util::Error::{BlockBadTarget, BlockBadProofOfWork};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_coinbase_and_bip34() {
|
fn test_coinbase_and_bip34() {
|
||||||
|
@ -434,7 +455,7 @@ mod tests {
|
||||||
assert!(decode.is_ok());
|
assert!(decode.is_ok());
|
||||||
assert!(bad_decode.is_err());
|
assert!(bad_decode.is_err());
|
||||||
let real_decode = decode.unwrap();
|
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!(serialize(&real_decode.header.prev_blockhash), prevhash);
|
||||||
assert_eq!(real_decode.header.merkle_root, real_decode.compute_merkle_root().unwrap());
|
assert_eq!(real_decode.header.merkle_root, real_decode.compute_merkle_root().unwrap());
|
||||||
assert_eq!(serialize(&real_decode.header.merkle_root), merkle);
|
assert_eq!(serialize(&real_decode.header.merkle_root), merkle);
|
||||||
|
@ -469,7 +490,7 @@ mod tests {
|
||||||
|
|
||||||
assert!(decode.is_ok());
|
assert!(decode.is_ok());
|
||||||
let real_decode = decode.unwrap();
|
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.prev_blockhash), prevhash);
|
||||||
assert_eq!(serialize(&real_decode.header.merkle_root), merkle);
|
assert_eq!(serialize(&real_decode.header.merkle_root), merkle);
|
||||||
assert_eq!(real_decode.header.merkle_root, real_decode.compute_merkle_root().unwrap());
|
assert_eq!(real_decode.header.merkle_root, real_decode.compute_merkle_root().unwrap());
|
||||||
|
@ -496,19 +517,19 @@ mod tests {
|
||||||
let decode: Result<Block, _> = deserialize(&block);
|
let decode: Result<Block, _> = deserialize(&block);
|
||||||
assert!(decode.is_ok());
|
assert!(decode.is_ok());
|
||||||
let real_decode = decode.unwrap();
|
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 block2 = Vec::from_hex("000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
|
||||||
let decode2: Result<Block, _> = deserialize(&block2);
|
let decode2: Result<Block, _> = deserialize(&block2);
|
||||||
assert!(decode2.is_ok());
|
assert!(decode2.is_ok());
|
||||||
let real_decode2 = decode2.unwrap();
|
let real_decode2 = decode2.unwrap();
|
||||||
assert_eq!(real_decode2.header.version, BlockVersion(-2147483648));
|
assert_eq!(real_decode2.header.version, Version(-2147483648));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn validate_pow_test() {
|
fn validate_pow_test() {
|
||||||
let some_header = Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap();
|
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());
|
assert_eq!(some_header.validate_pow(some_header.target()).unwrap(), some_header.block_hash());
|
||||||
|
|
||||||
// test with zero target
|
// test with zero target
|
||||||
|
@ -518,7 +539,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
// test with modified header
|
// test with modified header
|
||||||
let mut invalid_header: BlockHeader = some_header;
|
let mut invalid_header: Header = some_header;
|
||||||
invalid_header.version.0 += 1;
|
invalid_header.version.0 += 1;
|
||||||
match invalid_header.validate_pow(invalid_header.target()) {
|
match invalid_header.validate_pow(invalid_header.target()) {
|
||||||
Err(BlockBadProofOfWork) => (),
|
Err(BlockBadProofOfWork) => (),
|
||||||
|
@ -530,7 +551,7 @@ mod tests {
|
||||||
fn compact_roundrtip_test() {
|
fn compact_roundrtip_test() {
|
||||||
let some_header = Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap();
|
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());
|
assert_eq!(header.bits, header.target().to_compact_lossy());
|
||||||
}
|
}
|
||||||
|
@ -539,7 +560,7 @@ mod tests {
|
||||||
fn soft_fork_signalling() {
|
fn soft_fork_signalling() {
|
||||||
for i in 0..31 {
|
for i in 0..31 {
|
||||||
let version_int = (0x20000000u32 ^ 1<<i) as i32;
|
let version_int = (0x20000000u32 ^ 1<<i) as i32;
|
||||||
let version = BlockVersion(version_int);
|
let version = Version(version_int);
|
||||||
if i < 29 {
|
if i < 29 {
|
||||||
assert!(version.is_signalling_soft_fork(i));
|
assert!(version.is_signalling_soft_fork(i));
|
||||||
} else {
|
} else {
|
||||||
|
@ -547,7 +568,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let segwit_signal = BlockVersion(0x20000000 ^ 1<<1);
|
let segwit_signal = Version(0x20000000 ^ 1<<1);
|
||||||
assert!(!segwit_signal.is_signalling_soft_fork(0));
|
assert!(!segwit_signal.is_signalling_soft_fork(0));
|
||||||
assert!(segwit_signal.is_signalling_soft_fork(1));
|
assert!(segwit_signal.is_signalling_soft_fork(1));
|
||||||
assert!(!segwit_signal.is_signalling_soft_fork(2));
|
assert!(!segwit_signal.is_signalling_soft_fork(2));
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::blockdata::script;
|
||||||
use crate::blockdata::opcodes::all::*;
|
use crate::blockdata::opcodes::all::*;
|
||||||
use crate::blockdata::locktime::absolute;
|
use crate::blockdata::locktime::absolute;
|
||||||
use crate::blockdata::transaction::{OutPoint, Transaction, TxOut, TxIn, Sequence};
|
use crate::blockdata::transaction::{OutPoint, Transaction, TxOut, TxIn, Sequence};
|
||||||
use crate::blockdata::block::{Block, BlockHeader, BlockVersion};
|
use crate::blockdata::block::{self, Block};
|
||||||
use crate::blockdata::witness::Witness;
|
use crate::blockdata::witness::Witness;
|
||||||
use crate::network::constants::Network;
|
use crate::network::constants::Network;
|
||||||
use crate::pow::CompactTarget;
|
use crate::pow::CompactTarget;
|
||||||
|
@ -111,8 +111,8 @@ pub fn genesis_block(network: Network) -> Block {
|
||||||
match network {
|
match network {
|
||||||
Network::Bitcoin => {
|
Network::Bitcoin => {
|
||||||
Block {
|
Block {
|
||||||
header: BlockHeader {
|
header: block::Header {
|
||||||
version: BlockVersion(1),
|
version: block::Version::ONE,
|
||||||
prev_blockhash: Hash::all_zeros(),
|
prev_blockhash: Hash::all_zeros(),
|
||||||
merkle_root,
|
merkle_root,
|
||||||
time: 1231006505,
|
time: 1231006505,
|
||||||
|
@ -124,8 +124,8 @@ pub fn genesis_block(network: Network) -> Block {
|
||||||
}
|
}
|
||||||
Network::Testnet => {
|
Network::Testnet => {
|
||||||
Block {
|
Block {
|
||||||
header: BlockHeader {
|
header: block::Header {
|
||||||
version: BlockVersion(1),
|
version: block::Version::ONE,
|
||||||
prev_blockhash: Hash::all_zeros(),
|
prev_blockhash: Hash::all_zeros(),
|
||||||
merkle_root,
|
merkle_root,
|
||||||
time: 1296688602,
|
time: 1296688602,
|
||||||
|
@ -137,8 +137,8 @@ pub fn genesis_block(network: Network) -> Block {
|
||||||
}
|
}
|
||||||
Network::Signet => {
|
Network::Signet => {
|
||||||
Block {
|
Block {
|
||||||
header: BlockHeader {
|
header: block::Header {
|
||||||
version: BlockVersion(1),
|
version: block::Version::ONE,
|
||||||
prev_blockhash: Hash::all_zeros(),
|
prev_blockhash: Hash::all_zeros(),
|
||||||
merkle_root,
|
merkle_root,
|
||||||
time: 1598918400,
|
time: 1598918400,
|
||||||
|
@ -150,8 +150,8 @@ pub fn genesis_block(network: Network) -> Block {
|
||||||
}
|
}
|
||||||
Network::Regtest => {
|
Network::Regtest => {
|
||||||
Block {
|
Block {
|
||||||
header: BlockHeader {
|
header: block::Header {
|
||||||
version: BlockVersion(1),
|
version: block::Version::ONE,
|
||||||
prev_blockhash: Hash::all_zeros(),
|
prev_blockhash: Hash::all_zeros(),
|
||||||
merkle_root,
|
merkle_root,
|
||||||
time: 1296688602,
|
time: 1296688602,
|
||||||
|
@ -224,7 +224,7 @@ mod test {
|
||||||
fn bitcoin_genesis_full_block() {
|
fn bitcoin_genesis_full_block() {
|
||||||
let gen = genesis_block(Network::Bitcoin);
|
let gen = genesis_block(Network::Bitcoin);
|
||||||
|
|
||||||
assert_eq!(gen.header.version, BlockVersion(1));
|
assert_eq!(gen.header.version, block::Version::ONE);
|
||||||
assert_eq!(gen.header.prev_blockhash, Hash::all_zeros());
|
assert_eq!(gen.header.prev_blockhash, Hash::all_zeros());
|
||||||
assert_eq!(gen.header.merkle_root.to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
|
assert_eq!(gen.header.merkle_root.to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn testnet_genesis_full_block() {
|
fn testnet_genesis_full_block() {
|
||||||
let gen = genesis_block(Network::Testnet);
|
let gen = genesis_block(Network::Testnet);
|
||||||
assert_eq!(gen.header.version, BlockVersion(1));
|
assert_eq!(gen.header.version, block::Version::ONE);
|
||||||
assert_eq!(gen.header.prev_blockhash, Hash::all_zeros());
|
assert_eq!(gen.header.prev_blockhash, Hash::all_zeros());
|
||||||
assert_eq!(gen.header.merkle_root.to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
|
assert_eq!(gen.header.merkle_root.to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
|
||||||
assert_eq!(gen.header.time, 1296688602);
|
assert_eq!(gen.header.time, 1296688602);
|
||||||
|
@ -249,7 +249,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn signet_genesis_full_block() {
|
fn signet_genesis_full_block() {
|
||||||
let gen = genesis_block(Network::Signet);
|
let gen = genesis_block(Network::Signet);
|
||||||
assert_eq!(gen.header.version, BlockVersion(1));
|
assert_eq!(gen.header.version, block::Version::ONE);
|
||||||
assert_eq!(gen.header.prev_blockhash, Hash::all_zeros());
|
assert_eq!(gen.header.prev_blockhash, Hash::all_zeros());
|
||||||
assert_eq!(gen.header.merkle_root.to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
|
assert_eq!(gen.header.merkle_root.to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
|
||||||
assert_eq!(gen.header.time, 1598918400);
|
assert_eq!(gen.header.time, 1598918400);
|
||||||
|
|
|
@ -318,7 +318,7 @@ pub fn read_scriptint(v: &[u8]) -> Result<i64, Error> {
|
||||||
Some(last) => last,
|
Some(last) => last,
|
||||||
None => return Ok(0),
|
None => return Ok(0),
|
||||||
};
|
};
|
||||||
// Comment and code copied from bitcoin core:
|
// Comment and code copied from Bitcoin Core:
|
||||||
// https://github.com/bitcoin/bitcoin/blob/447f50e4aed9a8b1d80e1891cda85801aeb80b4e/src/script/script.h#L247-L262
|
// https://github.com/bitcoin/bitcoin/blob/447f50e4aed9a8b1d80e1891cda85801aeb80b4e/src/script/script.h#L247-L262
|
||||||
// If the most-significant-byte - excluding the sign bit - is zero
|
// If the most-significant-byte - excluding the sign bit - is zero
|
||||||
// then we're not minimal. Note how this test also rejects the
|
// then we're not minimal. Note how this test also rejects the
|
||||||
|
|
|
@ -115,7 +115,7 @@ use std::io;
|
||||||
use core2::io;
|
use core2::io;
|
||||||
|
|
||||||
pub use crate::address::{Address, AddressType};
|
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::locktime::{self, absolute, relative};
|
||||||
pub use crate::blockdata::script::{self, Script};
|
pub use crate::blockdata::script::{self, Script};
|
||||||
pub use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut};
|
pub use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut};
|
||||||
|
|
|
@ -182,7 +182,7 @@ pub enum NetworkMessage {
|
||||||
/// `block`
|
/// `block`
|
||||||
Block(block::Block),
|
Block(block::Block),
|
||||||
/// `headers`
|
/// `headers`
|
||||||
Headers(Vec<block::BlockHeader>),
|
Headers(Vec<block::Header>),
|
||||||
/// `sendheaders`
|
/// `sendheaders`
|
||||||
SendHeaders,
|
SendHeaders,
|
||||||
/// `getaddr`
|
/// `getaddr`
|
||||||
|
@ -317,7 +317,7 @@ impl RawNetworkMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HeaderSerializationWrapper<'a>(&'a Vec<block::BlockHeader>);
|
struct HeaderSerializationWrapper<'a>(&'a Vec<block::Header>);
|
||||||
|
|
||||||
impl<'a> Encodable for HeaderSerializationWrapper<'a> {
|
impl<'a> Encodable for HeaderSerializationWrapper<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -380,7 +380,7 @@ impl Encodable for RawNetworkMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HeaderDeserializationWrapper(Vec<block::BlockHeader>);
|
struct HeaderDeserializationWrapper(Vec<block::Header>);
|
||||||
|
|
||||||
impl Decodable for HeaderDeserializationWrapper {
|
impl Decodable for HeaderDeserializationWrapper {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -479,7 +479,7 @@ mod test {
|
||||||
use crate::network::address::{Address, AddrV2, AddrV2Message};
|
use crate::network::address::{Address, AddrV2, AddrV2Message};
|
||||||
use super::message_network::{Reject, RejectReason, VersionMessage};
|
use super::message_network::{Reject, RejectReason, VersionMessage};
|
||||||
use crate::network::message_blockdata::{Inventory, GetBlocksMessage, GetHeadersMessage};
|
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::network::message_filter::{GetCFilters, CFilter, GetCFHeaders, CFHeaders, GetCFCheckpt, CFCheckpt};
|
||||||
use crate::blockdata::transaction::Transaction;
|
use crate::blockdata::transaction::Transaction;
|
||||||
use crate::blockdata::script::Script;
|
use crate::blockdata::script::Script;
|
||||||
|
@ -498,7 +498,7 @@ mod test {
|
||||||
let version_msg: VersionMessage = deserialize(&Vec::from_hex("721101000100000000000000e6e0845300000000010000000000000000000000000000000000ffff0000000000000100000000000000fd87d87eeb4364f22cf54dca59412db7208d47d920cffce83ee8102f5361746f7368693a302e392e39392f2c9f040001").unwrap()).unwrap();
|
let version_msg: VersionMessage = deserialize(&Vec::from_hex("721101000100000000000000e6e0845300000000010000000000000000000000000000000000ffff0000000000000100000000000000fd87d87eeb4364f22cf54dca59412db7208d47d920cffce83ee8102f5361746f7368693a302e392e39392f2c9f040001").unwrap()).unwrap();
|
||||||
let tx: Transaction = deserialize(&Vec::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").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 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 script: Script = deserialize(&Vec::from_hex("1976a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac").unwrap()).unwrap();
|
||||||
let merkle_block: MerkleBlock = deserialize(&Vec::from_hex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101").unwrap()).unwrap();
|
let merkle_block: MerkleBlock = deserialize(&Vec::from_hex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101").unwrap()).unwrap();
|
||||||
let cmptblock = deserialize(&Vec::from_hex("00000030d923ad36ff2d955abab07f8a0a6e813bc6e066b973e780c5e36674cad5d1cd1f6e265f2a17a0d35cbe701fe9d06e2c6324cfe135f6233e8b767bfa3fb4479b71115dc562ffff7f2006000000000000000000000000010002000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0302ee00ffffffff0100f9029500000000015100000000").unwrap()).unwrap();
|
let cmptblock = deserialize(&Vec::from_hex("00000030d923ad36ff2d955abab07f8a0a6e813bc6e066b973e780c5e36674cad5d1cd1f6e265f2a17a0d35cbe701fe9d06e2c6324cfe135f6233e8b767bfa3fb4479b71115dc562ffff7f2006000000000000000000000000010002000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0302ee00ffffffff0100f9029500000000015100000000").unwrap()).unwrap();
|
||||||
|
|
|
@ -237,7 +237,7 @@ impl Target {
|
||||||
/// `0xffff_ffff_ffff_ffff_ffff_ffff` `difficulty()` will saturate at `u128::MAX`.
|
/// `0xffff_ffff_ffff_ffff_ffff_ffff` `difficulty()` will saturate at `u128::MAX`.
|
||||||
///
|
///
|
||||||
/// [max]: Target::max
|
/// [max]: Target::max
|
||||||
/// [target]: crate::blockdata::block::BlockHeader::target
|
/// [target]: crate::blockdata::block::Header::target
|
||||||
pub fn difficulty(&self) -> u128 {
|
pub fn difficulty(&self) -> u128 {
|
||||||
let d = Target::MAX.0 / self.0;
|
let d = Target::MAX.0 / self.0;
|
||||||
d.saturating_to_u128()
|
d.saturating_to_u128()
|
||||||
|
|
|
@ -1152,7 +1152,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sighashes_keyspending() {
|
fn test_sighashes_keyspending() {
|
||||||
// following test case has been taken from bitcoin core test framework
|
// following test case has been taken from Bitcoin Core test framework
|
||||||
|
|
||||||
test_taproot_sighash(
|
test_taproot_sighash(
|
||||||
"020000000164eb050a5e3da0c2a65e4786f26d753b7bc69691fabccafb11f7acef36641f1846010000003101b2b404392a22000000000017a9147f2bde86fe78bf68a0544a4f290e12f0b7e0a08c87580200000000000017a91425d11723074ecfb96a0a83c3956bfaf362ae0c908758020000000000001600147e20f938993641de67bb0cdd71682aa34c4d29ad5802000000000000160014c64984dc8761acfa99418bd6bedc79b9287d652d72000000",
|
"020000000164eb050a5e3da0c2a65e4786f26d753b7bc69691fabccafb11f7acef36641f1846010000003101b2b404392a22000000000017a9147f2bde86fe78bf68a0544a4f290e12f0b7e0a08c87580200000000000017a91425d11723074ecfb96a0a83c3956bfaf362ae0c908758020000000000001600147e20f938993641de67bb0cdd71682aa34c4d29ad5802000000000000160014c64984dc8761acfa99418bd6bedc79b9287d652d72000000",
|
||||||
|
|
|
@ -49,11 +49,11 @@ use crate::io;
|
||||||
use crate::hashes::Hash;
|
use crate::hashes::Hash;
|
||||||
use crate::hash_types::{Txid, TxMerkleNode};
|
use crate::hash_types::{Txid, TxMerkleNode};
|
||||||
|
|
||||||
|
use crate::blockdata::block::{self, Block};
|
||||||
use crate::blockdata::transaction::Transaction;
|
use crate::blockdata::transaction::Transaction;
|
||||||
use crate::blockdata::constants::{MAX_BLOCK_WEIGHT, MIN_TRANSACTION_WEIGHT};
|
use crate::blockdata::constants::{MAX_BLOCK_WEIGHT, MIN_TRANSACTION_WEIGHT};
|
||||||
use crate::consensus::encode::{self, Decodable, Encodable};
|
use crate::consensus::encode::{self, Decodable, Encodable};
|
||||||
use crate::util::merkleblock::MerkleBlockError::*;
|
use crate::util::merkleblock::MerkleBlockError::*;
|
||||||
use crate::{Block, BlockHeader};
|
|
||||||
|
|
||||||
/// An error when verifying the merkle block.
|
/// An error when verifying the merkle block.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
@ -408,7 +408,7 @@ impl Decodable for PartialMerkleTree {
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct MerkleBlock {
|
pub struct MerkleBlock {
|
||||||
/// The block header
|
/// The block header
|
||||||
pub header: BlockHeader,
|
pub header: block::Header,
|
||||||
/// Transactions making up a partial merkle tree
|
/// Transactions making up a partial merkle tree
|
||||||
pub txn: PartialMerkleTree,
|
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
|
/// 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.
|
/// `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<F>(
|
pub fn from_header_txids_with_predicate<F>(
|
||||||
header: &BlockHeader,
|
header: &block::Header,
|
||||||
block_txids: &[Txid],
|
block_txids: &[Txid],
|
||||||
match_txids: F,
|
match_txids: F,
|
||||||
) -> Self
|
) -> Self
|
||||||
|
|
|
@ -336,12 +336,12 @@ impl From<&TaprootSpendInfo> for TapTweakHash {
|
||||||
/// in a depth-first search (DFS) walk order to construct this tree.
|
/// in a depth-first search (DFS) walk order to construct this tree.
|
||||||
///
|
///
|
||||||
/// See Wikipedia for more details on [DFS](https://en.wikipedia.org/wiki/Depth-first_search).
|
/// See Wikipedia for more details on [DFS](https://en.wikipedia.org/wiki/Depth-first_search).
|
||||||
// Similar to Taproot Builder in bitcoin core.
|
// Similar to Taproot Builder in Bitcoin Core.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
||||||
pub struct TaprootBuilder {
|
pub struct TaprootBuilder {
|
||||||
// The following doc-comment is from bitcoin core, but modified for Rust. It describes the
|
// The following doc-comment is from Bitcoin Core, but modified for Rust. It describes the
|
||||||
// current state of the builder for a given tree.
|
// current state of the builder for a given tree.
|
||||||
//
|
//
|
||||||
// For each level in the tree, one NodeInfo object may be present. Branch at index 0 is
|
// For each level in the tree, one NodeInfo object may be present. Branch at index 0 is
|
||||||
|
@ -1248,7 +1248,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn control_block_verify() {
|
fn control_block_verify() {
|
||||||
let secp = Secp256k1::verification_only();
|
let secp = Secp256k1::verification_only();
|
||||||
// test vectors obtained from printing values in feature_taproot.py from bitcoin core
|
// test vectors obtained from printing values in feature_taproot.py from Bitcoin Core
|
||||||
_verify_tap_commitments(&secp, "51205dc8e62b15e0ebdf44751676be35ba32eed2e84608b290d4061bbff136cd7ba9", "6a", "c1a9d6f66cd4b25004f526bfa873e56942f98e8e492bd79ed6532b966104817c2bda584e7d32612381cf88edc1c02e28a296e807c16ad22f591ee113946e48a71e0641e660d1e5392fb79d64838c2b84faf04b7f5f283c9d8bf83e39e177b64372a0cd22eeab7e093873e851e247714eff762d8a30be699ba4456cfe6491b282e193a071350ae099005a5950d74f73ba13077a57bc478007fb0e4d1099ce9cf3d4");
|
_verify_tap_commitments(&secp, "51205dc8e62b15e0ebdf44751676be35ba32eed2e84608b290d4061bbff136cd7ba9", "6a", "c1a9d6f66cd4b25004f526bfa873e56942f98e8e492bd79ed6532b966104817c2bda584e7d32612381cf88edc1c02e28a296e807c16ad22f591ee113946e48a71e0641e660d1e5392fb79d64838c2b84faf04b7f5f283c9d8bf83e39e177b64372a0cd22eeab7e093873e851e247714eff762d8a30be699ba4456cfe6491b282e193a071350ae099005a5950d74f73ba13077a57bc478007fb0e4d1099ce9cf3d4");
|
||||||
_verify_tap_commitments(&secp, "5120e208c869c40d8827101c5ad3238018de0f3f5183d77a0c53d18ac28ddcbcd8ad", "f4", "c0a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f40090ab1f4890d51115998242ebce636efb9ede1b516d9eb8952dc1068e0335306199aaf103cceb41d9bc37ec231aca89b984b5fd3c65977ce764d51033ac65adb4da14e029b1e154a85bfd9139e7aa2720b6070a4ceba8264ca61d5d3ac27aceb9ef4b54cd43c2d1fd5e11b5c2e93cf29b91ea3dc5b832201f02f7473a28c63246");
|
_verify_tap_commitments(&secp, "5120e208c869c40d8827101c5ad3238018de0f3f5183d77a0c53d18ac28ddcbcd8ad", "f4", "c0a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f40090ab1f4890d51115998242ebce636efb9ede1b516d9eb8952dc1068e0335306199aaf103cceb41d9bc37ec231aca89b984b5fd3c65977ce764d51033ac65adb4da14e029b1e154a85bfd9139e7aa2720b6070a4ceba8264ca61d5d3ac27aceb9ef4b54cd43c2d1fd5e11b5c2e93cf29b91ea3dc5b832201f02f7473a28c63246");
|
||||||
_verify_tap_commitments(&secp, "5120567666e7df90e0450bb608e17c01ed3fbcfa5355a5f8273e34e583bfaa70ce09", "203455139bf238a3067bd72ed77e0ab8db590330f55ed58dba7366b53bf4734279ac", "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400");
|
_verify_tap_commitments(&secp, "5120567666e7df90e0450bb608e17c01ed3fbcfa5355a5f8273e34e583bfaa70ce09", "203455139bf238a3067bd72ed77e0ab8db590330f55ed58dba7366b53bf4734279ac", "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400");
|
||||||
|
|
Loading…
Reference in New Issue