Skip to content

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

@ufoscout

Description

@ufoscout

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));
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions