Implement Display for block::Header
Not all the fields within `block::Header` implement `Display` however a block header can reasonably be displayed by using 160 hex characters. Implement `Display` for `block::Header` by printing the header in hex in the same layout as we hash it in `block_hash`.
This commit is contained in:
parent
7d05078b6a
commit
e3b059cebf
|
@ -111,6 +111,7 @@ name = "bitcoin-primitives"
|
||||||
version = "0.101.0"
|
version = "0.101.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arbitrary",
|
"arbitrary",
|
||||||
|
"arrayvec",
|
||||||
"bincode",
|
"bincode",
|
||||||
"bitcoin-internals",
|
"bitcoin-internals",
|
||||||
"bitcoin-units",
|
"bitcoin-units",
|
||||||
|
|
|
@ -110,6 +110,7 @@ name = "bitcoin-primitives"
|
||||||
version = "0.101.0"
|
version = "0.101.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arbitrary",
|
"arbitrary",
|
||||||
|
"arrayvec",
|
||||||
"bincode",
|
"bincode",
|
||||||
"bitcoin-internals",
|
"bitcoin-internals",
|
||||||
"bitcoin-units",
|
"bitcoin-units",
|
||||||
|
|
|
@ -16,7 +16,7 @@ exclude = ["tests", "contrib"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "hex"]
|
default = ["std", "hex"]
|
||||||
std = ["alloc", "hashes/std", "hex?/std", "internals/std", "units/std"]
|
std = ["alloc", "hashes/std", "hex?/std", "internals/std", "units/std", "arrayvec/std"]
|
||||||
alloc = ["hashes/alloc", "hex?/alloc", "internals/alloc", "units/alloc"]
|
alloc = ["hashes/alloc", "hex?/alloc", "internals/alloc", "units/alloc"]
|
||||||
serde = ["dep:serde", "hashes/serde", "hex?/serde", "internals/serde", "units/serde", "alloc", "hex"]
|
serde = ["dep:serde", "hashes/serde", "hex?/serde", "internals/serde", "units/serde", "alloc", "hex"]
|
||||||
arbitrary = ["dep:arbitrary", "units/arbitrary"]
|
arbitrary = ["dep:arbitrary", "units/arbitrary"]
|
||||||
|
@ -26,6 +26,7 @@ hex = ["dep:hex", "hashes/hex", "internals/hex"]
|
||||||
hashes = { package = "bitcoin_hashes", path = "../hashes", default-features = false }
|
hashes = { package = "bitcoin_hashes", path = "../hashes", default-features = false }
|
||||||
internals = { package = "bitcoin-internals", path = "../internals" }
|
internals = { package = "bitcoin-internals", path = "../internals" }
|
||||||
units = { package = "bitcoin-units", path = "../units", default-features = false }
|
units = { package = "bitcoin-units", path = "../units", default-features = false }
|
||||||
|
arrayvec = { version = "0.7", default-features = false }
|
||||||
|
|
||||||
arbitrary = { version = "1.4", optional = true }
|
arbitrary = { version = "1.4", optional = true }
|
||||||
hex = { package = "hex-conservative", version = "0.3.0", default-features = false, optional = true }
|
hex = { package = "hex-conservative", version = "0.3.0", default-features = false, optional = true }
|
||||||
|
|
|
@ -207,6 +207,27 @@ impl Header {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
|
impl fmt::Display for Header {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
use fmt::Write as _;
|
||||||
|
use hex::DisplayHex as _;
|
||||||
|
|
||||||
|
let mut buf = arrayvec::ArrayString::<160>::new();
|
||||||
|
write!(
|
||||||
|
&mut buf,
|
||||||
|
"{}{}{}{}{}{}",
|
||||||
|
self.version.to_consensus().to_le_bytes().as_hex(),
|
||||||
|
self.prev_blockhash.as_byte_array().as_hex(),
|
||||||
|
self.merkle_root.as_byte_array().as_hex(),
|
||||||
|
self.time.to_u32().to_le_bytes().as_hex(),
|
||||||
|
self.bits.to_consensus().to_le_bytes().as_hex(),
|
||||||
|
self.nonce.to_le_bytes().as_hex(),
|
||||||
|
)?;
|
||||||
|
fmt::Display::fmt(&buf, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Header {
|
impl fmt::Debug for Header {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("Header")
|
f.debug_struct("Header")
|
||||||
|
@ -535,4 +556,35 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(format!("{:?}", header), expected);
|
assert_eq!(format!("{:?}", header), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
|
fn header_display() {
|
||||||
|
let seconds: u32 = 1_653_195_600; // Arbitrary timestamp: May 22nd, 5am UTC.
|
||||||
|
|
||||||
|
let header = Header {
|
||||||
|
version: Version::TWO,
|
||||||
|
prev_blockhash: BlockHash::from_byte_array([0xab; 32]),
|
||||||
|
merkle_root: TxMerkleNode::from_byte_array([0xcd; 32]),
|
||||||
|
time: BlockTime::from(seconds),
|
||||||
|
bits: CompactTarget::from_consensus(0xbeef),
|
||||||
|
nonce: 0xcafe,
|
||||||
|
};
|
||||||
|
|
||||||
|
let want = concat!(
|
||||||
|
"02000000", // version
|
||||||
|
"abababababababababababababababababababababababababababababababab", // prev_blockhash
|
||||||
|
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", // merkle_root
|
||||||
|
"50c38962", // time
|
||||||
|
"efbe0000", // bits
|
||||||
|
"feca0000", // nonce
|
||||||
|
);
|
||||||
|
assert_eq!(want.len(), 160);
|
||||||
|
assert_eq!(format!("{}", header), want);
|
||||||
|
|
||||||
|
// Check how formatting options are handled.
|
||||||
|
let want = format!("{:.20}", want);
|
||||||
|
let got = format!("{:.20}", header);
|
||||||
|
assert_eq!(got, want);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue