Stores Actors Data Tree Downloads
Architecture Encryption Folder HTTP


A Condensation store holds a set of immutable objects, and a set of accounts with mutable boxes. It offers 5 functions to access the object store and the boxes.

Object store public put object get object list add ... Account store private in-queue public private in-queue public private in-queue remove


An object consists of a list of hashes and data:

H Data Hashes (H ⨯ 32 bytes)

H is a 4-byte big-endian integer denoting the number of hashes. Each following hash is a reference to another object. The data is simply a sequence of bytes, and usually encrypted.

Objects are identified by their SHA-256 hash:

Object hash ⇐ SHA-256 of

Hashes are always 32 bytes long, and sometimes written as 64 hexadecimal digits. Through the hash list, an object may span a tree:

Data Hashes Hash
Objects and trees are inherently immutable. If their content changes, their hashes inevitably change, too.


Since a single hash may refer to an arbitrarily large tree (with an arbitrarily large amount of data), the state of some data is entirely defined by its tree hash (root object hash). Such tree hashes are stored in boxes.

A box holds a small number of entries. A box entry consists of:

Store URLs are used to point to objects on other stores.


An account consists of three boxes:

Object store interface

An object store keeps a set of hash → object pairs, usually structured as a hash table, and exposes 2 functions.

Get object

getobject Hash Object bytes Not found

Given a hash, this function returns the corresponding object, or a not found message.

Put object

putobject HashObject bytes OK putobject Object bytes Hash Wrong hash

This function stores an object. The object must exist when the function returns. Depending on the protocol, one or both of the above versions of this function may be available.

Many stores offer an additional function to check for object existence prior to upload its contents:

bookobject Hash Booked Not found

Account store interface

The account store keeps a set of accounts with 3 boxes each (in-queue, private, public), and exposes 3 functions.

List box

list Account identifierBox label Set of object references

This function returns the set of references currently stored in the box. Each reported reference is either a hash, or an object URL. If the account or box does not exist, or has never been used before, an empty list is returned.

Add object reference

add Account identifierBox labelObject reference Success

This function adds an object reference to a box. The reference must be added (or exist already) before the function returns. It however may not exist any more when the function returns, as a concurrent removal request may have deleted it.

Remove object hash

remove Account identifierBox labelHash Success

This function removes all object references with a given hash from a box. The function may return immediately, and defer the actual removal.

For increased efficiency, addition and removal are usually implemented as a single account modification function.


Any request may fail for technical reasons, such as storage system failures, full disks, or network errors. Note that requests may fail before or after their execution. Subsequent requests may again succeed.


Concurrent requests may be executed (and completed) in any order.

Add requests must behave atomically. If a list request sees the object reference, all following list requests must see the reference as well until its removal.

Remove requests provide no such guarantees. Affected object references may disappear one-by-one (in any order), and even reappear.

Additional functions

The above functions are sufficient to run the Condensation protocol. A store implementation may expose additional functions, however, e.g. functions to create or close accounts.

Garbage collection

At any time, a store may remove objects that are not referenced (directly or indirectly) through any box. Stores should however avoid deleting objects created recently, as they may have been uploaded, but not referenced in any box yet.

When and how garbage collection is performed is up to the implementation.