Today we’ll do a small exercise - I want you to see Cinode in action for yourself. For that I wanted to make the Cinode data format a bit more stable so that certain magic values used in this post will keep working for at least some time. I’m pretty sure this is now the case - and even if I find some critical bug, I did some preparations to be able to maintain backwards compatibility.

Let’s play then.

Prerequisites

Since there are no precompiled binaries nor docker images of Cinode yet, we will have to work a little bit with the source code. Following tools will be required:

  • go compiler - to compile and run the source code.
  • git (optional) to fetch Cinode source code (alternatively it can be downloaded directly from github)

How to set up those tools is beyond the scope of this blog post, I leave this part of the exercise up to you.

We’ll also be working mostly on the command line - the way true HaCkErS do this 😉.

Fetching Cinode source code

Let’s start by downloading the Cinode source code:

With git:

1
2
3
4
5
6
7
8
9
$ git clone -b v2023-01-27 https://github.com/cinode/go.git .
Cloning into '.'...
remote: Enumerating objects: 1478, done.
remote: Counting objects: 100% (57/57), done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 1478 (delta 0), reused 3 (delta 0), pack-reused 1421
Receiving objects: 100% (1478/1478), 384.00 KiB | 1.10 MiB/s, done.
Resolving deltas: 100% (892/892), done.
...

Or by downloading and extracting the zip archive from this link: https://github.com/cinode/go/archive/refs/tags/v2023-01-27.zip.

Running cinode proxy

To run the server:

1
2
3
4
5
6
$ # Configuration
$ export CINODE_ENTRYPOINT="9g1R5xUqhAxfHnVBPAyBY9NXNe1dzKK949czZtT9THSMesRk3tKSRTWh2bsaKp4ivFVYyZX3vXMdE74XiAw9ckEWQoKLRouJnn"
$ export CINODE_ADDITIONAL_DATASTORE_1="https://datastore.cinodenet.org/"
$ # Lift off
$ go run cmd/cinode_web_proxy/main.go
2023/01/28 13:58:49 Listening on http://localhost:8080

Now if you open http://localhost:8080 in a local browser, you’ll see Cinode blog.

Congratulations 🎆 - you have just become a Cinode network member 🥂.

Under the hood

What we’ve done here is that we’ve created a small process called cinode proxy. That process connects to some number of cinode datastores, and exposes a web server where the content is a directory structure stored in cinode with the root of that directory pointed out through specified entrypoint.

Entrypoint - this is the cryptic 9g1R5x.... value - it contains the information about the starting point - the root of the whole tree of blobs, similarly to the root of a filesystem. Internally this value contains the blob name of the root directory and the encryption key that allows reading the plaintext data from that blob.

In case of the Cinode blog - this entrypoint is the root dynamic link to the blog content. Whenever the content changes, the link data will be updated and will point to something else. Cinode proxy server does periodic refresh (currently fixed 1h interval) that makes sure the link data is up-to-date.

Cinode proxy example

Where does cinode proxy take the data from? It connects to a cinode datastore - https://datastore.cinodenet.org/. It contains encrypted blobs necessary to view the current version of the blog. Internally cinode proxy creates one more datastore - but it is purely in-memory one. Blobs from the blog datastore are cached in memory to avoid unnecessary queries to the remote datastore server.

Interesting fact here is that cinode proxy is already acting as if it was a node in the network - it does not trust the datastore behind https://datastore.cinodenet.org/. It does its own validation for every blob that is retrieved from it. If there was broken data or if there was an older version of the blog, things would not propagate.

There are many more unexplored functions of cinode proxy. It can for example query multiple cinode servers for the data or it can use local disk instead of memory to store local cache. The tool itself is pretty simple and still needs some work, but is already a useful to play with Cinode network. And exactly that tool powers the backend of this blog at https://blog.cinodenet.org/.

What I want to leave for another post is how to generate al those datastore blobs and the entrypoint information. And before I cover that, I’d also like to take a step back and summarize the current state of Cinode first, so… stay tuned.