Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

non-canonical encoding #31

Closed
wellcaffeinated opened this issue Apr 20, 2024 · 3 comments · Fixed by #34
Closed

non-canonical encoding #31

wellcaffeinated opened this issue Apr 20, 2024 · 3 comments · Fixed by #34

Comments

@wellcaffeinated
Copy link

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
Copy link
Member

rvagg commented Apr 20, 2024

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

@vmx
Copy link
Member

vmx commented Apr 22, 2024

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.

vmx added a commit that referenced this issue Apr 22, 2024
Rust structs have their entries ordered the same way as they are
defined. When serialized to CBOR, they become maps by default. In
 DAG-CBOR the maps need to have a specific order, hence the keys
might need to be re-ordered, so that they are independent of the
order they were defined. This commit makes sure that it's actually
the case.

Fixes #31.
vmx added a commit that referenced this issue Apr 22, 2024
Rust structs have their entries ordered the same way as they are
defined. When serialized to CBOR, they become maps by default. In
 DAG-CBOR the maps need to have a specific order, hence the keys
might need to be re-ordered, so that they are independent of the
order they were defined. This commit makes sure that it's actually
the case.

Fixes #31.
@vmx vmx closed this as completed in #34 Apr 24, 2024
vmx added a commit that referenced this issue Apr 24, 2024
Rust structs have their entries ordered the same way as they are
defined. When serialized to CBOR, they become maps by default. In
 DAG-CBOR the maps need to have a specific order, hence the keys
might need to be re-ordered, so that they are independent of the
order they were defined. This commit makes sure that it's actually
the case.

Fixes #31.
@wellcaffeinated
Copy link
Author

Fantastic! Thanks for the quick turnaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants