A Condensation store holds a set of immutable objects, and a set of accounts with mutable boxes. It provides 5 functions to access the object store and the boxes.
The object store keeps a set of hash → object pairs (usually structured as a hash table) and exposes 2 functions.
Given a hash, this function returns the corresponding object, or a not found message.
Stores an object. The object must exist when the function returns.
For efficiency, most protocols often offer an additional function to check for object existence prior to uploading its contents:
The account store keeps a set of accounts. An account is identified by the hash of the actor's public key object and consists of 3 boxes:
- public box
- private box
- message box
A box stores a set of hashes, each of which points to an existing envelope object in the object store.
Public and private box typically hold a 1-2 hashes, while the message box may contain thousands of hashes.
The account store exposes 3 functions.
Returns the set of hashes currently stored in the box. Each hash points to an envelope object. If the account or box does not exist, or has never been used before, an empty list is returned.
Adds a hash to a box. The hash is added before the function returns, but a concurrent removal request may remove it before the function returns. A store may refuse to add the hash if the corresponding object does not exist, or is not an envelope.
Removes a hash from a box. The function may return immediately, and defer the actual removal. An actor may only remove hashes from its own boxes, or envelopes that he sent.
Many stores offer a modify operation to put objects, add hashes, and remove hashes in a single request.
A public store should authenticate actors, and enforce the following access rights:
|put object||registered actors|
|list box||message box||any actor mentioned on the account's public card, or everybody¹|
|private box||any actor mentioned on the account's public card, or everybody¹|
|private box||authenticated actor|
|public box||authenticated actor|
|remove hash||any sender or recipient mentioned on the envelope, and any actor mentioned on the account's public card|
- Granting access to everybody does not undermine data security, but unnecessarily leaks side information about the user's behavior.
- For non-registered actors, the envelope size is usually limited to 16 KiB, and submissions may be rate-limited.
Any request may fail before or after its execution. Typical reasons for failure include:
- Failing disks, full disks, or other problem related to the underlying storage system.
- Problems related to the network, resulting in intermittent or no connectivity.
- Requests with incomplete or invalid parameters, such as objects larger than the supported size, dangling links on complete stores, or unsupported box labels. These usually point to errors in the application.
Concurrent requests may be executed (and completed) in any order.
Add requests must behave atomically. If a list request sees the new object hash, all following list requests must see the hash as well, until it is removed.
Remove requests provide no such guarantees. Hashes may disappear in any order, and even reappear sporadically.
At any time, a store may remove objects that are not referenced (directly or indirectly)
- through any box
- a recently uploaded (or booked) object
General-purpose stores should keep uploaded or booked objects with all their descendants for at least one hour. Stores for specific purposes may use shorter timeouts.
Stores are not obliged to carry out garbage collection in a regular fashion, or within a certain time.
The above functions are sufficient to run the Condensation protocol. A store implementation may offer additional functions, however, e.g. functions to create or remove accounts.