Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: avoid copying digests where possible #153

Merged
merged 1 commit into from
Oct 29, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/multihash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,14 @@ impl<const S: usize> From<Multihash<S>> for Vec<u8> {
#[cfg(feature = "scale-codec")]
impl<const S: usize> parity_scale_codec::Encode for Multihash<S> {
fn encode_to<EncOut: parity_scale_codec::Output + ?Sized>(&self, dest: &mut EncOut) {
let mut digest = [0; S];
digest.copy_from_slice(&self.digest);
self.code.encode_to(dest);
self.size.encode_to(dest);
// **NOTE** We write the digest directly to dest, since we have known the size of digest.
//
// We do not choose to encode &[u8] directly, because it will add extra bytes (the compact length of digest).
// For a valid multihash, the length of digest must equal to `size`.
// Therefore, we can only read raw bytes whose length is equal to `size` when decoding.
dest.write(&digest[..self.size as usize]);
dest.write(self.digest());
}
}

Expand All @@ -215,15 +213,17 @@ impl<const S: usize> parity_scale_codec::Decode for Multihash<S> {
fn decode<DecIn: parity_scale_codec::Input>(
input: &mut DecIn,
) -> Result<Self, parity_scale_codec::Error> {
let code = parity_scale_codec::Decode::decode(input)?;
let size = parity_scale_codec::Decode::decode(input)?;
if size as usize > S {
let mut mh = Multihash {
code: parity_scale_codec::Decode::decode(input)?,
size: parity_scale_codec::Decode::decode(input)?,
digest: [0; S],
};
if mh.size as usize > S {
return Err(parity_scale_codec::Error::from("invalid size"));
}
// For a valid multihash, the length of digest must equal to the size.
let mut digest = [0; S];
input.read(&mut digest[..size as usize])?;
Ok(Multihash { code, size, digest })
input.read(&mut mh.digest[..mh.size as usize])?;
Ok(mh)
}
}

Expand Down