Skip to content

Commit

Permalink
perf: avoid temporary Vec allocations when computing commitments (#939)
Browse files Browse the repository at this point in the history
* perf: avoid temporary Vec allocations when computing commitments

* review

* Update crates/ibc/src/core/ics04_channel/commitment.rs

Co-authored-by: Rano | Ranadeep <[email protected]>
Signed-off-by: Michal Nazarewicz <[email protected]>

* Update crates/ibc/src/core/ics04_channel/commitment.rs

Co-authored-by: Rano | Ranadeep <[email protected]>
Signed-off-by: Michal Nazarewicz <[email protected]>

* Update crates/ibc/src/core/ics04_channel/commitment.rs

Co-authored-by: Rano | Ranadeep <[email protected]>
Signed-off-by: Michal Nazarewicz <[email protected]>

* review

* Update .changelog/unreleased/improvements/939-less-alloc.md

Co-authored-by: Rano | Ranadeep <[email protected]>
Signed-off-by: Michal Nazarewicz <[email protected]>

---------

Signed-off-by: Michal Nazarewicz <[email protected]>
Co-authored-by: Rano | Ranadeep <[email protected]>
  • Loading branch information
mina86 and rnbguy authored Nov 2, 2023
1 parent 599644c commit ccca3ff
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 13 deletions.
2 changes: 2 additions & 0 deletions .changelog/unreleased/improvements/939-less-alloc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Reduce vector allocations in Commitment computation.
([\#939](https://github.com/cosmos/ibc-rs/pull/939))
54 changes: 41 additions & 13 deletions crates/ibc/src/core/ics04_channel/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,31 +86,59 @@ pub(crate) fn compute_packet_commitment(
timeout_height: &TimeoutHeight,
timeout_timestamp: &Timestamp,
) -> PacketCommitment {
let mut hash_input = timeout_timestamp.nanoseconds().to_be_bytes().to_vec();
let mut hash_input = [0; 8 * 3 + 32];

let revision_number = timeout_height.commitment_revision_number().to_be_bytes();
hash_input.append(&mut revision_number.to_vec());
hash_input[..8].copy_from_slice(&timeout_timestamp.nanoseconds().to_be_bytes());
hash_input[8..16].copy_from_slice(&timeout_height.commitment_revision_number().to_be_bytes());
hash_input[16..24].copy_from_slice(&timeout_height.commitment_revision_height().to_be_bytes());
hash_input[24..].copy_from_slice(&hash(packet_data));

let revision_height = timeout_height.commitment_revision_height().to_be_bytes();
hash_input.append(&mut revision_height.to_vec());

let packet_data_hash = hash(packet_data);
hash_input.append(&mut packet_data_hash.to_vec());

hash(&hash_input).into()
hash(&hash_input).to_vec().into()
}

/// Compute the commitment for an acknowledgement.
pub(crate) fn compute_ack_commitment(ack: &Acknowledgement) -> AcknowledgementCommitment {
hash(ack.as_ref()).into()
hash(ack.as_ref()).to_vec().into()
}

/// Helper function to hash a byte slice using SHA256.
///
/// Note that computing commitments with anything other than SHA256 will
/// break the Merkle proofs of the IBC provable store.
fn hash(data: impl AsRef<[u8]>) -> Vec<u8> {
fn hash(data: &[u8]) -> [u8; 32] {
use sha2::Digest;

sha2::Sha256::digest(&data).to_vec()
sha2::Sha256::digest(data).into()
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_compute_packet_commitment() {
let expected: [u8; 32] = [
0xa9, 0x28, 0xb5, 0x1f, 0x62, 0xbd, 0x54, 0x00, 0x91, 0xec, 0x45, 0x1f, 0x4e, 0xf3,
0x45, 0x79, 0x4f, 0x05, 0x9e, 0x65, 0x91, 0x08, 0x16, 0x86, 0x61, 0x26, 0xdc, 0x36,
0x4f, 0x84, 0xcc, 0x15,
];
let actual = compute_packet_commitment(
"packet data".as_bytes(),
&TimeoutHeight::At(crate::Height::new(42, 24).unwrap()),
&Timestamp::from_nanoseconds(0x42).unwrap(),
);
assert_eq!(&expected[..], actual.as_ref());
}

#[test]
fn test_compute_ack_commitment() {
let expected: [u8; 32] = [
0x05, 0x4e, 0xde, 0xc1, 0xd0, 0x21, 0x1f, 0x62, 0x4f, 0xed, 0x0c, 0xbc, 0xa9, 0xd4,
0xf9, 0x40, 0x0b, 0x0e, 0x49, 0x1c, 0x43, 0x74, 0x2a, 0xf2, 0xc5, 0xb0, 0xab, 0xeb,
0xf0, 0xc9, 0x90, 0xd8,
];
let ack = Acknowledgement::try_from(vec![0, 1, 2, 3]).unwrap();
let actual = compute_ack_commitment(&ack);
assert_eq!(&expected[..], actual.as_ref())
}
}

0 comments on commit ccca3ff

Please sign in to comment.