From aj at erisian.com.au Mon Aug 31 02:24:26 2015 From: aj at erisian.com.au (Anthony Towns) Date: Mon, 31 Aug 2015 12:24:26 +1000 Subject: [Lightning-dev] A state machine. In-Reply-To: <874mjgqne2.fsf@rustcorp.com.au> References: <87si7eiehg.fsf@rustcorp.com.au> <87h9ntifwf.fsf@rustcorp.com.au> <877fopi4un.fsf@rustcorp.com.au> <20150829074239.GA15643@navy> <874mjgqne2.fsf@rustcorp.com.au> Message-ID: On 31 August 2015 at 11:04, Rusty Russell 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: