ink icon indicating copy to clipboard operation
ink copied to clipboard

`ink_codec` library to use dynamic dispatch instead of monomorphization

Open xgreenx opened this issue 3 years ago • 1 comments

As part of our grant, we want to help to reduce the size of contracts. We analyzed the binary(web assembler) file and found that ink! generates many the same code in the case of scale::Decode and scale::Encode.

So, we decided to create the ink_codec library which allows us to use it in a dynamic dispatch manner.

Example of traits:

pub trait Encodable {
    /// Convert self to an owned vector.
    fn encode(&self) -> Vec<u8> {
        let mut dest = Vec::new();
        self.encode_to(&mut dest);
        dest
    }

    /// Convert self to a slice and append it to the destination.
    fn encode_to(&self, dest: &mut dyn Output);
}

pub trait Decodable {
    /// Attempt to deserialize the value from input.
    /// 
    /// # Note
    /// The object must exist before calling the `decode`.
    fn decode(&mut self, input: &mut dyn Input) -> Result<(), Error>;
}

We've already started working on this change(it is based on the code of release 3.0-rc5). This issue is needed to avoid duplication of work(as it was with https://github.com/paritytech/ink/issues/945) and track the progress. After the implementation of the change, we will provide a report about the size of ERC-20(and maybe other heavy contracts from the example folder) and the source code. If the result is good and you agree with our idea, we will open a pull request.

xgreenx avatar Oct 21 '21 08:10 xgreenx

Note that dynamic dispatch prevents tons of optimizations that the compiler usually can perform with static dispatch and inlined functions. So inlining usually is not only evil with respect to Wasm file sizes but might even be superior to what you save through dynamic dispatch and non-inlining. Still, I am looking forward to your research results.

Robbepop avatar Oct 21 '21 10:10 Robbepop