CIDs¶
A CID (Content Identifier) is an immutable blob record managed by ip.cid.
Every binary file that crosses a swarm boundary — attachments, avatars, arbitrary payloads — is transferred by content hash rather than by URL, so any node that holds the blob can serve it and duplicates are automatically merged.
The cid field is a transport-specific checksum: SHA-1 for HTTP, CIDv1 for Kubo/IPFS.
Once a CID record is created, its ip.cid.cid and ip.cid.data_raw fields are immutable — the same hash always resolves to the same bytes.
New CID records are created idempotently via ip.cid.find_or_create(), which returns an existing record if the CID is already known.
See also
Technical references — sync_base.ip.cid, sync_http.ip.cid.
Fields¶
Field |
Description |
|---|---|
Sync Content Identifier (CID) string
|
|
State of the CID in the Sync network
See States below for the full state machine. |
|
Raw binary content of this CID, stored via ir.attachment in Odoo’s filestore. Odoo automatically detects duplicate filestore content and stores it only once.
|
|
Byte size of the stored raw binary content.
|
|
The node that first broadcasted this CID. Used by HTTP transport to locate the file.
See CID Resolution below. |
|
Events that reference this CID.
Inverse of |
States¶
wanted ──▶ pending ──▶ pinned
└──▶ failed
└──▶ oversized
State |
Meaning |
|---|---|
|
Referenced by an event but not yet fetched from the network. |
|
Fetch is in progress. |
|
Content is locally available in |
|
Fetch failed permanently; check gateway logs for the error. |
|
Blob exceeds the transport size limit (default 10 MB). Reduce the payload or raise the limit in gateway config. |
CID Resolution¶
While the CID state machine is transport-agnostic, the mechanism for resolving a CID depends on your swarm’s network layer:
HTTP Transport: The node acts as a direct client. It calls
ip.node.cat()on the sender’s host node (via the blob endpoint) to download bytes synchronously.Kubo Transport: The node acts as a P2P participant. It relies on the Kubo daemon to locate the blob via the DHT or direct P2P connections.
The waiting state is the “buffer” for both transports—it ensures your database never imports a record until the associated binary data is fully verified and available in your local filestore.
See also
sync_base — blob endpoints (blob_content_bearer, blob_content_user) that serve CID content to authenticated callers.
Fetch Flow¶
An inbound event references a CID string in its payload. The
is_cidtrait in the mapping engine creates awantedip.cidrecord and blocks the event inmapping_state: waiting.The gateway picks up the
wantedCID and enqueues it for download. HTTP:_http_fetch_wanted_cids()issues a synchronous fetch. Kubo:ip.swarm._express_fetch_cids()triggers the sidecar’s priority fetch queue.The fetcher calls
ip.node.cat()onhost_node_idto retrieve the raw bytes.On success:
data_rawis written,cid_statetransitions topinned, andhost_node_idis re-anchored to the local gateway. For attachments,ir.attachment._get_sync_cid()handles the lazy CID computation and links the resultingip.cidto their.attachment.cid_idfield.Any events that were
waitingon this CID are automatically re-queued for mapping.On failure:
cid_statetransitions tofailed(network error) oroversized(blob exceeds the transport size limit).
Fetch Content — action_fetch_content()
Manually triggers steps 3—5 for a single CID record.
Raises UserError if no host node is set or if the node returns no content.
See also
Odoo Schema —
is_cidtrait: how CIDs attach to schema fields, thewaitingblock, and theMissingCidErrorflow.HTTP Transport — HTTP CID resolution (synchronous request-response).
Kubo / IPFS Transport — Kubo CID resolution (DHT, priority queue).
sync_base.ip.cid— technical reference.