Infinit Logo Created with Sketch. memo logo
github logo  

Value Store API Reference

A comprehensive reference guide to the complete value store API.

Overview

Here is the list of all methods used in the value store API.

MakeImmutableBlock(MakeImmutableBlockRequest) Block
MakeMutableBlock(MakeMutableBlockRequest) Block
Fetch(FetchRequest) FetchResponse
Insert(InsertRequest) InsertResponse
Update(UpdateRequest) UpdateResponse
Delete(DeleteRequest) DeleteResponse

Generate Stubs

memo exposes a gRPC API, offering a portable and language-agnostic channel of interaction. gRPC relies on Protocol Buffers (protobuf) to serialize the remote procedure calls' (RPC) messages. The protocol format and the list of RPCs is described in a simple .proto file.

As a client, you need to download memo's official memo_vs.proto file for interacting with the key-value store API. You then have to generate the package/module/header/class (depending on the language or your choice) that will provide you with functions to easily call the RPCs.

NOTE: In C++, you will need to build the gRPC plugin for protoc. A clear procedure is given by the gRPC website.

$ go get -u github.com/golang/protobuf/protoc-gen-go 
$ export KVS_PROTO_OUT=$GOPATH/src/google.golang.org/grpc/memo/kvs 
$ mkdir -p $KVS_PROTO_OUT 
$ protoc --proto_path=$HOME/Downloads --go_out=plugins=grpc:$KVS_PROTO_OUT $HOME/Downloads/memo_vs.proto 
$ ls $KVS_PROTO_OUT 
memo_vs.pb.go
$ export KVS_PROTO_OUT=$HOME/projects/memo/src 
$ mkdir -p $KVS_PROTO_OUT 
$ protoc --proto_path=$HOME/Downloads --cpp_out=$KVS_PROTO_OUT --plugin=protoc-gen-grpc=$(whereis grpc_cpp_plugin) --grpc_out=$KVS_PROTO_OUT $HOME/Downloads/memo_vs.proto 
$ ls -lx $KVS_PROTO_OUT 
memo_vs.grpc.pb.cc memo_vs.grpc.pb.h memo_vs.pb.cc memo_vs.pb.h
$ python3 -m pip install grpcio grpcio-tools 
$ export KVS_PROTO_OUT=$HOME/projects/memo/src 
$ mkdir -p $KVS_PROTO_OUT 
$ python3 -m grpc_tools.protoc --proto_path=$HOME/Downloads --python_out=$KVS_PROTO_OUT --grpc_python_out=$KVS_PROTO_OUT $HOME/Downloads/memo_vs.proto 
$ ls -lx $KVS_PROTO_OUT 
memo_vs_pb2_grpc.py memo_vs_pb2.py

Deploy memo

To deploy a memo value store exposing a gRPC interface, please follow our "getting started with memo" guide.

Methods

MakeImmutableBlock

(MakeImmutableBlockRequest) Block

Ask for a brand new block, representing an ImmutableBlock.

The address of an ImmutableBlock is based on its owner public key and the payload of the block, given by the MakeImmutableBlockRequest. N.B. The Block is not pushed yet.

# Create the immutable block.
block = vs.MakeImmutableBlock(
  MakeImmutableBlockRequest(data = b'some data'))
# Actually insert the block.
vs.Insert(InsertRequest(block = block))
// Create the immutable block with a payload.
iblock, _ := client.MakeImmutableBlock(
               context.Background(),
               &vs.MakeImmutableBlockRequest{Data: []byte("some data")})
// Actually insert the block.
client.Insert(context.Background(), &vs.InsertRequest{Block: iblock})
// Create an immutable block creation request.
::memo::vs::MakeImmutableBlockRequest make_block;
// Set the payload.
make_block.set_data("some data");
// Create an empty block.
::memo::vs::Block block;
{
  // Create a context.
  grpc::ClientContext ctx;
  // Construct the immutable block and store it in `block`.
  auto status = vs->MakeImmutableBlock(&ctx, make_block, &block);
  if (!status.ok())
    throw std::runtime_error("Cannot make immutable block");
}
// Create a insertion response.
::memo::vs::InsertResponse insertion;
{
  // Create a context.
  grpc::ClientContext ctx;
  // Create an insertion request.
  ::memo::vs::InsertRequest insert;
  // Set the block to the insertion request using the setter.
  //
  // N.B. `mutable_block` is to access to a mutable version of the attribute
  // `block`. It's not correlated with MutableBlock or ImmutableBlock.
  insert.mutable_block()->CopyFrom(block);
  // Actually insert the block.
  auto status = vs->Insert(&ctx, insert, &insertion);
  if (!status.ok())
    throw std::runtime_error("Cannot insert block");
}
Arguments
MakeImmutableBlockRequest { bytes data,   bytes owner }
bytes data
bytes owner
Return
Block { string type,   bytes address,   oneof payload,   bytes salt,   bytes owner... see all
string type
bytes address
oneof payload — bytes data — bytes data_plain
bytes salt
bytes owner
bytes signature
bytes owner_rsa
bytes name
Key key_koh
int64 version
int64 editor
bytes owner_token
repeated ACLEntry acl
int64 data_version
bytes data_signature
bool world_readable
bool world_writable
repeated ACLEntry group_acl
repeated int64 group_version
bool deleted
Version seal_version
int64 next_seal_version

MakeMutableBlock

(MakeMutableBlockRequest) Block

Ask for a brand new Block, representing a MutableBlock.

The address is chosen randomly by the key-value store. Hence, the MakeMutableBlockRequest has no attributes. N.B. The Block is not pushed yet.

# Create the block, empty.
block = vs.MakeMutableBlock(MakeMutableBlockRequest())
# Set the block payload.
block.data_plain = b'some data'
# Actually insert the block.
vs.Insert(InsertRequest(block = block))
// Create the block, empty.
mblock, _ := client.MakeMutableBlock(context.Background(),
                                     &vs.MakeMutableBlockRequest{})
// Create a payload.
payload := []byte("some data")
// Set the block payload.
mblock.Payload = &vs.Block_DataPlain{payload}
// Actually insert the block.
client.Insert(context.Background(),
              &vs.InsertRequest{Block: mblock})
// Create an insertion request.
::memo::vs::InsertRequest insert;
// Create a mutable block creation request.
::memo::vs::MakeMutableBlockRequest empty;
// Construction.
{
   // Set a context.
   grpc::ClientContext ctx;
   // Create the mutable block and store the result in the insertion request
   // field.
   //
   // N.B. `mutable_` is to access to a mutable version of the attribute
   // `block`. It's not correlated with MutableBlock or ImmutableBlock.
   auto status = vs->MakeMutableBlock(&ctx, empty, insert.mutable_block());
   if (!status.ok())
     throw std::runtime_error("Cannot make mutable block");
   // Set the payload.
   insert.mutable_block()->set_data_plain("some data");
}
{
  // Create an insertion response.
  ::memo::vs::InsertResponse insertion;
  // Set a context.
  grpc::ClientContext ctx;
  // Actually insert the block.
  auto status = vs->Insert(&ctx, insert, &insertion);
  if (!status.ok())
    throw std::runtime_error("Cannot insert block");
}
Arguments
MakeMutableBlockRequest { }
Return
Block { string type,   bytes address,   oneof payload,   bytes salt,   bytes owner... see all
string type
bytes address
oneof payload — bytes data — bytes data_plain
bytes salt
bytes owner
bytes signature
bytes owner_rsa
bytes name
Key key_koh
int64 version
int64 editor
bytes owner_token
repeated ACLEntry acl
int64 data_version
bytes data_signature
bool world_readable
bool world_writable
repeated ACLEntry group_acl
repeated int64 group_version
bool deleted
Version seal_version
int64 next_seal_version

Fetch

(FetchRequest) FetchResponse

Fetch the block at given address.

# Fetch a block at the address given by `address`.
block = vs.Fetch(FetchRequest(address = address)).block
// Fetch a block at the address given by `address`.
res, _ := client.Fetch(context.Background(), &vs.FetchRequest{Address: address})
block := res.Block
// Create a fetch response.
::memo::vs::FetchResponse res;
// Create a context.
grpc::ClientContext ctx;
// Create a fetch request.
::memo::vs::FetchRequest fetch;
// Set the address to fetch request.
fetch.set_address(address);
// Actually fetch the block.
{
  auto status = vs->Fetch(&ctx, fetch, &res);
  if (!status.ok())
    throw std::runtime_error("Unable to fetch block");
}
// Retrieve the block.
auto block = res.block();
Arguments
FetchRequest { bytes address,   bool decrypt_data }
bytes address
bool decrypt_data
Return
FetchResponse { string type,   Block block }
string type
Block block
Exceptions
INVALID_ARGUMENT: The address format is invalid.
NOT_FOUND: Nothing at the given address.

Insert

(InsertRequest) InsertResponse

Insert a new Block.

The Block to insert is given by the InsertRequest. The Block should have been created by using Make<...>Block. Insert returns an InsertResponse, containing the information related to the Insertion.

# Given a block `block`, insert the block.
vs.Insert(InsertRequest(block = block))
// Given a block `block`, insert the block.
//
client.Insert(context.Background(),
              &vs.InsertRequest{Block: block})
// XXX: wrong.
//
// Depending on the type of block (mutable or immutable), insertion differs.
//
// Given a mutable block `mblock`, insert the mutable block.
{
  // Create an insert response.
  ::memo::vs::InsertResponse insertion;
  // Create a context.
  grpc::ClientContext ctx;
  // Create an insertion request.
  ::memo::vs::InsertRequest insert;
  // Set the block to the insertion request using the setter.
  //
  // N.B. `mutable_block` is to access to a mutable version of the attribute
  // `block`. It's not correlated with MutableBlock or ImmutableBlock.
  insert.mutable_block()->set_data_plain("some data");
  // Actually insert the block.
  auto status = vs->Insert(&ctx, insert, &insertion);
  if (!status.ok())
    throw std::runtime_error("Cannot insert block");
}
// Given a immutable block with a payload already set, insert a immutable block.
{
  // Create an insert response.
  ::memo::vs::InsertResponse insertion;
  // Create a context.
  grpc::ClientContext ctx;
  // Create an insertion request.
  ::memo::vs::InsertRequest insert;
  // Set the block to the insertion request using the setter.
  //
  // N.B. `mutable_block` is to access to a mutable version of the attribute
  // `block`. It's not correlated with MutableBlock or ImmutableBlock.
  insert.mutable_block()->CopyFrom(block);
  // Actually insert the block.
  auto status = vs->Insert(&ctx, insert, &insertion);
  if (!status.ok())
    throw std::runtime_error("Cannot insert block");
}
Arguments
InsertRequest { Block block }
Block block
Return
InsertResponse { string type,   bool bool }
string type
bool bool
Exceptions
NOT_FOUND: Nothing at the given address.
INTERNAL: See message but can be: collision, etc.

Update

(UpdateRequest) UpdateResponse

Update an existing block.

The address and the new content of the Block are given by the UpdateRequest. Update doesn't perform an upsert, hence, the update will fail if the block doesn't exist, but also you are not allowed to update it. The UpdateResponse will contain the information related to the result of the insertion attempt.

# Given a block `block` and a payload `payload`.
#
# Set the block new payload.
block.data_plain = payload
# Perform the update.
#
# Setting the update request `decrypt_data` field to `True` so the `block`
# field of the update response will be decrypted. This is useful if you need
# to fix potential conflicts resulting of the update.
response = vs.Update(UpdateRequest(block = block,
                                   decrypt_data = True))
if response.current:
  # Solve conflict here, `response.current` contains the current version of
  # the block in the value-store.
  pass
// Given a block `block` and a payload `payload`.
//
// Set the block new payload.
block.Payload = &vs.Block_DataPlain{payload}
// Perform the update.
//
// Setting the update request `DecryptData` field to `true` so the `Block`
// field of the update response will be decrypted. This is useful if you need
// to fix potential conflicts resulting of the update.
status, _ := client.Update(context.Background(),
                           &vs.UpdateRequest{Block: block,
                                             DecryptData: true})
// If there is a conflict.
if (status.GetCurrent() != nil) {
  // Solve conflict here, `response.block` contains the current version of
  // the block in the value-store.
}
// Given a block `block` and a payload `payload`.
//
// Create an update response.
::memo::vs::UpdateResponse response;
// Set the block new payload.
block.set_data_plain(payload);
{
  // Create a context.
  grpc::ClientContext ctx;
  // Create an update request.
  ::memo::vs::UpdateRequest update;
  // Set the update request `block` field with the updated version of the block.
  update.mutable_block()->CopyFrom(block);
  // Set the update request `decrypt_data` field to `true` so the `block` field
  // of the update response will be decrypted. This is useful if you need to fix
  // potential conflicts resulting of the update.
  update.set_decrypt_data(true);
  // Actually update the block.
  auto status = vs->Update(&ctx, update, &response);
  if (!status.ok())
    throw std::runtime_error("Unable to update the block");
  // If there is a conflict.
  if (response.has_current())
  {
    // Solve conflict here, `response.block` contains the current version of
    // the block in the value-store.
  }
}
Arguments
UpdateRequest { Block block,   bool decrypt_data }
Block block
bool decrypt_data
Return
UpdateResponse { string type,   bytes message,   Block current,   bool bool }
string type
bytes message
Block current
bool bool
Exceptions
NOT_FOUND: Nothing at the given address.

Delete

(DeleteRequest) DeleteResponse

Erase the block at the given address.

The address of the Block is given by the DeleteRequest. The ability to remove a Block is determined by two factors: The existence of the Block and the permission to delete it. The DeleteResponse will contain the information related to result of the deletion attempt.

# Given an address `address`, remove the block at `address`.
#
vs.Delete(DeleteRequest(address = address))
// Given an address `address`, remove the block at `address`.
//
_, err := client.Delete(context.Background(),
                        &vs.DeleteRequest{Address: address})
if err != nil {
  log.Fatal("Unable to remove block")
}
// Given an address `address`, remove the block at `address`.

// Create a remove request.
::memo::vs::DeleteRequest remove;
// Create a remove status.
::memo::vs::DeleteResponse removal;
// Set the address.
remove.set_address(address);
// Create a context.
grpc::ClientContext ctx;
// Actually remove the block.
auto status = vs->Delete(&ctx, remove, &removal);
if (!status.ok())
  throw std::runtime_error("Cannot remove block");
Arguments
DeleteRequest { bytes address }
bytes address
Return
DeleteResponse { string type,   bool bool }
string type
bool bool
Exceptions
NOT_FOUND: Nothing at the given address.

Messages

MakeMutableBlockRequest

index name type abstract

MakeImmutableBlockRequest

index name type abstract
1 data bytes The payload of the ImmutableBlock
2 owner bytes The address of the owner block

InsertRequest

index name type abstract
1 block Block The block to insert

UpdateRequest

index name type abstract
1 block Block The new value of the block
2 decrypt_data bool Whether to decrypt data automatically

FetchRequest

index name type abstract
1 address bytes The address of the Block to fetch
2 decrypt_data bool Whether to decrypt data automatically

DeleteRequest

index name type abstract
1 address bytes The address of the Block to remove

Version

index name type abstract
1 major int64 The major
2 minor int64 The minor
3 subminor int64 The subminor

ACLEntry

index name type abstract
1 key_koh Key The key public to manage permissions of
2 read bool Whether read permission is granted
3 write bool Whether write permission is granted
4 token bytes Token, containing the secret to read encrypted data

PublicKey

index name type abstract
1 rsa bytes The DER representation of the PublicKey (RSA)

Key

index name type abstract
1 type string [internal]
2 public_key PublicKey A public key, used for

Block

index name type abstract
1 type string The type of Block
2 address bytes The address of the Block
payload oneof The payload of the block, data or data_plain, depeding of the Block
3 data bytes The raw data of the block (N.B. This can be encrypted)
22 data_plain bytes The decyphered data payload of the block
4 salt bytes A constant salt, used when computing the address of the block
5 owner bytes The representation of the owner public key
6 signature bytes The signature of the block content. The signature proves the integrity of the block by ensuring data have been signed using the owner private key
7 owner_rsa bytes [internal]
8 name bytes The name of the block
9 key_koh Key A Key object, that can be a hash, used to the find the a User Block (UB) or the public key of the owner of the Block
10 version int64 The version of the Block
11 editor int64 The index of the editor in the `acl` or `acl_group` to check permissions
12 owner_token bytes A token, containing the secret used encipher the data
13 acl repeated ACLEntry The list of ACL entries (one for each user referenced in the ACB)
14 data_version int64 The version of the data
15 data_signature bytes The signature of the data
16 world_readable bool Whether the Block is readable by everybody
17 world_writable bool Whether the Block is writable by everybody
18 group_acl repeated ACLEntry A list of ACL entries (one for each group referenced in the ACB)
19 group_version repeated int64 A list of indexes of the group key used to encipher the token
20 deleted bool Wheter the Block was marked for deletion
21 seal_version Version The version to determine the type of algorithm used / to use when sealing the Block
23 next_seal_version int64 The version of the seal to use during next sealing

FetchResponse

index name type abstract
1 type string [internal]
2 block Block The fetched Block, at it latest version

InsertResponse

index name type abstract
1 type string [internal]
2 bool bool Whether the update succeeded

UpdateResponse

index name type abstract
1 type string [internal]
2 message bytes A message describing the error
3 current Block The current block stored at the address
4 bool bool Whether the update succeeded

DeleteResponse

index name type abstract
1 type string [internal]
2 bool bool Whether the update was successful