4

I'm developing a Rust script that I need to convert to WebAssembly (WASM). In this script, I'm using the BlakeTwo256 hasher, which is imported from the sp_runtime crate. However, I'm unable to compile the code(cargo build --release) with sp_runtime in a no_std environment. I need to enable the std feature to compile it, but this prevents the code from being converted to WASM. What alternative can I use to BlakeTwo256 that will work in a no_std environment?

use crate::{Decode, Encode, DispatchError};

use sp_std::vec::Vec;
use sp_trie::{
    trie_types::{TrieDBBuilder, TrieDBMutBuilderV0},
    LayoutV0, MemoryDB, Recorder, Trie, TrieMut, EMPTY_PREFIX,
};

/// A trait for creating a merkle trie for checking and generating merkle proofs.
pub trait ProvingTrie<Hashing, Hash, Key, Value>
    where
        Self: Sized,
{
    /// Create a new instance of a `ProvingTrie` using an iterator of key/value pairs.
    fn generate_for<I>(items: I) -> Result<Self, DispatchError>
        where
            I: IntoIterator<Item = (Key, Value)>;
}

/// A basic trie implementation for checking and generating proofs for a key / value pair.
pub struct BasicProvingTrie<Hashing, Hash, Key, Value>
    where
        Hashing: sp_core::Hasher<Out = Hash>,
{
    db: MemoryDB<Hashing>,
    root: Hash,
    _phantom: core::marker::PhantomData<(Key, Value)>,
}

impl<Hashing, Hash, Key, Value> ProvingTrie<Hashing, Hash, Key, Value>
for BasicProvingTrie<Hashing, Hash, Key, Value>
    where
        Hashing: sp_core::Hasher<Out = Hash>,
        Hash: Default + Send + Sync,
        Key: Encode,
        Value: Encode + Decode,
{
    fn generate_for<I>(items: I) -> Result<Self, DispatchError>
        where
            I: IntoIterator<Item = (Key, Value)>,
    {
        let mut db = MemoryDB::default();
        let mut root = Default::default();

        {
            let mut trie = TrieDBMutBuilderV0::new(&mut db, &mut root).build();
            for (key, value) in items.into_iter() {
                key.using_encoded(|k| value.using_encoded(|v| trie.insert(k, v)))
                    .map_err(|_| "failed to insert into trie")?;
            }
        }

        Ok(Self { db, root, _phantom: Default::default() })
    }
}

This is where I'm calling generate_for()

type BalanceTrie = BasicProvingTrie<BlakeTwo256, H256, String, u128>;
    let trie = BalanceTrie::generate_for(map).expect("Root not generated");

Cargo.toml

[dependencies]
csv = { version = "1.3.0", default-features = false }
hex = { version = "0.4.3", default-features = false }
log = { version = "0.4.22", default-features = false }
sp-core = { version = "34.0.0", default-features = false }
sp-runtime = { version = "39.0.0", default-features = false }
codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" }
sp-std = { version = "14.0.0", default-features = false }
sp-trie = { version = "37.0.0", default-features = false }
anyhow = "1.0.86"

If i run cargo build --release with the above code then I'm getting this error:

error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
  --> /Users/deepak/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sp-runtime-interface-28.0.0/src/impls.rs:45:1
   |
45 | assert_eq_size!(usize, u32);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: source type: `usize` (64 bits)
   = note: target type: `u32` (32 bits)
   = note: this error originates in the macro `assert_eq_size` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
  --> /Users/deepak/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sp-runtime-interface-28.0.0/src/impls.rs:47:1
   |
47 | assert_eq_size!(*const u8, u32);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: source type: `*const u8` (64 bits)
   = note: target type: `u32` (32 bits)
   = note: this error originates in the macro `assert_eq_size` (in Nightly builds, run with -Z macro-backtrace for more info)

But If I add std in cargo.toml, then it is compiling successfully.

[features]
default = ["std"]
std = [
    "sp-runtime/std",
]

2 Answers 2

1

sp-runtime-interface compiled without std will force to be compiled in a 32bits environment, but you want to compile to wasm which is 32bits AFAIK.

So you can compile to std for testing with:

cargo build --release

And compile to wasm without std using:

cargo build --release --target wasm32-unknown-unknown --no-default-features
0

Try another version of sp_runtime: https://paritytech.github.io/polkadot-sdk/master/src/sp_runtime/traits.rs.html#1028

Latest version no longer requires std for BlakeTwo256

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.