[Lightning-dev] A state machine.

Rusty Russell rusty at rustcorp.com.au
Tue Sep 1 07:32:49 UTC 2015


Anthony Towns <aj at erisian.com.au> writes:
> On 31 August 2015 at 11:04, Rusty Russell <rusty at rustcorp.com.au> wrote:
>
>> > I was thinking it would be possible to update many HTLCs at once, so
>> > I was expecting a single PKT_UPDATE_CHANNEL rather than the ADD_HTLC,
>> > COMPLETE_HTLC, TIMEOUT_HTLC, etc variants. From a protocol POV, I guess
>> > that's something like:
>> This is the kind of optimization we may see later, but I really shy away
>> from doing it now.  Your diagram looks simpler because you removed all
>> the rest of the handshaking.  Try this:
>>
>
> ​I think the statepy.svg includes all the handshaking (including errors,
> but I think excluding internal errors) apart from the nop state
> transitions. Having a single PKT_UPDATE_CHANNEL would just combine those
> into one subgraph / one edge.

My instinct is to encode as much in the state itself as possible,
because it simplifies verification.

> I'm a bit surprised that CMD_CLOSE isn't a valid option when proposing an
> update -- it's valid during WAIT_FOR_UPDATE_SIG but not
> WAIT_FOR_HTLC_ACCEPT/WAIT_FOR_UPDATE_COMPLETE.

Looking at that git tree (I've done some work since then)...  Ah, you
can't send a command while processing an existing command.  Seems a
logical simplification.

> (Correspondingly, PKT_CLOSE
> doesn't seem valid during WAIT_FOR_UPDATE_SIG)

It's a corrollary of the above.

> A: ADD_HTLC --> B: DECLINE_HTLC
>>   OR
>> A: ADD_HTLC --> B: ACCEPT --> A: SIGNATURE --> B: COMPLETE
>>
>> After success:
>>
>> B: FULFILL_HTLC -> A: ACCEPT --> B: SIGNATURE --> A: COMPLETE
>>   OR
>> B: ROUTEFAIL_HTLC -> A: ACCEPT --> B: SIGNATURE --> A: COMPLETE
>>   OR
>> A: TIMEDOUT_HTLC -> B: ACCEPT --> A: SIGNATURE --> B: COMPLETE
>>
>> This makes the constraints clearer, eg. you can't DECLINE_HTLC anything
>> but an ADD_HTLC.
>>
>
> ​Your states currently allow declining those though:

Not at all (or if it does, it's a bug).  Each state is defined as
something which can accept inputs, and for which all those inputs are
always valid.

> If your counterparty proposes a broken HTLC update, I'm not sure there's
> harm in being allowed to decline it? They can choose to close the channel
> if they think you're unreasonable, retry the update if they found a
> mistake, or just forget it and not worry (if they were issuing a ROUTEFAIL,
> it's not /their/ funds that are on the line eg).

The simplest (and safest) system is always to error and close when they
break protocol.  There's some game theory involved in whether you should
wait or not, but in the end, they're broken and there's not much you can
do.

> I also wonder if
>
>   A: TIMEDOUT_HTLC -> B: DECLINE (err_time_sync_lost)
>
> might be useful.

I don't think it's useful, though if you disagree on time you might get
an error packet.  (What else can you do?)

Perhaps we should add a current time field to UPDATE_ADD_HTLC so you can
defuse clock sync problems earlier?

>> AFAICS, you still have a potential deadlock atm if you think you're
>> > high priority but your counterparty also thinks they're high priority,
>> > or just missed your update packet. I think there might be a similar
>> > deadlock if both systems think they're low priority.
>> They can't get into that state.
>
> ​Sorry, I was assuming that one or both implementations were buggy. I meant
> to make that explicit.​ You're talking with strangers on the network, so
> you can't assume their software is bug free, right?

That applies to any scheme you come up with, though.  Propose something
simpler, and I'll gladly rewrite.

> BTW, your states currently switch priority even when an update is declined,
> so the low bit of the current commitment id (which obviously isn't changed
> on a declined update) doesn't actually give you the priority afaics.

True!  I will change that, since it's conceptually simpler.

Thanks,
Rusty.


More information about the Lightning-dev mailing list