Currently, the first 2*numParticipants
turns are devoted towards channel setup in a directly or indirectly funded channel. This is hard-coded into the ForceMove
rules: only the turn number is allowed to change during this channel setup phase. This is an artifact from an older version of ForceMove which didn’t support multiple signatures on the same state.
forceMove
requires a supported state to launch a challenge. Therefore, the first numParticipants
states form the “PreFundSetup” phase: without these states, any deposit could be locked forever, because no ForceMove functions can be called. The next numParticipants
states form the “PostFundSetup” phase, where each participant only deposits after all prior participants have already deposited.
Now, a state s
can be supported by having each participant sign s
. Therefore, we could reduce this “PreFundSetup” phase to just one states, at turn numParticipants - 1
. At this point, we might as well make the setup phase last only numparticipants + 1
turns.
I also believe that the second half of this “setup” phase is unnecessary – I need to be convinced every few months that it’s important. If I am correct, then turns 1,...,numParticipants + 1
are unnecessary during the setup phase, and the setup phase has been reduced to just state 0.
In fact, at that point, there is no special logic required for the setup phase at all. Suppose we remove the special setup logic:
- All participants sign state 0, in whatever turn they want
- All participants then deposit, in order. No rational participant would deposit out of order.
- All participants wait until the channel is fully funded before signing turn
i
fori > 0
. No rational participant would deviate from this. - Once the channel is fully funded, participant 1 can update the
appData
according to the application-specific rules.
Note that the same argument can be made about final states: it’s unnecessary to increment the turn number, and it’s also unnecessary to sign in order. Participants could simply all sign the first final
state.
Summary
Therefore, the valid transition rules (excluding support checks) could be written without any conditional logic:
function validTransition(a, b) <=>
b.turnNum == a.turnNum + 1
b.chainId == a.chainId
b.participants == a.participants
b.appDefinition == a.appDefinition
b.challengeDuration == a.challengeDuration
app.validTransition(a, b)
!a.isFinal
Here are my claims that make this validTransition
“safe”.
- No rational participant would deposit before state
0
is supported. - No rational participant would deposit out of order.
- No rational participant would move past state
0
before the channel is fully funded. - No rational participant would insist on incrementing
turnNum
on a final state.