paritytech / parity-scale-codec

Lightweight, efficient, binary serialization and deserialization codec
Apache License 2.0
246 stars 95 forks source link

More `codec` edge cases #555

Open mrcnski opened 8 months ago

mrcnski commented 8 months ago

https://github.com/paritytech/parity-scale-codec/issues/507 covers one but there are two more:

For example:

enum Foo {
    #[codec(index = 0)]
    #[codec(index = 1)]
    A,
    B,
}

This kind of bug can happen due to a copy/paste mistake or a mistake when resolving a merge conflict (as it did to me). When there are many attributes this kind of mistake can be hard to spot. In my case it resulted in the decoded value being different from the original value before encoding, which made for a fun debugging session.

mrcnski commented 8 months ago

Output of cargo expand

// before

PrepareError::JobDied { ref err, ref job_pid } => {
    __codec_dest_edqy.push_byte(10usize as ::core::primitive::u8);
    ::parity_scale_codec::Encode::encode_to(err, __codec_dest_edqy);
    ::parity_scale_codec::Encode::encode_to(
        job_pid,
        __codec_dest_edqy,
    );
}
PrepareError::Kernel(ref aa) => {
    __codec_dest_edqy.push_byte(10u8 as ::core::primitive::u8);
    ::parity_scale_codec::Encode::encode_to(aa, __codec_dest_edqy);
}

// after

PrepareError::JobDied { ref err, ref job_pid } => {
    __codec_dest_edqy.push_byte(10u8 as ::core::primitive::u8);
    ::parity_scale_codec::Encode::encode_to(err, __codec_dest_edqy);
    ::parity_scale_codec::Encode::encode_to(
        job_pid,
        __codec_dest_edqy,
    );
}
PrepareError::Kernel(ref aa) => {
    __codec_dest_edqy.push_byte(11u8 as ::core::primitive::u8);
    ::parity_scale_codec::Encode::encode_to(aa, __codec_dest_edqy);
}

Thanks @maksimryndin for researching it!