Open liamsi opened 4 years ago
Some precedent:
If someone wants to work on this in the meantime, I would suggest the following API for a start:
trait MerkelizedHasher {
/// Adds data to be merkelized.
fn add<D: Into<Vec<u8>>>(&self, d: D);
/// Takes all data and returns the hash.
fn merkelize<H: Digest>(&self) -> Hash; // the return elem also needs to be sth, generic
}
I'm not saying this needs to be a trait for now. Instead this could be a struct. It would be cool if the (inner/leaf node) Hasher (here called Digest) would be replaceable, and we can collect the data to be merkelized with add
(or a smarter name) to make this look more understandable:
Note that there is currently no need to replace underlying hash algo. In the go code it can be swapped via swapping tmhash
. This could also be done later or when need arises. I just think that if this (simple merkle) was rather seen as a useful library to merkelize structs / their fields, it would feel natural if we can replace the underlying hasher, too.
Something else you might want to look at for inspiration is the Rust Hash
and Hasher
traits:
https://doc.rust-lang.org/std/hash/trait.Hash.html
pub trait Hash {
fn hash<H>(&self, state: &mut H)
where
H: Hasher;
fn hash_slice<H>(data: &[Self], state: &mut H)
where
H: Hasher;
}
https://doc.rust-lang.org/std/hash/trait.Hasher.html
pub trait Hasher {
fn finish(&self) -> u64;
fn write(&mut self, bytes: &[u8]);
// [...]
}
It would be good to make simple merkle a trait (and/or use generics) to make it take any parameter that can be hashable or to make it easy to swap the underlying hash algo. See comment in: https://github.com/interchainio/tendermint-rs/pull/59#pullrequestreview-319176856
While at it, we can also rename the method's name: https://github.com/interchainio/tendermint-rs/pull/59#discussion_r346802972