From rusty at rustcorp.com.au Fri Aug 21 05:32:32 2015 From: rusty at rustcorp.com.au (Rusty Russell) Date: Fri, 21 Aug 2015 15:02:32 +0930 Subject: [Lightning-dev] A state machine. In-Reply-To: <87h9ntifwf.fsf@rustcorp.com.au> References: <87si7eiehg.fsf@rustcorp.com.au> <87h9ntifwf.fsf@rustcorp.com.au> Message-ID: <877fopi4un.fsf@rustcorp.com.au> Rusty Russell writes: > Yeah. Let me generate a decent text flowchart for the normal cases... I've taken out some transitions for simplicity (eg. ERR_ANCHOR_LOST and ERR_INFORMATION_LEAK, which shouldn't happen): Normal opening states: INIT_NOANCHOR: INPUT_NONE -> OPEN_WAIT_FOR_OPEN_NOANCHOR (=>PKT_OPEN) INIT_WITHANCHOR: INPUT_NONE -> OPEN_WAIT_FOR_OPEN_WITHANCHOR (=>PKT_OPEN) OPEN_WAIT_FOR_OPEN_NOANCHOR: PKT_OPEN -> OPEN_WAIT_FOR_ANCHOR CMD_CLOSE -> CLOSED OPEN_WAIT_FOR_OPEN_WITHANCHOR: PKT_OPEN -> OPEN_WAIT_FOR_COMMIT_SIG (=>PKT_OPEN_ANCHOR) CMD_CLOSE -> CLOSED OPEN_WAIT_FOR_ANCHOR: PKT_OPEN_ANCHOR -> OPEN_WAITING_THEIRANCHOR (=>PKT_OPEN_COMMIT_SIG) CMD_CLOSE -> CLOSED OPEN_WAIT_FOR_COMMIT_SIG: PKT_OPEN_COMMIT_SIG -> OPEN_WAITING_OURANCHOR CMD_CLOSE -> CLOSED OPEN_WAITING_OURANCHOR: PKT_CLOSE -> WAIT_FOR_CLOSE_ACK (=>PKT_CLOSE_COMPLETE) BITCOIN_ANCHOR_DEPTHOK -> OPEN_WAIT_FOR_COMPLETE_OURANCHOR (=>PKT_OPEN_COMPLETE) BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM (=>PKT_ERROR) CMD_CLOSE -> WAIT_FOR_CLOSE_COMPLETE (=>PKT_CLOSE) OPEN_WAITING_THEIRANCHOR: PKT_CLOSE -> WAIT_FOR_CLOSE_ACK (=>PKT_CLOSE_COMPLETE) PKT_ERROR -> CLOSE_WAIT_OURCOMMIT BITCOIN_ANCHOR_DEPTHOK -> OPEN_WAIT_FOR_COMPLETE_THEIRANCHOR (=>PKT_OPEN_COMPLETE) BITCOIN_ANCHOR_TIMEOUT -> ERR_ANCHOR_TIMEOUT (=>PKT_ERROR) BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM (=>PKT_ERROR) CMD_CLOSE -> WAIT_FOR_CLOSE_COMPLETE (=>PKT_CLOSE) OPEN_WAIT_FOR_COMPLETE_OURANCHOR: PKT_OPEN_COMPLETE -> NORMAL_HIGHPRIO PKT_CLOSE -> WAIT_FOR_CLOSE_ACK (=>PKT_CLOSE_COMPLETE) PKT_ERROR -> CLOSE_WAIT_OURCOMMIT BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM (=>PKT_ERROR) CMD_CLOSE -> WAIT_FOR_CLOSE_COMPLETE (=>PKT_CLOSE) OPEN_WAIT_FOR_COMPLETE_THEIRANCHOR: PKT_OPEN_COMPLETE -> NORMAL_LOWPRIO PKT_CLOSE -> WAIT_FOR_CLOSE_ACK (=>PKT_CLOSE_COMPLETE) PKT_ERROR -> CLOSE_WAIT_OURCOMMIT BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM (=>PKT_ERROR) CMD_CLOSE -> WAIT_FOR_CLOSE_COMPLETE (=>PKT_CLOSE) Operational state loop: ====================== I've folded high and low here, but we alternate. NORMAL_LOWPRIO: NORMAL_HIGHPRIO: PKT_UPDATE -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_ADD_HTLC -> NORMAL_HIGHPRIO (=>PKT_UPDATE_DECLINE_HTLC) PKT_UPDATE_ADD_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_COMPLETE_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_TIMEDOUT_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_ROUTEFAIL_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_CLOSE -> WAIT_FOR_CLOSE_ACK (=>PKT_CLOSE_COMPLETE) PKT_ERROR -> CLOSE_WAIT_OURCOMMIT BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM (=>PKT_ERROR) BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL (=>PKT_ERROR) CMD_SEND_UPDATE -> WAIT_FOR_UPDATE_ACCEPT_LOWPRIO (=>PKT_UPDATE) CMD_SEND_HTLC_UPDATE -> WAIT_FOR_HTLC_ACCEPT_LOWPRIO (=>PKT_UPDATE_ADD_HTLC) CMD_SEND_HTLC_COMPLETE -> WAIT_FOR_HTLC_ACCEPT_LOWPRIO (=>PKT_UPDATE_COMPLETE_HTLC) CMD_SEND_HTLC_TIMEDOUT -> WAIT_FOR_HTLC_ACCEPT_LOWPRIO (=>PKT_UPDATE_TIMEDOUT_HTLC) CMD_SEND_HTLC_ROUTEFAIL -> WAIT_FOR_HTLC_ACCEPT_LOWPRIO (=>PKT_UPDATE_ROUTEFAIL_HTLC) CMD_CLOSE -> WAIT_FOR_CLOSE_COMPLETE (=>PKT_CLOSE) WAIT_FOR_HTLC_ACCEPT_LOWPRIO: WAIT_FOR_HTLC_ACCEPT_HIGHPRIO: PKT_UPDATE -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_ADD_HTLC -> NORMAL_HIGHPRIO (=>PKT_UPDATE_DECLINE_HTLC) PKT_UPDATE_ADD_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_ACCEPT -> WAIT_FOR_UPDATE_COMPLETE_LOWPRIO (=>PKT_UPDATE_SIGNATURE) PKT_UPDATE_DECLINE_HTLC -> NORMAL_HIGHPRIO PKT_UPDATE_COMPLETE_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_TIMEDOUT_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_ROUTEFAIL_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_CLOSE -> WAIT_FOR_CLOSE_ACK (=>PKT_CLOSE_COMPLETE) PKT_ERROR -> CLOSE_WAIT_OURCOMMIT BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM (=>PKT_ERROR) BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL (=>PKT_ERROR) WAIT_FOR_HTLC_ACCEPT_HIGHPRIO: PKT_UPDATE_ACCEPT -> WAIT_FOR_UPDATE_COMPLETE_HIGHPRIO (=>PKT_UPDATE_SIGNATURE) PKT_UPDATE_DECLINE_HTLC -> NORMAL_LOWPRIO PKT_CLOSE -> WAIT_FOR_CLOSE_ACK (=>PKT_CLOSE_COMPLETE) PKT_ERROR -> CLOSE_WAIT_OURCOMMIT BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM (=>PKT_ERROR) BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL (=>PKT_ERROR) WAIT_FOR_UPDATE_ACCEPT_LOWPRIO: WAIT_FOR_UPDATE_ACCEPT_HIGHPRIO: PKT_UPDATE -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_ADD_HTLC -> NORMAL_HIGHPRIO (=>PKT_UPDATE_DECLINE_HTLC) PKT_UPDATE_ADD_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_ACCEPT -> WAIT_FOR_UPDATE_COMPLETE_LOWPRIO (=>PKT_UPDATE_SIGNATURE) PKT_UPDATE_COMPLETE_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_TIMEDOUT_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_UPDATE_ROUTEFAIL_HTLC -> WAIT_FOR_UPDATE_SIG_LOWPRIO (=>PKT_UPDATE_ACCEPT) PKT_CLOSE -> WAIT_FOR_CLOSE_ACK (=>PKT_CLOSE_COMPLETE) PKT_ERROR -> CLOSE_WAIT_OURCOMMIT BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM (=>PKT_ERROR) BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL (=>PKT_ERROR) WAIT_FOR_UPDATE_COMPLETE_LOWPRIO: WAIT_FOR_UPDATE_COMPLETE_HIGHPRIO: PKT_UPDATE_COMPLETE -> NORMAL_HIGHPRIO PKT_CLOSE -> WAIT_FOR_CLOSE_ACK (=>PKT_CLOSE_COMPLETE) PKT_ERROR -> CLOSE_WAIT_OURCOMMIT BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM (=>PKT_ERROR) BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL (=>PKT_ERROR) WAIT_FOR_UPDATE_SIG_LOWPRIO: PKT_UPDATE_SIGNATURE -> NORMAL_HIGHPRIO (=>PKT_UPDATE_COMPLETE) ... WAIT_FOR_UPDATE_SIG_HIGHPRIO: PKT_UPDATE_SIGNATURE -> NORMAL_LOWPRIO (=>PKT_UPDATE_COMPLETE) PKT_ERROR -> CLOSE_WAIT_OURCOMMIT BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM (=>PKT_ERROR) BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL (=>PKT_ERROR) CMD_CLOSE -> WAIT_FOR_CLOSE_COMPLETE (=>PKT_CLOSE) Normal closing: ============== WAIT_FOR_CLOSE_COMPLETE: PKT_CLOSE -> CLOSE_WAIT_CLOSE (=>PKT_CLOSE_ACK) PKT_CLOSE_COMPLETE -> CLOSE_WAIT_CLOSE (=>PKT_CLOSE_ACK) BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM_CLOSE BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_CLOSE BITCOIN_CLOSE_DONE -> CLOSED INPUT_CLOSE_COMPLETE_TIMEOUT -> CLOSE_WAIT_CLOSE_OURCOMMIT (=>PKT_ERROR) WAIT_FOR_CLOSE_ACK: PKT_CLOSE_ACK -> CLOSE_WAIT_CLOSE PKT_ERROR -> CLOSE_WAIT_CLOSE BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM_CLOSE BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_CLOSE BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_CLOSE: BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM_CLOSE BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_CLOSE BITCOIN_CLOSE_DONE -> CLOSED Weird close states ================== Eg. steal transction, unilateral close, combinations thereof: CLOSE_WAIT_STEAL: BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM BITCOIN_STEAL_DONE -> CLOSED CLOSE_WAIT_SPENDTHEM: BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM BITCOIN_SPEND_THEIRS_DONE -> CLOSED CLOSE_WAIT_STEAL_SPENDTHEM: BITCOIN_SPEND_THEIRS_DONE -> CLOSED BITCOIN_STEAL_DONE -> CLOSED CLOSE_WAIT_STEAL_CLOSE: BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE BITCOIN_STEAL_DONE -> CLOSED BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_SPENDTHEM_CLOSE: BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE BITCOIN_SPEND_THEIRS_DONE -> CLOSED BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE: BITCOIN_SPEND_THEIRS_DONE -> CLOSED BITCOIN_STEAL_DONE -> CLOSED BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_OURCOMMIT: BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED -> CLOSE_WAIT_SPENDOURS BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM_OURCOMMIT BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_OURCOMMIT CLOSE_WAIT_STEAL_OURCOMMIT: BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED -> CLOSE_WAIT_STEAL_SPENDOURS BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM_OURCOMMIT BITCOIN_STEAL_DONE -> CLOSED CLOSE_WAIT_SPENDTHEM_OURCOMMIT: BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED -> CLOSE_WAIT_SPENDTHEM_SPENDOURS BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM_OURCOMMIT BITCOIN_SPEND_THEIRS_DONE -> CLOSED CLOSE_WAIT_STEAL_SPENDTHEM_OURCOMMIT: BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED -> CLOSE_WAIT_STEAL_SPENDTHEM_SPENDOURS BITCOIN_SPEND_THEIRS_DONE -> CLOSED BITCOIN_STEAL_DONE -> CLOSED CLOSE_WAIT_CLOSE_OURCOMMIT: BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED -> CLOSE_WAIT_CLOSE_SPENDOURS BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM_CLOSE_OURCOMMIT BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_CLOSE_OURCOMMIT BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_STEAL_CLOSE_OURCOMMIT: BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED -> CLOSE_WAIT_STEAL_CLOSE_SPENDOURS BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_OURCOMMIT BITCOIN_STEAL_DONE -> CLOSED BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_SPENDTHEM_CLOSE_OURCOMMIT: BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED -> CLOSE_WAIT_SPENDTHEM_CLOSE_SPENDOURS BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_OURCOMMIT BITCOIN_SPEND_THEIRS_DONE -> CLOSED BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_OURCOMMIT: BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED -> CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_SPENDOURS BITCOIN_SPEND_THEIRS_DONE -> CLOSED BITCOIN_STEAL_DONE -> CLOSED BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_SPENDOURS: BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM_SPENDOURS BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_SPENDOURS BITCOIN_SPEND_OURS_DONE -> CLOSED CLOSE_WAIT_STEAL_SPENDOURS: BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM_SPENDOURS BITCOIN_SPEND_OURS_DONE -> CLOSED BITCOIN_STEAL_DONE -> CLOSED CLOSE_WAIT_SPENDTHEM_SPENDOURS: BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM_SPENDOURS BITCOIN_SPEND_THEIRS_DONE -> CLOSED BITCOIN_SPEND_OURS_DONE -> CLOSED CLOSE_WAIT_STEAL_SPENDTHEM_SPENDOURS: BITCOIN_SPEND_THEIRS_DONE -> CLOSED BITCOIN_SPEND_OURS_DONE -> CLOSED BITCOIN_STEAL_DONE -> CLOSED CLOSE_WAIT_CLOSE_SPENDOURS: BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_SPENDTHEM_CLOSE_SPENDOURS BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_CLOSE_SPENDOURS BITCOIN_SPEND_OURS_DONE -> CLOSED BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_STEAL_CLOSE_SPENDOURS: BITCOIN_ANCHOR_THEIRSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_SPENDOURS BITCOIN_SPEND_OURS_DONE -> CLOSED BITCOIN_STEAL_DONE -> CLOSED BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_SPENDTHEM_CLOSE_SPENDOURS: BITCOIN_ANCHOR_OTHERSPEND -> CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_SPENDOURS BITCOIN_SPEND_THEIRS_DONE -> CLOSED BITCOIN_SPEND_OURS_DONE -> CLOSED BITCOIN_CLOSE_DONE -> CLOSED CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_SPENDOURS: BITCOIN_SPEND_THEIRS_DONE -> CLOSED BITCOIN_SPEND_OURS_DONE -> CLOSED BITCOIN_STEAL_DONE -> CLOSED BITCOIN_CLOSE_DONE -> CLOSED