Page: Distributed storage (SLOT1)
2019-12-13 20:12
Distributed storage (SLOT1)
Topic: Java API
See other Java API features at Software Developer Central: Java API at whole, Contracts Service, Distributed Storage, etc.
To start using Java API, you can add com.icodici:universa_core:3.13.3 dependency from Universa public Maven repository. See more details at Maven repository page.
This feature is available in package com.icodici.universa.node2.network
, as a part of Client
class; see it on GitHub at
Concepts
Distributed storage is designed to provide secure distributed storage over the Universa network: each Universa node keeps its copy of the information and receives payment for it. The client can query the network for the information in the distributed storage and receive its copy from any node.
The balance
Universa keep information in the pre-paid storage slots where both storage space and time are charged. The unit to measure data storage for some period of time is a storage unit, which allows to store 1024 bytes of data for 24 hours, or, Kilo-Day, or KD.
As space and time could be traded, the 100kd is enough to keep 10kb of data for 10 days, or 100kb of data for 1 day.
It sounds more complex than it actually is. In fact, the system recalculates the number of storage days left each time the amount of stored data is changed. For example, you can keep one revision, and the new revisions may be both bigger and smaller than the first revision kept. Therefore the system recalculates storage time left every time the revision changes.
The KD rate
KD can be purchased for U (stage 1) and UTN (stage 2) only. The current rate can be achieved with special API call.
Storage slots
The SLOT is a simplest storage unit capable of keeping the latest revisions of some contract, tracked contract. User create a slot contract, prepays some KDs and puts some data in it. The slot keeps the contract and updates it as new revisions appear as long as the balance is positive and the new revision owner matches slot creator keys.
In the other words, one can prepay the keeping only own contracts, when ownership is transferred, the slot will not copy and retain contract data anymore. In that case, though, slot owner can update the slot with new keys to keep the track providing these are in its disposal.
Slots are manipulated by creating and updating special kind of Universa smart contract.
Other types of storage
We plan to add the general binary data storage to hold any type of information, stay tuned for updates.
API
Unless it is otherwise specified, all API calls are performed using Universa protected client channel using client key authorization.
Get the KD rate (under develop)
storageGetRate() -> { "U" : decimal_string }
Returns the rate at the call moment. There is no guarantee the rate will not be changed in the future.
Create a slot
The client creates a special contract type using the prepaid parcel with a minimum payment of 100U (which is roughly equivalent to €1). The smaller payment will not be accepted and the slot will not be created. The payment will be converted to KDs balance using the current KD rate as the prepaid balance.
The contract to store and track is stored inside the slot contract (in data section). The prepaid balance should be enogh to keep the stored contract for 30 days. In other words, if the transaction pack of the stored contract takes 8kb of disk space, the prepaid balancs should be at least 240KD. If it is less, the slot contract will not be approved and the slot will not be created.
definition.extended_type: SLOT1
(note thatdefinition.extended_type
is not available for free usage, unlikedefinition.data
so this key won't be misused by occasion).creator role
: sign in with all keys needed to playowner
role in the tracking contractstate.data.tracking_contract
: the transaction pack with contract data to store and track. Note that the contract will always be accepted as long as the balance is above minimal, but its newer revisions will be tracked only as long as new revision owner role can be played with lates slot contract revision creator keys. E.g. one can store anything, but can track only own changes.state.data.keep_revisions: (int)
: positive number. Will keep up to specified number of revisions. Older revisions will be dropped automatically.modify_data
permission ondata.action
field, better allowed forowner
role. It is important to perform actions such as top up the balance or close the slot passing the remaining balance to another slot.
It is important to add permissions to modify tracking contract and
keep_revisions
field to be able to edit slot settings.
The Node checks that the slot is OK and balance is enough, and then registers the contract as usual and creates the storage slots, returning a slot state extra result (ItemResult#extra).
Slot state structure
{
slot_id: binary,
expires_at: unixtime,
data_size: int_bytes,
tracking_origin: binary_ID,
revisions: [
{ revision: int, id: binary_ID, size: int_size_in_bytes }
]
}
slot_id
: is the origin of the slot contratexpires_at
: time to slot expiration providing no data will be changed.data_size
: number of bytes used with all revisions kepttracking_origin
: the origin of the tracking contractrevisions
: revisions in the storage, for each the revition number andid
are returned.
Note that the slot contract is also kept in the distributed storage and its size is counted in data_size
, so the data_size > sum(revisions.size)
so the difference is the slot contract size.
Change the slot
Is performed by approving new version of the slot contract, as usual, like chaging the tracking contract, changing the number of kept revisions and so on.
Important. When the tracking contract is being reassigned, it clears the storage, so all the information in it will be lost.
Returns the slot state structure, as slot creation does.
If the change is made with a paying parcel, the extra payment will top up the slot balance.
Top up the balance
Create a new revision with a paying parcel with desired payment, set the data.action: top_up/(timestamp)
where timestamp should be current unix timestamp.
Returns the slot state structure.
Close the slot
Under considering.
Querying the slot info (under develop)
Is performed using an authenticated API call:
queryContract(slot_id: binary)
-> (slot state structire)
Getting the stored contract
Is performed using an authenticated API call:
queryContract(slot_id: binary, origin_id: binary, contract_id: binary)
-> binary
Only one origin_id
or contract_id
is allowed. For the origin_id
the latest revision will be returned.