ipld / serde_ipld_dagcbor

DAG-CBOR implementation for Serde
Other
10 stars 8 forks source link

non-canonical encoding #31

Closed wellcaffeinated closed 6 months ago

wellcaffeinated commented 6 months ago

Hey there. I've been using the ipld/dag-cbor library to encode my data.

I just tried using this crate to encode the same data and noticed that it encodes it in the order the struct is declared in.

Here's a test you can run:

#[test]
  fn test_canonical(){
    use serde::{Serialize, Deserialize};
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct First {
      a: u32,
      b: u32,
    }
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Second {
      b: u32,
      a: u32,
    }

    let first = First { a: 1, b: 2 };
    let second = Second { a: 1, b: 2 };

    let first_bytes = DagCborCodec::encode_to_vec(&first).unwrap();
    let second_bytes = DagCborCodec::encode_to_vec(&second).unwrap();

    assert_eq!(first_bytes, second_bytes);

  }

it fails with:

assertion `left == right` failed
  left: [162, 97, 97, 1, 97, 98, 2]
 right: [162, 97, 98, 2, 97, 97, 1]
rvagg commented 6 months ago

@vmx do we not sort maps when it comes from a struct? It should be the first of these encodings for both cases.

vmx commented 6 months ago

Thanks for the bug report and the test to reproduce it. I can see where the problem is, I'm working on a fix, which hopefully also catches all other cases.

wellcaffeinated commented 6 months ago

Fantastic! Thanks for the quick turnaround.