From ff5c240fccb4cb6001fefa65de22aa28dcadd1fe Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 12 Apr 2023 10:52:28 -0400 Subject: [PATCH] Fix a bug in the merkle algorithm --- coordinator/tributary/src/merkle.rs | 2 +- coordinator/tributary/src/tests/merkle.rs | 34 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 coordinator/tributary/src/tests/merkle.rs diff --git a/coordinator/tributary/src/merkle.rs b/coordinator/tributary/src/merkle.rs index ed44a5cc..175ec022 100644 --- a/coordinator/tributary/src/merkle.rs +++ b/coordinator/tributary/src/merkle.rs @@ -18,7 +18,7 @@ pub(crate) fn merkle(hash_args: &[[u8; 32]]) -> [u8; 32] { b"branch_hash".as_ref(), hashes[i].as_ref(), hashes - .get(i + i) + .get(i + 1) .map(|hash| { let res: &[u8] = hash.as_ref(); res diff --git a/coordinator/tributary/src/tests/merkle.rs b/coordinator/tributary/src/tests/merkle.rs new file mode 100644 index 00000000..c3b0e626 --- /dev/null +++ b/coordinator/tributary/src/tests/merkle.rs @@ -0,0 +1,34 @@ +use std::collections::HashSet; + +use rand_core::{RngCore, OsRng}; + +#[test] +fn merkle() { + let mut used = HashSet::new(); + // Test this produces a unique root + let mut test = |hashes: &[[u8; 32]]| { + let hash = crate::merkle(hashes); + assert!(!used.contains(&hash)); + used.insert(hash); + }; + + // Zero should be a special case which return 0 + assert_eq!(crate::merkle(&[]), [0; 32]); + test(&[]); + + let mut one = [0; 32]; + OsRng.fill_bytes(&mut one); + let mut two = [0; 32]; + OsRng.fill_bytes(&mut two); + let mut three = [0; 32]; + OsRng.fill_bytes(&mut three); + + // Make sure it's deterministic + assert_eq!(crate::merkle(&[one]), crate::merkle(&[one])); + + // Test a few basic structures + test(&[one]); + test(&[one, two]); + test(&[one, two, three]); + test(&[one, three]); +}