paritytech / paritytech/parity-scale-codec

Implement `MaxEncodedLen` for all types that don't implement it and return 0

Open
#465 9 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
287
Forks
103
Avg merge
6d 13h
Merged PRs (30d)
1

Description

Сoncept

For example, we have some type of data that can be encoded. We also have a function in the smart contract to send the encoded value to some other address.

#[derive(Debug, Encode, Decode, TypeInfo/*, MaxEncodedLen*/)]
#[codec(crate = gstd::codec)]
#[scale_info(crate = gstd::scale_info)]
pub enum FTEvent {
    Transfer {
        from: ActorId,
        to: ActorId,
        amount: u128,
    },
    // ...
    Balance(u128),
}

pub fn send<E: Encode>(program: ActorId, payload: E, value: u128) -> Result<MessageId> { ... }

If we add an implementation of MaxEncodedLen for all types that do not implement and return 0 in the max_encoded_len() method, then in this case the send(...) function will have the opportunity to choose where to encode the data type. If max_encoded_len() == 0 then encoding is done on the heap, otherwise on the stack.

pub fn send<E: Encode + MaxEncodedLen>(program: ActorId, payload: E, value: u128) -> Result<MessageId> {
    let max_encoded_len = E::max_encoded_len();
    match () {
        () if max_encoded_len == 0 => {
            //payload.encode() on the heap when max_encoded_len is not specified
            super::send_bytes(program, payload.encode(), value)
        }
        () if size <= 0x1 => {
            //use 0x1 stack size to encode
            let buf = [0u8; 0x1];
            payload.encode_to(&mut buf);
            //send_bytes(...)
        },
        () if size <= 0x2 => {
            //use 0x2 stack size to encode
            let buf = [0u8; 0x2];
            payload.encode_to(&mut buf);
            //send_bytes(...)
        },
        // ...
        () if size <= 0x4000 => {
            //use 0x4000 stack size to encode
            let buf = [0u8; 0x4000];
            payload.encode_to(&mut buf);
            //send_bytes(...)
        },
        _ => {
            //payload.encoded() on the heap when there is not enough space on the stack
            super::send_bytes(program, payload.encode(), value)
        }
    }
}

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by surveying the existing MaxEncodedLen implementations and the Encode and derive behavior in this codec. Determine which types currently lack the trait and how a zero return value should interact with encoding and generated implementations. Done means the intended types support the trait, the zero-size fallback is defined, and relevant codec tests cover the behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.