DApps running on Cartesi Machines are great, but one important limitation is clear: there is currently no way of composing Cartesi DApps except for going through the base layer. For Cartesi Rollups, this means that for DApp A to communicate with DApp B, it currently needs to emit a voucher (e.g., to add an input to DApp B) which can only be executed once its epoch is finalized - and requiring an external client to submit a transaction to execute it. This is slow, expensive, and cumbersome.
This proposal suggests using the Dehashing Device, and preferably Lambda, to allow one DApp to directly and instantly read the state of another, but still remain disputable on-chain.
The basic dehashing primitive would define a DApp’s state by specifying its identifier (i.e., address or VM ID) and an appropriate input index or block height. So the dehashing call itself, in terms of (namespace, id)
, could be something like ("cartesi", <address_index>)
.
The dehashing component on the outside (running in the Cartesi L2 Node) would ensure the requested DApp is executed up to the specified input, and then return its state (ideally the Lambda state). In theory, it could rely on querying some trusted 3rd-party Node or even just read the state someone posted on IPFS, but in practice it would probably make sense for Validators of the DApp requesting the state to also always validate the requested DApp(s). As such, the URL to pull from when dehashing a Cartesi DApp state would probably be a configuration defined by the Validator when setting up the Node.
In terms of resource consumption, it would be naturally up to each DApp’s logic to decide which other DApps it wants to pull state from. This could mean that a higher salary would need to be paid for validators (e.g., Sunodo) for them to run a DApp that requests state from others (so that they are paid to run the other DApps too). Alternatively, a validator could already be explicitly receiving salaries to run all involved DApps; in such instances, no additional resources are really consumed. In any case, we can assume that validators will simply stop if they run out of funds.
In terms of on-chain arbitration, any dispute about the requested state of another DApp would naturally fall back to a regular dispute on that other DApp itself. In other words, if such a dispute arises, there could be a regular verification game (VG) to reach the exact point of disagreement between some known prior finalized claim for that DApp and its final state in dispute (as specified by the input index used in the dehashing call).
But what could become possible with this kind of composability?
An example would be a DEX system where multiple Cartesi Machines are used as “shards”, so as to dramatically scale the number of trades that can be made. Each shard could be a “market”, and while most transactions would happen inside a shard, users would be able to move their assets to other markets instantly, without having to wait for finality on L1!
Technically speaking, it is worth noting that this approach still requires some limits on the amount of “jumping around” that could be done. To be clear: this is not generic parallel processing! It is rather a framework for checkpointing multiple DApps with each other. If every DApp reads the state of every other all the time, we would still need to execute one transaction at a time and have each machine waiting for the other - and in the end it would be no more efficient than running everything in one single machine. Moreover, you of course cannot have DApps that simultaneously depend on each other’s state to proceed (an infinite loop): that would be a bug!
More technical details and discussions can be found in this Discord thread.