3333
3434 Withdrawn = fsm .StateType ("Withdrawn" )
3535
36+ LoopingIn = fsm .StateType ("LoopingIn" )
37+
38+ LoopedIn = fsm .StateType ("LoopedIn" )
39+
40+ SweepHtlcTimout = fsm .StateType ("SweepHtlcTimout" )
41+
42+ HtlcTimeoutSwept = fsm .StateType ("HtlcTimeoutSwept" )
43+
3644 PublishExpiredDeposit = fsm .StateType ("PublishExpiredDeposit" )
3745
3846 WaitForExpirySweep = fsm .StateType ("WaitForExpirySweep" )
@@ -44,13 +52,17 @@ var (
4452
4553// Events.
4654var (
47- OnStart = fsm .EventType ("OnStart" )
48- OnWithdrawInitiated = fsm .EventType ("OnWithdrawInitiated" )
49- OnWithdrawn = fsm .EventType ("OnWithdrawn" )
50- OnExpiry = fsm .EventType ("OnExpiry" )
51- OnExpiryPublished = fsm .EventType ("OnExpiryPublished" )
52- OnExpirySwept = fsm .EventType ("OnExpirySwept" )
53- OnRecover = fsm .EventType ("OnRecover" )
55+ OnStart = fsm .EventType ("OnStart" )
56+ OnWithdrawInitiated = fsm .EventType ("OnWithdrawInitiated" )
57+ OnWithdrawn = fsm .EventType ("OnWithdrawn" )
58+ OnLoopinInitiated = fsm .EventType ("OnLoopinInitiated" )
59+ OnSweepingHtlcTimout = fsm .EventType ("OnSweepingHtlcTimout" )
60+ OnHtlcTimeoutSwept = fsm .EventType ("OnHtlcTimeoutSwept" )
61+ OnLoopedIn = fsm .EventType ("OnLoopedIn" )
62+ OnExpiry = fsm .EventType ("OnExpiry" )
63+ OnExpiryPublished = fsm .EventType ("OnExpiryPublished" )
64+ OnExpirySwept = fsm .EventType ("OnExpirySwept" )
65+ OnRecover = fsm .EventType ("OnRecover" )
5466)
5567
5668// FSM is the state machine that handles the instant out.
@@ -169,6 +181,7 @@ func (f *FSM) DepositStatesV0() fsm.States {
169181 Transitions : fsm.Transitions {
170182 OnExpiry : PublishExpiredDeposit ,
171183 OnWithdrawInitiated : Withdrawing ,
184+ OnLoopinInitiated : LoopingIn ,
172185 OnRecover : Deposited ,
173186 },
174187 Action : fsm .NoOpAction ,
@@ -232,7 +245,57 @@ func (f *FSM) DepositStatesV0() fsm.States {
232245 Transitions : fsm.Transitions {
233246 OnExpiry : Expired ,
234247 },
235- Action : f .WithdrawnDepositAction ,
248+ Action : f .FinalizeDepositAction ,
249+ },
250+ LoopingIn : fsm.State {
251+ Transitions : fsm.Transitions {
252+ // This event is triggered when the loop in
253+ // payment has been received. We consider the
254+ // swap to be completed and transition to a
255+ // final state.
256+ OnLoopedIn : LoopedIn ,
257+
258+ // If the deposit expires while the loop in is
259+ // still pending, we publish the expiry sweep.
260+ OnExpiry : PublishExpiredDeposit ,
261+
262+ // We encounter this signal if the server
263+ // published the htlc tx without paying us. We
264+ // then need to monitor for the timeout path to
265+ // open up to sweep it.
266+ OnSweepingHtlcTimout : SweepHtlcTimout ,
267+
268+ OnLoopinInitiated : LoopingIn ,
269+
270+ OnRecover : LoopingIn ,
271+ fsm .OnError : Deposited ,
272+ },
273+ Action : fsm .NoOpAction ,
274+ },
275+ LoopedIn : fsm.State {
276+ Transitions : fsm.Transitions {
277+ OnExpiry : Expired ,
278+ },
279+ Action : f .FinalizeDepositAction ,
280+ },
281+ SweepHtlcTimout : fsm.State {
282+ Transitions : fsm.Transitions {
283+ OnHtlcTimeoutSwept : HtlcTimeoutSwept ,
284+ OnRecover : SweepHtlcTimout ,
285+ },
286+ Action : fsm .NoOpAction ,
287+ },
288+ HtlcTimeoutSwept : fsm.State {
289+ Transitions : fsm.Transitions {
290+ OnExpiry : HtlcTimeoutSwept ,
291+ },
292+ Action : f .FinalizeDepositAction ,
293+ },
294+ Withdrawn : fsm.State {
295+ Transitions : fsm.Transitions {
296+ OnExpiry : Expired ,
297+ },
298+ Action : f .FinalizeDepositAction ,
236299 },
237300 Failed : fsm.State {
238301 Transitions : fsm.Transitions {
@@ -257,14 +320,7 @@ func (f *FSM) updateDeposit(notification fsm.Notification) {
257320
258321 f .deposit .SetState (notification .NextState )
259322
260- // Don't update the deposit if we are in an initial state or if we
261- // are transitioning from an initial state to a failed state.
262- d := f .deposit
263- if d .IsInState (fsm .EmptyState ) || d .IsInState (Deposited ) ||
264- (notification .PreviousState == Deposited && d .IsInState (
265- Failed ,
266- )) {
267-
323+ if skipUpdate (notification , f .deposit ) {
268324 return
269325 }
270326
@@ -274,6 +330,23 @@ func (f *FSM) updateDeposit(notification fsm.Notification) {
274330 }
275331}
276332
333+ // Don't update the deposit if we are in an initial state or if we are
334+ // transitioning from an initial state to a failed state.
335+ func skipUpdate (notification fsm.Notification , d * Deposit ) bool {
336+ prevState := notification .PreviousState
337+ if d .IsInState (fsm .EmptyState ) || d .IsInState (Deposited ) &&
338+ prevState == fsm .EmptyState ||
339+ d .IsInState (prevState ) ||
340+ prevState == Deposited && d .IsInState (Deposited ) ||
341+ prevState == Deposited && d .IsInState (Failed ) ||
342+ prevState == LoopingIn && d .IsInState (LoopingIn ) {
343+
344+ return true
345+ }
346+
347+ return false
348+ }
349+
277350// Infof logs an info message with the deposit outpoint.
278351func (f * FSM ) Infof (format string , args ... interface {}) {
279352 log .Infof (
0 commit comments