# Integrating ForceMove with Raiden
## Purpose
We want to use Raiden to fund ForceMove applications. For that, both Raiden and ForceMove have to change a bit. I'm sketching one plausible option.
In short, when a Raiden channel is closed, some reserved amount of tokens move into ForceMove, and ForceMove applications continue.
## Structure of this document
This document goes from the high-level view to the low-level details. I've already written about the highest goal above ("Purpose"). Next I want to describe use-cases of the integrated system, but for that I need basic vocabulary around ForceMove and Raiden.
## Basic Vocabulary
This document is about putting together two systems. Before doing that, we review each system briefly. The focus is on who can do what on which order.
### ForceMove Basic Vocabulary
ForceMove allows participants to use any state-transition-based applications offchain (but with possible onchain disputes). ForceMove applications can be funded directly or through another application channel.
#### Directly funded application channels
Participants make the following actions [(described here)](https://quirky-panini-27752c.netlify.com/docs/quick-start):
1. Somebody deploys a state transition rule as a smart contrat conforming to `ForceMoveApp` interface. This contrat encodes a `ForceMove` application.
2. Participants exchange opening state updates. They identify the application with the address of the `ForceMoveApp` and a `ChannelId`. `ChannelId` is determined by the chain ID, an array of participants and a `channelNonce` (an arbitrary number chosen by participants).
3. Participants make deposits on a ForceMove `ChannelID` to `AssetHolder`.
* Participants need to make deposit in a strict ordering, corresponding to the payout priority. If Bob has the highest priority claim over 100 tokens, until Bob deposits more than 100 tokens, Alice does not make a deposit.
4. Participants exchange state updates
5. Participants make moves offchain until they cooperatively finalize the ForceMove application or enter an onchain dispute.
6. Even if the application is finalized cooperatively, there will eventually be an onchain transaction that tells the `AssetHolder` to move tokens according to the agreed finalization.
#### Application channels funded by another application channel
ForceMove also supports indirectly funded applications. A ForceMove channel can be funded by another ForceMove channel. Raiden does not fit in this pattern.
The Nitro documentation explains [Auxiliary protocols](https://quirky-panini-27752c.netlify.com/docs/auxiliary-protocols#topping-up) that can fund ForceMove application channels from ledger channels. The ledger channel has to be a special form of ForceMove application called a consensus game, where all parties agree on every new state.
Raiden does not fit in this model because Raiden is not a consensus game. During normal operation, Raiden participants do not agree on the current state of their Raiden channel. Alice keeps updating the Alice-to-Bob side of the state, and Bob keeps updating the Bob-to-Alice side of the state.
### Raiden Basic Vocabulary
1. Somebody deploys `TokenNetwork` contract. One deployed, the `TokenNetwork` instance manages all Raiden channels for a token.
2. Anybody can open a channel between any two different addresses (if there is none). The two addresses are called participants of the raiden channel.
3. Anybody can deposit tokens on behalf of any participant of any Raiden channel.
4. On a channel between Alice and Bob, Alice sends Bob a sequence of balance proofs. A balance proof contains the amount of tokens that Alice has transferred to Bob. Bob sends Alice another sequence of balance proofs. These balance proofs contain the amount of tokens sent in the other direction. The two directions are independent (it's up to each participant to calculate the current capacities from these two directions).
5. Balance proofs from Alice to Bob also contain a hash of all pending hashtimelocks from Alice to Bob.
7. Anybody with a participant's signature can close the Raiden channel. They have to call `TokenNetwork.closeChannel()` with a blinded balance proof signed by the closing participant.
8. Anybody can submit counter-signed and blinded balance proofs of the other direction during the settlement window.
9. After the settlement window expires, anybody can reveal the previously blinded balance proofs.
## Funding from Single Raiden Channel
The simplest way to combine ForceMove and Raiden is to fund a ForceMove application from a single Raiden channel. This method is only available to two participants that share a Raiden channel, so I'll be thinking about "Funding from Multiple raiden Channels" later.
We describe the dispute case first because the cooperative executions sometimes fall back on the dispute case.
In case of disputes, `TokenNetwork` will make a `deposit()` into a ForceMove `AssetHolder` so that the participants can continue the offchain/onchain interactions following the ForceMove protocol.
Until disputes happen, participants exchange signed messages that instructs `TokenNetwork` to make deposits into `AssetHolder`. The participants can use those instructions when they close and settle the Raiden channel.
### Why this Approach?
The [auxiliary protocol](https://quirky-panini-27752c.netlify.com/docs/auxiliary-protocols) approach cannot be followed literally because Raiden is not a consensus game.
`TokenNetwork` itself cannot act as `AssetHolder` while a Raiden channel is open, because `TokenNetwork` does not know how much tokens a participant controls. After a Raiden channel is settled, it's easier to move the funds to a separate `AssetHolder` because that moment cuts off Raiden and the ForceMove application.
### How to make a deposit from a Raiden channel into a ForceMove application channel? (Here lie dragons.)
* Every Raiden balance proof will contain a new hash
* `forcemoveDepositHash`, which commits to a set of ForceMove deposits.
* Alice can send Bob a message: `addForceMoveDeposit(uint256 amount, bytes32 destination, uint256 expectedHeld, uint256 nonce_of_dependent_deposit, <balance proof>)`.
* Alice does this only after seeing a ForceMove application onchain
* More generally, Alice does this only if she has enough signatures from other participants that she can make a ForceMove deposit
* The `<balance proof>` contains the new `forcemoveDepositHash` that represents the previous deposit set plus the new ForceMove deposit
* The `<balance proof>` also contains a nonce that can identify the ForceMove deposit later.
* Alice can also send Bob a message `dropForcemoveDeposit(uint256 nonce_of_dropped_forcemove_deposit, <balance proof>)`
* The `<balance proof>` contains the new `forcemoveDroppedDepositHash` that represents the previous dropped deposit set plus the dropped deposit.
* When the Raiden channel closes, each Raiden channel participants chooses a balance proof. They can even use an older balance proof.
* When Bob submits an Alice-to-Bob balance proof, Bob might not have received the newest Alice-to-Bob balance proof.
* This means, Bob can sometimes choose to block Alice's deposit into the ForceMove application.
* That would be stupid if Alice has the most prior claim. Then Bob's deposits go to Alice.
* If Bob has the most prior claim, Bob can only get back his deposits.
* This also means, Bob can sometimes choose to forget that Alice has dropped some deposits.
* If Alice has the most prior claim, Alice gets what she accidentially gives.
* If Bob has the most prior claim, Bob gets what Alice accidentially gives (!!!). This is a problem.
* One way to solve this: drop Alice's deposits in Bob's balance proof.
* But then, this has to happen atomically with an increase of Alice's transfer to Bob.
* Another way to solve this: allow ForceMove application to access TokenNetwork to determine the balance proofs used for the settlement.
* Another way to solve this: never allow dropping the deposits. Instead, when the ForceMove application finishes onchain, the `AssetAllocator` can open a channel in Raiden and move tokens there. Anticipating that, users can send around balance proofs in this to-be-created Raiden channel.
* After Raiden channel settles, anybody can call `TokenNetwork.performForcemoveDeposit()` so `TokenNetwork` calls `deposit()` on an AssetHolder.
### How does a ForceMove application end?
We consider three scenarios:
* Participants dispute over the result of the ForceMove application, and one of them wants to execute the Forcemove application onchain
* Alice closes Raiden channel with a blinded balance proof (containing Bob's deposit into the Forcemove application)
* Bob sends a blinded balance proof to `TokenNetwork` (Bob might send a stale balance proof without Alice's contribution to the application channel, the application has to detect this in this case? How does `AssetHolder` behave when the application tells it to pay out more than it controls?)
* On the Raiden channel, the settlement period runs out
* Alice, Bob or anybody who has the balance proofs can call `TokenNetwork.settleChannel()`
* Anybody can call `TokenNetwork.performNitroDeposit()`. `TokenNetwork` makes a deposit into the Nitro `AssetHolder`.
* Alice and Bob can execute the Forcemove application offchain or onchain, but in this case Alice wants to run the Forcemove application onchain.
* Participants agree on the outcome of the Forcemove application, but Alice wants to close the Raiden channel for some other reason.
* Alice sends Bob a `dropNitroDeposit` message. This removes Alice's Forcemove Deposit and adds some transferred amounts from Alice to Bob.
* Bob sends Alice a similar `dropNitroDeposit` message.
* If any participant is not happy about the `dropForcemoveDeposit` messages, they close the channel, and the execution falls back to the dispute case.
* Otherwise, `TokenNetwork`'s settlement can continue without invoking the Forcemove protocol.
* Participants agree on the outcome of the Forcemove application, and agree to finalize the application offchain.
* Alice sends Bob a `dropForcemoveDeposit` message. This removes Alice's ForcemoveDeposit and adds some transferred amounts from Alice to Bob.
* Bob sends Alice a similar `dropForcemoveDeposit` message.
* If any party is not happy about the `dropForcemoveDeposit` contents, they close the channel, and the execution falls back to the dispute case.
* Otherwise they keep the Raiden channel.
* Bob can be mean and close the Raiden channel using an old balance proof so `TokenNetwork` makes a deposit into the ForceMove application. The ForceMove application needs to detect this kind of situation where only one party made a deposit.
### Interface Design
#### From the ForceMove Perspectives
From the Forcemove perspectives, nothing happen onchain until a dispute happens. Participants send each other `addForceMoveDeposit` messages instead of making deposits. The participants interact with each other on the Forcemove protocol around this time. They don't see tokens in `AssetHolder` but they are sure that they can force the tokens to go to `AssetHolder`.
When a dispute happens, `TokenNetwork` makes a deposit (indirectly) to `AssetHolder`, and participants continue the Forcemove application.
However, if `TokenNetwork` directly makes a deposit, Nitro's `AssetHolder` becomes confused. `AssetHolder` uses `msg.sender` to identify the depositor. For this reason, `TokenNetwork` deploys wallets for Alice and Bob, and make these wallets deposit tokens into Forcemove's `AssetHolder`.
The ForceMove protocol needs to change a bit. It must allow the application to access `TokenNetwork` to determine the balance proofs that were used for Raiden channel settlement.
Malicious participants can invoke a ForceMove application using a stale BalanceProof. In that case, Bob forces the `TokenNetwork` to make a deposit on behalf of Alice, but Bob does not make a deposit. The ForceMove application needs to detect these cases.
#### From the Raiden Perspectives
From the Raiden perspectives, the Forcemove deposits are similar to hashtime locks. They are similar because
* they lock up some channel capacity, and
* the destination of the locked funds depend on some external conditions.
However, Forcemove deposits differ from hashtime locks in that:
* the destination of the hashtimelock is determined onchain by the time the settlement window is over, while the destination of the ForceMove application is determined later
There will be a new field `forcemoveDepositRoot` in the balance proofs.
There will be changes to `TokenNetwork` contract:
* `settleChannel()` takes two new arguments `forcemoveDepositRoot1` and `forcemoveDepositRoot2`. They come from the two hydrated balance proofs.
* There will be a new method `TokenNetwork.forcemoveDeposit()` that can be called after the channel settlement.
* This method creates two wallets. Each wallet is controlled by the `TokenNetwork` and one participant.
* `TokenNetwork` moves tokens into the wallet.
* Before the participant can touch the tokens, `TokenNetwork` moves them to `AssetHolder`. So from the Forcemove protocol, the deposit looks like coming from the wallets.
* Must these wallets perform arbitrary message calls?
* Must the addresses of these wallets known in advance?
##### Small Generalization
I want to design a more general mechanism. Instead of adding special changes for Forcemove, Raiden can add a general mechanism to send tokens to other contracts after settlement.
## Funding from Multiple Channels
When there is a sequence of channels (A--B, B--C, C--D, ..., E--F) with enough capacities, there has to be a way to fund an application using these channels. The next step is to solve the (A--B, B--C) case. Using two ledger channels A--B and B--C, we want to fund an application that runs between A and C.
A consequence of this is that B cannot close the ledger channels until A and C close the application. One approach is to allow B to challenge A and C so they must close the application in time.
Perhaps Nitro team has figured out how "three party joint channel" works.
## Related Issues
### General Locks
When Raiden switched from keccak to SHA256, the team discussed generalizing the hashtimelocks so any hash algorithm can be used.
The design above is of course general enough to cover this usecase.
### Virtual Channels
If we can make deposits from two channels (Alice--Bob and Bob--Charlie) can we support a virtual channel between Alice and Charlie?
Does the above design support virtual channels? Is it easy to extend the above design?
## Next Actions
* figuring out whether this idea works.
* figuring out whether Raiden team is happy with this idea
* figuring out whether L4 team is happy with this idea.