title: How do Spritely's actor and storage layers tie together?
date: 2019-06-27 13:15
author: Christine Lemmer-Webber
tags: spritely, datashards
slug: how-do-spritelys-actor-and-storage-layers-tie-together
---
I've been hacking away at [Spritely](https://gitlab.com/spritely) (see
[previously](https://dustycloud.org/blog/tag/spritely/)). Recently I've
been making progress on both the actor model
([goblins](https://gitlab.com/spritely/goblins) and its rewrite
[goblinoid](https://gitlab.com/spritely/goblinoid)) as well as the
storage layers (currently called
[Magenc](https://gitlab.com/dustyweb/magenc/blob/master/magenc/scribblings/intro.org)
and
[Crystal](https://gitlab.com/spritely/crystal/blob/master/crystal/scribblings/intro.org),
but we are talking about probably renaming the both of them into a suite
called "datashards"... yeah, everything is moving and changing fast
right now.)

In the [#spritely channel on
freenode](https://webchat.freenode.net/?channels=spritely) a friend
asked, what is the big picture idea here? Both the actor model layer and
the storage layer describe themselves as using "capabilities" (or more
precisely "object capabilities" or "ocaps") but they seem to be
implemented differently. How does it all tie together?

A great question! I think the first point of confusion is that while
both follow the ocap paradigm (which is to say,
reference/possession-based authority... possessing the capability gives
you access, and it does not matter what your identity is for the most
part for access control), they are implemented very differently because
they are solving different problems. The storage system is based on
encrypted, persistent data, with its ideas drawn from
[Tahoe-LAFS](https://tahoe-lafs.org/trac/tahoe-lafs) and
[Freenet](https://freenetproject.org/), and the way that capabilities
work is based on possession of cryptographic keys (which are themselves
embedded/referenced in the URIs). The actor model, on the other hand, is
based on holding onto a reference to a unique, unguessable URL (well,
that's a bit of an intentional oversimplification for the sake of this
explaination but we'll run with it) where the actor at that URL is
"live" and communicated with via message passing. (Most of the ideas
from this come from [E](http://erights.org/) and
[Waterken](http://waterken.sourceforge.net/).) Actors are connected to
each other over secure channels to prevent eavesdropping or leakage of
the capabilities.

So yeah, how do these two seemingly very different layers tie together?
As usual, I find that I most easily explain things via narrative, so
let's imagine the following game scenario: Alice is in a room with a
goblin. First Alice sees the goblin, then Alice attacks the goblin, then
the goblin and Alice realize that they are not so different and become
best friends.

The goblin and Alice both manifest in this universe as live actors. When
Alice walks into the room (itself an actor), the room gives Alice a
reference to the goblin actor. To "see" the goblin, Alice sends a
message to it asking for its description. It replies with its datashards
storage URI with its 3d model and associated textures. Alice can now
query the storage system to reconstruct these models and textures from
the datashards storage systems she uses. (The datashards storage systems
themselves can't actually see the contents if they don't have the
capability itself; this is much safer for peers to help the network
share data because they can help route things through the network
without personally knowing or being responsible for what the contents of
those messages are. It could also be possible for the goblin to provide
Alice with a direct channel to a storage system to retrieve its assets
from.) Horray, Alice got the 3d model and images! Now she can see the
goblin.

Assuming that the goblin is an enemy, Alice attacks! Attacking is common
in this game universe, and there is no reason necessarily to keep around
attack messages, so sending a message to the goblin is just a one-off
transient message... there's no need to persist it in the storage
system.

The attack misses! The goblin shouts, "Wait!" and makes its case, that
both of them are just adventurers in this room, and shouldn't they both
be friends? Alice is touched and halts her attack. These messages are
also sent transiently; while either party could log them, they are
closer to an instant messenger or IRC conversation rather than something
intended to be persisted long-term.

They exchange their mailbox addresses and begin sending each other
letters. These, however, are intended to be persisted; when Alice
receives a message from the goblin in her mailbox (or vice versa), the
message received contains the datashards URI to the letter, which Alice
can then retrieve from the appropriate store. She can then always refer
to this message, and she can choose whether or not to persist it locally
or elsewhere. Since the letter has its own storage URI, when Alice
constructs a reply, she can clearly mark that it was in reference to the
previous letter. Even if Alice or the goblin's servers go down, either
can continue to refer to these letters. Alice and the goblin have the
freedom to choose what storage systems they wish, whether
targeted/direct/local or via a public peer to peer routing system, with
reasonable assumptions (given the continued strength of the underlying
cryptographic algorithms used) that the particular entities storing or
forwarding their data cannot read its content.

And so it is: live references of actors are able to send live, transient
messages, but can only be sent to other actors whose
(unguessable/unforgeable) address you have. This allows for highly
dynamic and expressive interactions while retaining security. Datashards
URIs allow for the storage and retrieval of content which can continue
to be persisted by interested parties, even if the originating host goes
down.

There are some things I glossed over in this writeup. The particular
ways that the actors' addresses and references work is one thing
(unguessable http based capability URLs on their own have [leakage
problems](https://www.w3.org/TR/capability-urls/) due to the way various
web technologies are implemented, and not even every actor reference
needs to be a long-lived URI; see [CapTP for more
details](http://erights.org/elib/distrib/captp/index.html)), how to
establish connections between actor processes/servers (we can reuse TLS,
or even better, something like tor's onion services), so are how
interactions such as fighting can be scoped to a room ([this
paper](https://www.uni-weimar.de/fileadmin/user/fak/medien/professuren/Virtual_Reality/documents/publications/capsec_vr2008_preprint.pdf)
explains how), as well as how we can map human meaningful names onto
unguessable identifiers (the answer there is
[petnames](https://github.com/cwebber/rebooting-the-web-of-trust-spring2018/blob/petnames/draft-documents/making-dids-invisible-with-petnames.md)).
But I have plans for this and increasing confidence that it will come
together... I think we're already on track.

Hopefully this writeup brings some clarity on how some of the components
will work together, though!
