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

invalid map key type {type} #52

Open
pacu opened this issue Jun 10, 2024 · 3 comments
Open

invalid map key type {type} #52

pacu opened this issue Jun 10, 2024 · 3 comments

Comments

@pacu
Copy link

pacu commented Jun 10, 2024

when generating bindings for Go, the generated code fails with
invalid map key type ParticipantIdentifier

Example:

this struct is equatable yet, GoLang bindings don't generate code to make ParticipantIdentifier comparable in GoLang

note: this is not an issue on generated Swift Bindings

#[derive(uniffi::Record, Hash, Eq, PartialEq, Clone)]
pub struct ParticipantIdentifier {
    pub data: Vec<u8>,
}


#[derive(uniffi::Record)]
pub struct TrustedKeyGeneration {
    pub secret_shares: HashMap<ParticipantIdentifier, FrostSecretKeyShare>,
    pub public_key_package: FrostPublicKeyPackage,
}

This generates these two types in Go

type TrustedKeyGeneration struct {
	SecretShares     map[ParticipantIdentifier]FrostSecretKeyShare
	PublicKeyPackage FrostPublicKeyPackage
}

type ParticipantIdentifier struct {
	Data []byte
}

But there is not generated code to honor the Eq proc macro and make it possible for ParticipantIdentifier to be used as key on a map because the byte[] type is not comparable.

Edit: This might not have a simple solution. If someone is running into this problem you probably want to encode your bytes into a comparable primitive type. It's not ideal, but it works. For example, encode the data into a hex string using hex crate in Rust

@arg0d
Copy link
Collaborator

arg0d commented Jun 10, 2024

In Go, slices can't be used as map keys. Any ideas what to do in this case?

@pacu
Copy link
Author

pacu commented Jun 10, 2024

I ended up using a String but it's not ideal. Maybe the FFI code could actually create an intermediate type that it's actually comparable?

pacu added a commit to zecdev/frost-uniffi-sdk that referenced this issue Jun 10, 2024
This chances `ParticipantIdentifier` to be represented as a hex
string instead of bytes, because GoLang can use Bytes as a key
for maps [see](NordSecurity/uniffi-bindgen-go#52)
pacu added a commit to zecdev/frost-uniffi-sdk that referenced this issue Jun 10, 2024
This commit does:
- Downgrade to uniffi 0.25.0 because of Go bindings
- Fix compile error. upgrade macos to 10_15
- fix Swift build path for RustFramework
- Add cdylib type for [lib] so that GoLang can build bindings from
- proc_macros
- Generate Go Bindings
-
- changes `ParticipantIdentifier` to be represented as a hex
-   string instead of bytes, because GoLang can use Bytes as a key
-   for maps [see](NordSecurity/uniffi-bindgen-go#52)
- Go module + tests
- Add GoLang to README and build scripts
- Github action to build and test bindings
- Build and test swift package locally
- Fix target replacement
- remove pipefail because github action does not like it
- fix swift.yml
- fix build go bindings script
- fix go bindings generation
@arg0d
Copy link
Collaborator

arg0d commented Jun 12, 2024

I'm not super deep into Go, but from some light reading and asking ChatGPT, it does not seem possible to make arbitrary types compatible as map keys. In Go fixed-size arrays are valid map keys, but variable sized-arrays (slices) are not.

I think for your use case a fixed size array would work just as well, but unfortunately it looks like uniffi-rs upstream does not support fixed-size arrays.

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

No branches or pull requests

2 participants