[Lightning-dev] A state machine.

Anthony Towns aj at erisian.com.au
Mon Aug 31 02:24:26 UTC 2015


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.

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. (Correspondingly, PKT_CLOSE
doesn't seem valid during WAIT_FOR_UPDATE_SIG)

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:

        case STATE_NORMAL_LOWPRIO:
        case STATE_NORMAL_HIGHPRIO:
                } else if (input_is(input, CMD_SEND_HTLC_COMPLETE)) {
                        /* We are to send an HTLC complete. */
                        set_effect(effect, send,
                                   pkt_htlc_complete(effect, sdata,
idata->cmd));
                        return prio(state, STATE_WAIT_FOR_HTLC_ACCEPT);

        case STATE_WAIT_FOR_HTLC_ACCEPT_LOWPRIO:
        case STATE_WAIT_FOR_HTLC_ACCEPT_HIGHPRIO:
                /* HTLCs can also evoke a refusal. */
                if (input_is(input, PKT_UPDATE_DECLINE_HTLC)) {
                        fail_cmd(effect, CMD_SEND_HTLC_UPDATE, idata->pkt);
                        /* Toggle between high and low priority states. */
                        return toggle_prio(state, STATE_NORMAL);
                }

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).

I also wonder if

  A: TIMEDOUT_HTLC -> B: DECLINE (err_time_sync_lost)

might be useful.

> 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?

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.

Cheers,
aj


-- 
Anthony Towns <aj at erisian.com.au>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20150831/b67b1611/attachment-0001.html>


More information about the Lightning-dev mailing list