# Trustless State Export: Juno -> Filecoin This document describes a method of securely exporting state from the Juno chain to Filecoin using FVM and un-trusted message relayers. # Implementing Secure State Export Secure State Export from Juno to Filecoin is achieved via deployment of an FVM actor capable of verifying transactions on the Juno chain (effectively a light client) ## Juno FVM Actor ### Overview An FVM Actor (`Juno Actor`) is initialized with an `interrop-genesis-header`. `interrop-genesis-header` is a Juno network block header roughly corresponding to when the Juno FVM Actor is deployed (actual Juno genesis not used because it would require committing entirety of current header chain to FVM state immediately before any useful interrop could occur; there also shouldn't be any relevant transactions prior to this actor deployment). The `interrop-genesis-header` can be easily verified by a party with read access to both Filecoin and Juno chains before they choose to rely on it. This alone (plus supporting actor code) is enough for any party to fully trust this interrop that relies on trusting no 3rd parties, it only requires trust of the underlying security mechanisms of the Juno and Filecoin networks. This actor supports methods to submit new block headers with corresponding proofs in order to track the current state of Juno. Any motivated party may submit these new blocks. The party submitting new blocks does not need to be trusted as tendermint consensus allows each block header to be validated based only on the previous block header which is already known by the FVM actor. This actor also supports methods to verify input Juno chain transactions against the current Juno state. This is possible because the Juno chain block headers stored by the `Juno Actor` on FVM contain the merkle tree root hash of all the transaction data in the block. Likely one or more interested parties using this interrop would run a service to periodically submit new block headers. Now a user of this interrop can design their own coordination scheme for transactions on the Juno chain to trigger actions in an FVM actor. This requires committing the chain of block headers generated by the Juno chain to the FVM state. Estimation of this requirement is below. ### Juno Header | Size | Parameter | |---------|--| | 8 + 8 | Version | | 50 | ChainID | | 8 | Height | | 12 | Time | | 32 + 4 + 32 | LastBlockID | | 32 | LastCommitHash | | 32 | DataHash | | 32 | ValidatorHash | | 32 | NextValidatorHash | | 32 | ConsensusHash | | 32 | AppHash | | 32 | LastResultHash | | 32 | EvidenceHash | | 20 | ProposerAddress | Header Size = `430` bytes ### Juno Header Accumulation on FVM To store all Juno chain headers for a single day: ``` (header size) * (1 day) / (block time) = 430 * (86400 s) / (6 s) = 6192000 bytes = 6.2 MB ``` Continuously accumulating Juno Headers on FVM requires committing 6.2 MB of state space per day. This requires gas, how much I don't know. (https://filecoinproject.slack.com/archives/C029MT4PQB1/p1667316894544039) This is probably unreasonable to store. A subset of the header fields can be stored to minimize the amount of state storage required. The `Commit` and accompanying validator sets that correpond to the merkle roots in the header also need to be provided during the actor's verification of a new header, but don't necessarily need to be stored. If re-validation of the light-chain is not a priority we might even be able to get away with only storing the `DataHash` for each block. ### Computation The verifications the `Juno Actor` performs rely on computing hashes and checking signatures from the FVM environment, so all of the algorithms used need to be available as a syscall from FVM as running a WASM implementation of any of them would probably be too gas intensive. **TODO**: Find all crypto algs that are required by the `Juno Actor` and check availability. # Application of State Export ## On Juno Side Develop a scheme for Juno transactions meant to affect state on Filecoin. This would likely manifest as a smart-contract with a product-type `ExecuteMsg`, where each option of the product-type defines a different type of message for affecting state on Filecoin. This is all that needs to be done on Juno side. Since this state export is 1-way, Juno does no further action or validation that Filecion properly receives this state. ## On FVM Side Develop `Juno Message Handler Actor/s` capable of: 1. Taking a Juno TX + Block ID + TX Merkle Proof as method input 2. Requesting Juno TX verification from the `Juno Actor` 3. Executing on behalf of the Juno TX based on defined scheme (request storage deal, transfer FIL, etc) ## Message Relayer Off-chain actors need to relay the Juno Transaction to the corresponding Actors on FVM. This would likely be automated by running a service that watches the Juno chain and submits any candidate transactions to the approporiate FVM Actor. Again, the message relayer need not be trusted so this is totally fine. In fact this is no less automated than how the results of DaoDao proposals currently execute; since there is no CRON service on Juno, all proposal results need to be manually triggered by an off-chain actor after the proposal passes. ## Flow of Action 1. Juno actor submits a "Juno -> Filecoin Interrop" TX on Juno chain 2. Juno TX is commited to Juno chain 3. Off-chain Message Relayer sees "Juno -> Filecoin Interrop" TX on Juno chain and submits it to corresponding `Juno Message Handler Actor` on Filecoin 4. `Juno Message Handler Actor` on Filecoin submits received Juno TX to the `Juno Actor` to verify that it is a valid Juno transaction 5. `Juno Message Handler Actor` executes logic on behalf of the Juno TX