-
Notifications
You must be signed in to change notification settings - Fork 280
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
fetch: Change identifier pb type from string
to bytes
?
#656
Comments
string
to bytes
?string
to bytes
?
This is a backwards compatible change, as you say. Given that we are already treating it as bytes, I think this is a reasonable change. Could you please add a link to the code that treats this as bytes just for reference? |
Makes sense to me, this is likely just a bug in the original spec since it is used in practice for arbitrary bytes (e.g. the IPNS example you gave). |
I think it's this line:
...which receives the identifier here: Unless I'm mis-reading the code, I think the problem is that the fetch protocol as implemented in If it had some sort of per-prefix lookup function or other indirection we could use the IPNS Name string representation instead and |
To allow use cases like fetching IPNS records in a way compatible with go-libp2p we need to send binary as fetch identifiers. JavaScript strings are UTF-16 so we can't round-trip binary reliably since some byte sequences are interpreted as multi-byte characters. Instead we need to accept Uint8Arrays and send them over the wire as-is. Refs: libp2p/specs#656 BREAKING CHANGE: registered lookup functions now receive a Uint8Array identifier instead of a string
Allows the use case of fetching IPNS records via go-libp2p-pubsub-router's fetch implementation from environments such as JavaScript where you cannot reliably round-trip bytes to strings and back due to strings being UTF-16. Fixes #656
To allow use cases like fetching IPNS records in a way compatible with go-libp2p we need to send binary as fetch identifiers. JavaScript strings are UTF-16 so we can't round-trip binary reliably since some byte sequences are interpreted as multi-byte or otherwise non-printable characters. Instead we need to accept Uint8Arrays and send them over the wire as-is. This is a backwards compatible change as far as interop goes since protobuf `bytes` and `string` types are identical on the wire, but it's breaking for API consumers in that the lookup function now needs to accept a `Uint8Array` identifier instead of a `string`. Refs: libp2p/specs#656 BREAKING CHANGE: registered lookup functions now receive a Uint8Array identifier instead of a string
The
fetch
protocol uses this protobuf:One use case for fetch is resolving IPNS records directly from other nodes (ref).
The identifier for this operation is
"/ipns/" + public-key-multihash-bytes
.Treating
identifier
as astring
means we need to stringify the value before serializing it to pb bytes, and we'll also interpret any received value as a string.golang treats
public-key-multihash-bytes
as a char array so this works as expected.JavaScript strings are all
UTF-16
, all the time so it's possible to have a series of bytes that we can't round trip to a string if some pairs of byte values happen to be interpretable as a multi-byte character.Since the on-the-wire format of
string
andbytes
in protobuf is identical, JS could just unilaterally treatidentifier
asbytes
to make the problem go away, or we can change the type in the spec definition so it's clear for implementers?cc @aschmahmann
The text was updated successfully, but these errors were encountered: