This issue is a grab bag of updates and interesting info. First up, I’m happy to share that the Holo dev team has the OS working on the HoloPort Nano’s hardware!
The Holo dev team is now working on all the failure modes for a web user and the HoloPort(s) supporting them. This might be an interesting read if you’re curious about how Holo-hosted apps work.
Eric Yang, founder of Junto, has shared some of his project’s plans to support the Holochain developer ecosystem and pioneer some hybrid deployment techniques.
- HoloPort Nano now working with the most recent OS
- A look at how a Holo-hosted hApp can break
- Junto’s progress and contributions to Holochain dev ecosystem
HoloPort Nano now working with most recent OS
Those of you who’ve ordered a HoloPort Nano are likely itching for another update. In May we shared that work was still continuing, with the big blocker being the hardware manufacturer having troubles with the OS image we supplied. I got good news last week: the OS is now working on the Nano! This means we’ll be able to deliver a new master image to our manufacturer soon.
Here’s a video of Alastair, our HoloPort Product Lead, booting up and registering a Nano.
A look at how a Holo-hosted hApp can break
You may ask, dear reader, why would you voluntarily talk about how your product can break? The fact is that computers are just really good at breaking things, especially networked computers, and any stack that doesn’t anticipate and handle failure modes is asking for trouble.
In the last Dev Pulse I shared a diagram of some of the failure modes we’ve identified for a Holo-hosted hApp, but I didn’t explain it. Now that the Holo dev team is working on this very thing, I thought I’d dig deeper. By way of explaining what can go wrong, I hope I can shine some more light on how Holo hosting works.
Let’s follow Alice through an unusually bad brush with Murphy’s Law on the internet.
Alice hears about a new ride-sharing website for her city and wants to try it out. So she goes to the website https://mycityrides.app (not a real URL), unaware that she’s about to secure just a little bit of sovereignty for herself through the sneaky cooperation of Holochain and a network of independent hosting providers.
When Alice types in that URL, a traditional centralised server serves up all the static assets for the app’s front-end.
One of the downloaded assets is the Holo Web SDK, which creates a tiny iframe. This iframe loads Chaperone, the cryptographic goodness that lets her browser connect to a host. (This iframe’s content is hosted on Holo’s servers, which is important—you’ll see why later.)
Once it’s loaded, the Chaperone script is responsible for connecting to the Holo resolver service and the user’s assigned host, and mediating communications between them and the UI using the browser’s window-to-window messaging channel. This channel lets the UI interface with the Chaperone without leaking any of the Chaperone’s internals (the browser’s Same Origin Policy takes care of this).
The Chaperone will try to gracefully handle most of the following failure cases, either by displaying its own UI or trying to resolve them itself. We intend to give UI developers as few error messages to have to handle! Ultimately we think that the only errors passed back to the UI will be errors generated by the back end DNA (the Holo-hosted part). At that point the UI is free to handle the error however the developer likes.
Whenever the Chaperone needs to interact directly with the user, such as showing the sign-up/sign-in dialog or showing an error message for an unrecoverable failure, it makes itself visible, expands to full screen, and momentarily takes over the UI.
Domain not registered
Let’s say Alice types the URL incorrectly and reaches a fake ride sharing website—a feeble phishing attempt. When the Chaperone iframe loads, it asks the Holo resolver service for the domain name of the UI that loaded it. If it can’t find that domain, it displays an error message. Presumably the phishing website will try to hide this error, but it won’t matter because it can’t progress past this point. The Chaperone will have done its job.
(Here’s reason #1 why it’s important for Holo to host the Chaperone iframe’s content: it’d be too easy for a fake UI to spoof that domain. The domain is extracted from the iframe’s referrer property, which is controlled by the browser, not the UI, which makes it impossible to spoof. It also gives the resolver service the chance to reject requests from fake phishing chaperones, thanks to the browser’s Cross-Origin Resource Sharing mechanism.)
No hosts available for hApp
Alice gets the URL right and the Chaperone loads the details about the hApp for its registry. Now it asks the Holo resolver service for some hosts that claim to be hosting it. But the resolver can’t find any. (Maybe by some strange coincidence they all go offline at the same time. Hey, it’s unlikely but possible, so we have to plan for it.) Now the chaperone displays an error message.
Cannot reach host
Alice complains to the ride-share company and they fix the problem. Now the Holo resolver service returns the addresses of a few random hosts. The Chaperone picks the first one and tries to establish a connection to it. This host seems to be offline, but the Chaperone is smart enough to try the next one on the list.
No alternative hosts
But there’s bad weather on the internet today, and none of the hosts are online. Now the Chaperone has to display an error message.
Alice finally accesses the app
Alice is getting annoyed, but she still wants to give this new service a chance. Another angry email later, and the company has now managed to provision more hosts for their DNAs.
Alice tries again and is connected to a host that has an ‘anonymous’ instance running. This is a special case that lets hApp developers give anonymous users (both humans and search engine crawlers) an appropriate amount of access to the app’s data without letting them actually create data themselves.
Alice thinks the app looks worthwhile, so she clicks the ‘book a ride’ button. This triggers a function call to the back end DNA. The UI calls the Web SDK, the Web SDK calls the Chaperone, and the Chaperone calls the host. But the host says “this is just an anonymous instance of the app, and this function call requires a real user.”
Alice creates an account
The Chaperone handles this error message from the host by starting the sign-up process. First it shows Alice the sign-up dialog. She enters her email address, makes up a strong password, and submits the form.
Once the Chaperone receives her credentials, it sends them to… nobody. The UI can’t access them; the Same Origin Policy prevents that yet again. They’re not stored in the Chaperone iframe’s memory either. The Holo router and Alice’s chosen host can’t access them, because the Chaperone doesn’t pass them on. (Reason #2 why we host the Chaperone on our server. And if you’re concerned about whether we’re telling the truth, you can view the source and fire up your browser’s dev tools to see what sort of stuff the Chaperone is sending out.)
Instead, what the Chaperone does is create a public/private key pair using Alice’s credentials as a ‘seed’. This guarantees that her key pair is both unique and can be reconstructed in any browser from something only she knows. The seed is then stored in the browser’s localStorage so that it can regenerate Alice’s key pair across tabs and page reloads, and it can only be retrieved by the Chaperone (thanks again, Same Origin Policy).
Now it’s time for Alice to get assigned to her very own host. The Chaperone gives the public component of Alice’s key pair to the resolver service and asks it to choose a new random set of ‘source chain hosts’—hosts with an uptime record of at least 90%. (Note: for Holo beta we’ll replicate Alice’s data across five hosts to increase reliability to 99.999%.) The connection to the anonymous instance is closed, and a connection to a new host is opened.
No agent hosts available
At this point the Chaperone may have to deal with ‘No agent hosts available’, which is similar to ‘No available hosts’ but means that none of the available hosts qualify as source chain hosts. Once a host is selected, the ‘Cannot reach host’ failure mode might be encountered again.
An instance is created
Now the Chaperone asks the new host to create an account for Alice. This involves creating a new instance of each of the app’s back end DNAs and spinning them up, which creates her source chain and runs any required initialisation functions.
Host can’t create an instance
If the host isn’t able to create a new DNA instance for Alice (for instance, it’s too busy, runs out of storage, or is no longer hosting the DNA), or the initialisation function returns an error, it communicates this back to the Chaperone. The Chaperone falls back to anonymous mode and has a chance to handle the error itself with a helpful dialog before returning the error to the UI. (Note: this behaviour may change; we may get the Chaperone to try other source chain hosts first.)
Failed to assign host in resolver
Once Alice’s assigned host has successfully created an instance for her, her Chaperone now asks the resolver service to register this as her official host. This will allow the resolver to assign the same host for her next time she signs in. But if something has gone wrong the Chaperone displays an error message. This is very unlikely and likely will only happen if we deploy a bug or Alice is trying to do something bad
Alice signs in on another computer
Now Alice uses the app on her phone. Once again, when she tries to book a ride, the Chaperone iframe expands to fill the whole screen. This time she chooses the sign-in form and enters her credentials.
User doesn’t exist
If Alice types her username or password wrong, her Chaperone creates a very different key pair from the one it created when she signed up. When the Chaperone asks the resolver service for her assigned host, it responds that it hasn’t seen her public key before. The Chaperone’s UI handles this failure mode by asking her to try again or sign up.
Cannot reach host
Yup, this one keeps showing up. It's always a possibility.
Agent not known, Verification failed
These are two more “this should never happen” cases.
In the first case, the host tells Alice’s Chaperone that it isn’t actually hosting her instance. In the second case, the host recognises that it’s hosting Alice’s instance but doesn’t recognise her signed proof that she’s holding the keys to her account.
The Chaperone would probably handle these cases by displaying a generic “something went wrong” message.
Alice is now signed in and using her hApp
Once Alice has successfully navigated any sign-up or sign-in failure modes, she’s finally connected to her very own host and making function calls to the DNA back end. If the developer has done things right, her Chaperone shouldn’t see many errors. There are, of course, exceptions.
The most likely cause of this kind of error would be a validation failure. The front end developer is encouraged to prevent these issues by pre-validating data before it’s sent to the back end DNA, but if they don’t, the back end ought to send back a helpful message for the front end to handle. The Chaperone will pass along any of these error messages to the UI.
Another error can occur if two function calls are running at the same time and both try to write to Alice’s source chain. The one that writes first will have a lock on the source chain, and the second one will get its writes rejected. This is something that the UI should handle gracefully as well.
Finally, the DNA back end might just have a bug, in which case the UI won’t know how to handle it. Cue another annoyed email to the company!
Lose connection to host
Alice is on the subway, going through a tunnel, and loses her connection as she’s trying to book a ride from the station to her house. The Chaperone tries to reestablish the connection and eventually triggers an error.
Service logger error, Conductor error, Wormhole error
These three failure cases indicate something has gone seriously wrong on the host. If the Chaperone receives them, it should try to resolve the issue itself before showing a “Something went wrong” message.
That’s a lot of failure modes!
Yes, it is. There are a lot of components—the UI and the server that serves it, the Chaperone and the server that serves it, the Holo host resolver service, the Holo router gateway, the pool of hosts, the Holochain software they’re running, and of course the DNA back ends that they host for users. Added to that are Alice’s browser, her computer and OS, her ISP and router manufacturer, the host’s ISP, and all the network plumbing in between. By programming our components defensively, we plan to give developers the tools to gracefully handle all sorts of failures so that users have a great experience.
Junto’s progress and contributions to Holochain dev ecosystem
This week we published an Ecosystem Sessions video with Eric Yang, founder of Junto. One of the first projects to commit to building on Holochain, Junto is a social app that aims to respect users’ dignity and encourage a healthy relationship with their online world. Currently available on the iTunes Store and Play store by invite only, it’s in alpha and enjoying positive feedback from invitees.
Eric shared that his team was drawn to Holochain not only because it had the potential to be much more scalable and energy-efficient than blockchain. He also said that our team’s vision and philosophy seemed well-aligned with theirs:
“We chose Holochain for several reasons. First and foremost, the spirit of their project feels very kindred to ours. Holochain is also important to us because it realizes the dream of a distributed web where people are in control. It’s a very powerful thing to enable people to keep ownership of their data and maintain that sovereignty.”
— Eric Yang, Junto co-founder, in an interview from January 2019
Eric also shared some of the details of their progress and plans for building on Holochain. While the infrastructure is all centralised right now, they’re pioneering a hybrid approach to Holochain migration in a few ways:
- They’re designing their back end API as a graph database with GraphQL, which makes it amenable to being ported to Holochain. This is because Holochain’s DHT is a graph database at heart, and a lot of emerging dev tooling and literature for hApps is focused on GraphQL.
- Because they’re building centralised first and Holochain later, they’ll be one of the first projects to migrate an existing codebase.
- They’ll be developing Holochain back ends component-by-component, which will demonstrate an app that bridges between centralised and decentralised worlds.
- They plan to have decentralised (Holochain), centralised (cloud), and in-between (Holo hosted) back end options for users to choose from based on their preferences.
Here’s a glimpse of their plans in Eric’s words:
For now, our alpha is running on a centralized API we built using Rust. It's an open source graph database that will serve as a bridge to being fully distributed over Holochain when ready. We are simultaneously building out Holochain components, starting with DMs. We're currently working on getting the Holochain conductor to run on people's mobile devices and packaging it on our mobile app (written in Flutter) so folks can use this technology without any technical set up. Over time, we will build out all of the features of Junto on Holochain and have both centralized and decentralized environments that our members will be able to seamlessly toggle between within the same UI.
One last important thing to note is that we've defined shared traits for our Holochain DNAs in social contexts (expression, social graph, social contexts, etc). The idea here is to create a unified standard that any Holochain developer can use so apps and user interfaces become far more interoperable. We've open sourced some of our early brainstorming on this here: https://github.com/juntofoundation/Holochain-Trait-Definitions
Our mobile app is also open source: https://github.com/juntofoundation/junto-mobile
It's exciting that they’re planning on contributing back to the Holochain ecosystem. While we’ve boasted that Holochain can even run on a smartphone, so far we’ve only focused on macOS and Linux so that we can complete our alpha and move to beta. It’s encouraging to hear that we’ve got some allies in the community to help us port it over.
I’m also happy to see them attempting to define standards for interoperable social graph implementations. If this is adopted by the wider community, it’ll create a common language for any hApp that wants to implement, or talk to, a social media hApp.
- Holochain Core: 0.0.51-alpha1 (blessed) | Changelog
- Holonix: 0.0.81 (blessed) | Changelog
- Tryorama: 0.3.4 (blessed)
- hc-happ-scaffold: 0.1.0 (blessed) | Project
- Holoscape: 0.0.9-alpha (contains Holochain Core 0.0.47-alpha1) | Download
Blessed (available via https://holochain.love)
- Holonix: 0.0.81
- Holochain Core: 0.0.51-alpha1
- hc-happ-scaffold: 0.1.0