Merge rust-bitcoin/rust-bitcoin#1250: Simplify `PublicKey` serialization code

b9a512330a Simplify `PublicKey` serialization code (Martin Habovstiak)

Pull request description:

  There were a bunch of `if self.serialized` expressions repeated in the code. This change simplifies it by putting the `if` in a function that calls a closure with a slice containing the serialized bytes.

ACKs for top commit:
  apoelstra:
    ACK b9a512330a
  sanket1729:
    utACK b9a512330a. I don't have strong preferences on naming. `serialize_and_call` sounds better because so far I have only seen `with_*` used with constructors.
  tcharding:
    ACK b9a512330a

Tree-SHA512: 5d90a73f87fa36bd45a5765542ec24994d601d32ad6529fff5d5140ded2b86eb40e00bfba4955e94d2c468983e3e7683ca5f8ece7a205d9b9944334a19b06015
This commit is contained in:
sanket1729 2022-09-11 15:32:43 -07:00
commit 3cbab2870c
No known key found for this signature in database
GPG Key ID: 648FFB183E0870A2
1 changed files with 16 additions and 23 deletions

View File

@ -109,13 +109,17 @@ impl PublicKey {
} }
} }
fn with_serialized<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
if self.compressed {
f(&self.inner.serialize())
} else {
f(&self.inner.serialize_uncompressed())
}
}
/// Returns bitcoin 160-bit hash of the public key /// Returns bitcoin 160-bit hash of the public key
pub fn pubkey_hash(&self) -> PubkeyHash { pub fn pubkey_hash(&self) -> PubkeyHash {
if self.compressed { self.with_serialized(PubkeyHash::hash)
PubkeyHash::hash(&self.inner.serialize())
} else {
PubkeyHash::hash(&self.inner.serialize_uncompressed())
}
} }
/// Returns bitcoin 160-bit hash of the public key for witness program /// Returns bitcoin 160-bit hash of the public key for witness program
@ -133,11 +137,7 @@ impl PublicKey {
/// Write the public key into a writer /// Write the public key into a writer
pub fn write_into<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> { pub fn write_into<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
if self.compressed { self.with_serialized(|bytes| writer.write_all(bytes))
writer.write_all(&self.inner.serialize())
} else {
writer.write_all(&self.inner.serialize_uncompressed())
}
} }
/// Read the public key from a reader /// Read the public key from a reader
@ -272,16 +272,13 @@ pub struct SortKey(u8, [u8; 32], [u8; 32]);
impl fmt::Display for PublicKey { impl fmt::Display for PublicKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.compressed { // TODO: fast hex encoding
for ch in &self.inner.serialize()[..] { self.with_serialized(|bytes| {
for ch in bytes {
write!(f, "{:02x}", ch)?; write!(f, "{:02x}", ch)?;
} }
} else {
for ch in &self.inner.serialize_uncompressed()[..] {
write!(f, "{:02x}", ch)?;
}
}
Ok(()) Ok(())
})
} }
} }
@ -485,11 +482,7 @@ impl serde::Serialize for PublicKey {
if s.is_human_readable() { if s.is_human_readable() {
s.collect_str(self) s.collect_str(self)
} else { } else {
if self.compressed { self.with_serialized(|bytes| s.serialize_bytes(bytes))
s.serialize_bytes(&self.inner.serialize()[..])
} else {
s.serialize_bytes(&self.inner.serialize_uncompressed()[..])
}
} }
} }
} }