Skip to content
This repository was archived by the owner on Sep 3, 2021. It is now read-only.
This repository was archived by the owner on Sep 3, 2021. It is now read-only.

CIDs across the message channels #109

@Gozala

Description

@Gozala

In the context ipfs/js-ipfs#3022 I'm running into problem with CIDs that is not too dissimilar from ones that come from Buffers. I would like to bring those up here for a discussion.

Problem

When you post things across browsing contexts data browsers perform structured cloning which implies that only handful of things will come out with the same prototype chain on the other end. Including table from MDN below:

Supported types

Object type Notes
All primitive types However, not symbols.
Boolean objects
String objects
Date
RegExp lastIndex is not preserved.
Blob
File
FileList
ArrayBuffer
ArrayBufferView Including other typed arrays.
ImageBitmap
ImageData
Array
Object Only plain objects (e.g. from object literals)
Map
Set

This implies that node Buffers come out as Uint8Arrays (as they are sub-classes) and CIDs come out as plain objects, that is following most of the time:

{
  version: 0|1,
  codec: string,
  multihash: Uint8Array,
  multibaseName: string
}

Which is problematic because e.g. dag-cbor encoder will not recognize such structures as CID and would encode it as JSON. In other words only way for things to work across message-channel we need either to:

  1. DeepCopy+Encode -> Structure Clone -> Traverse+Decode

    • Sender needs to deep-copy arbitrary data structures to swap CIDs with some encoded version.
    • Which browser will structure clone (another copy).
    • Receiver needs to traverse inputs to find endoced CIDs and swap those with decoded instances (I think copying can be avoided here)
  2. Structure Clone -> Traverse+Decode

    • CID class can be made recognizable to remove need for deep-copy + CID encoding.
    • Browser will structure clone.
    • Receiver will traverse inputs to find structure cloned CIDs and swap those with decoded instances

Neither of two is ideal. What would be much better if CID had a canonical representation that is not tied to specific class. Kind of how ArrayBuffer represents bytes and Uint8Array is just a view.

I am recognizing that this might be almost impossible change to make at this point, however it is still worse having a discussion I think. Furthermore there might be certain compromises that may provide workable compromise. E.g. if all the IPFS internals did recognized canonical representation which is not tied to CID class that would remove need for decode / encode at least on messages going from client to server. I can also imagine that new Block API might be made to recognize that canonical representation which would effectively remove need for arbitrary traversals and limit CID encode / decode to very specific API endpoints.

/cc @mikeal @vmx @achingbrain @hugomrdias @lidel

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions