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

fix: unique metadata is not properly typed as a Uint8Array #3141

Closed
wants to merge 2 commits into from

Conversation

dbcfd
Copy link
Contributor

@dbcfd dbcfd commented Feb 2, 2024

multiformats will fail encoding unless this is specifically a Uint8array

@dbcfd dbcfd requested review from PaulLeCam and stbrody February 2, 2024 22:13
@PaulLeCam
Copy link
Contributor

Seems like this change fixes a symptom rather than the cause of the issue. Why isn't the cloned value a Uint8Array in the first place please?

@dbcfd
Copy link
Contributor Author

dbcfd commented Feb 5, 2024

Seems like this change fixes a symptom rather than the cause of the issue. Why isn't the cloned value a Uint8Array in the first place please?

Arrays coming through http client won't be a Uint8array. We would need to adjust the parser to force this to be a uint8array, but that would leak this logic into the http server, which doesn't need to care that it is a uint8array.

@PaulLeCam
Copy link
Contributor

Arrays coming through http client won't be a Uint8array. We would need to adjust the parser to force this to be a uint8array, but that would leak this logic into the http server, which doesn't need to care that it is a uint8array.

That's why we encode the Uint8Arrays to base64 in the client, no? I don't think in any case the Uint8Arrays should be encoded as regular Arrays in the APIs, that would make us lose the information that it's binary data.

@stbrody
Copy link
Contributor

stbrody commented Feb 5, 2024

We would need to adjust the parser to force this to be a uint8array, but that would leak this logic into the http server, which doesn't need to care that it is a uint8array.

Isn't the parser the exact right place to be doing type conversions and enforcement? Generally good practice is do all your parsing, validation, and type conversation at the edge of the system, then have something strongly typed and of the structure you want everywhere else inside the bounds of the system.

By "parser" here I'm talking about the codeco codec we use to explicitly parse messages once they come in to the http endpoint. That seems like the right place for this.

@dbcfd
Copy link
Contributor Author

dbcfd commented Feb 6, 2024

@PaulLeCam @stbrody It's possible it's being decoded correctly at the http layer, but then "lost" when we put it in stream state.

export interface StreamMetadata { controllers: Array<string> model?: StreamID context?: StreamID family?: string // deprecated schema?: string // deprecated tags?: Array<string> // deprecated forbidControllerChange?: boolean // deprecated, only used by TileDocument [index: string]: any // allow arbitrary properties }

Unique is in the arbitrary properties, so does not retain information that it is a Uint8array. Should unique be a field in StreamMetadata?

@stbrody
Copy link
Contributor

stbrody commented Feb 6, 2024

Unique is in the arbitrary properties, so does not retain information that it is a Uint8array. Should unique be a field in StreamMetadata?

Yeah I'd be down with adding unique to StreamMetadata. Honestly I kind of feel like StreamMetadata should not allow arbitrary additional properties, each new field added to metadata should be added to the type explicitly. Tagging in @ukstv in case he disagrees on that

@dbcfd
Copy link
Contributor Author

dbcfd commented Feb 7, 2024

Unique is in the arbitrary properties, so does not retain information that it is a Uint8array. Should unique be a field in StreamMetadata?

Yeah I'd be down with adding unique to StreamMetadata. Honestly I kind of feel like StreamMetadata should not allow arbitrary additional properties, each new field added to metadata should be added to the type explicitly. Tagging in @ukstv in case he disagrees on that

Although we can do this, it doesn't fix the problem, since unique can be Uint8Array | string in GenesisHeader. But if we change that, we may still find unique as a Uint8Array since GenesisHeader extends CommitHeader which has [index: string]: any // allow support for future changes.

Additionally, the SET relation functionality specifies a unique with is an array of string joined by | and converted as a utf-8 to a Uint8array, whereas other places convert it to/from base64.

TLDR: This is the easiest fix, whereas other fixes cascade with impacts, possibly on the statestore.

@stbrody
Copy link
Contributor

stbrody commented Feb 7, 2024

@dbcfd can you share what made you open this PR in the first place? Are you seeing some behavior in the wild? Is there a repro of the issue you can share?

@dbcfd
Copy link
Contributor Author

dbcfd commented Feb 14, 2024

@dbcfd can you share what made you open this PR in the first place? Are you seeing some behavior in the wild? Is there a repro of the issue you can share?

3box/ceramic-http-client-rs#9 includes the ability to create single/deterministic models and model instances. Attempting to do so will fail because of this issue.

@dbcfd
Copy link
Contributor Author

dbcfd commented Feb 14, 2024

fixed by #3149 (or possibly another PR)

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 this pull request may close these issues.

3 participants