This week’s Holochain release brings a large and anticipated change, what will become the foundation for the 0.1.0 release of the HDK and the Stable Validation milestone. I hinted at it a few months ago, and now the time is finally upon us.

Holochain 0.0.143: Maintenance release

HDK compatibility: 0.0.129 to 0.0.136

This release brought more documentation updates to a couple packages, and that’s about it.

Holochain 0.0.144: Integrity/coordination split

HDI compatibility: 0.0.9
HDK compatibility: 0.0.137

This release sees a number of changes to the HDK in preparation for the next release. You’ll note that I’m now listing the previously announced HDI (Holochain Deterministic Integrity) crate as a separate thing — this library has only existed as part of the HDK before this release, but it becomes a separate thing from now on.

I have to admit that the title of this Dev Pulse is not exactly true. As you may know, data integrity is critical when groups of people want to coordinate their actions. If you can’t trust what your peers are saying and doing, you can’t move forward safely with them.

Also, when I say ‘coordination’ I’m not even talking about that kind of coordination. I’m talking about something more low-level and programmer-ish: one application instance coordinating the flow of its own processing and data, nothing more.

And finally, they’re not really parting ways — it’s just that the pieces of your hApp’s code that are responsible for data integrity will be split from the pieces that are responsible for application execution. They’ll exist in separate zomes in your DNA. If you’re familiar with the MVC (model, view, controller) programming pattern, you could look at it this way:

Your application’s integrity zomes comprise its model layer — everything that defines the shape of the data. In practice, this means three things: entry type definitions, link type definitions, and a validation callback that constrains the kinds of data that can validly be called entries and links of those types.

And the coordination zomes comprise its controller layer — the code that actually commits data, retrieves it, handles countersigning sessions, and sends and receives messages between peers or between a cell and its UI. In other words, all your zome functions, your `init` functions, your remote signal receivers, and your scheduler callbacks will all live in coordination zomes.

To repeat what I described a few months ago, the intention is to let you split the core integrity components of your application, which define the unalterable rules of the game, from the business logic. That way, your DHT can last a long time yet still receive upgrades and bug fixes — as long as you don’t need to change your integrity components.

And we’re making the same promise for the reduced library that your integrity components are built on — the HDI (Holochain Deterministic Integrity) crate. Once it reaches its 0.1.0 release, we plan to keep HDI stable for a while between minor releases.

You’re probably wondering how to refactor your hApp given this substantial change. Here are the most important things to know:

Your DNA manifest file is broken into integrity and coordinator sections. integrity holds everything that affects the DNA’s hash: the list of integrity zomes, the DNA properties, the UID, and a new origin_time field that indicates the earliest possible timestamp for a source chain entry, which is used to prevent time-travel attacks. Only the integrity section affects your DNA hash.

coordinator holds the list of coordination zomes. Coordination zomes must explicitly list their dependencies; that is, the integrity zomes that contain definitions for the entry and link types they intend to write. (If you have only one integrity zome, however, you don’t need to list it as a dependency in any of the coordination zomes.) Here’s a complex example with multiple zomes of both kinds:

manifest_version: "1"
name: multi integrity dna
integrity:
  uid: 00000000-0000-0000-0000-000000000000
  properties: ~
  origin_time: 2022-02-11T23:05:19.470323Z
  zomes:
    - name: zome1
      bundled: ../dna1/zomes/zome1.wasm
    - name: zome2
      bundled: ../dna2/zomes/zome1.wasm
coordinator:
  zomes:
    - name: zome3
      bundled: ../dna1/zomes/zome2.wasm
      dependencies:
        - name: zome1
    - name: zome4
      bundled: ../dna2/zomes/zome2.wasm
      dependencies:
        - name: zome1
        - name: zome2

As mentioned, your entry/link definitions, membrane proof self-checks, and validation callbacks will need to be moved into integrity zomes with only one core dependency on the HDI crate holochain_deterministic_integrity. This crate has been around for a while, but you haven’t needed to worry about it until now because it was just part of the HDK. (It still is, but it now is meant to exist independently of the HDK.) integrity zomes should not depend on the full HDK — it’s not going to remain stable over time like HDI is. There are new macro helpers for defining entry and link types. The test suite has examples of an integrity zome with entry types and link types.

All of your zome functions, init callbacks, remote signal receivers, and scheduler callbacks should go into coordination zomes. They can (and likely should) depend on the full HDK, which still includes holochain_deterministic_integrity as a dependency.

Only the coordination zomes can use non-deterministic host functions in the full HDK such as source chain commits and queries, DHT gets, agent activity queries, signal emitters, remote calls, and complex crypto functions. Integrity zomes can only use deterministic functions such as must_get_*, dna_info, zome_info, and simple crypto functions such as hashing. This makes sense, because the only functions available to your validation callback are the deterministic ones; this just becomes explicit with the separation between HDI and the rest of the HDK.

There are some changes that remove zome_id from the headers of entry and link creation elements. These changes are temporary and will be reverted in a future release. In fact, before the 0.1.0 release of HDI there will likely be more changes, although they will mostly be hidden behind macros and other conveniences. If you want to have a say in the usability of the hApp development experience, please jump in now and tell us what you think. But if you desire stability, it’s probably best to wait until 0.1.0.

You can also look at the full changelog or the integrity PR (#1325) for the fine details.

There are a lot of other changes in this release, some related to the integrity/coordinator split and some not:

  • New: wasm_error! macro in the HDK, which captures line numbers. (#1380)
  • New: Stubs for libsodium Salsa20-Poly1305 secret box encryption in the HDK. It’s not yet supported by the Lair keystore, so it will currently throw unimplemented errors. (#1410)
  • New: Updated to newest Wasmer, which allows us to implement metering. Zome calls are now limited to a generous 10 giga-operations, which should prevent infinite loops from overwhelming an agent’s machine. (#1386)
  • Breaking: When using get_links, the link_type parameter now takes more than one link type at a time. And because a coordination zome can depend on more than one integrity zome, you can even specify link types from multiple integrity zomes. Any link types not defined in a coordination zome’s dependencies will be filtered out.
  • Breaking: call and call_remote can now take anything that implements the Into<ZomeName> trait.
  • Breaking: create_entry takes anything that implements both the TryInto<EntryDefIndex> and TryInto<EntryVisibility> traits rather than EntryDefRegistration.
  • Breaking: update now takes an UpdateInput struct to make it align more closely with other host functions, and UpdateInput now has separate entry and chain_top_ordering params rather than wrapping a CreateInput.
  • Breaking: update_entry takes anything that implements TryInto<Entry> rather than EntryDefRegistration.
  • Breaking: Path now must be typed to a specific LinkType.
  • Breaking: CreateInput, used in create_entry, replaces entry_def_id with entry_location which allows you to specify that the entry is either an app entry (with entry def ID) or a capability grant/claim. In practice, you don’t need to worry about this if you’re using the entry def helper macro, because it will create a type that can be converted into a CreateInput.
  • Breaking: The register_entry! macro has been replaced by an #[hdk_entry_defs] helper.
  • Breaking: The struct returned by zome_info now has a zome_types field that lists all the global IDs of the zome’s entry and link types.
  • Breaking: EntryDefs::entry_def_index_from_id(), ZomeInfo::matches_entry_def_id(), CreateLink::zome_id, and AppEntryType::zome_ID have been removed because there is no way to go from a local ID to a global ID. This may change again in the future.
  • Breaking: EntryDef::required_validation_type has been removed because validation packages are not going to be implemented.
  • Breaking: ZomeName is now a Cow<’static, string> instead of a String.

Read the changelog for all the details.

Holochain 0.0.145: Source chain name change, countersigning updates

HDI compatibility: 0.0.10
HDK compatibility: 0.0.138
Lair compatibility: 0.2.0

There are three important changes in this release:

  • Breaking: Element and Header, two structures that make up the source chain, have been renamed to Record and Action, along with changes to related types. We believe these language changes will make it easier for new developers to understand what these structures are about. Every source chain commit is a record of a particular type of action (publishing an agent key, creating data, deleting a link, etc), so this language aligns with that reality. Entry is remaining the same. (#1441)
  • Breaking: When you’re using an ‘enzyme’ in countersigning (a trusted agent who collects all the signatures, rather than waiting for signatures to get published to the DHT and broadcast to all signers), you now specify that a session is enzymatic, and the enzyme agent will be the first countersigner by convention. Previously the enzyme's agent ID was specified explicitly and separately from the other counterparties. (Note: the API is fully fleshed out, but the network plumbing to support enzymes is not functional yet.) (#1394)
  • Breaking: In a countersigning session, you can now specify a number of optional signers. You can specify how many of them must sign in order for the session to complete; that number must be equal to or greater than a majority of the optional signers. This is useful for reaching ‘micro-consensus’ over rivalrous data such as usernames, in a way that tolerates downtime among trusted authorities. Note: When using optional witnesses, the session must use an enzyme, who must be the first agent in both the list of signing agents and the list of optional signers. This allows the process to be more efficient and less ambiguous than waiting for the DHT to reach consistency. (#1394)

Read the changelog for more details.

Launcher 0.4.8: Improved DevHub UX

This release adds support for Holochain 0.0.141 and 0.0.143, and also comes with DevHub 0.7.0, with better UX for uploading packages. If you’ve already added your hApp’s packages to the DevHub, that DHT isn’t shared with the new one, so you’ll probably want to upload it again. (I should point out that, once we reach the Stable Validation milestone, this will become a thing of the past!)

Get Launcher from GitHub

DevHub 0.7.0: Improved DNA uploading UX

This is the release that comes bundled with Launcher 0.4.8.

  • New: Support DNA properties in bundle uploading.
  • New: Support .webhapp bundles and GUI file in hApp release uploading.
  • Bugfix: Fix list sorting.
  • Bugfix: Fix reset in hApp release uploading.
  • Bugfix: Fix bundled resource key mismatch in hApp release uploading.

Check out the release page if you want to know more or look at the source code.

DevHub 0.7.1: Improved hApp uploading UX

This release didn’t make it into Launcher 0.4.8, but you can download it and test its developer UI from the version of DevHub that comes bundled with Launcher 0.4.8.

  • New: Implement new UX for hApp bundle uploading.
  • New: Support markdown for hApp Release descriptions.

Check out the release page if you want to know more or look at the source code.

News from around the ecosystem

I’ve already written a lot, so I’m not surprised if you’re ready to take a break. But if you’re still with me, there is all sorts of exciting news from around the ecosystem!

  • After a brief pause, Elemental Chat is once again hosted on the Holo hosting network. It’s being joined by a new hApp, Elemental Chess! Watch Holo’s Twitter account for upcoming links to try them out. We’ll also be inviting other projects to start hosting and testing their hApps on Holo soon.
  • Acorn, Lightning Rod Labs’ beautiful collaborative goal-tracking hApp, is celebrating its first major milestone release, v1.0.2-alpha. It has new features, more UI refinements, and a clarified focus on supporting the work of distributed software development teams. To get involved, download the release for Windows, macOS, or Linux, read the knowledge base, and join the alpha testing list.
  • hREA, the toolkit for building economic networks, is working toward a major milestone release as well. They have a new website with roadmap, a sponsorship campaign, and a Discord server.
  • We’ve closed applications to the Holochain and Rust Developer Immersive and are now interviewing applicants. Everybody involved is busy but excited.

All of these things deserve special attention of their own, so I plan to write more about them soon!

Cover photo by Jens Lelie on Unsplash