Safe API - Registers

For interest I have a register_history example working and will be submitting a PR for this once I clean things up.

If you remember, the existing register example simulates a simple chat with two or more users all updating the same register. With this additional example you can get the current state and history of that (or any other register). Here’s a sample of the output including a history of all Nodes (Entries) in the register after two users have exchanged a few lines (three each - their messages are numbered for clarity):

Current total number of items in Register: 6
Latest value (more than one if concurrent writes were made):
--------------
[alice]: this is alice 3
[bob]: this is bob 3
--------------

Enter a blank line to print the latest register history (or 'Q' <Enter> to quit)

Syncing with SAFE in 2s...
synced!
======================
Root (Latest) Node(s):
[ 0] Node("4eadd9"..) Entry("[alice]: this is alice 3")
[ 3] Node("f05112"..) Entry("[bob]: this is bob 3")
======================
Register History:
[ 0] Node("4eadd9"..) Entry("[alice]: this is alice 3")
  [ 1] Node("f5afb2"..) Entry("[alice]: this is alice 2")
    [ 2] Node("7693eb"..) Entry("[alice]: hello this is alice")
[ 3] Node("f05112"..) Entry("[bob]: this is bob 3")
  [ 4] Node("8c3cce"..) Entry("[bob]: this is bob 2")
    [ 5] Node("c7f9fc"..) Entry("[bob]: this is bob 1")
    [ 1] Node("f5afb2"..) Entry("[alice]: this is alice 2")
      [ 2] Node("7693eb"..) Entry("[alice]: hello this is alice")
======================

Current total number of items in Register: 6
Latest value (more than one if concurrent writes were made):
--------------
[alice]: this is alice 3
[bob]: this is bob 3
--------------

Enter a blank line to print the latest register history (or 'Q' <Enter> to quit)

The number in brackets before each Node is an order derived by traversing the history of all Nodes. It doesn’t exist in the Register but shows the order in which each entry was applied (in reverse, so 0 is the most recent node).


It’s amazing what you can achieve when you don’t hang out on the forum so much! :laughing:

Working on this has given me a better understanding of Registers on Safe Network. Regardless of my views on what an Entry should hold (key and/or data) Registers are a very powerful and flexible data type, but because of their power, they’re a bit tricky to understand and use.

What Power?

  • local first storage means local first software.
  • synchronising over Safe Network with multiple replicas using underlying MerkleReg CRDT from the rust crdts crate. There are a lot more data types in there too.
  • a history of all previous states of the Register and its entries

Tricky Bits

To get the power this is an unusual kind of data structure and not instantly clear how to use it. In time there may be higher level APIs to simplify this by presenting implementations of more familiar data structures on top of the Register, but for now you need to understand how to write entries and how to access entries in a way that makes sense for your application. None of that is straightforward because it is unfamiliar and not well documented yet.

Writing Entries though is easy! Getting the particular data back in a form useful in your app is not so easy. For example, you don’t have an array, or even a map of variable names to values. What you have is a set of one or more current values and access to the full history, or to any particular point in the history if you know the hash of the Node you want.

So using it like an array or a collection of values is complicated at the moment, but if you look at the history above you can see the makings of how to do that.

For applications that just want the latest value (e.g. of a file or document) you could use one Register per document and track its history though the sequence of entries.

But where you have multiple related values - where you want to know the state of a set of values at a particular time - as in a filesystem time-machine style, you need to manage those multiple entries in some way. I’m still scratching my head about the ways you might do that, but at least we have a tool to inspect the history of entries in a register now.

But all budding geniuses will though be able to store arbitrary data (probably by reference rather than in the Register) and create an endless history accessible by traversing the Entries starting from the most recent.

This is incredibly powerful. I don’t know if there’s any other system able to do this.

Hats off to MaidSafe for this innovation… hang on, what’s this…

:laughing:

13 Likes