Editorial note - this topic will be covered in more detail in the controllers report, but I think it’s worth giving a basic overview here of what the application concerns will look like, and the interfaces / constraints here should match up with what the controllers report specifies.
Distributed state synchronization
The basic goal of distributed state synchronization is to allow application state (resources) to be distributed among various independent domains, each of which has their own security model and local ordering, and all of which may execute in parallel, while preserving a single global state namespace, such that resources may (when permitted by their logics) move freely across domains, and while preserving fault isolation, such that faults on one of the domains do not violate any correctness or liveness properties of state living elsewhere.
Recall the description of storage, in particular the commitment tree and nullifier set. Suppose that we have a (possibly infinite) number n of domains, where domain n is identified as D_n.
The basic idea of distributed state synchronization is to:
- Partition the commitment tree into a set of sub-trees, where each sub-tree T_n is associated with exactly one domain D_n, and the overall commitment tree root is a second-order Merkle tree where the leaves are the roots of T_n.
- Fix a domain D_n in each resource such that the resource can only be consumed on D_n. A reference to D_n can be stored in the resource value, and this can be enforced by the resource logic (checking some kind of attestation from D_n). This means, in particular, that each resource can only be nullified on one domain, which is necessary to preserve linearity in a concurrent environment.
- Periodically synchronize sub-trees - for each sub-tree T_n, after some updates (the result of executing transactions), the latest root for T_n is sent by D_n to other interested domains, and they update their commitment tree to reflect it. To preserve fault isolation, this synchronization must come attached with a proof sufficient to prove to the receiving domain that these updates are correct (in the typical resource machine sense).
Resources can then be transferred from one domain to another - say D_a to D_b - simply by:
- Submitting a transaction to D_a which consumes the resource on D_a and creates an identical one assigned to D_b, the commitment for which is now in T_a.
- Wait for T_a to be sent over to D_b via the synchronization process.
- The new resource can now be consumed on D_b.
This system provides several important affordances to applications:
- Applications can support multi-domain usage, interactions, and state transfer without any additional programming required.
- The state synchronization system, with the appropriate sorts of proofs (e.g. zero-knowledge), can preserve full programmable disclosure, such that a third-party observer knows nothing about what state is being transferred between domains apart from what is explicitly disclosed to them.