Can everyone hear me?
Hello everyone, I'm Jessica Talon.
As you heard, I've been working on activity football for quite a while and then more recently
at the Spritely Institute and I am involved in both the implementation and standardization
of O'Capon. Spritely is a research institute and we are trying to research and develop
the sort of next generation of decentralized web. We have a few projects,
which is an active model aimed to build decentralized and peer-to-peer applications,
and it's also an implementation of O'Capon.
Huit, which is our scheme to where the assembly compilers, so we can bring us to the web,
and O'Capon, which is something we are involved in the standardization of,
where a US-5.0.1, C3 registered nonprofit, and we can't do our work without donations.
If you think what we're doing is interesting, check us out and if you can donate.
So, what is O'Capon? It stands for object capability network and I know a few of the talks
at least have mentioned capabilities. It's built to allow peer-to-peer communication
and it's utilising capability as it's security model. It has actors at the core
and supports messaging between those actors. It includes something called
promised-fightlining and promises. It's network transport,
agnostic. It has a cyclical distributive GC and third-party hand-offs.
Some of those you don't understand, hopefully you will at the end of this talk.
But why O'Capon? Why are we building this thing?
And my background is in activity purpose, I said,
and when we're building that, we built it with client server and service
federating between one another.
We're building this for the web and people are building these things with Django and Rails
and things like that. That works great.
People are deploying, you know, massive on-service or something.
They've got lots of users, but you're sort of seeding some control
and sometimes privacy to these servers.
And it would be much better if we could build actually peer-to-peer applications
where users can just run their own and they make point-to-point connections
and we can build applications on top of those.
But it can be really hard to do this. There's a lot of things to think about
and so this is where O'Capon is coming in.
And it's designed to make building these peer-to-peer applications
ergonomic and secure and easy.
And O'Capon is a protocol, so it's something you implement
or hopefully use an implementation of.
And then, you know, you can then focus on your application logic
and leave the peer-to-peer stuff to O'Capon.
Well, O'Capon doesn't actually have an opinion on where the
system is fault-tolerant or not.
This is something that typically goes hand in hand with the actor model
as we'll see.
And so this is important in that you often want distributed
applications to be quite fault-tolerant.
And because it's network transport, agnostic applications
don't have to worry about the network and the transport
can be swapped out to their needs.
So capability security, I know the previous talk
and several other talks have mentioned this.
So hopefully you're off a million,
but if you're not, I'll quickly go over it.
We like to say it's brightly.
If you don't have it, you can't use it.
And that means basically if you have a reference to something,
or something like that, you can just use it.
There isn't anything to stop you doing that.
And you can think of this as like procedure arguments
or something, you get past something into a procedure
and then it can use that thing to pass it into it.
Or file handles.
You give it a file handle instead of the entire access
to the file system.
And capability security often goes hand in hand
with the principle of least authority,
which is you give programs just the privileges they need
to do their job.
The alternative to capability security is usually
access control lists, which are susceptible to
confused deputy attacks, which is a security vulnerability.
And also ACLs tend to lead, lend themselves
to centralized systems.
There is usually a program that has a lot of power,
and then gives that out to two other programs.
And this is somewhat inherently centralized.
So capability security can help with building distributed applications.
I'm sorry that these are a little small.
I should have made them bigger.
But this is a very basic diagram showing a blog
and in the middle, you've got these posts,
and these arrows of the capabilities.
And this is showing attenuation,
making a giving just a part of the capability out.
And so you can see here the admin has the capability
to write, that's what the W if you can make that out,
is meaning and the blog itself has the capability to read,
but not write.
So you can take a read write capability and split out.
Just part of the capability and hand bad out.
And so that's a really interesting and useful property
of capabilities.
This is a somewhat scary looking diagram,
but it's not too bad.
This is Lauren and she's got a blog with an admin.
And she wants to give this out to Robert.
And she doesn't just give her entire capability.
She gives a proxy to that capability.
And this proxy is revocable and will log what Robert is doing.
So Lauren can look at the log and then if she chooses,
revoke this arrow, you can see pointing
between the proxy half moon and the admin in the middle.
It's pointing at some kind of like switch in a circuit
or fuse.
And so this would be really difficult to model in a classic ACL system.
But this is actually something pretty easy to model in
capability security system.
The act of model is at the heart of a captain.
And so I'll go over it a little bit.
Actors communicate with other actors by message passing,
sending messages to other actors.
And actors work great in concurrent systems.
So you can have multiple actors working at the same time.
And actors are also great for distributed applications.
You can usually put a network boundary,
sort of have an actor system and then put a network boundary in the middle.
And that's usually fairly trivial.
And again, they often lend themselves to fault-polar
systems, things like Erlang and Lixer,
often tap this and they're relying on the act model.
So to get into a captain, I'm going to sort of go through the protocol
and show you what these messages look like on the wire.
And I've mentioned that we're sending messages to actors.
And so how are actors represented on the wire?
There is this notion of imports and exports.
And these are a pairwise within a session,
ways of representing an actor,
and you represent them with a positive integer.
And these are sessions specific.
So the integer 5 is specific to say an A and B,
P A and B session, but that could reference a completely different actor
within another session.
And this is sort of like the most important operator within O'CAPAN.
And this is how actors message one another.
And this is OP Deliver.
And it takes four arguments.
And you'll see how these two final arguments are used in later slides,
when I go over other features.
But the first one is where which actor are we sending this message to.
And this will be using those imports and exports,
but I was talking about.
And then there is a list of arguments that you're sending to the actor.
The answer position is used for promised pipelining,
but I'll get into.
And this to resolve me descriptor is used for promises.
I'll also get into that in a second.
And so I've got two things here.
The first is a line of goblins code.
Goblins is written in scheme.
And so you're seeing parentheses.
And the first argument is a procedure call.
And so it's this arrow NP, which stands for no promise.
And this is how you message in goblins.
So it's saying message Bob with the argument hello.
And this is a symbol.
And on the wire this is this OP Deliver operator.
And I just made up a number here,
but it could be any number in this case just number one.
And we're messaging Bob who is exported
at position one on the other node.
And we're delivering it with hello.
But that's great sending a message to an actor.
But what if Bob wanted to reply with a greeting or something?
And so this is where promises come in.
This is sort of how you get an answer back when you send a message.
And so promises may resolve to lots of different things.
They may be resolved to a reference to an actor
that either won the actor's spawned itself or a reference
that had to be given it.
But they can also resolve to concrete values
or indeed other promises.
And you can chain promises together.
And you can break promises with an error.
Something goes wrong or indeed promises can be broken
if something went wrong in the network,
such as the network's reference.
And promises can be listened to.
And in the training example where you have, say, promise one.
That's filled with promise two and so forth.
If you listen to it, you'll finally get the answer at the end of the chain,
including errors.
And so this is an example of how promises look in code.
If you're not familiar with scheme, I'll try to explain it.
Define is we're defining a variable.
And in goblins by convention, they're suffixed with vow
if it's a promise.
And so we've got Greeking vow.
And we're using the arrow procedure.
This time not arrow NP, because we're wanting a promise.
And we're sending Alice, hello, and Bob.
So two arguments, hello and Bob.
Alice is our reference here to another actor.
Probably another machine.
And we're then calling this om procedure,
which is how you listen to a promise in goblins.
And we've got this lambda, which is our callback.
And so when that promise finally resolves to some value,
we'll do this, this is how you print something to the terminal in
Gile.
So you'll see you promised said, and then whatever Alice replied with.
And so how's this working on the wire?
So I've got again, we're sending a message with OP deliver.
And this OP deliver will come up a lot.
It's used a lot of no-cuffin.
And this time where we've got both of our arguments,
we've got a good example.
I'm still not using this answer position, so that's set to false.
And now I've got this resolved me descriptor.
And this is this is telling the implementation on the other side.
When you finally get an answer to this, or if you need to break it due to an error,
let me know here.
And this is another object, another actor in the actor model.
And we're just exporting this to the other side.
And so we say it's an import object and two.
So we just made up an available number to export this.
You export by just referencing an object.
And so we've referenced this object.
And then finally later on when our actor, when we get a resolution to it,
they will send another OP deliver.
And this time they're referencing that resolved me descriptor actor.
And they will use the fulfill method on this.
In this case, Alice is saying hello Bob, my name is Alice.
They don't care any about any resolution or promise to get back,
so they've just got the false for the unsubosition and resolved me descriptor.
This is the basic building blocks of OCAPAN and how you would message actors
that might be across the network.
But that's pretty basic stuff.
But that's not the only thing you can do with OCAPAN.
There is this feature called promise pipelineing.
And this allows you to do some pretty neat stuff.
So in this example, I'm going to walk through the example and then explain as they go
why this is so interesting.
So we're starting with this car factory valve.
And we're messaging this actor somewhere on the network and we're saying,
hey, make me a factory, a car factory.
And then we're immediately on the next line,
sending message to this promise.
And how's that happening?
The message may not have left my machine.
Certainly it takes some time to build a car factory right.
And so how am I managing to send a message to this?
But I am sending a message to this and saying, hey, make a car.
And then on the next line, I'm even messaging that promise.
This promise to the car I've just asked for.
And I'm saying, hey, drive a car.
And then I listen to this drive promise.
And I've got another handler.
And you can see here, I've included some error handling to in case something.
Bro, but in most systems, you might send a message to the factory builder.
And then say, wait for the response.
And the other side will say, oh, here's your car factory.
I've just spent a bunch of time building it.
And then you'll say, okay, then now I want that car.
And then I'll go ahead and make the car.
And you'll wait for the answer.
And you'll say, hey, go ahead and drive.
But this I can just have this nice flat ergonomic structure in the code.
And I don't need to do that.
I can just dispatch all my messages to the other side.
And then get my answer back at the end.
And so this both allows for this ergonomic code.
But it also prevents this sort of back and forth conversation,
where I'm going A to B and then B to A.
And then A to B and B to A.
When I'm sending these messages and getting a reply.
And so this saves on network traffic, it saves on time.
And how are we achieving this?
Well, you can see this OP deliver at the top.
In this case, I've just said the car factory builder is number five.
And we're saying, make a factory.
And this is our position two.
And when now using this answer position.
And that side just makes up an integer to represent the promise.
And then you start messaging that answer.
So saying, hey, at that thing, I just hold you to make.
I want you to deliver this message.
And then again, we specified three.
And we're saying, hey, at that car, just hold you to make.
Deliver this message.
And this time, we don't want to pipeline anymore.
So we've just given it a resolve me descriptor.
And B can then fulfill this for the answer or break it with an error
if something would happen.
I don't want to spend too much time on this slide.
But GC turns out to be very important in distributed systems.
You often want to clean up objects.
And if you're handing out references and stuff,
you need to know when the other side's done with that reference.
And so I just want to say that we do have a cyclic garbage collection.
Distributed garbage collection, you know, Captain.
And it works by reference counting on the wire.
And then we have it for both of those answers
from performance supply planning and for regular objects.
Now, this is my favorite feature of our cabin.
It's very neat.
So this is being sent by Alicia on PRA, one machine.
And it's being sent to Ben, who's on another machine, PAB.
And then saying, I'm going to call this method meet.
And interestingly, Ben's passing Carroll on PSE.
So this is Alicia has two sections here.
And how Alicia do this when you've just got integers.
It turns out we've got this third-party handoff thing.
And I'm running out of time to explain this.
I'm going to go very quickly.
Don't worry if you don't understand.
But basically, no-day gives Carroll a gift.
And says, look after this for me.
And then node A then sends a message to Ben,
that OP deliver.
And it includes this certificate.
And you can see it's secure, it's signed.
You can see, because it's got this little rubber stamp on it.
It's a signed certificate.
And that includes information from the A to C session.
And the A to B session.
And then Ben can then establish a new connection to C.
And include some information on its own.
And the certificate it got.
And then finally, node B can kind of have a session with node C.
And there's no proxy in going on here.
Node A could then go down.
And they could continue talking and sending messages.
And Ben has that reference to Carroll.
And so, like I said, don't worry if you don't understand this.
The takeaways that you can have this ergonomic,
intuitive way of programming in with OCAPAN.
And it will handle this secure handoff of references.
And create in connections to other nodes.
And it handles all the security issues with replay attacks and things like that.
It's split into three layers.
Everything I've talked about so far is in CAPTP.
But there is net layers.
Support for TORANY net layers.
Repeat P to P web sockets.
In the X domain sockets and things like that.
You can sort of just pick one and run with it.
And new ones can be defined.
And then there are locators for specifying capabilities
to connect to a machine and get objects and things like that.
The next work I'll be working on is a relay.
Pit peer.
Things can be very difficult in a lot of situations.
Web browsers is one.
It can be really hard to get true peer to peer stuff there.
But also network configurations.
You could be behind firewalls and things.
And so relays do have a use.
But it's important not to have too much centralized relays.
So the relays will be federated.
You don't have to share the relay to form a connection.
And they will leverage their transport agnostic stuff in the net layers.
What happened isn't done.
We have draft specs.
And we meet every month and try and standardize this.
We have an implementation guide on the test suite in Python.
If this sounds really interesting to you.
Check out the website and consider joining.
And if we have time for questions.
Our head.
Let's give it a round of applause.
Unfortunately, we don't have time for a full Q&A right now.
But if you have questions, yeah.
Please talk to Jessica afterwards.