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

trie panics with cannot convert a slice of length 29 to FixedBytes<32> with small data #9

Open
ufoscout opened this issue Apr 17, 2024 · 1 comment

Comments

@ufoscout
Copy link

I am trying to replace triehash::ordered_trie_root with an equivalent function based on alloy-trie. Even if it works pretty well, sometimes alloy-trie panics with a cannot convert a slice of length 29 to FixedBytes<32> error. Here is a complete reproducer for the issue:

use std::collections::BTreeMap;

use alloy_primitives::{keccak256, B256};
use alloy_rlp::Encodable;
use alloy_trie::HashBuilder;
use nybbles::Nibbles;

fn triehash_ordered_trie_root<I>(iter: I) -> B256
where
    I: IntoIterator,
    I::Item: AsRef<[u8]>,
{
    struct Keccak256Hasher;
    impl hash_db::Hasher for Keccak256Hasher {
        type Out = B256;
        type StdHasher = plain_hasher::PlainHasher;

        const LENGTH: usize = 32;

        fn hash(x: &[u8]) -> Self::Out {
            keccak256(x)
        }
    }

    triehash::ordered_trie_root::<Keccak256Hasher, _>(iter)
}

fn alloy_ordered_trie_root<I>(iter: I) -> B256
where
    I: IntoIterator,
    I::Item: AsRef<[u8]>,
{

    let hashed = iter
    .into_iter()
    .enumerate()
    .map(|(i, v)| {
        let mut buf = Vec::new();
        i.encode(&mut buf);
        (buf, v)
    })
    .collect::<BTreeMap<_, _>>();

    let mut hb = HashBuilder::default();

    hashed.iter().for_each(|(key, val)| {
        let nibbles = Nibbles::unpack(key);
        hb.add_leaf(nibbles, val.as_ref());
    });

    hb.root()
}

// This fails with error:
// cannot convert a slice of length 29 to FixedBytes<32>
#[test]
fn small_data() {
    let data = &["cake", "pie", "candy"];
    assert_eq!(triehash_ordered_trie_root(data), alloy_ordered_trie_root(data));
}

// This succeeds.
#[test]
fn big_data() {
    let data = &["a_very_big_cake", "a_very_big_pie", "a_lots_of_candies"];
    assert_eq!(triehash_ordered_trie_root(data), alloy_ordered_trie_root(data));
}
@DaniPopes
Copy link
Member

DaniPopes commented Apr 17, 2024

cc @rkrasiuk @klkvr

Should we also add these helpers in this crate?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants